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

halo-mvc

v1.3.1

Published

Mediator based client-side MVC framework heavily inspired by Addy Osmani's talks on Aura.

Downloads

12

Readme

Halo

Client-side MVC framework based on Addy Osmani's Aura.

Getting Started

Download the production version or the development version.

In your web page:

<script src="dist/Halo.js"></script>
<script>
// Define a controller. Each controller has its start/stop methods proxied via Sauron, a global mediator.
define('controllers/main', ['jquery', 'mvc!c/HtmlController'], function ($, HtmlController) {
  var params = {
    // Name of the controller -- this acts as the channel for Sauron
    'name': 'main',
    // Start method to call -- invoked via Sauron.controller('main').start(args);
    'start': function (data, cb) {
      // Generate and callback with some content $("<div>hello world</div>")
      var $content = $('<div>' + data + '</div>');
      cb($content);
    }
  };
  return HtmlController(params);
});

// Require Sauron and our controller
require(['Sauron', 'controllers/main'], function (Sauron) {
  // Start the controller and render $content to $main
  var $main = $('body');

  // These are the (data, cb) passed to the 'start' defined above via Sauron, our global mediator.
  // The first parameter is stripped and used as the container for the called-back $content
  Sauron.controller('main').start($main, 'hello world', function () {
    // The callback is wrapped such that $content is automatically appended to $main
    $main.html(); // "<div>hello world</div>"
  });
});
</script>

There are also a bunch of framework-specific libraries to make your life easier. Continue reading Documentation to find our more.

Documentation

Halo comes packaged with require.js and jquery as well as a bunch of MVC nicities.

Each script is namespaced within require.js to its own filename (except for require.js).

External libraries

| File | Require.js namespace | Description | |-------------------------|----------------------|--------------------------------------------------------------------------------------| | require.js | N/A | AMD loader which exposes require and define globally. | | jquery.js | jquery | One does not simply describe jQuery. | | socket.io | socket.io | Cross-browser WebSocket implementation. | | Sauron | Sauron | Mediator which provides a channel system for talking between models and controllers. | | Builder | Builder | Build chain for client-side MVC views. You will <3 me later. |

Framework-specific libraries

mvc

mvc is a require.js plugin which allows for easy routing to your models, views, and controllers. For example,

require(['mvc!m/user']); // is equivalent to require(['models/user.js']);
require(['mvc!v/main']); // is equivalent to require(['text!views/main.html']);
require(['mvc!c/home']); // is equivalent to require(['controllers/home.js']);

// Coming soon!
require(['mvc!c/main!c/home!m/user']); // is equivalent to...
// require(['controllers/main.js', 'controllers/home.js', 'models/user']);

mvc is configured via require.js' configuration.

require.config({
  'paths': {
    _modelDir: 'path/to/models', // Default: 'models'
    _modelExt: '.modelExtension', // Default: '.js'
    _controllerDir: 'path/to/controllers', // Default: 'controllers'
    _controllerExt: '.controllerExtension', // Default: '.js'
    _viewDir: 'path/to/views', // Default: 'views'
    _viewExt: '.viewExtension', // Default: '.html'
  }
});

URLs are constructed via directory + '/' + module + extension.

Models

Halo comes with two model templates for usage: CrudModel and SocketModel.

CrudModel provides the memory mixin and Sauron hooks for create, retrieve, update, and delete.

SocketModel extends on top CrudModel by adding a socket.io to all methods, this.socket, as well as Sauron hooks for createEvent, updateEvent, and deleteEvent which are intended to handle server push events.

More information on CrudModel, SocketModel, and their mixins/methods can be found in [docs/models.md][docModels].

Controllers

There are two controller templates available: BaseController and HtmlController.

BaseController does not provide any mixins by default and binds start and stop to Sauron listeners.

HtmlController wraps BaseController and proxies start and stop to append and remove generated content respectively.

Detailed explanations of BaseController, HtmlController, and their behaviors can be found in docs/controllers.md.

Views

We have tried to stay as true to the thought

A view is markup and interactive logic

as much as possible.

As a result, we built tools like Builder and jqueryp to make all of your interactive set up a breeze.

Further documentation can be can be found in docs/views.md

Examples

Full stack

// index.html
<script>
  // Configure everything and kick-off the index controller
  require(['config'], function () {
    require(['Sauron', 'mvc!c/index'], function () {
      Sauron.controller('index').start(document.body, function () {
        // document.body will either display an error message about failing to load user
        // or it will display the user's name and email
      });
    });
  })
</script>

// config.js
// Load in Builder, jade, and all jQuery plugins
define(['Builder', 'jade', 'jqueryp!bootstrap!timpicker'], function (Builder, jade, $) {
  // Set jade as the template engine
  Builder.set('template engine', jade.render);

  // Add in all jQuery plugins (Builder.jquery specific)
  Builder.addPlugin('tooltip');
  Builder.addPlugin({'module': 'timepicker', 'selector': '.bootstrap-timepicker'});

  // Return an empty config
  return {};
});

// views/index.jade
.container
  if (err)
    p An error occurred. =(
  else
    h1 User info
    .row
      .span6 Name: #{user.name}
      .span6 Email: #{user.email}

// controllers/index.js
define(['Sauron', 'Builder', 'HtmlController', 'mvc!v/index.jade', 'mvc!m/user'],
  function (Sauron, Builder, HtmlController, template) {

  // Create and return our HtmlController
  return HtmlController({
    'name': 'index',
    'start': function (cb) {
      // Grab user info
      Sauron.model('user').retrieve({'id': 1}, function (err, user) {
        // Create data to render with
        var data = {'err': err, 'user': user};

        // Render the content and callback
        var $html = Builder(template, data);
        cb($html);
      });
  });
});

// models/user.js
define(['SocketModel'], function (SocketModel) {
  // Forward all socket.io calls to server
  return SocketModel({
    'name': 'user',
    'mixin': 'autoCRUD'
  });
});

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using grunt.

Also, please don't edit files in the "dist" or "stage" subdirectories as they are generated via grunt. You'll find source code in the "src" subdirectory!

PhantomJS

While grunt can run the included unit tests via PhantomJS, this shouldn't be considered a substitute for the real thing. Please be sure to test the test/*.html unit test file(s) in actual browsers.

See the Why does grunt complain that PhantomJS isn't installed? guide in the Grunt FAQ for help with installing or troubleshooting PhantomJS.

License

Copyright (c) 2013 Ensighten Licensed under the MIT license.