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

winjsrocks

v0.6.15

Published

WinJS-based MVVM architecture for cross-platform apps

Downloads

162

Readme

logo

An ES6 MVVM framework optimized for WinJS

Dependency Status Build Status Download Status Build Status devDependency Status

Built to support amazing app developers targetting:

  • Windows 10
  • Windows 8/8.1
  • XboxOne
  • Windows Phone 10
  • Android
  • iOS
  • FireTV
  • Playstation 3/4/tv
  • Web

Featuring the Commandments of great code:

  • View, ViewModel, Model coordination
  • Message based Communication
  • Navigation Framework
  • Command Pattern
  • Event/Dispatch Pattern
  • Providers
  • Services
  • Plugins
  • Domain model indexing with Lokijs

See Technical Documentation for APIs


Why WinJS?

WinJS is a visual framwork that really considers a few important factors that other frameworks fall short on:

  • Input Modalities - Given a world of accelerating device fragmentation, people interact with UI's from a variety of input patterns. WinJS is built with the exectation that elements should automatically support Mouse, Keyboard, Gesture, Remote and Controller interaction patterns seamlessly. This support is not a weak accessibility-focused implementation, but one that actually attempts to provide core persona support for each input type.
  • Command/Property Binding - WinJS supports a variety of markup-driven binding styles that allows developers to avoid common pitfalls with Javascript memory management. This allows clear seperation of concerns when diagnosing memory performant creative View development. Many frameworks don't do this and seem to encourage Views, Models and Controllers to all be directly bound to the DOM, leaving the advanced topic of Javascript Memory Profiling
  • Dynamic View Resolve - Views can be either packaged in the app, fetched from a CDN or remotely generated via Web API. This allows application developers to use the tools that work for creative View development while still offering the advantages of dynamic server-side generation of artifacts.
  • Localization - Views can use localized strings to bind declaratively and developers can support a wide range of localization sets

WinJS is a future-facing UI Framework that really is designed to allow your Information Architecture to adapt to Desktop, Console, Mobile and Web without having to frankenstein your development architecture.

Sample Apps

Project Setup

Install Packages

Install the framework and the current WinJS bits:

npm install winjs --save
npm install winjsrocks --save

Note: Though WinJSRocks is tested against a specific version (latest verified) of the WinJS library, the distribution does not package these bits. So, "Bring your own WinJS" and "Millage may vary" if not the same version tested with WinJSRocks.

Optionally, install the maintained pluglin library WinJSRocks-Extras. This project includes cool plugins like IndexDB Storage, JQuery Adapters and shows really good examples of how to write your own application plugins.

npm install winsrocks-extras --save

Load WinJS

Application developers are required to pre-load WinJS before attempting run of the library.

var WinJS = require('winjs');
var WinJSRocks = require('winjsrocks');

Create Application Instance

Create a version of the Application object:

var WinJSRocks = require('winjsrocks');
var app = new WinJSRocks.Application();

Once the application is instatiated, access is available as a singleton:

var app = WinJSRocks.Application.Instance;

The Application Object

The Application object has three important phases that need to be implemented for an application:

  • configure - Allows plugin registration and generally is the best place to build up the container with Services and Providers.
var app = new WinJSRocks.Application();
var CustomProvider = require('providers/customProvider');
var CustomService = require('services/customService');
var CustomPlugin = require('plugins/customPlugin');
app.configure({
    plugins: [
      CustomPlugin
    ]
  }, function(err){
    if(err)
      console.error(err);
    // Load up the container with goodies
    app.container.registerProvider("customProvider", CustomProvider);
    app.container.registerService("customService", CustomService);
  });
app.load({},
  function(err){
    if(err)
      console.error(err);

    // Application has loaded and ready for use

    // Suggestion: Inject the Message Service and navigate to a view
    // see [Building Views](#building-views)
    var MessageService = app.container.getService('message');
    MessageService.send("navigateToMessage", {
      viewKey: "landing"
    });
  });
  • unload - Stops Services and unloads all known components.
app.unload({},
  function(err){
    if(err)
      console.error(err);

    // All components have been notified of the shutdown
  });

Building Views

The WinJSRocks MVVM framework provides the View/ViewModel sequencing to enable the fastest possible asynchronous load behavior for application developers.

This is achieved by using a NavigationService to instantiate ViewModels at the same time as their respective View, kicking off the ViewModel's load life-cycle before WinJS starts up the native page life-cycle.

Then, the View is allowed to render while the native WinJS Page ready method is suspended until the ViewModel has fully loaded initially.

In result, application developers can rely on the native WinJS Page ready method to fire after the View Template is fully rendered, the ViewModel has loaded up principle Models and the initial *.processAll() phases have completed on the visual tree.

sequence-navigation

ViewKey Registration

The framework provides the WinJSRocks.Application.Instance.builder API to aid in view/item registrations around a single ViewKey.

Example of registering views:

var app = new WinJSRocks.Application();
var viewKeys = ['splash', 'landing', 'items', 'article', 'contributor'];
viewKeys.forEach(function(viewKey) {
  app.builder.registerView(
    viewKey, // framework ViewKey
    require('./views/' + viewKey + '/view'),
    require('./views/' + viewKey + '/view-model'),
    'views/' + viewKey + '/view.html');
});

Note: View registration should occur before calling load on the Application object

View

Building a view is a combination of a Template, Component and ViewKey. The Template/Component will be associated with a ViewKey and will be joined together at runtime upon navigation to a view.

Template

Templates are expected to be compliant HTML mark-up files and their defintion is based on the WinJS navigation framework's formal definition of an WinJS.UI.Pages.PageControl

Generally, anything goes here and this is where most teams will match the UI creative pattern to each target User-Experience.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Landing Screen</title>
</head>

<body>
  <h1>Landing Screen</h1>
  <!-- Bind directly to the ViewModel using ES6 property compatible Binding Helpers  -->
  <div data-win-bind="innerHTML: sampleData WinJSRocks.Binding.Mode.Property"></div>

  <!-- Execute ViewModel Commands directly from markup -->
  <button data-win-bind="onclick: navigateToListPageCommand WinJSRocks.Binding.Mode.Command">Navigate To List Page</button>

  <div id="landingPivot" data-win-control="WinJS.UI.Pivot">
    <div data-win-control="WinJS.UI.PivotItem" data-win-options="{'header': 'PivotItem1'}">
      PivotItem1 Content
    </div>
    <div data-win-control="WinJS.UI.PivotItem" data-win-options="{'header': 'PivotItem2'}">
      PivotItem2 Content
    </div>
  </div>
</body>

</html>

Component

import WinJSRocks from "winjsrocks";

export default class extends WinJSRocks.View.Page {
  // Polymorphic constructor that already integrates into the WinJS.Page base structure
  constructor(element, viewModel) {
    super(element, viewModel);
  }

  // Ready is supsensed until both:
  //  - View element (this.element) has been loaded into the DOM
  //  - ViewModel loading state has fired
  ready(element, options) {

    // Managed events automatically get disconnected when the view unloads
    // The binding context is managed too!
    this.addManagedEventListener(landingPivot.winControl, "selectionchanged",
      this._onPivotSelectionChanged);

    return super.ready(element, options);
  }

  _onPivotSelectionChanged() {
    // ViewModel is already bound to the View and can be used to monitor events
    // and send commands
    this.viewModel.onPivotSelectedCommand.execute();
  }
}

ViewModel

import WinJSRocks from "winjsrocks";

export default class extends WinJSRocks.ViewModel.Base {
  constructor(application) {
    super(application);
  }

  // All ViewModel classes have a Data property that is
  // posted during navigation events
  onDataSet(callback) {
    var that = this;
    super.onDataSet(function() {
      return callback();
    });
  }

  // Encapsulate your data with Getters/Setters for view binding
  get sampleData(){
    return this._sampleData;
  }

  // Dispatch events when properties are set
  set sampleData(val){
    this._sampleData = val;
    this.notify("sampleData");
  }

  // Expose commands for execution
  get navigateToListPageCommand() {
    return new WinJSRocks.Command.Base(function() {
      console.log("navigateToListPageCommand command called!");
    });
  }
}

#Working with Plugins Plugins are the recommended way of bolting on features into the WinJSRocks application life-cycle.

These types of components are loaded after the core framework has loaded and enables access to all of the goodies (Services/Providers) without any load order mishaps. They are loaded in series, so make sure you provide them in the order of dependence.

To activate, register the class plugin class definition in the WinJSRocks.Application.Instance.configure options as a plugins array:

var WinJSRocks = require('winjsrocks');
var app = new WinJSRocks.Application();
app.configure({
    plugins:[
      MyAwesomePlugin // Provide the Class Definition of the Plugin
    ]
  },
  function(err){
  });

Building Providers

Providers are an elegant design pattern for decoupling application behavior into implementation strategies that might vary in different situations.

As an example, a common use-case is selecting a provider type to fullfill a need within a service Service at runtime based on measured conditions within application state.

In the WinJSRocks framework, providers have the following expecations:

  • remain Stateless (don't expect the same instance to be used in all places)
  • Use a self reference to application to manage their stateful needs
  • Does all build-up in the Constructor (no load/unload cycle)

To build a provider, inherit from the WinJSRocks.Provider.Base class:

import WinJSRocks from "winjsrocks";

export default class KeyboardCatProvider extends WinJSRocks.Provider.Base {
  constructor(application) {
    super(application);
  }

  methodA: function(args){
    return this.methodB(args);
  }

  methodB: function(args){
    return "Keyboard cat";
  }
};

To activate a provider, register using the WinJSRocks.Application.Instance.builder before calling configure:

var WinJSRocks = require('winjsrocks');
var app = new WinJSRocks.Application();
app.builder.registerProvider("localStorage", KeyboardCatProvider);

Providers are registered in the WinJSRocks.Application.Instance.container before the load method is called on the application instance to assure custom Services and Providers are first-class citizens during application start-up.