sophie-router
TypeScript icon, indicating that this package has built-in type declarations

1.0.8-beta • Public • Published

Sophie Router

Provides simple components in order to have routing in your application. Ideal for single page applications where you need to handle the routing.

Part of the SPA framework Sophie

npm version npm dependencies npm downloads

INSTALLATION

yarn add sophie-router

USAGE

Basically consist of an Application class you need to extend from. This will be your shared state across different pages.

Then you need to instantiate Resource Routers and associate to them Resources the first ones will match a wildcard for a path while the second ones are the concrete resource to run for a matching path. For example we have an application that consists of the home page, and two other pages.

We need to handle the following paths:

  • /
  • /page1
  • /page2

So first we can create the ResourceRouter that will handle the root path

HomeResourceRouter.ts

import { AbstractResourceRouter } from 'sophie-router';

export const HOME_PATH = /^\/+$/g;

export class HomeResourceRouter extends AbstractResourceRouter
{
	protected canRoute (pathName: string): boolean
	{
		return !!pathName.match(HOME_PATH);
	}
}

Then the Resource

HomeResource.ts

import { AbstractApplication, AbstractResource } from 'sophie-router';

import { HOME_PATH } from './HomeResourceRouter';

export class HomeResource extends AbstractResource
{
	public getPath (): RegExp
	{
		return HOME_PATH;
	}

	public run (app: AbstractApplication, pathName?: string, search?: string): void
	{
		console.log('Run Homepage');
	}
}

The same for the other pages

PageResourceRouter.ts

import { AbstractResourceRouter } from 'sophie-router';

export const PAGE_PATH = /page\d?/g;

export class PageResourceRouter extends AbstractResourceRouter
{
    protected canRoute (pathName: string): boolean
    {
        return !!pathName.match(PAGE_PATH);
    }
}

Page1Resource.ts

import { AbstractApplication, AbstractResource } from 'sophie-router';

export class Page1Resource extends AbstractResource
{
	public getPath (): RegExp
	{
		return /page1/g;
	}

	public run (app: AbstractApplication, pathName?: string, search?: string): void
	{
		console.log('Run Page 1');
	}
}

Page2Resource.ts

import { AbstractApplication, AbstractResource } from 'sophie-router';

export class Page2Resource extends AbstractResource
{
    public getPath (): RegExp
    {
        return /page2/g;
    }

    public run (app: AbstractApplication, pathName?: string, search?: string): void
    {
        console.log('Run Page 2');
    }
}

Now we can create our Application, the one that we get in the run methods from the Resources

Application.ts

import { AbstractApplication } from 'sophie-router';

export class Application extends AbstractApplication
{
// Extend me ...
}

To finish we just need to create our index or entry point

index.ts

import {
	AbstractApplication,
    Framework,
    AbstractResourceRouter,
    AbstractResource
} from 'sophie-router';

import { Application } from './Application';
import { HomeResourceRouter } from './HomeResourceRouter';
import { PageResourceRouter } from './PageResourceRouter';
import { HomeResource } from './HomeResource';
import { Page1Resource } from './Page1Resource';
import { Page2Resource } from './Page2Resource';

// Instantiate objects
const application: AbstractApplication = new Application(); // Create our application
const framework: Framework = Framework.createInstance(application); // Create the framework that will handle the routing

// Create the resource routers
const homeResourceRouter: AbstractResourceRouter = new HomeResourceRouter();
const pageResourceRouter: AbstractResourceRouter = new PageResourceRouter();

// Create some resources for the routers
const homePage: AbstractResource = new HomeResource();
const page1: AbstractResource = new Page1Resource();
const page2: AbstractResource = new Page2Resource();

// Add resources to routers
homeResourceRouter.addResource(homePage);
pageResourceRouter.addResource(page1);
pageResourceRouter.addResource(page2);

// Register the routers in the framework
framework.registerResourceRouter(homeResourceRouter);
framework.registerResourceRouter(pageResourceRouter);

// Run the application
framework.run(location.pathname, location.search);

TIP: You need to handle the navigation in your application in order to have a SPA to avoid normal navigation and instead use the router, for that I recommend the following snippet

index.ts

// Add this to the imports
import { bubbleUpToTag } from "sophie-helpers";

// Add the next to the end of index.ts
const HTTP_PROTOCOL: string = 'http://';
const HTTPS_PROTOCOL: string = 'https://';
const MAIL_TO_PROTOCOL: string = 'mailto:';

document.addEventListener('click', (event) =>
{
    const link = bubbleUpToTag(event.target as HTMLElement || event.srcElement as HTMLElement, 'a');

    if (link)
    {
        const href = (link as HTMLLinkElement).getAttribute('href');
        if (
            href &&
            href.substr(0, HTTP_PROTOCOL.length) !== HTTP_PROTOCOL &&
            href.substr(0, HTTPS_PROTOCOL.length) !== HTTPS_PROTOCOL &&
            href.substr(0, MAIL_TO_PROTOCOL.length) !== MAIL_TO_PROTOCOL)
        {
            event.stopPropagation();
            event.preventDefault();

            history.pushState({}, '', href);

            framework.run(href);
        }
    }
});

window.onpopstate = () => {
    framework.run(location.pathname, location.search);
};

Changelog

Changelog

Contributing

contributions welcome

License

This software is licensed under the terms of the MIT license. See LICENSE for the full license.

Readme

Keywords

none

Package Sidebar

Install

npm i sophie-router

Weekly Downloads

2

Version

1.0.8-beta

License

MIT

Unpacked Size

137 kB

Total Files

32

Last publish

Collaborators

  • xtrimsystems