Skip to content

Commit

Permalink
Merge pull request #12 from mcollina/useful-stuff
Browse files Browse the repository at this point in the history
Updated override and after/ready callbacks
  • Loading branch information
mcollina authored Mar 21, 2017
2 parents f15a7ff + 05368b2 commit 6317939
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 38 deletions.
60 changes: 31 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,26 @@ The functions will be loaded in the same order as they are inside the array.
-------------------------------------------------------
<a name="after"></a>

### app.after(func([done]), [cb])
### app.after(func([context], [done]), [cb])

Calls a functon after all the previously defined plugins are loaded, including
all their dependencies. The `'start'` event is not emitted yet.
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.

```js
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.
Expand All @@ -167,16 +178,26 @@ chainable API.
-------------------------------------------------------
<a name="ready"></a>

### app.ready(func([done]))
### app.ready(func([context], [done]))

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.

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.
```js
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.
Expand Down Expand Up @@ -204,11 +225,12 @@ boot(app, {
-------------------------------------------------------
<a name="override"></a>

### app.override(server)
### app.override(server, plugin)

Allows to override the instance of the server for each loading
plugin. It allows the creation of an inheritance chain for the
server instances.
server instances.
The first parameter is the server instance and the second is the plugin function.

```js
const boot = require('avvio')
Expand All @@ -218,7 +240,7 @@ const app = boot(server)

console.log(app !== server, 'override must be set on the Avvio instance')

app.override = function (s) {
app.override = function (s, fn) {
// create a new instance with the
// server as the prototype
const res = Object.create(s)
Expand All @@ -241,26 +263,6 @@ app.use(function first (s1, opts, cb) {
}
})
```
<a name="skip-override"></a>
#### Skip override
If for some reason you have set an override and you want to skip it for a *specific function*, you must add `functionName[Symbol.for('skip-override')] = true` to your code.
Example:
```js
const server = { my: 'server' }
const app = boot(server)

app.override = function (s) {
return Object.create(s)
}

first[Symbol.for('skip-override')] = true
app.use(first)

function first (s, opts, cb) {
// some code
cb()
}
```
-------------------------------------------------------

## Acknowledgements
Expand Down
20 changes: 13 additions & 7 deletions boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Boot.prototype._init = function () {
}

// allows to override the instance of a server, given a plugin
Boot.prototype.override = function (server) {
Boot.prototype.override = function (server, func) {
return server
}

Expand Down Expand Up @@ -153,9 +153,10 @@ Boot.prototype._addPlugin = function (plugin, opts, callback) {

Boot.prototype.after = function (func, cb) {
// TODO do not rely on .use()
// const server = this._server
this.use(function (s, opts, done) {
callWithCbOrNextTick(func, done)
}, cb)
callWithCbOrNextTick.call(this, func, done)
}.bind(this), cb)
return this
}

Expand All @@ -173,7 +174,6 @@ function Plugin (parent, func, opts, callback) {
this.deferred = false
this.onFinish = null
this.parent = parent
this.skipOverride = !!func[Symbol.for('skip-override')]

this.q = fastq(parent, loadPlugin, 1)
this.q.pause()
Expand All @@ -187,7 +187,7 @@ function Plugin (parent, func, opts, callback) {

Plugin.prototype.exec = function (server, cb) {
const func = this.func
this.server = this.skipOverride ? server : this.parent.override(server)
this.server = this.parent.override(server, func)
func(this.server, this.opts, cb)
}

Expand Down Expand Up @@ -217,12 +217,18 @@ function loadPlugin (toLoad, cb) {
})
}

function callWithCbOrNextTick (func, cb) {
function callWithCbOrNextTick (func, cb, context) {
if (this && this._server) {
context = this._server
}

if (func.length === 0) {
func()
process.nextTick(cb)
} else {
} else if (func.length === 1) {
func(cb)
} else {
func(context, cb)
}
}

Expand Down
21 changes: 21 additions & 0 deletions test/after-and-ready.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,24 @@ test('ready adds at the end of the queue', (t) => {
t.ok(readyCalled, 'ready called')
})
})

test('if the after/ready callback has two parameters, the first one must be the context', (t) => {
t.plan(2)

const server = { my: 'server' }
const app = boot(server)

app.use(function (s, opts, done) {
done()
})

app.after(function (context, cb) {
t.equal(server, context)
cb()
})

app.ready(function (context, cb) {
t.equal(server, context)
cb()
})
})
27 changes: 25 additions & 2 deletions test/override.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,36 @@ test('fastify test case', (t) => {
})
})

test('skip override', (t) => {
test('override should pass also the plugin function', (t) => {
t.plan(3)

const server = { my: 'server' }
const app = boot(server)

app.override = function (s, fn) {
t.type(fn, 'function')
t.equal(fn, first)
return s
}

app.use(first)

function first (s, opts, cb) {
t.equal(s, server)
cb()
}
})

test('skip override - fastify test case', (t) => {
t.plan(2)

const server = { my: 'server' }
const app = boot(server)

app.override = function (s) {
app.override = function (s, func) {
if (func[Symbol.for('skip-override')]) {
return s
}
return Object.create(s)
}

Expand Down

0 comments on commit 6317939

Please sign in to comment.