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

sandbox-pattern

v1.0.4

Published

Uses the Sandbox Javascript pattern to help rationalize load order in projects without good dependency management

Downloads

8

Readme

Sandbox Pattern

Working on a project where your javascript files are arbitrarily loaded? Need a tool besides CommonJS or Browserify to easily manage dependencies? Then you should consider using the sandbox pattern.

The code in this repository is an implementation of the Sandbox javascript pattern as illustrated in Stoyan Stefanov's book Javascript Patterns.

Installation

NodeJS:

$ npm install --save sandbox-pattern

and in your javascript:

var sandbox = require('sandbox-pattern');

// Glorius

Meteor:

$ meteor add calebmer:sandbox

Are you using Meteor? Awesome, there are just a few things you really should know.

Usage

A sandbox is a scoped context block with one variable passed in, the box variable. The easiest way to visualize how the sandbox module works is with the following (we assume sandbox is defined in the global scope, Sandbox for Meteor users).

sandbox('bird', function () {
  return {
    chirp: function () {
      console.log('cawcaw!');
    }
  };
});

sandbox(['bird'], function (box) {
  box.bird.chirp(); // # => cawcaw!
});

This may seem completely useless until you realize that the sandbox function allows you to define your "sandboxes" in any order. The following code will give the exact same output.

sandbox(['bird'], function (box) {
  box.bird.chirp(); // # => cawcaw!
});

sandbox('bird', function () {
  return {
    chirp: function () {
      console.log('cawcaw!');
    }
  };
});

Import and Export

A sandbox can be a module, and can call for modules at the same time. As long as no circular dependencies exist this will be fine. For example:

sandbox('bird', function () {
  return { color: 'tomato' };
});

sandbox('cat', ['bird'], function (box) {
  return { chases: [box.bird] };
});

sandbox(['bird', 'cat'], function (box) {
  console.log(box.bird.color === box.cat.chases[0].color); // # => true
});

Extending modules

One can also extend modules. Remember, the following sandboxes can be called in any order and the same output will be realized.

sandbox('bird', function () {
  return { color: 'tomato' };
});

sandbox('bird', function () {
  return {
    chirp: function () {
      console.log('cawcaw!');
    }
  };
});

sandbox(['bird'], function (box) {
  console.log(box.bird.color); // # => tomato
  box.bird.chirp();            // # => cawcaw!
});

Dot Syntax

You can use javascript's dot syntax to define module components.

sandbox('bird.color', function () {
  return 'tomato';
});

Will produce the same effect as:

sandbox('bird', function () {
  return { color: 'tomato' };
});

When declaring a module as a dependency, all child modules will also be added to the dependency list. For example, if one called for bird and bird.color was defined as a module, bird.color would be included in the box.

One advantage to using the dot syntax is you can retrieve them independently from the parent module. Again, the sandboxes can be defined in any order.

sandbox('bird', function () {
  return { gender: 'female' };
});

sandbox('bird.color', function () {
  return 'tomato';
});

sandbox('bird.size', function () {
  return 42;
});

sandbox(['bird.color'], function (box) {
  console.log(box.bird.color);  // # => tomato
  console.log(box.bird.gender); // # => undefined
  console.log(box.bird.size);   // # => undefined
});

sandbox(['bird'], function (box) {
  console.log(box.bird.color);  // # => tomato
  console.log(box.bird.gender); // # => female
  console.log(box.bird.size);   // # => 42
});

Error Handling

On some occasions, such as when a module does not exist, or a circular dependency is found, errors will be thrown. If you want to handle the error just add another parameter to the box function. For example:

sandbox(['doesNotExist'], function (err, box) {
  console.log(err); // # => (some Error)
  console.log(box); // # => undefined
});

If there is no error, err would be undefined and box would have the traditional box modules.

Manual Startup Control

In instances where sandboxes are defined asynchronously you need to manually choose when to start your sandboxes. By default, setTimeout is used to delay sandbox execution to the next loop. This is so that all the module references are defined by the time the sandboxes are executed. To manually accomplish this do the following:

sandbox.configure({
  startupWait: true
});

// Asynchronously define sandboxes

sandbox.startup();

// Sandbox has been reset

ECMA Script 6

With the coming adoption of ES6 (or with a tool like Babel) there is a nice syntactic sugar developers can use to easily access data inside the box variable. That would be by object destructuring in a way similar to that below, assuming the bird and dog modules are defined.

sandbox(['bird', 'dog'], function ({ bird, dog }) {
  console.log(bird === undefined); // # => false
  console.log(dog === undefined);  // # => false
  console.log(box === undefined);  // # => true
});

Dear Meteor Users

This package was initially created for Meteor, however the majority of the documentation is written for an NPM audience as NPM is more universal. As such there are a few differences Meteor users must know about. The docs have always referred to the sandbox variable as sandbox, however in Meteor it is defined as Sandbox with a capital S. That is very important to remember.

Second, since Meteor files are loaded asynchronously on the client, manual startup mode has been enabled for both sides (@see Manual Startup Control). Essentially that means you need to put a main.js file in the root of your directory (it must load last!) and run:

Sandbox.startup();

Remember, in Meteor it is Sandbox, not sandbox!

Is the README comprehensible?

If you don't understand something, or anything seems unclear, please submit an issue.

So long and thanks for all the fish

Enjoy the package? Connect with me on Twitter.

Make sure to check out the package on: