CommonJS Utils is a collection of general purpose CommonJS-compliant modules. These modules can be used on Narwhal, Node, and other CommonJS platforms. The modules include:
- json-schema.js – This is a JSON Schema validator module. It can be used to validate data structures using JSON schema definitions. For example:
var validate = require("json-schema").validate; var data = {name: "Test"}; var schema = { properties: { name: {type: "string"}, age: {type: "number"} } }; var validation = validate(data, schema); validation.valid -> false validation.errors -> indicates that age was not provided data.age = 30; var validation = validate(data, schema); validation.valid -> trueThis module also supports using standard native constructors as type definitions. The schema above could be written
more briefly:var schema = { properties: { name: String, age: Number } }; - json-ext.js – This module provides several JavaScript-valid extensions to a JSON for serialization and parsing of richer data structures. The json-ext.js module supports dates, NaN, Infinity, and undefined using standard JavaScript syntax. For example:
var JSONExt = require("json-ext"); var myObj = {now: new Date(), unreals: [NaN, Infinity, -Infinity], notDefined: undefined} asString = JSONExt.stringify(myObj); // asString -> {now:(new Date(1265260623866)), unreals:[NaN, Infinity, -Infinity], notDefined:undefined} myObj = JSONExt.parse(asString); - observe.js – The
observemodule event provides listening capabilities that normalize subscribing to events for CommonJS observable objects, Node.js EventEmitters, and plain JavaScript property functions. For those familiar with Dojo, theobservefunction is the Node/CommonJS equivalent ofdojo.connect:var observe = require("observe").observe; // listen to an "observable" object: observe(someObservableObject, "someEvent", function(event){ ... handle event }); // listen to a Node request var listener = observe(request, "body", function(data){...}); // we can later stop listening with: listener.dismiss(); // plain JavaScript objects can also serve as event sources myObj = { sayHi: function(){ print("hi"); } }; // listen for sayHi to be called observe(myObj, "sayHi", function(){ print("Observed sayHi being called"); }); myObj.sayHi(); // this will print out "hi" and then "Observed sayHi being called" - lazy-array.js – One can utilize lazy array-like structures with the
lazy-arraymodule. Normally with standard JavaScript arrays, one needs to populate all the slots in the array before it can utilized by a consumer. However, for scalability of large collections of data, it is often beneficial to only evaluate or load data as needed. This can avoid excessive memory consumption (storing everything in collection at once), and avoid unnecessary evaluations or loading operations if only a subset of a collection is actually used. With the lazy-array module, one can easily implement a lazy array-like collection that is aninstanceofArray, and provides all of the functions normally available on Arrays. One simply needs to implement the some() function and provide a length property. For example:var LazyArray = require("lazy-array").LazyArray; fibonaccis = LazyArray({ length: 10000000, // effectively Infinity, but that's not a valid array length in JS some: function(callback){ var a = 0, b = 1; do{ var next = a + b; a = b; b = next; var done = callback(next); }while(!done); } }); // now we can print the square of first 10: var i = 0; fibonaccis.map(function(value){ // lazy-array will use lazy evaluation of the map function, // so we can safely do this without an infinite loop return value*value; // compute the square of each }).some(function(value){ if(i++ == 10){ // after 10, signal we are done return true; } print(value); });Lazy arrays are not true arrays in that we can’t use the
[index]operator to access items. However, we can grab items by index using thegetexport fromlazy-array:var get = require("lazy-array").get; get(fibonaccis, 5) -> 13Furthermore, lazy arrays also support asynchronously evaluated lazy arrays. This effectively becomes a powerful generic data asynchronous streaming mechanism.
var LazyArray = require("lazy-array").LazyArray; var when = require("promise").defer; lazyFileParts = LazyArray({ length: file.size, some: function(callback){ var deferred = defer(); fileInput.addListener("data", function(data){ callback(data); }); fileInput.addListener("complete", deferred.resolve); } }); // now we can use it var defer = require("promise").when; when(lazyFileParts.forEach(function(part){ // called for each part }), function(){ // all done }); - jsgi-client.js – The
jsgi-clientmodule is an HTTP client module that is based on the CommonJS JSGI standard. The JSGI standard was originally developed for HTTP servers, but this module basically follows the same object structure and design, but in reverse. It also provides some alternate options to make it easier to create HTTP requests. This module relies on the browserjs package and Narwhal’s promise module. For example:var request = require("jsgi-client").request; request({ uri: "http://example.com/path", method: "POST", body: '{"foo":"bar"}', headers: { "Content-Type": "application/json" } }).then(function(response){ response.body // -> the response body response.headers // -> the response headers response.status // -> the response status }); - settings.js – The
settingsmodule provides access to local configuration information. This configuration information should be stored in alocal.jsonfile in your application.local.json: { "database": { "connection":"jdbc:mysql://localhost/..." "type": "mysql" }, ... }And then we can access this local information:
var dbConnectionInfo = require("settings").database.connection; - extend-error.js – The
extend-errormodule provides a means for creating custom error constructors. Creating custom error constructors can be tricky, particularly if you want to preserve the normal error properties with name, message, stack trace information, and standard toString() operations. This module makes it simple:var ErrorConstructor = require("extend-error").ErrorConstructor; MyCustomError = ErrorConstructor("MyCustomError"); // now we can use our new error constructor: try{ throw new MyCustomError("error message"); } catch(e){ print(e); // prints: "MyCustomError: error message" } - smtp.js – This module provides the ability to send email through SMTP. This module requires Rhino. For example:
var send = require("smpt").send; send({ to: "recipient@example.com", subject: "Example", message: "This is an example email" });And then your local.json file would need to have the appropriate SMTP settings:
{ "mail": { "host":"mail.site.com", "defaultFrom": "app@site.com" } } - xml-rpc.js – The XML RPC module provides basic method invocation through XML RPC. This module is dependent on the
browserjspackage. For example:var XmlRpc = require("xml-rpc").XmlRpc; var endPoint = XmlRpc("http://somesite.com/rpc-target"); var result = endPoint("someMethod", ["arg1", 2]);
The CommonJS utilities package provides these various general purpose utilities. Some of these modules may eventually warrant their own package/project. Any one of these modules can be downloaded from the CommonJS Utils project repository, or you can download the entire CommonJS Utils package.
- CommonJS/JSGI: The Emerging JavaScript Application Server Platform
- Introducing Pintura
- Nodules: Better Module/Package Handling for Node.js
- Getting Started With Pintura
- Promised-IO
- Pintura JSGI Modules
- Patr: Promise-based Asynchronous Test Runner
- CommonJS Utilities
- Run-Anywhere JavaScript Modules Boilerplate Code
- Multi-node: Concurrent NodeJS HTTP Server
- Object Capability Model and Facets in Persevere
- Real-time Comet Applications on Node with Tunguska
