feat(emit-async): handle async listeners (#3416)
Extracted from xo-server.
This commit is contained in:
parent
b4e4d32255
commit
8689cff26b
3
@xen-orchestra/emit-async/.babelrc.js
Normal file
3
@xen-orchestra/emit-async/.babelrc.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = require('../../@xen-orchestra/babel-config')(
|
||||||
|
require('./package.json')
|
||||||
|
)
|
24
@xen-orchestra/emit-async/.npmignore
Normal file
24
@xen-orchestra/emit-async/.npmignore
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/benchmark/
|
||||||
|
/benchmarks/
|
||||||
|
*.bench.js
|
||||||
|
*.bench.js.map
|
||||||
|
|
||||||
|
/examples/
|
||||||
|
example.js
|
||||||
|
example.js.map
|
||||||
|
*.example.js
|
||||||
|
*.example.js.map
|
||||||
|
|
||||||
|
/fixture/
|
||||||
|
/fixtures/
|
||||||
|
*.fixture.js
|
||||||
|
*.fixture.js.map
|
||||||
|
*.fixtures.js
|
||||||
|
*.fixtures.js.map
|
||||||
|
|
||||||
|
/test/
|
||||||
|
/tests/
|
||||||
|
*.spec.js
|
||||||
|
*.spec.js.map
|
||||||
|
|
||||||
|
__snapshots__/
|
71
@xen-orchestra/emit-async/README.md
Normal file
71
@xen-orchestra/emit-async/README.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# @xen-orchestra/emit-async [](https://travis-ci.org/${pkg.shortGitHubPath})
|
||||||
|
|
||||||
|
> ${pkg.description}
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/emit-async):
|
||||||
|
|
||||||
|
```
|
||||||
|
> npm install --save @xen-orchestra/emit-async
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
import EE from 'events'
|
||||||
|
import emitAsync from '@xen-orchestra/emit-async'
|
||||||
|
|
||||||
|
const ee = new EE()
|
||||||
|
ee.emitAsync = emitAsync
|
||||||
|
|
||||||
|
ee.on('start', async function () {
|
||||||
|
// whatever
|
||||||
|
})
|
||||||
|
|
||||||
|
// similar to EventEmmiter#emit() but returns a promise which resolves when all
|
||||||
|
// listeners have resolved
|
||||||
|
await ee.emitAsync('start')
|
||||||
|
|
||||||
|
// by default, it will rejects as soon as one listener reject, you can customise
|
||||||
|
// error handling though:
|
||||||
|
await ee.emitAsync({
|
||||||
|
onError (error) {
|
||||||
|
console.warn(error)
|
||||||
|
}
|
||||||
|
}, 'start')
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```
|
||||||
|
# Install dependencies
|
||||||
|
> yarn
|
||||||
|
|
||||||
|
# Run the tests
|
||||||
|
> yarn test
|
||||||
|
|
||||||
|
# Continuously compile
|
||||||
|
> yarn dev
|
||||||
|
|
||||||
|
# Continuously run the tests
|
||||||
|
> yarn dev-test
|
||||||
|
|
||||||
|
# Build for production (automatically called by npm install)
|
||||||
|
> yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributions
|
||||||
|
|
||||||
|
Contributions are *very* welcomed, either on the documentation or on
|
||||||
|
the code.
|
||||||
|
|
||||||
|
You may:
|
||||||
|
|
||||||
|
- report any [issue](${pkg.bugs})
|
||||||
|
you've encountered;
|
||||||
|
- fork and create a pull request.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
${pkg.license} © [${pkg.author.name}](${pkg.author.url})
|
47
@xen-orchestra/emit-async/package.json
Normal file
47
@xen-orchestra/emit-async/package.json
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "@xen-orchestra/emit-async",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"keywords": [],
|
||||||
|
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/emit-async",
|
||||||
|
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/vatesfr/xen-orchestra.git"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"name": "Julien Fontanet",
|
||||||
|
"email": "julien.fontanet@vates.fr"
|
||||||
|
},
|
||||||
|
"preferGlobal": false,
|
||||||
|
"main": "dist/",
|
||||||
|
"bin": {},
|
||||||
|
"files": [
|
||||||
|
"dist/"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
">2%"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/cli": "7.0.0",
|
||||||
|
"@babel/core": "7.0.0",
|
||||||
|
"@babel/preset-env": "7.0.0",
|
||||||
|
"babel-plugin-lodash": "^3.3.2",
|
||||||
|
"cross-env": "^5.1.3",
|
||||||
|
"rimraf": "^2.6.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
|
||||||
|
"clean": "rimraf dist/",
|
||||||
|
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
|
||||||
|
"prebuild": "yarn run clean",
|
||||||
|
"predev": "yarn run prebuild",
|
||||||
|
"prepublishOnly": "yarn run build"
|
||||||
|
}
|
||||||
|
}
|
26
@xen-orchestra/emit-async/src/index.js
Normal file
26
@xen-orchestra/emit-async/src/index.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
export default function emitAsync (event) {
|
||||||
|
let opts
|
||||||
|
let i = 1
|
||||||
|
|
||||||
|
// an option object has been passed as first param
|
||||||
|
if (typeof event !== 'string') {
|
||||||
|
opts = event
|
||||||
|
event = arguments[i++]
|
||||||
|
}
|
||||||
|
|
||||||
|
const n = arguments.length - i
|
||||||
|
const args = new Array(n)
|
||||||
|
for (let j = 0; j < n; ++j) {
|
||||||
|
args[j] = arguments[j + i]
|
||||||
|
}
|
||||||
|
|
||||||
|
const onError = opts != null && opts.onError
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
this.listeners(event).map(listener =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
resolve(listener.apply(this, args))
|
||||||
|
}).catch(onError)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
### Released packages
|
### Released packages
|
||||||
|
|
||||||
|
- @xen-orchestra/emit-async v0.0.0
|
||||||
- xo-server v5.27.0
|
- xo-server v5.27.0
|
||||||
- xo-web v5.27.0
|
- xo-web v5.27.0
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "7.0.0",
|
"@babel/polyfill": "7.0.0",
|
||||||
"@xen-orchestra/cron": "^1.0.3",
|
"@xen-orchestra/cron": "^1.0.3",
|
||||||
|
"@xen-orchestra/emit-async": "^0.0.0",
|
||||||
"@xen-orchestra/fs": "^0.3.0",
|
"@xen-orchestra/fs": "^0.3.0",
|
||||||
"ajv": "^6.1.1",
|
"ajv": "^6.1.1",
|
||||||
"app-conf": "^0.5.0",
|
"app-conf": "^0.5.0",
|
||||||
|
@ -1,34 +1,8 @@
|
|||||||
import createLogger from 'debug'
|
import createLogger from 'debug'
|
||||||
|
import emitAsync from '@xen-orchestra/emit-async'
|
||||||
|
|
||||||
const debug = createLogger('xo:hooks')
|
const debug = createLogger('xo:hooks')
|
||||||
|
|
||||||
function emitAsync (event) {
|
|
||||||
let opts
|
|
||||||
let i = 1
|
|
||||||
|
|
||||||
// an option object has been passed as first param
|
|
||||||
if (typeof event !== 'string') {
|
|
||||||
opts = event
|
|
||||||
event = arguments[i++]
|
|
||||||
}
|
|
||||||
|
|
||||||
const n = arguments.length - i
|
|
||||||
const args = new Array(n)
|
|
||||||
for (let j = 0; j < n; ++j) {
|
|
||||||
args[j] = arguments[j + i]
|
|
||||||
}
|
|
||||||
|
|
||||||
const onError = opts != null && opts.onError
|
|
||||||
|
|
||||||
return Promise.all(
|
|
||||||
this.listeners(event).map(listener =>
|
|
||||||
new Promise(resolve => {
|
|
||||||
resolve(listener.apply(this, args))
|
|
||||||
}).catch(onError)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeSingletonHook = (hook, postEvent) => {
|
const makeSingletonHook = (hook, postEvent) => {
|
||||||
let promise
|
let promise
|
||||||
return function () {
|
return function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user