Skip to content

Commit 88decae

Browse files
author
pooya parsa
committed
feat: rewrite for 1.0.0
BREAKING CHANGE: api change
1 parent a947b64 commit 88decae

File tree

13 files changed

+3117
-2750
lines changed

13 files changed

+3117
-2750
lines changed

.babelrc

Lines changed: 0 additions & 7 deletions
This file was deleted.

.eslintrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extends: standard

README.md

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![npm](https://img.shields.io/npm/dt/hable.svg?style=flat-square)](https://www.npmjs.com/package/hable)
77
[![size](http://img.badgesize.io/https://unpkg.com/hable/dist/hable.cjs.min.js?compression=gzip&style=flat-square)](https://unpkg.com/hable)
88

9-
> A simpler tapable alternative, which can be used to create hooks for plugins.
9+
> Awaitable hooks for Node.js
1010
1111
## Install
1212

@@ -39,8 +39,8 @@ export default class Foo extends Hookable {
3939
// Call and wait for `hook1` hooks (if any) sequential
4040
await this.callHook('hook1')
4141

42-
// Call and wait for `hook2` hooks (if any) in paraller
43-
await this.callHookAsync('hook2')
42+
// Call and wait for `hook2` hooks (if any) in parallel
43+
await this.callHookParallel('hook2')
4444
}
4545
}
4646
```
@@ -62,19 +62,48 @@ lib.hookObj({
6262

6363
## Hookable class
6464

65-
**private functions**
6665

67-
* `async callHook(name, ...args)`: Used by class itself to **sequentially** call handlers of a specific hook.
68-
* `async callHookAsync(name, ...args)`: Same as `callHook` but calls handlers in **parallel**.
66+
### `hook (name, fn)`
6967

70-
**public functions**
68+
Register a handler for a specific hook. `fn` can be a single function or an array.
7169

72-
* `hook(name, fn)`: Used by plugins to register a handler for an specific hook. `fn` can be a single function or an array.
73-
* `hookObj(hooksObj)`: Register many hooks using an object.
70+
### `addHooks(configHooks)`
7471

75-
**private attributes**
72+
Flatten and register hooks object.
7673

77-
* `$hooks`: An object which maps from each hook name to it's handlers.
74+
Example:
75+
76+
```js
77+
hookable.addHooks({
78+
test: {
79+
before: () => {},
80+
after: () => {}
81+
}
82+
})
83+
84+
```
85+
86+
This registers `test:before` and `test:after` hooks at bulk.
87+
88+
### `async callHook (name, ...args)`
89+
90+
Used by class itself to **sequentially** call handlers of a specific hook.
91+
92+
### `deprecateHook (old, name)`
93+
94+
Deprecate hook called `old` in flavor of `name` hook.
95+
96+
### `clearHook (name)`
97+
98+
Clear all hooks for a specific hook.
99+
100+
### `clearHooks ()`
101+
102+
Clear all hooks registered in the class.
103+
104+
### `flatHooks (hooksObj)`
105+
106+
Register many hooks using an object.
78107

79108
## Credits
80109

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
'testEnvironment': 'node',
3+
'collectCoverage': true,
4+
'collectCoverageFrom': [
5+
'lib/**/*.js'
6+
]
7+
}

lib/hookable.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const { serial } = require('items-promise')
2+
const consola = require('consola')
3+
const { flatHooks } = require('./utils')
4+
5+
module.exports = class Hookable {
6+
constructor () {
7+
this._hooks = {}
8+
this._deprecatedHooks = {}
9+
10+
this.hook = this.hook.bind(this)
11+
this.callHook = this.callHook.bind(this)
12+
}
13+
14+
hook (name, fn) {
15+
if (!name || typeof fn !== 'function') {
16+
return
17+
}
18+
19+
if (this._deprecatedHooks[name]) {
20+
consola.warn(`${name} hook has been deprecated, please use ${this._deprecatedHooks[name]}`)
21+
name = this._deprecatedHooks[name]
22+
}
23+
24+
this._hooks[name] = this._hooks[name] || []
25+
this._hooks[name].push(fn)
26+
}
27+
28+
deprecateHook (old, name) {
29+
this._deprecatedHooks[old] = name
30+
}
31+
32+
addHooks (configHooks) {
33+
const hooks = flatHooks(configHooks)
34+
for (const key in hooks) {
35+
this.hook(key, hooks[key])
36+
}
37+
}
38+
39+
async callHook (name, ...args) {
40+
if (!this._hooks[name]) {
41+
return
42+
}
43+
try {
44+
await serial(this._hooks[name], fn => fn(...args))
45+
} catch (err) {
46+
name !== 'error' && await this.callHook('error', err)
47+
consola.error(err)
48+
}
49+
}
50+
51+
clearHook (name) {
52+
if (name) {
53+
delete this._hooks[name]
54+
}
55+
}
56+
57+
clearHooks () {
58+
this._hooks = {}
59+
}
60+
}

lib/utils.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
exports.flatHooks = function flatHooks (configHooks, hooks = {}, parentName) {
2+
for (const key in configHooks) {
3+
const subHook = configHooks[key]
4+
const name = parentName ? `${parentName}:${key}` : key
5+
if (typeof subHook === 'object' && subHook !== null) {
6+
flatHooks(subHook, hooks, name)
7+
} else {
8+
hooks[name] = subHook
9+
}
10+
}
11+
return hooks
12+
}

package.json

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
{
22
"name": "hable",
33
"version": "0.0.7",
4-
"description": "A simpler tapable alternative, which can be used to create hooks for plugins",
5-
"author": "Pooya Parsa <pooya@pi0.ir>",
4+
"description": "Awaitable hooks for Node.js",
5+
"cintributors": [
6+
"Sebastien Chopin (@Atinux)",
7+
"Clark Du (@clarkdo)",
8+
"Pooya Parsa <pooya@pi0.ir>"
9+
],
610
"license": "MIT",
7-
"homepage": "https://github.com/pi0/hable#readme",
11+
"homepage": "https://github.com/jsless/hable#readme",
812
"repository": {
913
"type": "git",
10-
"url": "git+https://github.com/pi0/hable.git"
14+
"url": "git+https://github.com/jsless/hable.git"
1115
},
1216
"bugs": {
13-
"url": "https://github.com/pi0/hable/issues"
17+
"url": "https://github.com/jsless/hable/issues"
1418
},
1519
"keywords": [
1620
"tapable",
@@ -19,26 +23,30 @@
1923
"plugin",
2024
"hookable"
2125
],
22-
"main": "dist/hable.cjs.js",
23-
"module": "dist/hable.es.js",
24-
"jsnext:main": "dist/hable.es.js",
26+
"main": "lib/hable.js",
27+
"files": [
28+
"lib"
29+
],
2530
"scripts": {
26-
"build": "bili --format es,cjs,cjs-min --inline",
27-
"test": "jest",
28-
"dev": "npm run build --watch",
29-
"release": "npm run build && standard-version",
30-
"release2": "git push --follow-tags && npm publish"
31+
"test": "yarn lint && jest",
32+
"lint": "eslint",
33+
"prepublish": "yarn test",
34+
"release": "standard-version && git push --follow-tags && npm publish"
3135
},
3236
"dependencies": {
37+
"consola": "^2.4.0",
3338
"items-promise": "^1.0.0"
3439
},
3540
"devDependencies": {
36-
"babel-core": "^6.26.0",
37-
"babel-jest": "^22.1.0",
38-
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
39-
"bili": "^2.2.3",
4041
"codecov": "^3.0.0",
41-
"jest": "^22.1.4",
42+
"eslint": "^5.13.0",
43+
"eslint-config-standard": "^12.0.0",
44+
"eslint-plugin-import": "^2.16.0",
45+
"eslint-plugin-jest": "^22.2.2",
46+
"eslint-plugin-node": "^8.0.1",
47+
"eslint-plugin-promise": "^4.0.1",
48+
"eslint-plugin-standard": "^4.0.0",
49+
"jest": "^24.1.0",
4250
"standard-version": "^4.3.0"
4351
}
4452
}

renovate.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": [
3+
"@nuxtjs"
4+
],
5+
"baseBranches": [
6+
"dev"
7+
],
8+
"ignoreDeps": [
9+
"thread-loader"
10+
]
11+
}

src/index.js

Lines changed: 0 additions & 42 deletions
This file was deleted.

test/.eslintrc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
plugins:
2+
- jest
3+
env:
4+
jest/globals: true

0 commit comments

Comments
 (0)