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

jskit

v5.1.4

Published

A simple answer to jQuery soup

Downloads

143

Readme

JSkit

npm version

JSkit is a tiny library to end the problem of jQuery soup and $(document).ready() mess. JSkit introduces a simple, clean, and easily testable way to architect basic javascript enhanced web pages. Based on a simple event system, JSkit allows your back-end application to seamlessly integrate your javacsript code with minimal coupling.

Table of Contents

  1. Installation
  2. Basic Usage
  3. Dispatcher
  4. Controllers
  5. Testing
  6. Contributing

Installation

Using NPM

JSkit can be install using npm

npm install jskit

Or add it to your package.json:

"jskit": "^5.0.0",

Manual Install

  • Download the latest version
  • Include Script
    • include the jskit.js file in your application
<script type="text/javascript" src="path/to/jskit.js"></script>

Dependencies

Make sure that the dependencies are included and available globally.

<script type="text/javascript" src="path/to/lodash.js"></script>
<script type="text/javascript" src="path/to/jquery.js"></script>

-- or --

<script type="text/javascript" src="path/to/underscore.js"></script>
<script type="text/javascript" src="path/to/zepto.js"></script>

Basic Usage

Application

A JSkit.Application object serves as the interface to your JSkit components. To create an application you simply call JSkit.Application.create():

var App = JSkit.Application.create();

Dispatcher

Every application has a Dispatcher that allows you to register and trigger events throughout your JSkit application. In fact, JSkit is basically a thin wrapper around the Dispatcher that allows you to coordinate your javascript with minimal friction.

App.Dispatcher.on("some-event-name", function() {
    // handle some-event-name
});

App.Dispatcher.trigger("some-event-name");

Generally you will not have to manually register for events (App.Dispatcher.on) since JSkit Controllers register their own actions automatically.

Creating Controllers

The basic component of a JSkit application is a Controller. Controllers are basically objects that map events to methods (actions). To create a controller, call createController:

App.createController("Posts", {
  actions: ["index", "show", "new", "edit"],

  index: function() {
    // handle index action
  },

  show: function() {
    // handle show action
  }

  new: function() {
    // handle new action
  }

  edit: function() {
    // handle edit action
  }
})

When the Application creates a controller, it handles passing the Application's dispatcher to the Controller, creating the Controller's factory, and creating a controller on the Application's Controllers object.

Controller objects are stored in Application.Controllers by name. Looking at the "Posts" controller example above we know that there is a Posts Controller object at App.Controllers.Posts.

Controller factories are functions on the Application object itself with the suffix "Controller". These factories are useful in testing to create fresh copies of the controller object for testing. Given the example above there would be a Posts controller factory at App.PostsController

To create a Posts controller object, simply call create:

var testPostsController = App.PostsController.create();

The App.Controllers.Posts object is what the Application will use at runtime. The App.PostsController factory is simply a convenience for creating clean states for testing.

Controllers

Actions

Actions define events to which your controller responds. The Controller uses the actions array to map its methods to the Dispatcher's events. Actions are automatically mapped to the Dispatcher when the Controller is created. There are two ways to define an action mapping:

Named Actions

To map an action by name, simply provide the method name as a string in the actions array:

App.createController("Posts", {
  actions: ["foo"],

  foo: function() {
    // handle "controller:posts:foo" event
  }
});

Mapped Actions

Sometimes you may want to map an action to a specific method, or you may want to bind two actions to the same method, to do so simply provide an object keyed by the action name with value of the method name:

App.createController("Posts", {
  actions: [{
    new: "setupForm",
    edit: "setupForm"
  }],

  setupForm: function() {
    // handle "controller:posts:new" and "controller:posts:edit" events
  }
});

Action Mapping

When an action is mapped, it will be registered on the dispatcher for a specific event. The event that is registered depends on a few properties of the Controller which are: namespace, channel, name, and action. The default values for these are:

namespace = ""
channel = "controller"
controllerEventName = "{Controller.name}" (lowercase and underscored)
action = "{action}"
eventSeperator = ":"

So using the above examples, the event maps for the PostsController are:

controller:posts:foo  -> Controller.foo
controller:posts:new  -> Controller.setupForm
controller:posts:edit -> Controller.setupForm

Note: undefined/empty values effectively removes that segment from the event name

namespace

By default, Controller's have an empty namespace. If you wish to prefix the events with a namespace, set this property:

App.createController("Posts", {
  namespace: "admin"
  ...
});

This will register all events with the namespace prefix:

admin:controller:posts:foo  -> Controller.foo
admin:controller:posts:new  -> Controller.setupForm
admin:controller:posts:edit -> Controller.setupForm

channel

The default channel for a Controller is controller. To change this simply set the channel:

App.createController("Posts", {
  channel: "pages"
  ...
});

This will register all events with the channel:

pages:posts:foo  -> Controller.foo
pages:posts:new  -> Controller.setupForm
pages:posts:edit -> Controller.setupForm

controller event name

The Controller is given a name property by the Application.createController(name, attributes) method. The controller event name is automatically created by lowercasing and underscoring the name to normalize event names. The PostsController example has the name "Posts" and a controller event name` of "posts". CamelCased names will have underscores between each uppercased word:

App.createController("CamelCase", {...});

This would register all events with the controller controller event name of camel_case:

controller:camel_case:action -> Controller.action

eventSeparator

The eventSeparator property defines how the namespace, channel, name, and action will be joined to create an event name. You can change this by setting the eventSeparator on the Controller:

App.createController("Posts", {
  eventSeparator: "."
  ...
});

This would register all events using "." as a separator:

controller.posts.foo  -> Controller.foo
controller.posts.new  -> Controller.setupForm
controller.posts.edit -> Controller.edit

The all event

Every controller has an automatically wired all action. Other than being automatically wired, it is a simple action->event map like any other:

controller:posts:all -> Controller.all

Testing

JSkit is all about making testing javascript easier. When you create a controller with the Application.createController method. The created Controller's factory will be available on the Application object. Using the "Posts" controller example:

App.PostsController.create();

ALWAYS use the provided factories when testing your Controllers to ensure you don't pollute your tests with mutated state.

Contributing

  1. Fork it
  2. Clone it locally
  3. Set the upstream remote (git remote add upstream [email protected]:daytonn/jskit.git)
  4. Install the dependencies with npm (npm install)
  5. Run the specs with npm test
  6. Create your feature branch (git checkout -b my-new-feature)
  7. Commit your changes (git commit -am 'Add some feature')
  8. Ensure remote is updated (git remote update)
  9. Rebase from upstream (git rebase upstream/master)
  10. Push to the branch (git push origin my-new-feature)
  11. Create new Pull Request