npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

spine-router

v1.2.1

Published

Routing system for SPA

Downloads

6

Readme

spine-router

import {Router} from 'spine-router';

import {bundleLoader} from 'spine-router/src/middlewares/bundleLoader.js';
import {resourceLoader} from 'spine-router/src/middlewares/resourceLoader.js';
import {applicationLoader} from 'spine-router/src/middlewares/applicationLoader.js';
import {basicLayout} from 'spine-router/src/middlewares/basicLayout.js';
import {basicRender} from 'spine-router/src/middlewares/basicRender.js';

let router = new Router({
    routes: {
        'user[/:login]': 'user',
        'page:/:id': 'page',
        '': 'home'
    }
});

Routing system for SPA. This router is based on Backbone.Router and works like wrapper on it. Works great with marionette.js.

How it works

You can extend router by adding middlewares to it similar to connect. Each middleware will be consequentially executed according to labels. Each middleware can be labeled (optionally). Labels can be as follows:

  • When route is adding to router.
  • When route is changing.
  • When router caches error in any of middlewares above.

You can add function to chain as follows:

var middlewareFactory = function () {
    return function (event) {
        // middleware logic, function will be called for ALL labels
    }
};

router.use(middlewareFactory);

If you need specific labels:

var middlewareFactory = function () {
    return [{
        label: MATCHED_LABEL,
        handler: function (event) {
            // middleware logic, function will be called for MATCHED_LABEL only
        }
    }, {
        label: REGISTERED_LABEL,
        handler: function (event) {
            // middleware logic, function will be called for REGISTERED_LABEL only
        }
    }, {
        label: ERROR_LABEL,
        handler: function (event, errObj) {
            // middleware logic, function will be called for ERROR_LABEL only
        }
    }]
};

router.use(middlewareFactory);

Context of function is router instance itself. Middleware functions are not required to return anything. If function returns value other than false or Promise, it will be ignored.

To break middleware chain you need to return rejected Promise. In this case chain labeled as ERROR_LABEL will be executed with corresponding error. If you need to break chain silently, you can return false as middleware result.

Router event object

In each middleware you will receive event object. This object works as mediator between middlewares and can be extended. It will be passed as first argument to middleware function.

Event object properties:

| Name | Description | |:------------------------- |:----------------------------------------------------------------------------------------- | | name | Route name | | label | Event label, when middleware was called "matched|registered|error" | | route | Route template "test/:id/:name" | | routeParams | Hash object with route properties | | routeParams.paramNames | Array with parameter names ["id", "name"]. Will be available at route registration | | routeParams.urlTemplate | Route template ("test/:id/:name"). Will be available at route registration | | routeParams.params | Hash with actual route parameters (parsed). Will be available at route match | | bundles | (optional) Loaded bundles. Result of work of bundleLoader middleware | | resources | (optional) Loaded resources. Result of work of resourcesLoader middleware | | views | (optional) Loaded view. Result of work of basicLayout middleware |

Basic middlewares description

routeParamsFactory (cannot be disabled, works as default)

This middleware is parsing route and extracts its params. After each route match params will be updated accordingly. For example, for route template test/:id/:name and route test/1/hi params will be following:

routeParams: {
    paramNames: ['id', 'name'],
    urlTemplate: 'test/:id/:name',
    params: {
        id: '1',
        name: 'hi'
    }
}

reverseFactory (cannot be disabled, works as default)

Extends router adding to it methods:

  • reverse reverses back router by specifying route name and its params
  • buildUrl builds url by specifying url and query (will be encoded) test?param=one
  • buildQuery builds query by specifying query hash object (will be encoded) param=one

bundleLoader

Loads bundles, works with Webpack

import {bundleLoader} from 'spine-router/src/middlewares/bundleLoader.js';

router.use(bundleLoader.factory({
    // BaseLayout, HomeLayout, etc. will be found in the folder `views`
    Layout: require.context('bundle!./views/', true, /Layout.js$/),
    
    // BaseApplication, HomeApplication, etc. will be found in the folder `application`
    Application: require.context('bundle!./applications/', true, /Application.js$/)
}));

For each route the following will be done:

  1. Name will be transformed to CamelCase: home -> Home, user:page -> UserPage
  2. To this name bundle prefix will be added: Layout -> HomeLayout, UserPageLayout
  3. Search for file with the result name: home -> ./views/home/HomeLayout.js, user:page -> ./views/user/page/or/some/another/long/path/UserPageLayout.js
  4. Load bundles
  5. Bundles will be available at event.bundles[resourceName]

If bundle cannot be found, it will just be ignored without throwing an error

resourceLoader

Loads resourses and puts it to event.resources. What and how to load can be described in provider property. In this provider property should be defined functions that are returning ES6 promises.

import {resourceLoader} from 'spine-router/src/middlewares/resourceLoader.js';

let resources = {

    /**
     * @returns {Promise<User>}
     */
    user(event) {
        return User.fetchCurrentUser();
    },
    
    /**
     * @returns {Promise<i18next>}
     */
    translate(event) {
        return translate.init();
    },
    
    homeApplication(event) {
        ...
    }

};

router.use(resourceLoader.factory({
    provider: resources,
    mappings: {
        // Loads for each route
        defaults: ['user', 'translate'], 
        
        // Only for route with name `home`
        home: {
            model: 'homeApplication' 
        },
        
        // You can pass array, returns hash {homeApplication: *}
        user: ['homeApplication']
        
    }
}));

applicationLoader

Builds application through factory. Factory will be expected in event.bundles[applicationBundle].factory. Result will be put in event.resources[resourceKey]. Factory will receive event object as first argument.

bundleLoader middleware required in order to work.

import {applicationLoader} from 'spine-router/src/middlewares/applicationLoader.js';

router.use(applicationLoader);

// or

router.use(applicationLoader.factory({
    applicationBundle: 'Application', // default
    resourcesKey: 'model' // default
}));

basicLayout

Creates Layout from event.bundles[layoutBundle] with parameters from event.resources. Puts result in event.views[layoutName].

bundleLoader and resourceLoader or applicationLoader middlewares required in order to work.

import {basicLayout} from 'spine-router/src/middlewares/basicLayout.js';

router.use(basicLayout);
// or
router.use(basicLayout.factory({
    layoutBundle: 'Layout',  // default
    layoutName: 'layout'  // default
}));

basicRender

Inserts view to region

basicLayout middleware required in order to work.

import {basicRender} from 'spine-router/src/middlewares/basicRender.js';

router.use(basicRender.factory({
    region: new Marionette.Region({el: '#content'}),
    layoutName: 'layout' // default
}));

defaultErrorHandler

Caches errors and logs to console

import {defaultErrorHandler} from 'spine-router/src/middlewares/defaultErrorHandler.js';

router.use(defaultErrorHandler);

ES5 version

ES5 version (minified too) can be found at the folder dist. Requires dependencies from jquery, lodash, backbone.