hookable 5.4.0 → 5.4.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Pooya Parsa <pooya@pi0.ir>
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,82 +26,42 @@ function mergeHooks(...hooks) {
28
26
  }
29
27
  for (const key in finalHooks) {
30
28
  if (finalHooks[key].length > 1) {
31
- const arr = finalHooks[key];
32
- finalHooks[key] = (...args) => serial(arr, (fn) => fn(...args));
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, fn) {
40
- return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve(null));
37
+ function serial(tasks, function_) {
38
+ return tasks.reduce((promise, task) => promise.then(() => function_(task)), Promise.resolve());
41
39
  }
42
- function serialCaller(hooks, args) {
43
- return hooks.reduce((promise, hookFn) => promise.then(() => hookFn.apply(void 0, args)), Promise.resolve(null));
40
+ function serialCaller(hooks, arguments_) {
41
+ return hooks.reduce((promise, hookFunction) => promise.then(() => hookFunction.apply(void 0, arguments_)), Promise.resolve());
44
42
  }
45
- function parallelCaller(hooks, args) {
46
- return Promise.all(hooks.map((hook) => hook.apply(void 0, args)));
43
+ function parallelCaller(hooks, arguments_) {
44
+ return Promise.all(hooks.map((hook) => hook.apply(void 0, arguments_)));
47
45
  }
48
- function callEachWith(callbacks, arg0) {
49
- for (const cb of callbacks) {
50
- cb(arg0);
46
+ function callEachWith(callbacks, argument0) {
47
+ for (const callback of callbacks) {
48
+ callback(argument0);
51
49
  }
52
50
  }
53
- const isBrowser = typeof window !== "undefined";
54
- function createDebugger(hooks, _options = {}) {
55
- const options = {
56
- inspect: isBrowser,
57
- group: isBrowser,
58
- filter: () => true,
59
- ..._options
60
- };
61
- const _filter = options.filter;
62
- const filter = typeof _filter === "string" ? (name) => name.startsWith(_filter) : _filter;
63
- const logPrefix = options.tag ? `[${options.tag}] ` : "";
64
- const unsubscribeBefore = hooks.beforeEach(({ name }) => {
65
- if (!filter(name)) {
66
- return;
67
- }
68
- console.time(logPrefix + name);
69
- });
70
- const unsubscribeAfter = hooks.afterEach(({ name, args }) => {
71
- if (!filter(name)) {
72
- return;
73
- }
74
- if (options.group) {
75
- console.groupCollapsed(name);
76
- }
77
- if (options.inspect) {
78
- console.timeLog(logPrefix + name, args);
79
- } else {
80
- console.timeEnd(logPrefix + name);
81
- }
82
- if (options.group) {
83
- console.groupEnd();
84
- }
85
- });
86
- return {
87
- close: () => {
88
- unsubscribeBefore();
89
- unsubscribeAfter();
90
- }
91
- };
92
- }
93
51
 
94
52
  class Hookable {
95
53
  constructor() {
96
54
  this._hooks = {};
97
- this._before = null;
98
- this._after = null;
99
- this._deprecatedMessages = null;
55
+ this._before = void 0;
56
+ this._after = void 0;
57
+ this._deprecatedMessages = void 0;
100
58
  this._deprecatedHooks = {};
101
59
  this.hook = this.hook.bind(this);
102
60
  this.callHook = this.callHook.bind(this);
103
61
  this.callHookWith = this.callHookWith.bind(this);
104
62
  }
105
- hook(name, fn, opts = {}) {
106
- if (!name || typeof fn !== "function") {
63
+ hook(name, function_, options = {}) {
64
+ if (!name || typeof function_ !== "function") {
107
65
  return () => {
108
66
  };
109
67
  }
@@ -113,7 +71,7 @@ class Hookable {
113
71
  dep = this._deprecatedHooks[name];
114
72
  name = dep.to;
115
73
  }
116
- if (dep && !opts.allowDeprecated) {
74
+ if (dep && !options.allowDeprecated) {
117
75
  let message = dep.message;
118
76
  if (!message) {
119
77
  message = `${originalName} hook has been deprecated` + (dep.to ? `, please use ${dep.to}` : "");
@@ -127,30 +85,32 @@ class Hookable {
127
85
  }
128
86
  }
129
87
  this._hooks[name] = this._hooks[name] || [];
130
- this._hooks[name].push(fn);
88
+ this._hooks[name].push(function_);
131
89
  return () => {
132
- if (fn) {
133
- this.removeHook(name, fn);
134
- fn = null;
90
+ if (function_) {
91
+ this.removeHook(name, function_);
92
+ function_ = void 0;
135
93
  }
136
94
  };
137
95
  }
138
- hookOnce(name, fn) {
96
+ hookOnce(name, function_) {
139
97
  let _unreg;
140
- let _fn = (...args) => {
141
- _unreg();
142
- _unreg = null;
143
- _fn = null;
144
- return fn(...args);
98
+ let _function = (...arguments_) => {
99
+ if (typeof _unreg === "function") {
100
+ _unreg();
101
+ }
102
+ _unreg = void 0;
103
+ _function = void 0;
104
+ return function_(...arguments_);
145
105
  };
146
- _unreg = this.hook(name, _fn);
106
+ _unreg = this.hook(name, _function);
147
107
  return _unreg;
148
108
  }
149
- removeHook(name, fn) {
109
+ removeHook(name, function_) {
150
110
  if (this._hooks[name]) {
151
- const idx = this._hooks[name].indexOf(fn);
152
- if (idx !== -1) {
153
- this._hooks[name].splice(idx, 1);
111
+ const index = this._hooks[name].indexOf(function_);
112
+ if (index !== -1) {
113
+ this._hooks[name].splice(index, 1);
154
114
  }
155
115
  if (this._hooks[name].length === 0) {
156
116
  delete this._hooks[name];
@@ -175,7 +135,9 @@ class Hookable {
175
135
  const hooks = flatHooks(configHooks);
176
136
  const removeFns = Object.keys(hooks).map((key) => this.hook(key, hooks[key]));
177
137
  return () => {
178
- removeFns.splice(0, removeFns.length).forEach((unreg) => unreg());
138
+ for (const unreg of removeFns.splice(0, removeFns.length)) {
139
+ unreg();
140
+ }
179
141
  };
180
142
  }
181
143
  removeHooks(configHooks) {
@@ -184,45 +146,45 @@ class Hookable {
184
146
  this.removeHook(key, hooks[key]);
185
147
  }
186
148
  }
187
- callHook(name, ...args) {
188
- return this.callHookWith(serialCaller, name, ...args);
149
+ callHook(name, ...arguments_) {
150
+ return this.callHookWith(serialCaller, name, ...arguments_);
189
151
  }
190
- callHookParallel(name, ...args) {
191
- return this.callHookWith(parallelCaller, name, ...args);
152
+ callHookParallel(name, ...arguments_) {
153
+ return this.callHookWith(parallelCaller, name, ...arguments_);
192
154
  }
193
- callHookWith(caller, name, ...args) {
194
- const event = this._before || this._after ? { name, args, context: {} } : void 0;
155
+ callHookWith(caller, name, ...arguments_) {
156
+ const event = this._before || this._after ? { name, args: arguments_, context: {} } : void 0;
195
157
  if (this._before) {
196
158
  callEachWith(this._before, event);
197
159
  }
198
- const result = caller(this._hooks[name] || [], args);
160
+ const result = caller(this._hooks[name] || [], arguments_);
199
161
  if (result instanceof Promise) {
200
162
  return result.finally(() => {
201
- if (this._after) {
163
+ if (this._after && event) {
202
164
  callEachWith(this._after, event);
203
165
  }
204
166
  });
205
167
  }
206
- if (this._after) {
168
+ if (this._after && event) {
207
169
  callEachWith(this._after, event);
208
170
  }
209
171
  return result;
210
172
  }
211
- beforeEach(fn) {
173
+ beforeEach(function_) {
212
174
  this._before = this._before || [];
213
- this._before.push(fn);
175
+ this._before.push(function_);
214
176
  return () => {
215
- const index = this._before.indexOf(fn);
177
+ const index = this._before.indexOf(function_);
216
178
  if (index !== -1) {
217
179
  this._before.splice(index, 1);
218
180
  }
219
181
  };
220
182
  }
221
- afterEach(fn) {
183
+ afterEach(function_) {
222
184
  this._after = this._after || [];
223
- this._after.push(fn);
185
+ this._after.push(function_);
224
186
  return () => {
225
- const index = this._after.indexOf(fn);
187
+ const index = this._after.indexOf(function_);
226
188
  if (index !== -1) {
227
189
  this._after.splice(index, 1);
228
190
  }
@@ -233,6 +195,52 @@ function createHooks() {
233
195
  return new Hookable();
234
196
  }
235
197
 
198
+ const isBrowser = typeof window !== "undefined";
199
+ function createDebugger(hooks, _options = {}) {
200
+ const options = {
201
+ inspect: isBrowser,
202
+ group: isBrowser,
203
+ filter: () => true,
204
+ ..._options
205
+ };
206
+ const _filter = options.filter;
207
+ const filter = typeof _filter === "string" ? (name) => name.startsWith(_filter) : _filter;
208
+ const _tag = options.tag ? `[${options.tag}] ` : "";
209
+ const logPrefix = (event) => _tag + event.name + "".padEnd(event._id, "\0");
210
+ const _idCtr = {};
211
+ const unsubscribeBefore = hooks.beforeEach((event) => {
212
+ if (!filter(event.name)) {
213
+ return;
214
+ }
215
+ _idCtr[event.name] = _idCtr[event.name] || 0;
216
+ event._id = _idCtr[event.name]++;
217
+ console.time(logPrefix(event));
218
+ });
219
+ const unsubscribeAfter = hooks.afterEach((event) => {
220
+ if (!filter(event.name)) {
221
+ return;
222
+ }
223
+ if (options.group) {
224
+ console.groupCollapsed(event.name);
225
+ }
226
+ if (options.inspect) {
227
+ console.timeLog(logPrefix(event), event.args);
228
+ } else {
229
+ console.timeEnd(logPrefix(event));
230
+ }
231
+ if (options.group) {
232
+ console.groupEnd();
233
+ }
234
+ _idCtr[event.name]--;
235
+ });
236
+ return {
237
+ close: () => {
238
+ unsubscribeBefore();
239
+ unsubscribeAfter();
240
+ }
241
+ };
242
+ }
243
+
236
244
  exports.Hookable = Hookable;
237
245
  exports.createDebugger = createDebugger;
238
246
  exports.createHooks = createHooks;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare type HookCallback = (...args: any) => Promise<void> | void;
1
+ declare type HookCallback = (...arguments_: any) => Promise<void> | void;
2
2
  interface Hooks {
3
3
  [key: string]: HookCallback;
4
4
  }
@@ -34,24 +34,6 @@ declare type NestedHooks<T> = (Partial<StripGeneric<T>> | Partial<OnlyGeneric<T>
34
34
  }> & Partial<{
35
35
  [key in BareHooks<StripGeneric<T>>]: T[key];
36
36
  }>;
37
- interface CreateDebuggerOptions {
38
- /** An optional tag to prefix console logs with */
39
- tag?: string;
40
- /**
41
- * Show hook params to the console output
42
- *
43
- * Enabled for browsers by default
44
- */
45
- inspect?: boolean;
46
- /**
47
- * Use group/groupEnd wrapper around logs happening during a specific hook
48
- *
49
- * Enabled for browsers by default
50
- */
51
- group?: boolean;
52
- /** Filter which hooks to enable debugger for. Can be a string prefix or fn. */
53
- filter?: string | ((event: string) => boolean);
54
- }
55
37
 
56
38
  declare type InferCallback<HT, HN extends keyof HT> = HT[HN] extends HookCallback ? HT[HN] : never;
57
39
  declare type InferSpyEvent<HT extends Record<string, any>> = {
@@ -68,30 +50,49 @@ declare class Hookable<HooksT = Record<string, HookCallback>, HookNameT extends
68
50
  private _deprecatedHooks;
69
51
  private _deprecatedMessages;
70
52
  constructor();
71
- hook<NameT extends HookNameT>(name: NameT, fn: InferCallback<HooksT, NameT>, opts?: {
53
+ hook<NameT extends HookNameT>(name: NameT, function_: InferCallback<HooksT, NameT>, options?: {
72
54
  allowDeprecated?: boolean;
73
55
  }): () => void;
74
- hookOnce<NameT extends HookNameT>(name: NameT, fn: InferCallback<HooksT, NameT>): () => void;
75
- removeHook<NameT extends HookNameT>(name: NameT, fn: InferCallback<HooksT, NameT>): void;
56
+ hookOnce<NameT extends HookNameT>(name: NameT, function_: InferCallback<HooksT, NameT>): () => void;
57
+ removeHook<NameT extends HookNameT>(name: NameT, function_: InferCallback<HooksT, NameT>): void;
76
58
  deprecateHook<NameT extends HookNameT>(name: NameT, deprecated: HookKeys<HooksT> | DeprecatedHook<HooksT>): void;
77
59
  deprecateHooks(deprecatedHooks: Partial<Record<HookNameT, DeprecatedHook<HooksT>>>): void;
78
60
  addHooks(configHooks: NestedHooks<HooksT>): () => void;
79
61
  removeHooks(configHooks: NestedHooks<HooksT>): void;
80
- callHook<NameT extends HookNameT>(name: NameT, ...args: Parameters<InferCallback<HooksT, NameT>>): Promise<any>;
81
- callHookParallel<NameT extends HookNameT>(name: NameT, ...args: Parameters<InferCallback<HooksT, NameT>>): Promise<any[]>;
82
- 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>;
83
- beforeEach(fn: (event: InferSpyEvent<HooksT>) => void): () => void;
84
- afterEach(fn: (event: InferSpyEvent<HooksT>) => void): () => void;
62
+ callHook<NameT extends HookNameT>(name: NameT, ...arguments_: Parameters<InferCallback<HooksT, NameT>>): Promise<any>;
63
+ callHookParallel<NameT extends HookNameT>(name: NameT, ...arguments_: Parameters<InferCallback<HooksT, NameT>>): Promise<any[]>;
64
+ 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>;
65
+ beforeEach(function_: (event: InferSpyEvent<HooksT>) => void): () => void;
66
+ afterEach(function_: (event: InferSpyEvent<HooksT>) => void): () => void;
85
67
  }
86
68
  declare function createHooks<T>(): Hookable<T>;
87
69
 
88
70
  declare function flatHooks<T>(configHooks: NestedHooks<T>, hooks?: T, parentName?: string): T;
89
71
  declare function mergeHooks<T>(...hooks: NestedHooks<T>[]): T;
90
- declare function serial<T>(tasks: T[], fn: (task: T) => Promise<any> | any): Promise<any>;
91
- declare function serialCaller(hooks: HookCallback[], args?: any[]): Promise<any>;
92
- declare function parallelCaller(hooks: HookCallback[], args?: any[]): Promise<any[]>;
72
+ declare function serial<T>(tasks: T[], function_: (task: T) => Promise<any> | any): Promise<any>;
73
+ declare function serialCaller(hooks: HookCallback[], arguments_?: any[]): Promise<any>;
74
+ declare function parallelCaller(hooks: HookCallback[], arguments_?: any[]): Promise<any[]>;
75
+
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
+ }
93
94
  /** Start debugging hook names and timing in console */
94
- declare function createDebugger(hooks: Hookable, _options?: CreateDebuggerOptions): {
95
+ declare function createDebugger(hooks: Hookable<any>, _options?: CreateDebuggerOptions): {
95
96
  /** Stop debugging and remove listeners */
96
97
  close: () => void;
97
98
  };
package/dist/index.mjs CHANGED
@@ -24,82 +24,42 @@ function mergeHooks(...hooks) {
24
24
  }
25
25
  for (const key in finalHooks) {
26
26
  if (finalHooks[key].length > 1) {
27
- const arr = finalHooks[key];
28
- finalHooks[key] = (...args) => serial(arr, (fn) => fn(...args));
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, fn) {
36
- return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve(null));
35
+ function serial(tasks, function_) {
36
+ return tasks.reduce((promise, task) => promise.then(() => function_(task)), Promise.resolve());
37
37
  }
38
- function serialCaller(hooks, args) {
39
- return hooks.reduce((promise, hookFn) => promise.then(() => hookFn.apply(void 0, args)), Promise.resolve(null));
38
+ function serialCaller(hooks, arguments_) {
39
+ return hooks.reduce((promise, hookFunction) => promise.then(() => hookFunction.apply(void 0, arguments_)), Promise.resolve());
40
40
  }
41
- function parallelCaller(hooks, args) {
42
- return Promise.all(hooks.map((hook) => hook.apply(void 0, args)));
41
+ function parallelCaller(hooks, arguments_) {
42
+ return Promise.all(hooks.map((hook) => hook.apply(void 0, arguments_)));
43
43
  }
44
- function callEachWith(callbacks, arg0) {
45
- for (const cb of callbacks) {
46
- cb(arg0);
44
+ function callEachWith(callbacks, argument0) {
45
+ for (const callback of callbacks) {
46
+ callback(argument0);
47
47
  }
48
48
  }
49
- const isBrowser = typeof window !== "undefined";
50
- function createDebugger(hooks, _options = {}) {
51
- const options = {
52
- inspect: isBrowser,
53
- group: isBrowser,
54
- filter: () => true,
55
- ..._options
56
- };
57
- const _filter = options.filter;
58
- const filter = typeof _filter === "string" ? (name) => name.startsWith(_filter) : _filter;
59
- const logPrefix = options.tag ? `[${options.tag}] ` : "";
60
- const unsubscribeBefore = hooks.beforeEach(({ name }) => {
61
- if (!filter(name)) {
62
- return;
63
- }
64
- console.time(logPrefix + name);
65
- });
66
- const unsubscribeAfter = hooks.afterEach(({ name, args }) => {
67
- if (!filter(name)) {
68
- return;
69
- }
70
- if (options.group) {
71
- console.groupCollapsed(name);
72
- }
73
- if (options.inspect) {
74
- console.timeLog(logPrefix + name, args);
75
- } else {
76
- console.timeEnd(logPrefix + name);
77
- }
78
- if (options.group) {
79
- console.groupEnd();
80
- }
81
- });
82
- return {
83
- close: () => {
84
- unsubscribeBefore();
85
- unsubscribeAfter();
86
- }
87
- };
88
- }
89
49
 
90
50
  class Hookable {
91
51
  constructor() {
92
52
  this._hooks = {};
93
- this._before = null;
94
- this._after = null;
95
- this._deprecatedMessages = null;
53
+ this._before = void 0;
54
+ this._after = void 0;
55
+ this._deprecatedMessages = void 0;
96
56
  this._deprecatedHooks = {};
97
57
  this.hook = this.hook.bind(this);
98
58
  this.callHook = this.callHook.bind(this);
99
59
  this.callHookWith = this.callHookWith.bind(this);
100
60
  }
101
- hook(name, fn, opts = {}) {
102
- if (!name || typeof fn !== "function") {
61
+ hook(name, function_, options = {}) {
62
+ if (!name || typeof function_ !== "function") {
103
63
  return () => {
104
64
  };
105
65
  }
@@ -109,7 +69,7 @@ class Hookable {
109
69
  dep = this._deprecatedHooks[name];
110
70
  name = dep.to;
111
71
  }
112
- if (dep && !opts.allowDeprecated) {
72
+ if (dep && !options.allowDeprecated) {
113
73
  let message = dep.message;
114
74
  if (!message) {
115
75
  message = `${originalName} hook has been deprecated` + (dep.to ? `, please use ${dep.to}` : "");
@@ -123,30 +83,32 @@ class Hookable {
123
83
  }
124
84
  }
125
85
  this._hooks[name] = this._hooks[name] || [];
126
- this._hooks[name].push(fn);
86
+ this._hooks[name].push(function_);
127
87
  return () => {
128
- if (fn) {
129
- this.removeHook(name, fn);
130
- fn = null;
88
+ if (function_) {
89
+ this.removeHook(name, function_);
90
+ function_ = void 0;
131
91
  }
132
92
  };
133
93
  }
134
- hookOnce(name, fn) {
94
+ hookOnce(name, function_) {
135
95
  let _unreg;
136
- let _fn = (...args) => {
137
- _unreg();
138
- _unreg = null;
139
- _fn = null;
140
- return fn(...args);
96
+ let _function = (...arguments_) => {
97
+ if (typeof _unreg === "function") {
98
+ _unreg();
99
+ }
100
+ _unreg = void 0;
101
+ _function = void 0;
102
+ return function_(...arguments_);
141
103
  };
142
- _unreg = this.hook(name, _fn);
104
+ _unreg = this.hook(name, _function);
143
105
  return _unreg;
144
106
  }
145
- removeHook(name, fn) {
107
+ removeHook(name, function_) {
146
108
  if (this._hooks[name]) {
147
- const idx = this._hooks[name].indexOf(fn);
148
- if (idx !== -1) {
149
- this._hooks[name].splice(idx, 1);
109
+ const index = this._hooks[name].indexOf(function_);
110
+ if (index !== -1) {
111
+ this._hooks[name].splice(index, 1);
150
112
  }
151
113
  if (this._hooks[name].length === 0) {
152
114
  delete this._hooks[name];
@@ -171,7 +133,9 @@ class Hookable {
171
133
  const hooks = flatHooks(configHooks);
172
134
  const removeFns = Object.keys(hooks).map((key) => this.hook(key, hooks[key]));
173
135
  return () => {
174
- removeFns.splice(0, removeFns.length).forEach((unreg) => unreg());
136
+ for (const unreg of removeFns.splice(0, removeFns.length)) {
137
+ unreg();
138
+ }
175
139
  };
176
140
  }
177
141
  removeHooks(configHooks) {
@@ -180,45 +144,45 @@ class Hookable {
180
144
  this.removeHook(key, hooks[key]);
181
145
  }
182
146
  }
183
- callHook(name, ...args) {
184
- return this.callHookWith(serialCaller, name, ...args);
147
+ callHook(name, ...arguments_) {
148
+ return this.callHookWith(serialCaller, name, ...arguments_);
185
149
  }
186
- callHookParallel(name, ...args) {
187
- return this.callHookWith(parallelCaller, name, ...args);
150
+ callHookParallel(name, ...arguments_) {
151
+ return this.callHookWith(parallelCaller, name, ...arguments_);
188
152
  }
189
- callHookWith(caller, name, ...args) {
190
- const event = this._before || this._after ? { name, args, context: {} } : void 0;
153
+ callHookWith(caller, name, ...arguments_) {
154
+ const event = this._before || this._after ? { name, args: arguments_, context: {} } : void 0;
191
155
  if (this._before) {
192
156
  callEachWith(this._before, event);
193
157
  }
194
- const result = caller(this._hooks[name] || [], args);
158
+ const result = caller(this._hooks[name] || [], arguments_);
195
159
  if (result instanceof Promise) {
196
160
  return result.finally(() => {
197
- if (this._after) {
161
+ if (this._after && event) {
198
162
  callEachWith(this._after, event);
199
163
  }
200
164
  });
201
165
  }
202
- if (this._after) {
166
+ if (this._after && event) {
203
167
  callEachWith(this._after, event);
204
168
  }
205
169
  return result;
206
170
  }
207
- beforeEach(fn) {
171
+ beforeEach(function_) {
208
172
  this._before = this._before || [];
209
- this._before.push(fn);
173
+ this._before.push(function_);
210
174
  return () => {
211
- const index = this._before.indexOf(fn);
175
+ const index = this._before.indexOf(function_);
212
176
  if (index !== -1) {
213
177
  this._before.splice(index, 1);
214
178
  }
215
179
  };
216
180
  }
217
- afterEach(fn) {
181
+ afterEach(function_) {
218
182
  this._after = this._after || [];
219
- this._after.push(fn);
183
+ this._after.push(function_);
220
184
  return () => {
221
- const index = this._after.indexOf(fn);
185
+ const index = this._after.indexOf(function_);
222
186
  if (index !== -1) {
223
187
  this._after.splice(index, 1);
224
188
  }
@@ -229,4 +193,50 @@ function createHooks() {
229
193
  return new Hookable();
230
194
  }
231
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
+
232
242
  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.4.0",
3
+ "version": "5.4.2",
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,16 +23,16 @@
22
23
  "dist"
23
24
  ],
24
25
  "devDependencies": {
25
- "@nuxtjs/eslint-config-typescript": "latest",
26
- "@vitest/coverage-c8": "^0.24.1",
27
- "eslint": "latest",
28
- "expect-type": "^0.14.2",
29
- "standard-version": "latest",
30
- "typescript": "latest",
31
- "unbuild": "latest",
32
- "vitest": "latest"
26
+ "@vitest/coverage-c8": "^0.25.2",
27
+ "eslint": "^8.27.0",
28
+ "eslint-config-unjs": "^0.0.2",
29
+ "expect-type": "^0.15.0",
30
+ "standard-version": "^9.5.0",
31
+ "typescript": "^4.8.4",
32
+ "unbuild": "^0.9.4",
33
+ "vitest": "^0.25.2"
33
34
  },
34
- "packageManager": "pnpm@7.13.4",
35
+ "packageManager": "pnpm@7.16.0",
35
36
  "scripts": {
36
37
  "build": "unbuild",
37
38
  "dev": "vitest",