303 modules from 19 packages
13 thousand lines long and weights about 450kB
219kB when minified
60kB when minified and gzipped
One average picture on Facebook weights 100-500kB (depends on screen resolution)
add.js
module.exports = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) sum += args[i++];
return sum;
};
increment.js
var add = require('./add');
module.exports = function(val) {
return add(val, 1);
};
program.js
var inc = require('./increment');
var a = 1;
inc(a); // 2
Bundled for browser with modules-webmake
(function (modules) {
// about 60 lines of import/export path resolution logic
})({
"root": {
"add.js": function (exports, module, require) {
module.exports = function () {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) sum += args[i++];
return sum;
};
},
"increment.js": function (exports, module, require) {
var add = require('./add');
module.exports = function (val) {
return add(val, 1);
};
},
"program.js": function (exports, module, require) {
var inc = require('./increment');
var a = 1;
inc(a); // 2
}
}
})("root/program");
Simple key/value pairs
mongodb on a server
localStorage on a client
Evented database engine in JavaScript
var nsdoctor = db.create('doctor', {
name: { type: 'text', label: 'Name', required: true },
email: { type: 'email', label: 'E-mail', required: true }
});
var nspatient = db.create('patient', {
name: { type: 'text', label: 'Name', required: true },
doctor: { type: nsdoctor, label: 'Doctor', required: true }
});
var nsvisit = db.create('visit', {
doctor: { type: nsdoctor, label: 'Doctor', required: true },
patient: { type: nspatient, label: 'Patient', required: true },
date: { type: 'datetime', label: 'Date', required: true }
});
Objects
var john = nsdoctor.create({ name: 'John Smith', email: 'john.smith@roche.com' });
// Meta:
john._id // globally unique np. 'fsay6u234sd'
john._created // creation date
john._updated // modification date
// Visible object properties (possible only with ECMAScript5)
Object.keys(john) // ['name', 'email']
Collections of given type (namespaces)
// Unordered (hash objects)
// All visible properties are object instances:
nsdoctor // { fsay6u234sd: john }
Object.keys(nsdoctor) // ['fsay6u234sd']
var ian = nspatient.create({ name: 'Ian Tate', doctor: john });
var henry = nspatient.create({ name: 'Henry Wilkinson', doctor: john });
ian._id // 'gdsaa78sdf'
henry._id // '5rgrs23bfe'
Object.keys(nspatient) // ['gdsaa78sdf', '5rgrs23bfe']
Relations
var johnPatients = john._get(nspatient);
// Unordered
Object.keys(docPatients); // ['gdsaa78sdf', '5rgrs23bfe']
var carol = nspatient.create({ name: 'Carol Hanson', doctor: john });
carol._id // 'yuerert435'
// All data relations are updated realtime
Object.keys(johnPatients); // ['gdsaa78sdf', '5rgrs23bfe', 'yuerert435']
Ordered lists
var plist = nspatient.list('name');
plist // [carol, henry, ian]
// Updated in next event-loop
henry._set('name', 'Zahary Wilkinson');
setTimeout(function () {
plist // [carol, ian, henry]
}, 0);
Filters
var flist = nspatient.filter('name', function (name, obj) {
return name.indexOf('Ian') === 0;
});
Object.keys(flist) // ['gdsaa78sdf']
// Updated realtime
henry._set('name', 'Ian Wilkinson');
Object.keys(flist) // ['gdsaa78sdf', '5rgrs23bfe']
// We can created ordered lists from filters
flist.list('name') // [ian, henry]
No conflict resolution. Latest update wins
(instead of string-oriented)
header(
h1('Heading'),
h2('Subheading'));
nav(
ul({ 'class': 'breadcrumbs' },
li(a({ href: '/' }, 'Home')),
li(a({ href: '/section/'}, 'Section')),
li(a('Subject'))));
article(
p('Lorem ipsum...'));
footer('Footer stuff');
Construction doesn't have to be linear
var myul = ul(li('one'), li('two'), li('three'));
p("Lorem ipsum...");
// Add extra items to list
myul(li('four'), li('five'));
// Move list to other element
div(myul);
Single-page application with regular links and urls
Browser history is handled with HTML5 History
Link clicks are hijacked and view changes are invoked
Views are defined by describing differences from parent view
// |-> Home
// |-> Profile
// |-> Patients
// |-> Patient
// |-> Add visit
// |-> Visits
// |-> Visit
var home = view('home.tpl');
var profile = home.diff('profile.tpl');
var patients = home.diff('patients.tpl');
var patient = patients.diff('patient.tpl');
var addVisit = patient.diff('add-visit.tpl');
var visits = home.diff('visits.tpl');
var visit = visits.diff('visit.tpl');
Handles client/server socket connections
Handles asynchronous files uploads on server side
Keeps production server process running
Sends email notifications
Code quality guard
MongoDB driver for Node.js
Test suite
Extensions to EcmaScript5 API
Simple cross-environment event emitter interface
EcmaScript 5 application
Firefox 4+, Chrome 13+, Safari 5+, IE10+
IE9 can be supported in very limited way
(no Offline and no History)
With same code we can serve static pages using NodeJS server
Use a spacebar or arrow keys to navigate