hookable 5.4.1 → 5.5.0
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/LICENSE.md +1 -1
- package/dist/index.cjs +86 -47
- package/dist/index.d.ts +30 -27
- package/dist/index.mjs +86 -45
- package/package.json +16 -12
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) Pooya Parsa <pooya@pi0.io>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
function flatHooks(configHooks, hooks = {}, parentName) {
|
|
6
4
|
for (const key in configHooks) {
|
|
7
5
|
const subHook = configHooks[key];
|
|
@@ -28,42 +26,62 @@ function mergeHooks(...hooks) {
|
|
|
28
26
|
}
|
|
29
27
|
for (const key in finalHooks) {
|
|
30
28
|
if (finalHooks[key].length > 1) {
|
|
31
|
-
const
|
|
32
|
-
finalHooks[key] = (...
|
|
29
|
+
const array = finalHooks[key];
|
|
30
|
+
finalHooks[key] = (...arguments_) => serial(array, (function_) => function_(...arguments_));
|
|
33
31
|
} else {
|
|
34
32
|
finalHooks[key] = finalHooks[key][0];
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
return finalHooks;
|
|
38
36
|
}
|
|
39
|
-
function serial(tasks,
|
|
40
|
-
return tasks.reduce(
|
|
37
|
+
function serial(tasks, function_) {
|
|
38
|
+
return tasks.reduce(
|
|
39
|
+
(promise, task) => promise.then(() => function_(task)),
|
|
40
|
+
Promise.resolve()
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const defaultTask = { run: (function_) => function_() };
|
|
44
|
+
const _createTask = () => defaultTask;
|
|
45
|
+
const createTask = typeof console.createTask !== "undefined" ? console.createTask : _createTask;
|
|
46
|
+
function serialTaskCaller(hooks, name, ...args) {
|
|
47
|
+
const task = createTask(name);
|
|
48
|
+
return hooks.reduce(
|
|
49
|
+
(promise, hookFunction) => promise.then(() => task.run(() => hookFunction(...args))),
|
|
50
|
+
Promise.resolve()
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
function parallelTaskCaller(hooks, name, ...args) {
|
|
54
|
+
const task = createTask(name);
|
|
55
|
+
return Promise.all(hooks.map((hook) => task.run(() => hook(...args))));
|
|
41
56
|
}
|
|
42
|
-
function serialCaller(hooks,
|
|
43
|
-
return hooks.reduce(
|
|
57
|
+
function serialCaller(hooks, arguments_) {
|
|
58
|
+
return hooks.reduce(
|
|
59
|
+
(promise, hookFunction) => promise.then(() => hookFunction(...arguments_)),
|
|
60
|
+
Promise.resolve()
|
|
61
|
+
);
|
|
44
62
|
}
|
|
45
63
|
function parallelCaller(hooks, args) {
|
|
46
|
-
return Promise.all(hooks.map((hook) => hook
|
|
64
|
+
return Promise.all(hooks.map((hook) => hook(...args)));
|
|
47
65
|
}
|
|
48
66
|
function callEachWith(callbacks, arg0) {
|
|
49
|
-
for (const
|
|
50
|
-
|
|
67
|
+
for (const callback of callbacks) {
|
|
68
|
+
callback(arg0);
|
|
51
69
|
}
|
|
52
70
|
}
|
|
53
71
|
|
|
54
72
|
class Hookable {
|
|
55
73
|
constructor() {
|
|
56
74
|
this._hooks = {};
|
|
57
|
-
this._before =
|
|
58
|
-
this._after =
|
|
59
|
-
this._deprecatedMessages =
|
|
75
|
+
this._before = void 0;
|
|
76
|
+
this._after = void 0;
|
|
77
|
+
this._deprecatedMessages = void 0;
|
|
60
78
|
this._deprecatedHooks = {};
|
|
61
79
|
this.hook = this.hook.bind(this);
|
|
62
80
|
this.callHook = this.callHook.bind(this);
|
|
63
81
|
this.callHookWith = this.callHookWith.bind(this);
|
|
64
82
|
}
|
|
65
|
-
hook(name,
|
|
66
|
-
if (!name || typeof
|
|
83
|
+
hook(name, function_, options = {}) {
|
|
84
|
+
if (!name || typeof function_ !== "function") {
|
|
67
85
|
return () => {
|
|
68
86
|
};
|
|
69
87
|
}
|
|
@@ -73,7 +91,7 @@ class Hookable {
|
|
|
73
91
|
dep = this._deprecatedHooks[name];
|
|
74
92
|
name = dep.to;
|
|
75
93
|
}
|
|
76
|
-
if (dep && !
|
|
94
|
+
if (dep && !options.allowDeprecated) {
|
|
77
95
|
let message = dep.message;
|
|
78
96
|
if (!message) {
|
|
79
97
|
message = `${originalName} hook has been deprecated` + (dep.to ? `, please use ${dep.to}` : "");
|
|
@@ -86,31 +104,42 @@ class Hookable {
|
|
|
86
104
|
this._deprecatedMessages.add(message);
|
|
87
105
|
}
|
|
88
106
|
}
|
|
107
|
+
if (!function_.name) {
|
|
108
|
+
try {
|
|
109
|
+
Object.defineProperty(function_, "name", {
|
|
110
|
+
get: () => "_" + name.replace(/\W+/g, "_") + "_hook_cb",
|
|
111
|
+
configurable: true
|
|
112
|
+
});
|
|
113
|
+
} catch {
|
|
114
|
+
}
|
|
115
|
+
}
|
|
89
116
|
this._hooks[name] = this._hooks[name] || [];
|
|
90
|
-
this._hooks[name].push(
|
|
117
|
+
this._hooks[name].push(function_);
|
|
91
118
|
return () => {
|
|
92
|
-
if (
|
|
93
|
-
this.removeHook(name,
|
|
94
|
-
|
|
119
|
+
if (function_) {
|
|
120
|
+
this.removeHook(name, function_);
|
|
121
|
+
function_ = void 0;
|
|
95
122
|
}
|
|
96
123
|
};
|
|
97
124
|
}
|
|
98
|
-
hookOnce(name,
|
|
125
|
+
hookOnce(name, function_) {
|
|
99
126
|
let _unreg;
|
|
100
|
-
let
|
|
101
|
-
_unreg
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
127
|
+
let _function = (...arguments_) => {
|
|
128
|
+
if (typeof _unreg === "function") {
|
|
129
|
+
_unreg();
|
|
130
|
+
}
|
|
131
|
+
_unreg = void 0;
|
|
132
|
+
_function = void 0;
|
|
133
|
+
return function_(...arguments_);
|
|
105
134
|
};
|
|
106
|
-
_unreg = this.hook(name,
|
|
135
|
+
_unreg = this.hook(name, _function);
|
|
107
136
|
return _unreg;
|
|
108
137
|
}
|
|
109
|
-
removeHook(name,
|
|
138
|
+
removeHook(name, function_) {
|
|
110
139
|
if (this._hooks[name]) {
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
113
|
-
this._hooks[name].splice(
|
|
140
|
+
const index = this._hooks[name].indexOf(function_);
|
|
141
|
+
if (index !== -1) {
|
|
142
|
+
this._hooks[name].splice(index, 1);
|
|
114
143
|
}
|
|
115
144
|
if (this._hooks[name].length === 0) {
|
|
116
145
|
delete this._hooks[name];
|
|
@@ -133,9 +162,13 @@ class Hookable {
|
|
|
133
162
|
}
|
|
134
163
|
addHooks(configHooks) {
|
|
135
164
|
const hooks = flatHooks(configHooks);
|
|
136
|
-
const removeFns = Object.keys(hooks).map(
|
|
165
|
+
const removeFns = Object.keys(hooks).map(
|
|
166
|
+
(key) => this.hook(key, hooks[key])
|
|
167
|
+
);
|
|
137
168
|
return () => {
|
|
138
|
-
removeFns.splice(0, removeFns.length)
|
|
169
|
+
for (const unreg of removeFns.splice(0, removeFns.length)) {
|
|
170
|
+
unreg();
|
|
171
|
+
}
|
|
139
172
|
};
|
|
140
173
|
}
|
|
141
174
|
removeHooks(configHooks) {
|
|
@@ -144,18 +177,23 @@ class Hookable {
|
|
|
144
177
|
this.removeHook(key, hooks[key]);
|
|
145
178
|
}
|
|
146
179
|
}
|
|
147
|
-
|
|
148
|
-
|
|
180
|
+
removeAllHooks() {
|
|
181
|
+
for (const key in this._hooks) {
|
|
182
|
+
delete this._hooks[key];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
callHook(name, ...arguments_) {
|
|
186
|
+
return this.callHookWith(serialTaskCaller, name, ...arguments_);
|
|
149
187
|
}
|
|
150
|
-
callHookParallel(name, ...
|
|
151
|
-
return this.callHookWith(
|
|
188
|
+
callHookParallel(name, ...arguments_) {
|
|
189
|
+
return this.callHookWith(parallelTaskCaller, name, ...arguments_);
|
|
152
190
|
}
|
|
153
|
-
callHookWith(caller, name, ...
|
|
154
|
-
const event = this._before || this._after ? { name, args, context: {} } : void 0;
|
|
191
|
+
callHookWith(caller, name, ...arguments_) {
|
|
192
|
+
const event = this._before || this._after ? { name, args: arguments_, context: {} } : void 0;
|
|
155
193
|
if (this._before) {
|
|
156
194
|
callEachWith(this._before, event);
|
|
157
195
|
}
|
|
158
|
-
const result = caller(this._hooks[name] || [],
|
|
196
|
+
const result = caller(this._hooks[name] || [], arguments_);
|
|
159
197
|
if (result instanceof Promise) {
|
|
160
198
|
return result.finally(() => {
|
|
161
199
|
if (this._after && event) {
|
|
@@ -168,21 +206,21 @@ class Hookable {
|
|
|
168
206
|
}
|
|
169
207
|
return result;
|
|
170
208
|
}
|
|
171
|
-
beforeEach(
|
|
209
|
+
beforeEach(function_) {
|
|
172
210
|
this._before = this._before || [];
|
|
173
|
-
this._before.push(
|
|
211
|
+
this._before.push(function_);
|
|
174
212
|
return () => {
|
|
175
|
-
const index = this._before.indexOf(
|
|
213
|
+
const index = this._before.indexOf(function_);
|
|
176
214
|
if (index !== -1) {
|
|
177
215
|
this._before.splice(index, 1);
|
|
178
216
|
}
|
|
179
217
|
};
|
|
180
218
|
}
|
|
181
|
-
afterEach(
|
|
219
|
+
afterEach(function_) {
|
|
182
220
|
this._after = this._after || [];
|
|
183
|
-
this._after.push(
|
|
221
|
+
this._after.push(function_);
|
|
184
222
|
return () => {
|
|
185
|
-
const index = this._after.indexOf(
|
|
223
|
+
const index = this._after.indexOf(function_);
|
|
186
224
|
if (index !== -1) {
|
|
187
225
|
this._after.splice(index, 1);
|
|
188
226
|
}
|
|
@@ -232,6 +270,7 @@ function createDebugger(hooks, _options = {}) {
|
|
|
232
270
|
_idCtr[event.name]--;
|
|
233
271
|
});
|
|
234
272
|
return {
|
|
273
|
+
/** Stop debugging and remove listeners */
|
|
235
274
|
close: () => {
|
|
236
275
|
unsubscribeBefore();
|
|
237
276
|
unsubscribeAfter();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
type HookCallback = (...arguments_: any) => Promise<void> | void;
|
|
2
2
|
interface Hooks {
|
|
3
3
|
[key: string]: HookCallback;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
type HookKeys<T> = keyof T & string;
|
|
6
|
+
type DeprecatedHook<T> = {
|
|
7
7
|
message?: string;
|
|
8
8
|
to: HookKeys<T>;
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
type DeprecatedHooks<T> = {
|
|
11
11
|
[name in HookKeys<T>]: DeprecatedHook<T>;
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
type ValueOf<C> = C extends Record<any, any> ? C[keyof C] : never;
|
|
14
|
+
type Strings<T> = Exclude<keyof T, number | symbol>;
|
|
15
|
+
type KnownKeys<T> = keyof {
|
|
16
16
|
[K in keyof T as string extends K ? never : number extends K ? never : K]: never;
|
|
17
17
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
type StripGeneric<T> = Pick<T, KnownKeys<T> extends keyof T ? KnownKeys<T> : never>;
|
|
19
|
+
type OnlyGeneric<T> = Omit<T, KnownKeys<T> extends keyof T ? KnownKeys<T> : never>;
|
|
20
|
+
type Namespaces<T> = ValueOf<{
|
|
21
21
|
[key in Strings<T>]: key extends `${infer Namespace}:${string}` ? Namespace : never;
|
|
22
22
|
}>;
|
|
23
|
-
|
|
23
|
+
type BareHooks<T> = ValueOf<{
|
|
24
24
|
[key in Strings<T>]: key extends `${string}:${string}` ? never : key;
|
|
25
25
|
}>;
|
|
26
|
-
|
|
26
|
+
type HooksInNamespace<T, Namespace extends string> = ValueOf<{
|
|
27
27
|
[key in Strings<T>]: key extends `${Namespace}:${infer HookName}` ? HookName : never;
|
|
28
28
|
}>;
|
|
29
|
-
|
|
29
|
+
type WithoutNamespace<T, Namespace extends string> = {
|
|
30
30
|
[key in HooksInNamespace<T, Namespace>]: `${Namespace}:${key}` extends keyof T ? T[`${Namespace}:${key}`] : never;
|
|
31
31
|
};
|
|
32
|
-
|
|
32
|
+
type NestedHooks<T> = (Partial<StripGeneric<T>> | Partial<OnlyGeneric<T>>) & Partial<{
|
|
33
33
|
[key in Namespaces<StripGeneric<T>>]: NestedHooks<WithoutNamespace<T, key>>;
|
|
34
34
|
}> & Partial<{
|
|
35
35
|
[key in BareHooks<StripGeneric<T>>]: T[key];
|
|
36
36
|
}>;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
type InferCallback<HT, HN extends keyof HT> = HT[HN] extends HookCallback ? HT[HN] : never;
|
|
39
|
+
type InferSpyEvent<HT extends Record<string, any>> = {
|
|
40
40
|
[key in keyof HT]: {
|
|
41
41
|
name: key;
|
|
42
42
|
args: Parameters<HT[key]>;
|
|
@@ -50,28 +50,31 @@ declare class Hookable<HooksT = Record<string, HookCallback>, HookNameT extends
|
|
|
50
50
|
private _deprecatedHooks;
|
|
51
51
|
private _deprecatedMessages;
|
|
52
52
|
constructor();
|
|
53
|
-
hook<NameT extends HookNameT>(name: NameT,
|
|
53
|
+
hook<NameT extends HookNameT>(name: NameT, function_: InferCallback<HooksT, NameT>, options?: {
|
|
54
54
|
allowDeprecated?: boolean;
|
|
55
55
|
}): () => void;
|
|
56
|
-
hookOnce<NameT extends HookNameT>(name: NameT,
|
|
57
|
-
removeHook<NameT extends HookNameT>(name: NameT,
|
|
56
|
+
hookOnce<NameT extends HookNameT>(name: NameT, function_: InferCallback<HooksT, NameT>): () => void;
|
|
57
|
+
removeHook<NameT extends HookNameT>(name: NameT, function_: InferCallback<HooksT, NameT>): void;
|
|
58
58
|
deprecateHook<NameT extends HookNameT>(name: NameT, deprecated: HookKeys<HooksT> | DeprecatedHook<HooksT>): void;
|
|
59
59
|
deprecateHooks(deprecatedHooks: Partial<Record<HookNameT, DeprecatedHook<HooksT>>>): void;
|
|
60
60
|
addHooks(configHooks: NestedHooks<HooksT>): () => void;
|
|
61
61
|
removeHooks(configHooks: NestedHooks<HooksT>): void;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
removeAllHooks(): void;
|
|
63
|
+
callHook<NameT extends HookNameT>(name: NameT, ...arguments_: Parameters<InferCallback<HooksT, NameT>>): Promise<any>;
|
|
64
|
+
callHookParallel<NameT extends HookNameT>(name: NameT, ...arguments_: Parameters<InferCallback<HooksT, NameT>>): Promise<any[]>;
|
|
65
|
+
callHookWith<NameT extends HookNameT, CallFunction extends (hooks: HookCallback[], arguments_: Parameters<InferCallback<HooksT, NameT>>) => any>(caller: CallFunction, name: NameT, ...arguments_: Parameters<InferCallback<HooksT, NameT>>): ReturnType<CallFunction>;
|
|
66
|
+
beforeEach(function_: (event: InferSpyEvent<HooksT>) => void): () => void;
|
|
67
|
+
afterEach(function_: (event: InferSpyEvent<HooksT>) => void): () => void;
|
|
67
68
|
}
|
|
68
69
|
declare function createHooks<T>(): Hookable<T>;
|
|
69
70
|
|
|
70
71
|
declare function flatHooks<T>(configHooks: NestedHooks<T>, hooks?: T, parentName?: string): T;
|
|
71
72
|
declare function mergeHooks<T>(...hooks: NestedHooks<T>[]): T;
|
|
72
|
-
declare function serial<T>(tasks: T[],
|
|
73
|
-
|
|
74
|
-
declare function
|
|
73
|
+
declare function serial<T>(tasks: T[], function_: (task: T) => Promise<any> | any): Promise<any>;
|
|
74
|
+
/** @deprecated */
|
|
75
|
+
declare function serialCaller(hooks: HookCallback[], arguments_?: any[]): Promise<void>;
|
|
76
|
+
/** @deprecated */
|
|
77
|
+
declare function parallelCaller(hooks: HookCallback[], args?: any[]): Promise<void[]>;
|
|
75
78
|
|
|
76
79
|
interface CreateDebuggerOptions {
|
|
77
80
|
/** An optional tag to prefix console logs with */
|
package/dist/index.mjs
CHANGED
|
@@ -24,42 +24,62 @@ function mergeHooks(...hooks) {
|
|
|
24
24
|
}
|
|
25
25
|
for (const key in finalHooks) {
|
|
26
26
|
if (finalHooks[key].length > 1) {
|
|
27
|
-
const
|
|
28
|
-
finalHooks[key] = (...
|
|
27
|
+
const array = finalHooks[key];
|
|
28
|
+
finalHooks[key] = (...arguments_) => serial(array, (function_) => function_(...arguments_));
|
|
29
29
|
} else {
|
|
30
30
|
finalHooks[key] = finalHooks[key][0];
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
return finalHooks;
|
|
34
34
|
}
|
|
35
|
-
function serial(tasks,
|
|
36
|
-
return tasks.reduce(
|
|
35
|
+
function serial(tasks, function_) {
|
|
36
|
+
return tasks.reduce(
|
|
37
|
+
(promise, task) => promise.then(() => function_(task)),
|
|
38
|
+
Promise.resolve()
|
|
39
|
+
);
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
const defaultTask = { run: (function_) => function_() };
|
|
42
|
+
const _createTask = () => defaultTask;
|
|
43
|
+
const createTask = typeof console.createTask !== "undefined" ? console.createTask : _createTask;
|
|
44
|
+
function serialTaskCaller(hooks, name, ...args) {
|
|
45
|
+
const task = createTask(name);
|
|
46
|
+
return hooks.reduce(
|
|
47
|
+
(promise, hookFunction) => promise.then(() => task.run(() => hookFunction(...args))),
|
|
48
|
+
Promise.resolve()
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
function parallelTaskCaller(hooks, name, ...args) {
|
|
52
|
+
const task = createTask(name);
|
|
53
|
+
return Promise.all(hooks.map((hook) => task.run(() => hook(...args))));
|
|
54
|
+
}
|
|
55
|
+
function serialCaller(hooks, arguments_) {
|
|
56
|
+
return hooks.reduce(
|
|
57
|
+
(promise, hookFunction) => promise.then(() => hookFunction(...arguments_)),
|
|
58
|
+
Promise.resolve()
|
|
59
|
+
);
|
|
40
60
|
}
|
|
41
61
|
function parallelCaller(hooks, args) {
|
|
42
|
-
return Promise.all(hooks.map((hook) => hook
|
|
62
|
+
return Promise.all(hooks.map((hook) => hook(...args)));
|
|
43
63
|
}
|
|
44
64
|
function callEachWith(callbacks, arg0) {
|
|
45
|
-
for (const
|
|
46
|
-
|
|
65
|
+
for (const callback of callbacks) {
|
|
66
|
+
callback(arg0);
|
|
47
67
|
}
|
|
48
68
|
}
|
|
49
69
|
|
|
50
70
|
class Hookable {
|
|
51
71
|
constructor() {
|
|
52
72
|
this._hooks = {};
|
|
53
|
-
this._before =
|
|
54
|
-
this._after =
|
|
55
|
-
this._deprecatedMessages =
|
|
73
|
+
this._before = void 0;
|
|
74
|
+
this._after = void 0;
|
|
75
|
+
this._deprecatedMessages = void 0;
|
|
56
76
|
this._deprecatedHooks = {};
|
|
57
77
|
this.hook = this.hook.bind(this);
|
|
58
78
|
this.callHook = this.callHook.bind(this);
|
|
59
79
|
this.callHookWith = this.callHookWith.bind(this);
|
|
60
80
|
}
|
|
61
|
-
hook(name,
|
|
62
|
-
if (!name || typeof
|
|
81
|
+
hook(name, function_, options = {}) {
|
|
82
|
+
if (!name || typeof function_ !== "function") {
|
|
63
83
|
return () => {
|
|
64
84
|
};
|
|
65
85
|
}
|
|
@@ -69,7 +89,7 @@ class Hookable {
|
|
|
69
89
|
dep = this._deprecatedHooks[name];
|
|
70
90
|
name = dep.to;
|
|
71
91
|
}
|
|
72
|
-
if (dep && !
|
|
92
|
+
if (dep && !options.allowDeprecated) {
|
|
73
93
|
let message = dep.message;
|
|
74
94
|
if (!message) {
|
|
75
95
|
message = `${originalName} hook has been deprecated` + (dep.to ? `, please use ${dep.to}` : "");
|
|
@@ -82,31 +102,42 @@ class Hookable {
|
|
|
82
102
|
this._deprecatedMessages.add(message);
|
|
83
103
|
}
|
|
84
104
|
}
|
|
105
|
+
if (!function_.name) {
|
|
106
|
+
try {
|
|
107
|
+
Object.defineProperty(function_, "name", {
|
|
108
|
+
get: () => "_" + name.replace(/\W+/g, "_") + "_hook_cb",
|
|
109
|
+
configurable: true
|
|
110
|
+
});
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
}
|
|
85
114
|
this._hooks[name] = this._hooks[name] || [];
|
|
86
|
-
this._hooks[name].push(
|
|
115
|
+
this._hooks[name].push(function_);
|
|
87
116
|
return () => {
|
|
88
|
-
if (
|
|
89
|
-
this.removeHook(name,
|
|
90
|
-
|
|
117
|
+
if (function_) {
|
|
118
|
+
this.removeHook(name, function_);
|
|
119
|
+
function_ = void 0;
|
|
91
120
|
}
|
|
92
121
|
};
|
|
93
122
|
}
|
|
94
|
-
hookOnce(name,
|
|
123
|
+
hookOnce(name, function_) {
|
|
95
124
|
let _unreg;
|
|
96
|
-
let
|
|
97
|
-
_unreg
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
125
|
+
let _function = (...arguments_) => {
|
|
126
|
+
if (typeof _unreg === "function") {
|
|
127
|
+
_unreg();
|
|
128
|
+
}
|
|
129
|
+
_unreg = void 0;
|
|
130
|
+
_function = void 0;
|
|
131
|
+
return function_(...arguments_);
|
|
101
132
|
};
|
|
102
|
-
_unreg = this.hook(name,
|
|
133
|
+
_unreg = this.hook(name, _function);
|
|
103
134
|
return _unreg;
|
|
104
135
|
}
|
|
105
|
-
removeHook(name,
|
|
136
|
+
removeHook(name, function_) {
|
|
106
137
|
if (this._hooks[name]) {
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
this._hooks[name].splice(
|
|
138
|
+
const index = this._hooks[name].indexOf(function_);
|
|
139
|
+
if (index !== -1) {
|
|
140
|
+
this._hooks[name].splice(index, 1);
|
|
110
141
|
}
|
|
111
142
|
if (this._hooks[name].length === 0) {
|
|
112
143
|
delete this._hooks[name];
|
|
@@ -129,9 +160,13 @@ class Hookable {
|
|
|
129
160
|
}
|
|
130
161
|
addHooks(configHooks) {
|
|
131
162
|
const hooks = flatHooks(configHooks);
|
|
132
|
-
const removeFns = Object.keys(hooks).map(
|
|
163
|
+
const removeFns = Object.keys(hooks).map(
|
|
164
|
+
(key) => this.hook(key, hooks[key])
|
|
165
|
+
);
|
|
133
166
|
return () => {
|
|
134
|
-
removeFns.splice(0, removeFns.length)
|
|
167
|
+
for (const unreg of removeFns.splice(0, removeFns.length)) {
|
|
168
|
+
unreg();
|
|
169
|
+
}
|
|
135
170
|
};
|
|
136
171
|
}
|
|
137
172
|
removeHooks(configHooks) {
|
|
@@ -140,18 +175,23 @@ class Hookable {
|
|
|
140
175
|
this.removeHook(key, hooks[key]);
|
|
141
176
|
}
|
|
142
177
|
}
|
|
143
|
-
|
|
144
|
-
|
|
178
|
+
removeAllHooks() {
|
|
179
|
+
for (const key in this._hooks) {
|
|
180
|
+
delete this._hooks[key];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
callHook(name, ...arguments_) {
|
|
184
|
+
return this.callHookWith(serialTaskCaller, name, ...arguments_);
|
|
145
185
|
}
|
|
146
|
-
callHookParallel(name, ...
|
|
147
|
-
return this.callHookWith(
|
|
186
|
+
callHookParallel(name, ...arguments_) {
|
|
187
|
+
return this.callHookWith(parallelTaskCaller, name, ...arguments_);
|
|
148
188
|
}
|
|
149
|
-
callHookWith(caller, name, ...
|
|
150
|
-
const event = this._before || this._after ? { name, args, context: {} } : void 0;
|
|
189
|
+
callHookWith(caller, name, ...arguments_) {
|
|
190
|
+
const event = this._before || this._after ? { name, args: arguments_, context: {} } : void 0;
|
|
151
191
|
if (this._before) {
|
|
152
192
|
callEachWith(this._before, event);
|
|
153
193
|
}
|
|
154
|
-
const result = caller(this._hooks[name] || [],
|
|
194
|
+
const result = caller(this._hooks[name] || [], arguments_);
|
|
155
195
|
if (result instanceof Promise) {
|
|
156
196
|
return result.finally(() => {
|
|
157
197
|
if (this._after && event) {
|
|
@@ -164,21 +204,21 @@ class Hookable {
|
|
|
164
204
|
}
|
|
165
205
|
return result;
|
|
166
206
|
}
|
|
167
|
-
beforeEach(
|
|
207
|
+
beforeEach(function_) {
|
|
168
208
|
this._before = this._before || [];
|
|
169
|
-
this._before.push(
|
|
209
|
+
this._before.push(function_);
|
|
170
210
|
return () => {
|
|
171
|
-
const index = this._before.indexOf(
|
|
211
|
+
const index = this._before.indexOf(function_);
|
|
172
212
|
if (index !== -1) {
|
|
173
213
|
this._before.splice(index, 1);
|
|
174
214
|
}
|
|
175
215
|
};
|
|
176
216
|
}
|
|
177
|
-
afterEach(
|
|
217
|
+
afterEach(function_) {
|
|
178
218
|
this._after = this._after || [];
|
|
179
|
-
this._after.push(
|
|
219
|
+
this._after.push(function_);
|
|
180
220
|
return () => {
|
|
181
|
-
const index = this._after.indexOf(
|
|
221
|
+
const index = this._after.indexOf(function_);
|
|
182
222
|
if (index !== -1) {
|
|
183
223
|
this._after.splice(index, 1);
|
|
184
224
|
}
|
|
@@ -228,6 +268,7 @@ function createDebugger(hooks, _options = {}) {
|
|
|
228
268
|
_idCtr[event.name]--;
|
|
229
269
|
});
|
|
230
270
|
return {
|
|
271
|
+
/** Stop debugging and remove listeners */
|
|
231
272
|
close: () => {
|
|
232
273
|
unsubscribeBefore();
|
|
233
274
|
unsubscribeAfter();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hookable",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "Awaitable hook system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hook",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"exports": {
|
|
15
15
|
"import": "./dist/index.mjs",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
16
17
|
"require": "./dist/index.cjs"
|
|
17
18
|
},
|
|
18
19
|
"main": "./dist/index.cjs",
|
|
@@ -22,22 +23,25 @@
|
|
|
22
23
|
"dist"
|
|
23
24
|
],
|
|
24
25
|
"devDependencies": {
|
|
25
|
-
"@
|
|
26
|
-
"@vitest/coverage-c8": "^0.
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
26
|
+
"@types/node": "^18.15.0",
|
|
27
|
+
"@vitest/coverage-c8": "^0.29.2",
|
|
28
|
+
"changelogen": "^0.5.1",
|
|
29
|
+
"eslint": "^8.35.0",
|
|
30
|
+
"eslint-config-unjs": "^0.1.0",
|
|
31
|
+
"expect-type": "^0.15.0",
|
|
32
|
+
"prettier": "^2.8.4",
|
|
33
|
+
"typescript": "^4.9.5",
|
|
34
|
+
"unbuild": "^1.1.2",
|
|
35
|
+
"vitest": "^0.29.2"
|
|
33
36
|
},
|
|
34
|
-
"packageManager": "pnpm@7.
|
|
37
|
+
"packageManager": "pnpm@7.29.1",
|
|
35
38
|
"scripts": {
|
|
36
39
|
"build": "unbuild",
|
|
37
40
|
"dev": "vitest",
|
|
38
|
-
"lint": "eslint --ext .ts src",
|
|
41
|
+
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test",
|
|
42
|
+
"lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test -w",
|
|
39
43
|
"prepublish": "pnpm build",
|
|
40
|
-
"release": "pnpm test && pnpm build &&
|
|
44
|
+
"release": "pnpm test && pnpm build && changelogen --release --push && pnpm publish",
|
|
41
45
|
"test": "pnpm lint && vitest run --coverage",
|
|
42
46
|
"test:types": "tsc --noEmit"
|
|
43
47
|
}
|