hookable 5.3.0 → 5.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/index.cjs +61 -2
- package/dist/index.d.ts +27 -3
- package/dist/index.mjs +61 -3
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -220,6 +220,19 @@ hookable.hook('test', () => { console.log('running test hook') })
|
|
|
220
220
|
await hookable.callHook('test')
|
|
221
221
|
```
|
|
222
222
|
|
|
223
|
+
### `createDebugger`
|
|
224
|
+
|
|
225
|
+
Automatically logs each hook that is called and how long it takes to run.
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
const debug = hookable.createDebugger(hooks, { tag: 'something' })
|
|
229
|
+
|
|
230
|
+
hooks.callHook('some-hook', 'some-arg')
|
|
231
|
+
// [something] some-hook: 0.21ms
|
|
232
|
+
|
|
233
|
+
debug.close()
|
|
234
|
+
```
|
|
235
|
+
|
|
223
236
|
## Migration
|
|
224
237
|
|
|
225
238
|
### From `4.x` to `5.x`
|
package/dist/index.cjs
CHANGED
|
@@ -158,12 +158,12 @@ class Hookable {
|
|
|
158
158
|
const result = caller(this._hooks[name] || [], args);
|
|
159
159
|
if (result instanceof Promise) {
|
|
160
160
|
return result.finally(() => {
|
|
161
|
-
if (this._after) {
|
|
161
|
+
if (this._after && event) {
|
|
162
162
|
callEachWith(this._after, event);
|
|
163
163
|
}
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
|
-
if (this._after) {
|
|
166
|
+
if (this._after && event) {
|
|
167
167
|
callEachWith(this._after, event);
|
|
168
168
|
}
|
|
169
169
|
return result;
|
|
@@ -171,17 +171,76 @@ class Hookable {
|
|
|
171
171
|
beforeEach(fn) {
|
|
172
172
|
this._before = this._before || [];
|
|
173
173
|
this._before.push(fn);
|
|
174
|
+
return () => {
|
|
175
|
+
const index = this._before.indexOf(fn);
|
|
176
|
+
if (index !== -1) {
|
|
177
|
+
this._before.splice(index, 1);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
174
180
|
}
|
|
175
181
|
afterEach(fn) {
|
|
176
182
|
this._after = this._after || [];
|
|
177
183
|
this._after.push(fn);
|
|
184
|
+
return () => {
|
|
185
|
+
const index = this._after.indexOf(fn);
|
|
186
|
+
if (index !== -1) {
|
|
187
|
+
this._after.splice(index, 1);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
178
190
|
}
|
|
179
191
|
}
|
|
180
192
|
function createHooks() {
|
|
181
193
|
return new Hookable();
|
|
182
194
|
}
|
|
183
195
|
|
|
196
|
+
const isBrowser = typeof window !== "undefined";
|
|
197
|
+
function createDebugger(hooks, _options = {}) {
|
|
198
|
+
const options = {
|
|
199
|
+
inspect: isBrowser,
|
|
200
|
+
group: isBrowser,
|
|
201
|
+
filter: () => true,
|
|
202
|
+
..._options
|
|
203
|
+
};
|
|
204
|
+
const _filter = options.filter;
|
|
205
|
+
const filter = typeof _filter === "string" ? (name) => name.startsWith(_filter) : _filter;
|
|
206
|
+
const _tag = options.tag ? `[${options.tag}] ` : "";
|
|
207
|
+
const logPrefix = (event) => _tag + event.name + "".padEnd(event._id, "\0");
|
|
208
|
+
const _idCtr = {};
|
|
209
|
+
const unsubscribeBefore = hooks.beforeEach((event) => {
|
|
210
|
+
if (!filter(event.name)) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
_idCtr[event.name] = _idCtr[event.name] || 0;
|
|
214
|
+
event._id = _idCtr[event.name]++;
|
|
215
|
+
console.time(logPrefix(event));
|
|
216
|
+
});
|
|
217
|
+
const unsubscribeAfter = hooks.afterEach((event) => {
|
|
218
|
+
if (!filter(event.name)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (options.group) {
|
|
222
|
+
console.groupCollapsed(event.name);
|
|
223
|
+
}
|
|
224
|
+
if (options.inspect) {
|
|
225
|
+
console.timeLog(logPrefix(event), event.args);
|
|
226
|
+
} else {
|
|
227
|
+
console.timeEnd(logPrefix(event));
|
|
228
|
+
}
|
|
229
|
+
if (options.group) {
|
|
230
|
+
console.groupEnd();
|
|
231
|
+
}
|
|
232
|
+
_idCtr[event.name]--;
|
|
233
|
+
});
|
|
234
|
+
return {
|
|
235
|
+
close: () => {
|
|
236
|
+
unsubscribeBefore();
|
|
237
|
+
unsubscribeAfter();
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
184
242
|
exports.Hookable = Hookable;
|
|
243
|
+
exports.createDebugger = createDebugger;
|
|
185
244
|
exports.createHooks = createHooks;
|
|
186
245
|
exports.flatHooks = flatHooks;
|
|
187
246
|
exports.mergeHooks = mergeHooks;
|
package/dist/index.d.ts
CHANGED
|
@@ -62,8 +62,8 @@ declare class Hookable<HooksT = Record<string, HookCallback>, HookNameT extends
|
|
|
62
62
|
callHook<NameT extends HookNameT>(name: NameT, ...args: Parameters<InferCallback<HooksT, NameT>>): Promise<any>;
|
|
63
63
|
callHookParallel<NameT extends HookNameT>(name: NameT, ...args: Parameters<InferCallback<HooksT, NameT>>): Promise<any[]>;
|
|
64
64
|
callHookWith<NameT extends HookNameT, CallFunction extends (hooks: HookCallback[], args: Parameters<InferCallback<HooksT, NameT>>) => any>(caller: CallFunction, name: NameT, ...args: Parameters<InferCallback<HooksT, NameT>>): ReturnType<CallFunction>;
|
|
65
|
-
beforeEach(fn: (event: InferSpyEvent<HooksT>) => void): void;
|
|
66
|
-
afterEach(fn: (event: InferSpyEvent<HooksT>) => void): void;
|
|
65
|
+
beforeEach(fn: (event: InferSpyEvent<HooksT>) => void): () => void;
|
|
66
|
+
afterEach(fn: (event: InferSpyEvent<HooksT>) => void): () => void;
|
|
67
67
|
}
|
|
68
68
|
declare function createHooks<T>(): Hookable<T>;
|
|
69
69
|
|
|
@@ -73,4 +73,28 @@ declare function serial<T>(tasks: T[], fn: (task: T) => Promise<any> | any): Pro
|
|
|
73
73
|
declare function serialCaller(hooks: HookCallback[], args?: any[]): Promise<any>;
|
|
74
74
|
declare function parallelCaller(hooks: HookCallback[], args?: any[]): Promise<any[]>;
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
interface CreateDebuggerOptions {
|
|
77
|
+
/** An optional tag to prefix console logs with */
|
|
78
|
+
tag?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Show hook params to the console output
|
|
81
|
+
*
|
|
82
|
+
* Enabled for browsers by default
|
|
83
|
+
*/
|
|
84
|
+
inspect?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Use group/groupEnd wrapper around logs happening during a specific hook
|
|
87
|
+
*
|
|
88
|
+
* Enabled for browsers by default
|
|
89
|
+
*/
|
|
90
|
+
group?: boolean;
|
|
91
|
+
/** Filter which hooks to enable debugger for. Can be a string prefix or fn. */
|
|
92
|
+
filter?: string | ((event: string) => boolean);
|
|
93
|
+
}
|
|
94
|
+
/** Start debugging hook names and timing in console */
|
|
95
|
+
declare function createDebugger(hooks: Hookable<any>, _options?: CreateDebuggerOptions): {
|
|
96
|
+
/** Stop debugging and remove listeners */
|
|
97
|
+
close: () => void;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export { CreateDebuggerOptions, DeprecatedHook, DeprecatedHooks, HookCallback, HookKeys, Hookable, Hooks, NestedHooks, createDebugger, createHooks, flatHooks, mergeHooks, parallelCaller, serial, serialCaller };
|
package/dist/index.mjs
CHANGED
|
@@ -154,12 +154,12 @@ class Hookable {
|
|
|
154
154
|
const result = caller(this._hooks[name] || [], args);
|
|
155
155
|
if (result instanceof Promise) {
|
|
156
156
|
return result.finally(() => {
|
|
157
|
-
if (this._after) {
|
|
157
|
+
if (this._after && event) {
|
|
158
158
|
callEachWith(this._after, event);
|
|
159
159
|
}
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
-
if (this._after) {
|
|
162
|
+
if (this._after && event) {
|
|
163
163
|
callEachWith(this._after, event);
|
|
164
164
|
}
|
|
165
165
|
return result;
|
|
@@ -167,14 +167,72 @@ class Hookable {
|
|
|
167
167
|
beforeEach(fn) {
|
|
168
168
|
this._before = this._before || [];
|
|
169
169
|
this._before.push(fn);
|
|
170
|
+
return () => {
|
|
171
|
+
const index = this._before.indexOf(fn);
|
|
172
|
+
if (index !== -1) {
|
|
173
|
+
this._before.splice(index, 1);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
170
176
|
}
|
|
171
177
|
afterEach(fn) {
|
|
172
178
|
this._after = this._after || [];
|
|
173
179
|
this._after.push(fn);
|
|
180
|
+
return () => {
|
|
181
|
+
const index = this._after.indexOf(fn);
|
|
182
|
+
if (index !== -1) {
|
|
183
|
+
this._after.splice(index, 1);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
174
186
|
}
|
|
175
187
|
}
|
|
176
188
|
function createHooks() {
|
|
177
189
|
return new Hookable();
|
|
178
190
|
}
|
|
179
191
|
|
|
180
|
-
|
|
192
|
+
const isBrowser = typeof window !== "undefined";
|
|
193
|
+
function createDebugger(hooks, _options = {}) {
|
|
194
|
+
const options = {
|
|
195
|
+
inspect: isBrowser,
|
|
196
|
+
group: isBrowser,
|
|
197
|
+
filter: () => true,
|
|
198
|
+
..._options
|
|
199
|
+
};
|
|
200
|
+
const _filter = options.filter;
|
|
201
|
+
const filter = typeof _filter === "string" ? (name) => name.startsWith(_filter) : _filter;
|
|
202
|
+
const _tag = options.tag ? `[${options.tag}] ` : "";
|
|
203
|
+
const logPrefix = (event) => _tag + event.name + "".padEnd(event._id, "\0");
|
|
204
|
+
const _idCtr = {};
|
|
205
|
+
const unsubscribeBefore = hooks.beforeEach((event) => {
|
|
206
|
+
if (!filter(event.name)) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
_idCtr[event.name] = _idCtr[event.name] || 0;
|
|
210
|
+
event._id = _idCtr[event.name]++;
|
|
211
|
+
console.time(logPrefix(event));
|
|
212
|
+
});
|
|
213
|
+
const unsubscribeAfter = hooks.afterEach((event) => {
|
|
214
|
+
if (!filter(event.name)) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (options.group) {
|
|
218
|
+
console.groupCollapsed(event.name);
|
|
219
|
+
}
|
|
220
|
+
if (options.inspect) {
|
|
221
|
+
console.timeLog(logPrefix(event), event.args);
|
|
222
|
+
} else {
|
|
223
|
+
console.timeEnd(logPrefix(event));
|
|
224
|
+
}
|
|
225
|
+
if (options.group) {
|
|
226
|
+
console.groupEnd();
|
|
227
|
+
}
|
|
228
|
+
_idCtr[event.name]--;
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
close: () => {
|
|
232
|
+
unsubscribeBefore();
|
|
233
|
+
unsubscribeAfter();
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export { Hookable, createDebugger, createHooks, flatHooks, mergeHooks, parallelCaller, serial, serialCaller };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hookable",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.1",
|
|
4
4
|
"description": "Awaitable hook system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hook",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@nuxtjs/eslint-config-typescript": "
|
|
26
|
-
"@vitest/coverage-c8": "^0.
|
|
27
|
-
"eslint": "
|
|
28
|
-
"expect-type": "^0.
|
|
29
|
-
"standard-version": "
|
|
25
|
+
"@nuxtjs/eslint-config-typescript": "^11.0.0",
|
|
26
|
+
"@vitest/coverage-c8": "^0.24.3",
|
|
27
|
+
"eslint": "^8.25.0",
|
|
28
|
+
"expect-type": "^0.14.2",
|
|
29
|
+
"standard-version": "^9.5.0",
|
|
30
30
|
"typescript": "latest",
|
|
31
|
-
"unbuild": "
|
|
32
|
-
"vitest": "
|
|
31
|
+
"unbuild": "^0.8.2",
|
|
32
|
+
"vitest": "^0.24.3"
|
|
33
33
|
},
|
|
34
|
-
"packageManager": "pnpm@7.
|
|
34
|
+
"packageManager": "pnpm@7.13.4",
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "unbuild",
|
|
37
37
|
"dev": "vitest",
|