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 🙏

© 2026 – Pkg Stats / Ryan Hefner

ninjajs

v3.4.3

Published

frontend framework base on riot and redux

Readme

Like a ninja, Ninjajs dexterous and elegant, and its body full of magic weapons that simple but powerful. Ninjajs will help you to use the simple way to build complex systems. "Practical but not fancy" is its talisman.

Geting Started

Install

$ npm install ninjajs

Pay A Glance

$ npm run dev

http://localhost:8080

Usage

Startup

main.js

import App from 'path to xxx component'

let app = Ninja({container: window, reducer, middlewares, state: {}}) // container, reducer, middlewares, initialState

app.set('routes', routes)

app.start(async () => {
  // set entry for the application.
  app.set('entry', new App(document.getElementById('app')))
})

API

set(key, val)

  • key <String>

  • val <Any>

    buildin config - key -> value

    • env <Enum> application environment - production, development, test
    • mode <Enum> browser or history
    • context <Object> application context obj (store, tags, ...others)
    • routes <Object> expect a plain obj to describe the routes (more in below)
    • entry <Object> application entry component

registerWidget(options)

  • options.name <string>

  • options.methods <array>

    allow user to control component with method invocation.

    eg:

    app.registerWidget({ name: 'modal', methods: ['open'] })

start()

all ready callback

Component

Define component

@Componnet // register this component to hub, in order to use it in html directly.
export default class Todo extends Ninja.Component {

  get tmpl() {
    return require('path to template of component');
  }

  onCreate(opts) {}
}

State Management

redux like:

@Connect(
  state => ({
    ...states
  }),
  dispatch => ({
    ...actions
  })
)
export default class Todo extends Ninja.Component {}

Router

Define routes

import TodoList from '...path to component';

export default {
  component: App,
  path: '',
  children: [
    {
      path: '/',
      component: TodoList,
      defaultRoute: true
    }
  ]
}

Fields

| field | type | desc | | ------------- |:-------------:| :-----| | path         | string | Corresponding URI, Relative path | | component | Object | Component constructors | | children | Array | sub routes outlets | | defaultRoute | Boolean       | specify that this is a default route | | components   | Object       | dynamic route defined, get identifier from query string | | abstract   | Boolean     | specify that this is a abstract route, no Corresponding component | | ...others | Any | will be get from context.req.body |

Context

  1. req <Object>

| field | type | | -------- |:----------- | | params | Object     | | body | Object | | query | Object |

Router outlet in html

<div class="component">
  <div>greeting!</div>
  <router-outlet></router-outlet> <!-- sub routers will replace here  -->
</div>

Component life cycle about router

| evts | | ------------ | | enter         | | before-leave | | leave     | | leaved |

eg:

@View // this decorator specify that component will be a view, give the component relevant features
export default class Todo extends Ninja.Component {
  // ...others
  onCreate(opts) {
    this.on('enter', ctx => {
      // todo
    })
    this.on('before-leave', ctx => {
      // todo
    })
    this.on('leave', ctx => {
      // todo
    })
    this.on('leaved', ctx => {
      // todo
    })
  }
}
// Advanced Usage
class Foo extends Ninja.Component {
  // ...others
  
  // decorator onUse <Function>
  // @param <Array | String>, when nav to this component, the middlewares (defined in 'opts') will be invoke.
  //   each middleware method will be injected a callback ( component will be present when the callback invoked ) and a  
  //   router context object. 
  // eg: const enterFoo = (next, ctx)
  @onUse('enterFoo')
  onCreate(opts) {}
}

Route hooks

1. history-pending - callback(from, to, location, context[, next])

  • from <Object> from which Component
  • to <Object> to which Component
  • location <String> uri
  • context <Object> context object
    • req <Object> request object
      • params <Object>
      • body <Object>
      • query <Object>
  • next <Function> execution callback, if exists, the execution won`t be continue until next being executed

2. history-resolve - callback(from, to, context, routes, index[, next])

  • from <Object> from which Component
  • to <Object> to which Component
  • context <Object> context object
    • req <Object> request object
      • params <Object>
      • body <Object>
      • query <Object>
  • routes <Object> uris
  • index <Number> current index in uris
  • next <Function> execution callback, if exists, the execution won`t be continue until next being executed

eg:

app.hub.subscribe('history-pending', (from, to, location, context, next) => {})

app.hub.subscribe('history-resolve', (from, to, context, routes, index) => {})

Form

Buildin rules

  • required
  • max
  • min
  • maxlength
  • minlength
  • pattern

API

  • registerValidators(name, fn)
    • name <string>
    • fn <Function>

Register customer validators

Detail

  • Integrate with Redux A action will be dispatched when interact with inputs. You will get corrent value in state and opts. Attached to opts:

    • submit <Function> submit specific form manually.
    • forms <Object> forms map.
  • input fields & add class

    • field
      • $valid
      • $invalid
      • $dirty
      • $pristine
      • $error
      • $originVal
      • $val
    • class
      • f-valid
      • f-invalid
      • f-dirty
      • f-pristine
  • multi form validation supported

Example

@Form({
  username: {
    required: true,
    minlength: 2,
    maxlength: 20
  },
  password: {
    required: true,
    min: 1,
    max: 10
  },
  address: {
    pattern: /.*/
  }
})
class Foo extends Ninja.Component {
  // ...others
  async onSubmit() {
    e.preventDefault();
    this.opts.submit('FormA')   // submit specific form manually
    if (this.opts.forms.FormA.$invalid) {
      return;
    }
  }
}
<style>
  .f-valid {
    border: green
  }
  .f-invalid {
    border: red
  }
  .f-dirty {
  }
  .f-pristine {
  }
</style>
<form ref="FormA">
  <p if="{ opts.forms.FormA.$submitted && opts.forms.FormA.username.$error.required }" class="help-block" >username required! </p>
  <input type="text" ref="username">
</form>

Usage v2.* (Deprecated)

routes.js

export default {
  component: 'app',
  children: [
    {
      path: '/',
      defaultRoute: true,
      component: 'count',
    },
    {
      path: '/test',
      component: 'test',
      children: [
        {
          path: '/test2',
          component: 'test2'
        }
      ]
    }
  ]
}
//main.js
import { router Ninja } from 'ninjajs';

let app = new Ninja(container, reducer, middlewares, initialState);  // create ninja application

app.set('env', process.env.NODE_ENV === 'production' ? 'production' : 'development');

app.set('mode', 'browser');

app.set('context', { store: app.store, hub: router.hub, tags: {} });

router.hub.routes = routes;  // set routes

app.router(router);

app.start(async () => {
  //todo
})
//component

require('path-to-nest');

<app>
  <div>Hello World</div>
  <router-outlet></router-outlet>
  
  import { connect } from 'ninjajs';
  
  connect(              //redux like
    state => ({}),
    dispatch => ({})
  )(this)
  
  this.mixin('router');   // mixin router, if you wanna use middleware (the $use method)
  
  this.$use(function(next, ctx){
    //trigger when nav to this component
  })
</app>

Who's using

More

source for more detail

Contact

QQ: 2811786667