Socket
Socket
Sign inDemoInstall

avvio

Package Overview
Dependencies
Maintainers
2
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

avvio - npm Package Compare versions

Comparing version 2.2.0 to 3.0.0

19

boot.js

@@ -7,2 +7,3 @@ 'use strict'

const Plugin = require('./plugin')
const debug = require('debug')('avvio')

@@ -89,5 +90,8 @@ function wrap (server, opts, instance) {

this.booted = false
this._readyQ = fastq(this, callWithCbOrNextTick, 1)
this._readyQ.pause()
this._readyQ.drain = () => {
this.booted = true
this.emit('start')

@@ -109,7 +113,9 @@ }

// create the root node upon to hold each subsequent call to use()
// the root node is responsible for emitting 'start'
Boot.prototype._init = function () {
if (this.booted) {
throw new Error('root plugin has already booted')
}
if (this._current.length === 0) {
const main = new Plugin(this, (s, opts, done) => {
const main = new Plugin(this, function root (s, opts, done) {
// we need to wait any call to use() to happen

@@ -119,2 +125,3 @@ process.nextTick(done)

Plugin.loadPlugin.call(this, main, (err) => {
debug('root plugin ready')
if (err) {

@@ -172,4 +179,8 @@ this._error = err

if (current.loaded) {
throw new Error(`Impossible to load "${obj.name}" plugin because the parent "${current.name}" was already loaded`)
}
// we add the plugin to be loaded at the end of the current queue
current.q.push(obj, (err) => {
current.enqueue(obj, (err) => {
if (err) {

@@ -176,0 +187,0 @@ this._error = err

{
"name": "avvio",
"version": "2.2.0",
"version": "3.0.0",
"description": "Asynchronous bootstrapping of Node applications",
"main": "boot.js",
"scripts": {
"test": "standard && tap test/*.js"
"test": "standard && tap test/*test.js"
},

@@ -36,7 +36,9 @@ "precommit": "test",

"standard": "^10.0.3",
"tap": "^10.7.2"
"tap": "^10.7.2",
"then-sleep": "^1.0.1"
},
"dependencies": {
"debug": "^3.1.0",
"fastq": "^1.5.0"
}
}
'use strict'
const fastq = require('fastq')
const debug = require('debug')('avvio')

@@ -12,5 +13,7 @@ function Plugin (parent, func, opts, callback) {

this.parent = parent
this.name = func.name
this.q = fastq(parent, loadPlugin, 1)
this.q.pause()
this.loaded = false

@@ -21,3 +24,2 @@ // always start the queue in the next tick

// or they will end up at the top of _current
process.nextTick(this.q.resume.bind(this.q))
}

@@ -27,21 +29,81 @@

const func = this.func
var completed = false
var name = this.name
this.server = this.parent.override(server, func, this.opts)
// we must defer the loading of the plugin until the
// current execution has ended
process.nextTick(() => {
func(this.server, this.opts, cb)
})
debug('exec', name)
var promise = func(this.server, this.opts, done)
if (promise && typeof promise.then === 'function') {
debug('resolving promise', name)
promise.then(() => done()).catch(done)
}
function done (err) {
if (completed) {
return
}
debug('exec completed', name)
completed = true
cb(err)
}
}
Plugin.prototype.enqueue = function (obj, cb) {
debug('enqueue', this.name, obj.name)
this.q.push(obj, cb)
}
Plugin.prototype.finish = function (err, cb) {
debug('finish', this.name)
const callback = this.callback
// if 'use' has a callback
if (callback) {
callback(err)
// if 'use' has a callback but does not have parameters
cb(callback.length > 0 ? null : err)
} else {
cb(err)
const done = () => {
if (this.loaded) {
return
}
debug('loaded', this.name)
this.loaded = true
// if 'use' has a callback
if (callback) {
callback(err)
// if 'use' has a callback but does not have parameters
cb(callback.length > 0 ? null : err)
} else {
cb(err)
}
}
if (err) {
done()
return
}
const check = () => {
debug('check', this.name, this.q.length(), this.q.running())
if (this.q.length() === 0 && this.q.running() === 0) {
done()
} else {
debug('delayed', this.name)
// finish when the queue of nested plugins to load is empty
this.q.drain = () => {
debug('drain', this.name)
this.q.drain = noop
// we defer the check, as a safety net for things
// that might be scheduled in the loading callback
process.nextTick(check)
}
}
}
process.nextTick(check)
// we start loading the dependents plugins only once
// the current level is finished
this.q.resume()
}

@@ -54,18 +116,14 @@

this._current.unshift(toLoad)
toLoad.exec((last && last.server) || this._server, (err) => {
if (err || !(toLoad.q.length() > 0 || toLoad.q.running() > 0)) {
// finish now, because there is nothing left to do
toLoad.finish(err, (err) => {
this._current.shift()
toLoad.finish(err, cb)
} else {
// finish when the queue of nested plugins to load is empty
toLoad.q.drain = () => {
this._current.shift()
toLoad.finish(null, cb)
}
}
cb(err)
})
})
}
function noop () {}
module.exports = Plugin
module.exports.loadPlugin = loadPlugin

@@ -30,3 +30,3 @@ # avvio

The example below can be found [here][example] and ran using `node example.js`.
The example below can be found [here][example] and ran using `node example.js`.
It demonstrates how to use `avvio` to load functions / plugins in order.

@@ -47,11 +47,4 @@

avvio.use(third, (err) => {
if (err) {
console.log('something bad happened')
console.log(err)
}
avvio.use(third)
console.log('third plugin loaded')
})
avvio.ready(function () {

@@ -63,3 +56,4 @@ console.log('application booted!')

console.log('first loaded', opts)
instance.use(second, cb)
instance.use(second)
cb()
}

@@ -72,5 +66,5 @@

function third (instance, opts, cb) {
// async/await or Promise support
async function third (instance, opts) {
console.log('third loaded')
cb()
}

@@ -96,4 +90,4 @@ ```

Starts the avvio sequence.
As the name suggest, `instance` is the object representing your application.
Starts the avvio sequence.
As the name suggest, `instance` is the object representing your application.
Avvio will add the functions `use`, `after` and `ready` to the instance.

@@ -110,3 +104,4 @@

cb()
}, cb)
})
cb()
}).after(function (err, cb) {

@@ -145,5 +140,5 @@ // after first and second are finished

### app.use(func, [opts], [cb])
### app.use(func, [opts])
Loads one or more functions asynchronously.
Loads one or more functions asynchronously.
The function **must** have the signature: `instance, options, done`

@@ -161,2 +156,11 @@

async/await is also supported:
```js
async function plugin (server, opts) {
await sleep(10)
}
app.use(plugin)
```
`use` returns the instance on which `use` is called, to support a chainable API.

@@ -166,3 +170,3 @@

```js
app.use([first, second, third], opts, cb)
app.use([first, second, third], opts)
```

@@ -173,23 +177,16 @@ The functions will be loaded in the same order as they are inside the array.

#### Error handling
The third argument of the plugin, the `done` function can accept an error parameter, if you pass it, you **must** handle that error. You have two ways to do it:
1. the callback of the use function
In order to handle errors in the loading plugins, you must use the
`.ready()` method, like so:
```js
app.use(function (instance, opts, done) {
done(new Error('error'))
}, opts, function (err) {
if (err) throw err
})
```
2. the next `ready` or `after` callback
```js
app.use(function (instance, opts, done) {
done(new Error('error'))
done(new Error('error'))
}, opts)
app.ready(function (err) {
if (err) throw err
if (err) throw err
})
```
*Note if you pass a callback to `use` without an error parameter, the error will be automatically passed to the next `ready` or `after` callback.*
-------------------------------------------------------

@@ -201,7 +198,7 @@ <a name="after"></a>

Calls a function after all the previously defined plugins are loaded, including
all their dependencies. The `'start'` event is not emitted yet.
all their dependencies. The `'start'` event is not emitted yet.
The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.

@@ -240,7 +237,7 @@

Calls a function after all the plugins and `after` call are completed, but before `'start'` is emitted. `ready` callbacks are executed one at a time.
Calls a function after all the plugins and `after` call are completed, but before `'start'` is emitted. `ready` callbacks are executed one at a time.
The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.

@@ -296,4 +293,4 @@

Allows to override the instance of the server for each loading plugin.
It allows the creation of an inheritance chain for the server instances.
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 while the third is the options object that you give to use.

@@ -322,3 +319,4 @@

assert(s1.count === 1)
s1.use(second, cb)
s1.use(second)
cb()

@@ -341,4 +339,4 @@ function second (s2, opts, cb) {

The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `context`.
2. If two parameters are given to the callback, the first will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, the second will be the `done` callback.
1. If one parameter is given to the callback, that parameter will be the `context`.
2. If two parameters are given to the callback, the first will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, the second will be the `done` callback.

@@ -371,4 +369,4 @@ ```js

The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.

@@ -375,0 +373,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc