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

jasine

v0.1.12

Published

HTTP(S) server router with JSIN support

Downloads

14

Readme

Jasine

Router for Node.js's HTTP(S) server, calls JS controller and JSIN template using URL.

Basic

Install:

$ npm install jasine

Start test server (examples in node_modules/jasine/test directory):

$ npm test jasine

To stop test server use Ctrl+C.

Live example, where I'm using and testing Jasine server at the moment: kawaiinyan.com.

Start server:

$ node node_modules/jasine/server config.json

Stop server:

$ node node_modules/jasine/server config.json stop

Graceful reload server:

$ node node_modules/jasine/server config.json reload

Kill server:

$ node node_modules/jasine/server config.json kill

Default config:

{
    // Server settings
    "protocol":         "http", // http or https
    "host":             "localhost",
    "port":             8008,
    "socket":           null, // UNIX socket instead of host and port
    "workers":          null, // Default: count of CPUs
    "group":            null, // Default: nobody. Works under root only.
    "user":             null, // Default: nobody. Works under root only.
    "daemon":           false, // In most cases you should set it to TRUE, don't forget to set "pid" and "log" also
    "pid":              null, // Required for stop, reload and kill commands
    "log":              null,
    "logError":         null, // Default: same as "log"

    // Router settings
    "logLevel":         "info", // debug, info, warn, error
    "init":             null, // Module required before server starts (main application module)
    "error":            __dirname + "/public/", // Universal controller for all errors
    // Use errorXXX for specified error code.
    // Example: "error404": "/path/to/error404" will look for /path/to/error404.js and/or /path/to/error404.jsin.
    "dirRoot":          __dirname, // Should be overridden
    "dirPublic":        "public", // Where controllers and templates located
    "dirStatic":        "static", // Where static files located
    "uriStatic":        "/static/", // URL prefix for static files
    "mimeDefault":      "text/html",
    "mimeJSON":         "text/json",
    "charset":          "utf-8"
}

Server side

When you open any URL, Jasine first looks for .js file with same path in public directory:

http://localhost:8008/boo  -> public/boo.js
http://localhost:8008/boo/ -> public/boo/index.js
http://localhost:8008/     -> public/index.js

This .js file should be node module exporting one function:

module.exports = function(request, response, callback) {
    if (1 !== 1) {
        callback(new Error("Something went wrong: 1 !== 1"));
    } else {
        callback(null, {
            boo: "booooo",
            foo: "fooooo"
        });
    }
};

You can pass HTTP error code (404, 403, etc) to first argument of this function, or just throw this code.

callback(404);
// or
throw 404;

Also you can set statusCode of response:

response.statusCode = 404;

Data object, passed in callback, will be passed to JSIN template at same file path, but .jsin extension.

You can override template using property template of data object:

callback(null, {
    template: "overrided_template", // instead of URI + .jsin
    boo: "booooo",
    foo: "fooooo"
});

If .js file was not found at requested path in public dir, next, Jasine will try to load index module in same directory and call exported method with name equal to basename of URL.

For example URL http://localhost:8008/boo: if module public/boo.js not found, Jasine will try to call method boo of module public/index.js:

// public/index.js
module.exports.index = function(request, response, callback) {...}
module.exports.boo = function(request, response, callback) {...}

If method was not found, next, Jasine will look for router method in index module and call this method with basename of URL as additional argument.

For example URL http://localhost:8008/boo: if module public/boo.js not found, method boo in public/index.js not found also, Jasine will try to call method router of module public/index.js:

// public/index.js
module.exports.router = function(request, response, basename, callback) {
    // basename == 'boo'
    ...
}

If method was not found, next, Jasine will look for .jsin file at same path (public/boo.jsin), and call it without data.

If you open URL ending with .json extension, Jasine will look for .js module or appropriate method in the same way as explained above, and response generated data as JSON, without using JSIN template.

http://localhost:8008/boo.json -> public/boo.js or method boo in public/index.js

Client side

To make AJAX requests, include compiled JSIN templates and client side script jasine.js on html page. Call jasine.init at the end of body, or in window onload handler.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Test</title>
    </head>
    <body>

        <?js contents() ?>

        <script src="/static/jsin.compiled.js"></script>
        <script src="/static/jasine.js"></script>
        <script>
            jasine.init();
        </script>
    </body>
</html>

By default all AJAX requests attached to body element and excludes layout with name layout. You can set defaults, passing object with element and excludeLayout properties as argument to jasine.init method. URI for static files (by default /static/) ignored by Jasine, you can change default using property uriStatic.

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Test</title>
    </head>
    <body>

        <div id="my-main-content">
            <?js contents() ?>
        </div>

        <script src="/static/jsin.compiled.js"></script>
        <script src="/static/jasine.js"></script>
        <script>
            jasine.init({
                element: "#my-main-content",
                excludeLayout: [
                    "myMainLayout",
                    "layouts/additionalMainLayout"
                ],
                uriStatic: "/my_static/"
            });
        </script>
    </body>
</html>

Init method adds onclick handler to all a with href starting with / and any elements with data-href attribute starting with /. The handler will add .json extension to URL and make XMLHttpRequest. Resulting HTML will be generated using JSON response and pre-compiled JSIN templates. Generated HTML will replace inner contents of an element: body by default, or element defined in init method, or element defined in data-element attribute. You can specify element selector "by id" in href attribute, if actual link specified in data-href attribute. Also, data-href attribute has priority over href attribute of a element. In addition, you can specify comma-separated list of layout names to exclude in data-exclude-layout attribute.

<a href="/mypage">
    Will load contents of "/mypage"
    to body or default element
    using "/mypage.json"
</a>

<a href="/mypage2" data-exclude-layout="MyPage2Layout, MyPage2Layout2">
    Will load contents of "/mypage2"
    to body or default element
    using "/mypage2.json"
    excluding layout "MyPage2Layout" and "MyPage2Layout2" while rendering
</a>

<a href="/mypage" data-href="/mypage-priority">
    Will load contents of "/mypage-priority"
    to body or default element
    using "/mypage-priority.json"
</a>

<div id="my-block">
    <a href="/ajax/myblock?boo=123" data-element="#my-block">
        Will load contents of "/ajax/myblock?boo=123"
        to div with id "my-block"
        using "/ajax/myblock.json?boo=123"
    </a>
</div>

<div id="another-block">
    <a href="#another-block" data-href="/ajax/anotherblock">
        Will load contents of "/ajax/anotherblock"
        to div with id "another-block"
        using "/ajax/anotherblock.json"
    </a>
</div>

Clicking a with href starting with / will change history state for "back" button in browser. Clicking elements without href or href starting with # will not change history state. Method jasine.init adds popstate event listener of window to handle history "back" and "forward".

AJAX forms works in same manner as links, but with action and data-action attributes instead of href and data-href. AJAX forms supports next enctype: application/x-www-form-urlencoded, multipart/form-data (with file upload support) and text/json. Forms with method get will change history state if action starts with /. Forms with method post or action starting with # will not change history state.

You can make AJAX request using method jasine.load. This method has one argument - options object:

jasine.load({
    url: '/any_url', // same as "href" or "action"
    dataUrl: '/any_url', // same as "data-href" or "data-action"
    element: '#any-element', // same as "data-element"
    excludeLayout: 'layoutToExclude', // array or string: layouts to exclude, same as "data-exclude-layout"
    post: 'post data', // post data
    postType: 'mime/type', // mime type of post data
    onelementbeforeload: function(event){}, // event listener for "elementbeforeload"
    onelementload: function(event){}, // event listener for "elementload"
    onelementafterload: function(event){} // event listener for "elementafterload"
});

Jasine AJAX requests has three events:

  • elementbeforeload - fires before request.
  • elementload - fires after response received and before HTML and history were changed.
  • elementafterload - fires after response received and HTML and history were changed.

These events has additional properties:

  • options - Jasine options of request.
  • request - current XMLHttpRequest.
  • data - received JSON.
  • error - error occurred during request.

License

Copyright © 2014 Maksim Krylosov [email protected]

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.