Asynchronous bootstrapping made easy. Wait for all components/plugins to start, and then start your whole app.
avvio is fully reentrant and graph-based. You can load
components/plugins within plugins, and be still sure that things will
happen in the right order.
To install avvio, simply use npm:
npm install avvio --save
The example below can be found here and ran using node example.js. It
demonstrates how to use avvio to load functions /
plugins in
order.
'use strict'
const boot = require('avvio')()
boot
.use(first, { hello: 'world' })
.after((cb) => {
console.log('after first and second')
cb()
})
.use(third, (err) => {
if (err) {
console.log('something bad happened')
console.log(err)
}
console.log('third plugin loaded')
})
.ready(function () {
console.log('application booted!')
})
function first (instance, opts, cb) {
console.log('first loaded', opts)
instance.use(second, cb)
}
function second (instance, opts, cb) {
console.log('second loaded')
process.nextTick(cb)
}
function third (instance, opts, cb) {
console.log('third loaded')
cb()
}Start a boot sequence.
instance will be used as the first
argument of all plugins loaded and use, after and ready
function will be
added to that object, keeping the support for the chainable API:
const server = {}
require('avvio')(server)
server.use(function first (s, opts, cb) {
// s is the same of server
s.use(function second (s, opts, cb) {
cb()
}, cb)
}).after(function (cb) {
// after first and second are finished
cb()
})Options:
expose: a key/value property to change howuse,afterandreadyare exposed.
Events:
'error'if something bad happens'start'when the application starts
The boot function can be used also as a
constructor to inherits from.
Loads a functions asynchronously. The function must have the signature:
function plugin (server, opts, done) {
done()
}done must be called only once.
Returns the instance on which use is called, to support a
chainable API.
If you need to add more than a function and you don't need to use a different options object or callback, you can pass an array of functions to .use.
boot.use([first, second, third], opts, cb)The functions will be loaded in the same order as they are inside the array.
Calls a function after all the previously defined plugins are loaded, including
all their dependencies. The 'start' event is not emitted yet.
If one parameter is given to the callback, that parameter will be the done callback.
If two parameters are given to the callback, the first will be the contenxt, the second will be the done callback.
const server = {}
...
// after with one parameter
boot.after(function (done) {
done()
})
// after with two parameters
boot.after(function (context, done) {
assert.equal(context, server)
done()
})done must be called only once.
Returns the instance on which after is called, to support a
chainable API.
Calls a functon after all the plugins and after call are
completed, but befer 'start' is emitted. ready callbacks are
executed one at a time.
If one parameter is given to the callback, that parameter will be the done callback.
If two parameters are given to the callback, the first will be the contenxt, the second will be the done callback.
const server = {}
...
// ready with one parameter
boot.ready(function (done) {
done()
})
// ready with two parameters
boot.ready(function (context, done) {
assert.equal(context, server)
done()
})done must be called only once.
Returns the instance on which ready is called, to support a
chainable API.
Same as:
const app = express()
boot(app, {
expose: {
use: 'load'
}
})Allows to override the instance of the server for each loading
plugin. It allows the creation of an inheritance chain for the
server instances.
The first parameter is the server instance and the second is the plugin function.
const boot = require('avvio')
const assert = require('assert')
const server = { count: 0 }
const app = boot(server)
console.log(app !== server, 'override must be set on the Avvio instance')
app.override = function (s, fn) {
// create a new instance with the
// server as the prototype
const res = Object.create(s)
res.count = res.count + 1
return res
}
app.use(function first (s1, opts, cb) {
assert(s1 !== server)
assert(server.isPrototypeOf(s1))
assert(s1.count === 1)
s1.use(second, cb)
function second (s2, opts, cb) {
assert(s2 !== s1)
assert(s1.isPrototypeOf(s2))
assert(s2.count === 2)
cb()
}
})This project was kindly sponsored by nearForm.
Copyright Matteo Collina 2016, Licensed under MIT.