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

composer.js

v0.2.3

Published

Dead simple prototypical OO with musical flavor

Downloads

4

Readme

Composer.js

Ever needed a simple library to express ALL of your object creation? You have probably used (or just tried) libraries that try to sugarify the process to make it feel more classical. Well, just so you know, that method is dead.

In this page, I will show you how to write objects better using Stampit() or Composer(). I will even outline the differences so you can make an informed decision on your project and write better code!

So here's what you do instead:

Ditch your compositional library!

Include one of these scripts on your page or node.js application:

Stampit

Composer

Create a factory!

  • Stampit: var factory = Stampit();
  • Composer: var pieceFactory = Composer();

Now instead of defining your object as a constructor, let's make some closures.

function closure(){
   var store = {};
   _.mixIn(this, {
     "get": function(val){
        return store[val];
     },
     "set": function(val, value){
        store[val] = value;
        return this;
     }
  });
}

This closure is very simple, and defines a private variable store behind the scenes. Then it mixes into this functions called get and set.

There are 3 ways to use this (given an object myObject for factory-less):

var myObject = {};
  1. closure.call(myObject);
  2. var getsetFactory = Stampit().enclose(closure);
  3. var getsetFactory = Composer().phrase(closure);

... and finally if you used a factory...

  1. myObject = getsetFactory();

Give your object some Default Values!

States allow you to set properties inside of the object at creation time.

Noting the difference between the phrase (composer) function and the state (stampit) function, the phrase function is both the enclose function and the state function in stampit.

Using stampit:

Stampit().state({
    some: "properties",
    go: "here"
});

Using composer:

Composer.phrase({
    some: "properties",
    go: "here"
});

Obligatory mixin without factories example:

_.mixIn(obj, {
    some: "properties",
    go: "here"
});

Create a Prototype!

Some good ways to do prototype creation:

var myPrototype = {
   "test": function(){
     return "test";
   },
   "test2": function(a){
     return a;
   }
};

//Copy that prototype
var myobj = Object.create(prototypeDefinition);

//stampit example
var factory = Stampit().methods(myPrototype);
//Another stampit method
var factory = Stampit(myPrototype);
myobj = factory();

//Composer
var piece = Composer().motif(myPrototype);
myobj = piece();

myobj.test();
//"test"

myobj.test2(2);
//2

All of these functions are designed to place items on the object's prototype. Don't put static values here. Put them on the factory or in a namespace for later use so that they can be encapsulated instead of injected into the global namespace.

Composer also supports the following syntax:

piece.motif(function functionName(){
  //Your prototype definition goes here
  return "functionValue";
});
var myObj = piece();

myObj.functionName();
//"functionValue"

The name functionName will be added to the piece prototype.

Define a few properties!

This is rather tricky, because IE8 does not support getter and setter properties of any kind. Yet, Composer and Stampit can help you do this.

Upon object creation you can create a closure like this:

//Stampit
factory.enclose(function(){
    Object.defineProperty(this,"propertyName",{
       "get": function(){},
       "set": function(){}
    })
});

//Composer
piece.phrase(function(){
    Object.defineProperty(this,"propertyName",{
       "get": function(){},
       "set": function(){}
    })
});

or you can use Composer's dynamic function:

piece.dynamic({
   "propertyName":{
       "get": function(){},
       "set": function(){}
    }
});

Under the hood composer uses Object.defineProperties. This is not recommended for people who have to support older browsers, because there are no polyfills for this method.

Combine some factories! (and a few other things too)

Stampit Example var newFactory = Stampit.compose(factory1, factory2, factory3...);

Composer Example: var newPiece = Composer.symphony(piece1, piece2, closureOrPhrase, stateOrPhrase);

Note that closures, states, and pieces will be added in the order they are placed in the function for composer.

Parameters for Functions and Chainability

Every function described here accepts unlimited parameters so long as it matches the definition of the API.

//stampit example
var factory = Stampit().enclose(functionDefinition1, functionDefinition2,...);

//composer example
var piece = Composer().phrase(functionDefinition1, functionDefinition2, state1, state2...);

The API of both libraries is chainable.

var factory = Stampit().enclose(...).methods(...)...;

var piece = Composer().dynamics(...).phrase(...).motif(...)...;

Compose and Symphony return a factory so they should be chainable as well.

var piece = Composer.symphony(piece1, piece2).dynamics(...).phrase(...).motif(...)...;

Make your Library!

Composer was designed with portability in mind. Check out the following example.

var store = Composer().phrase(function(values){
  var key, myStore = {};
  for(key in values){
    set(key, values[key]);
  }
  function get(myKey){
     return myStore[myKey];
  }
  function set(myKey, val){
     myStore[myKey] = val;
     return this;
  }
  this.set = set;
  this.get = get;
});

Now just use your factory.

var myStore = store({
  "foo": "bar",
  "baz": "nee"
});

myStore.get("foo");
//"bar"

myStore.get("baz");
//"nee"

myStore.set("baz","blah").get("baz");
//"blah"

All parameters passed to the factory constructor get passed to the closures. Your library is now extendable using this API. Allow your users to mix/match/create a new library based on your own.

At this time, stampit does not support passing variables to the closures and sometimes it really isn't useful. In that case, use stampit.

Test Composer!

If you don't have Mocha installed, it's probably best to run npm start from a cloned repository. This process will install mocha globally and allow you to run mocha tests from the command line.

No mocha (Only need to run once):

npm start

Then just run:

npm test

Be Free!

Whatever library you choose to define your objects, always help out and file bug reports if found.

Please feel free to file an issue or submit a pull request with a small summary of suggested changes!

I'm looking for help wherever I can get it to help maintain this library. Feel free to email me at [email protected].

Thank you very much for your time and good luck with your javascript applications~

~function(){console.log("Josh");}();`
//"Josh"