Fabrice Matrat
Web Architect
15+ years experience
Yet again another MVC ?
Large scale application
Small module
Embrace standard
Fast
... or live with the mess
Asynchronous Module Definition
because nobody likes to wait
small
4k only
AMD-compliant asynchronous loader
and ...
Designed to be fast
AMD-formatted JS modules in // (fast!)
CommonJS modules (fast!)
non-AMD JS files in // (fast!)
CSS, text files in // (fast!)
Waits for dependencies before executing JS
Waits for domReady, if/when desired
And it's fast
cujoJS resource assembler
Compile all modules into one or small numbers of JS files
and it is...
... FAST
even for a resource assembler
No-configuration operation for simple applications
High performance operation
All-in-one bundling of Javascript, CSS, and HTML
Efficient, non-blocking loading of bundles
Just-in-time loading of bundles
In your index.html <script data-curl-run="" src="app/run.js"></script>
In your package.json { "name": "MyApp", .... "scripts": { "cram": "cram index.html --include curl/plugin/domReady --include curl/plugin/text --output app/run.cram.js", } }
define({ message: "I haz been wired", // Create an instance of the hello-wired module. helloWired: { create: { module: 'app/hello-wired', args: { $ref: 'dom.first!hello' } }, init: { sayHello: { $ref: 'message' } } }, plugins: [ { module: 'wire/debug' }, { module: 'wire/dom' } ] });
Aspect Oriented Programming
Being able to change/add behavior to existing methods
var origDoSomething = thing.doSomething; thing.doSomething = function() { doSomethingElseFirst(); return origDoSomething.apply(this, arguments); }
var myObject = { doSomething: function(a, b) { return a + b; } }; // Call a function after myObject.doSomething returns var remover = meld.after(myObject, 'doSomething', function(result) { console.log('myObject.doSomething returned: ' + result); }); myObject.doSomething(1, 2); // Logs: "myObject.doSomething returned: 3" remover.remove(); myObject.doSomething(1, 2); // Nothing logged
todos: { create: { module: 'cola/Collection', args: { strategyOptions: { validator: { module: 'app/create/validateTodo' } } } }, before: { add: 'cleanTodo | generateMetadata', update: 'cleanTodo' } }
meld + wire = <3
the Force unleashed
enjoy!
define({ $exports: { $ref: 'contacts' }, contacts: { create: { module: 'cola/Collection', }, before: { add: 'cleanContact | generateMetadata', } }, contactStore: { create: { module: 'cola/adapter/LocalStorage', args: 'contacts-demo' }, bind: { $ref: 'contacts' } }, cleanContact: { module: 'app/collection/cleanContact' }, generateMetadata: { module: 'app/collection/generateMetadata' }, $plugins: [ { module: 'wire/dom' }, { module: 'wire/on' }, { module: 'wire/aop' }, { module: 'cola' } ] });
Promise
Lightweight Promises/A+ implementation
Fast
No Dependencies
var when = require('when'); var promise = when(0); function increment(count) { console.log(count); return count + 1; } promise.then(increment) // 0 .then(increment) // 1 .then(increment) // 2 .then(increment); // 3
var rest = require('rest'); rest('/').then(function(response) { console.log('response: ', response); });
var bus, webSocketServer, redis; require('msgs/adapters/nodeStream'); require('msgs/adapters/redis'); require('msgs/channels/pubsub'); bus = require('msgs').bus(); redis = require('redis'); webSocketServer = ...; bus.pubsubChannel('fromClient'); bus.pubsubChannel('toClient'); webSocketServer.on('connection', function (connection) { bus.nodeStreamGateway(connection, { output: 'fromClient', input: 'toClient' }); }); bus.redisGateway(redis.createClient, 'redisTopic', { output: 'toClient', input: 'fromClient' });
Monadic Stream implementation
A bit of live coding with most