@shuvi/hook 0.0.1-rc.34 → 1.0.0-rc.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/esm/hookGroup.d.ts +56 -0
- package/esm/hookGroup.js +243 -0
- package/esm/hooks.d.ts +57 -0
- package/esm/hooks.js +123 -0
- package/esm/index.d.ts +2 -3
- package/esm/index.js +2 -2
- package/lib/hookGroup.d.ts +56 -0
- package/lib/hookGroup.js +248 -0
- package/lib/hooks.d.ts +57 -0
- package/lib/hooks.js +131 -0
- package/lib/index.d.ts +2 -3
- package/lib/index.js +16 -2
- package/package.json +8 -9
- package/esm/AsyncParallelHook.d.ts +0 -3
- package/esm/AsyncParallelHook.js +0 -13
- package/esm/AsyncSeriesBailHook.d.ts +0 -3
- package/esm/AsyncSeriesBailHook.js +0 -22
- package/esm/AsyncSeriesHook.d.ts +0 -3
- package/esm/AsyncSeriesHook.js +0 -16
- package/esm/AsyncSeriesWaterfallHook.d.ts +0 -3
- package/esm/AsyncSeriesWaterfallHook.js +0 -24
- package/esm/Hookable.d.ts +0 -9
- package/esm/Hookable.js +0 -87
- package/esm/types.d.ts +0 -44
- package/esm/types.js +0 -0
- package/esm/utils.d.ts +0 -6
- package/esm/utils.js +0 -45
- package/lib/AsyncParallelHook.d.ts +0 -3
- package/lib/AsyncParallelHook.js +0 -15
- package/lib/AsyncSeriesBailHook.d.ts +0 -3
- package/lib/AsyncSeriesBailHook.js +0 -24
- package/lib/AsyncSeriesHook.d.ts +0 -3
- package/lib/AsyncSeriesHook.js +0 -18
- package/lib/AsyncSeriesWaterfallHook.d.ts +0 -3
- package/lib/AsyncSeriesWaterfallHook.js +0 -26
- package/lib/Hookable.d.ts +0 -9
- package/lib/Hookable.js +0 -90
- package/lib/types.d.ts +0 -44
- package/lib/types.js +0 -2
- package/lib/utils.d.ts +0 -6
- package/lib/utils.js +0 -47
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SyncHook, SyncBailHook, SyncWaterfallHook, AsyncParallelHook, AsyncSeriesWaterfallHook, SyncHookHandler, SyncBailHookHandler, SyncWaterfallHookHandler, AsyncParallelHookHandler, AsyncSeriesWaterfallHookHandler } from './hooks';
|
|
2
|
+
export declare type PatchPluginParameter<T, C> = RemoveManagerVoidParameter<AddContextParameter<T, C>>;
|
|
3
|
+
export declare type AddContextParameter<T, C> = T extends (initalValue: infer I, extraArg: infer E) => infer R ? (initalValue: I, extraArg: E, context: C) => R : T;
|
|
4
|
+
export declare type AnyHook = SyncHook<any, any, any> | SyncBailHook<any, any, any> | SyncWaterfallHook<any, any> | AsyncParallelHook<any, any, any> | AsyncSeriesWaterfallHook<any, any>;
|
|
5
|
+
export interface HookMap {
|
|
6
|
+
[x: string]: AnyHook;
|
|
7
|
+
}
|
|
8
|
+
export declare type Setup<EHM> = (utils: {
|
|
9
|
+
addHooks: (hook: Partial<EHM>) => void;
|
|
10
|
+
}) => void;
|
|
11
|
+
export declare type CreatePlugin<HM extends HookMap, C, EHM extends HookMap> = (pluginHandlers: IPluginHandlers<HM & EHM, C> & {
|
|
12
|
+
setup?: Setup<EHM>;
|
|
13
|
+
}, options?: PluginOptions) => IPluginInstance<HM & EHM, C>;
|
|
14
|
+
export declare type HookManager<HM extends HookMap, C, EHM extends HookMap> = {
|
|
15
|
+
createPlugin: (pluginHandlers: IPluginHandlers<HM & EHM, C> & {
|
|
16
|
+
setup?: Setup<EHM>;
|
|
17
|
+
}, options?: PluginOptions) => IPluginInstance<HM & EHM, C>;
|
|
18
|
+
usePlugin: (...plugins: IPluginInstance<HM & EHM, C>[]) => void;
|
|
19
|
+
runner: RunnerType<HM, EHM>;
|
|
20
|
+
setContext: (context: C) => void;
|
|
21
|
+
clear: () => void;
|
|
22
|
+
addHooks: (hook: Partial<EHM>) => void;
|
|
23
|
+
hooks: HM | (HM & EHM);
|
|
24
|
+
getPlugins: () => IPluginInstance<HM & EHM, C>[];
|
|
25
|
+
};
|
|
26
|
+
export declare type RunnerType<HM, EHM> = {
|
|
27
|
+
[K in keyof (HM & EHM)]: HookRunnerType<(HM & EHM)[K]>;
|
|
28
|
+
} & {
|
|
29
|
+
setup: Setup<EHM>;
|
|
30
|
+
};
|
|
31
|
+
export declare type HookRunnerType<H> = H extends SyncHook<infer T, infer E, infer R> ? SyncHook<T, E, R>['run'] : H extends SyncBailHook<infer T, infer E, infer R> ? SyncBailHook<T, E, R>['run'] : H extends SyncWaterfallHook<infer T, infer E> ? SyncWaterfallHook<T, E>['run'] : H extends AsyncParallelHook<infer T, infer E, infer R> ? AsyncParallelHook<T, E, R>['run'] : H extends AsyncSeriesWaterfallHook<infer T, infer E> ? AsyncSeriesWaterfallHook<T, E>['run'] : never;
|
|
32
|
+
export declare type IPluginInstance<HM, C> = {
|
|
33
|
+
handlers: IPluginHandlers<HM, C>;
|
|
34
|
+
SYNC_PLUGIN_SYMBOL: 'SYNC_PLUGIN_SYMBOL';
|
|
35
|
+
} & PluginOptions;
|
|
36
|
+
export declare type IPluginHandlers<HM, C> = Partial<IPluginHandlersFullMap<HM, C>>;
|
|
37
|
+
export declare type IPluginHandlersFullMap<HM, C> = {
|
|
38
|
+
[K in keyof HM]: HM[K] extends SyncHook<infer T, infer E, infer R> ? PatchPluginParameter<SyncHookHandler<T, E, R>, C> : HM[K] extends SyncBailHook<infer T, infer E, infer R> ? PatchPluginParameter<SyncBailHookHandler<T, E, R>, C> : HM[K] extends SyncWaterfallHook<infer T, infer E> ? PatchPluginParameter<SyncWaterfallHookHandler<T, E>, C> : HM[K] extends AsyncParallelHook<infer T, infer E, infer R> ? PatchPluginParameter<AsyncParallelHookHandler<T, E, R>, C> : HM[K] extends AsyncSeriesWaterfallHook<infer T, infer E> ? PatchPluginParameter<AsyncSeriesWaterfallHookHandler<T, E>, C> : never;
|
|
39
|
+
};
|
|
40
|
+
export declare type PluginOptions = {
|
|
41
|
+
name?: string;
|
|
42
|
+
pre?: string[];
|
|
43
|
+
post?: string[];
|
|
44
|
+
rivals?: string[];
|
|
45
|
+
required?: string[];
|
|
46
|
+
order?: number;
|
|
47
|
+
[x: string]: any;
|
|
48
|
+
};
|
|
49
|
+
export declare const DEFAULT_OPTIONS: Required<PluginOptions>;
|
|
50
|
+
export declare const SYNC_PLUGIN_SYMBOL = "SYNC_PLUGIN_SYMBOL";
|
|
51
|
+
export declare const isPluginInstance: (plugin: any) => any;
|
|
52
|
+
export declare type ArrayElements<T extends {}> = {
|
|
53
|
+
[K in keyof T]: T[K][];
|
|
54
|
+
};
|
|
55
|
+
export declare const createHookManager: <HM extends HookMap, C = void, EHM extends HookMap = {}>(hookMap: HM, hasContext?: boolean) => HookManager<HM, C, EHM>;
|
|
56
|
+
export declare type RemoveManagerVoidParameter<T> = T extends (initalValue: infer I, extraArg: infer E, context: infer C) => infer R ? null extends I ? null extends E ? null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : void extends E ? null extends C ? (initialValue: I, context: C) => R : void extends C ? (initialValue: I) => R : (initialValue: I, context: C) => R : null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : void extends I ? null extends E ? null extends C ? (extraArg: E, context: C) => R : void extends C ? (extraArg: E) => R : (extraArg: E, context: C) => R : void extends E ? null extends C ? (context: C) => R : void extends C ? () => R : (context: C) => R : null extends C ? (extraArg: E, context: C) => R : void extends C ? (extraArg: E) => R : (extraArg: E, context: C) => R : null extends E ? null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : void extends E ? null extends C ? (initialValue: I, context: C) => R : void extends C ? (initialValue: I) => R : (initialValue: I, context: C) => R : null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : T;
|
package/esm/hookGroup.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { createSyncHook, createSyncBailHook, createSyncWaterfallHook, createAsyncParallelHook, createAsyncSeriesWaterfallHook } from './hooks';
|
|
2
|
+
export const DEFAULT_OPTIONS = {
|
|
3
|
+
name: 'untitled',
|
|
4
|
+
pre: [],
|
|
5
|
+
post: [],
|
|
6
|
+
rivals: [],
|
|
7
|
+
required: [],
|
|
8
|
+
order: 0
|
|
9
|
+
};
|
|
10
|
+
export const SYNC_PLUGIN_SYMBOL = 'SYNC_PLUGIN_SYMBOL';
|
|
11
|
+
export const isPluginInstance = (plugin) => plugin &&
|
|
12
|
+
plugin.hasOwnProperty(SYNC_PLUGIN_SYMBOL) &&
|
|
13
|
+
plugin.SYNC_PLUGIN_SYMBOL === SYNC_PLUGIN_SYMBOL;
|
|
14
|
+
const sortPlugins = (input) => {
|
|
15
|
+
let plugins = input.slice();
|
|
16
|
+
plugins.sort((a, b) => a.order - b.order);
|
|
17
|
+
for (let i = 0; i < plugins.length; i++) {
|
|
18
|
+
let plugin = plugins[i];
|
|
19
|
+
if (plugin.pre) {
|
|
20
|
+
for (const pre of plugin.pre) {
|
|
21
|
+
for (let j = i + 1; j < plugins.length; j++) {
|
|
22
|
+
if (plugins[j].name === pre) {
|
|
23
|
+
plugins = [
|
|
24
|
+
...plugins.slice(0, i),
|
|
25
|
+
plugins[j],
|
|
26
|
+
...plugins.slice(i, j),
|
|
27
|
+
...plugins.slice(j + 1, plugins.length)
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (plugin.post) {
|
|
34
|
+
for (const post of plugin.post) {
|
|
35
|
+
for (let j = 0; j < i; j++) {
|
|
36
|
+
if (plugins[j].name === post) {
|
|
37
|
+
plugins = [
|
|
38
|
+
...plugins.slice(0, j),
|
|
39
|
+
...plugins.slice(j + 1, i + 1),
|
|
40
|
+
plugins[j],
|
|
41
|
+
...plugins.slice(i + 1, plugins.length)
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return plugins;
|
|
49
|
+
};
|
|
50
|
+
const checkPlugins = (plugins) => {
|
|
51
|
+
for (const origin of plugins) {
|
|
52
|
+
if (origin.rivals) {
|
|
53
|
+
for (const rival of origin.rivals) {
|
|
54
|
+
for (const plugin of plugins) {
|
|
55
|
+
if (rival === plugin.name) {
|
|
56
|
+
throw new Error(`${origin.name} has rival ${plugin.name}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (origin.required) {
|
|
62
|
+
for (const required of origin.required) {
|
|
63
|
+
if (!plugins.some(plugin => plugin.name === required)) {
|
|
64
|
+
throw new Error(`The plugin: ${required} is required when plugin: ${origin.name} is exist.`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
function uuid() {
|
|
71
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
72
|
+
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
73
|
+
return v.toString(16);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const copyHookMap = (hookMap) => {
|
|
77
|
+
const newHookMap = {};
|
|
78
|
+
for (const hookName in hookMap) {
|
|
79
|
+
const hook = hookMap[hookName];
|
|
80
|
+
switch (hook === null || hook === void 0 ? void 0 : hook.type) {
|
|
81
|
+
case 'SyncHook':
|
|
82
|
+
newHookMap[hookName] = createSyncHook();
|
|
83
|
+
break;
|
|
84
|
+
case 'SyncBailHook':
|
|
85
|
+
newHookMap[hookName] = createSyncBailHook();
|
|
86
|
+
break;
|
|
87
|
+
case 'SyncWaterfallHook':
|
|
88
|
+
newHookMap[hookName] = createSyncWaterfallHook();
|
|
89
|
+
break;
|
|
90
|
+
case 'AsyncParallelHook':
|
|
91
|
+
newHookMap[hookName] = createAsyncParallelHook();
|
|
92
|
+
break;
|
|
93
|
+
case 'AsyncSeriesWaterfallHook':
|
|
94
|
+
newHookMap[hookName] = createAsyncSeriesWaterfallHook();
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return newHookMap;
|
|
100
|
+
};
|
|
101
|
+
export const createHookManager = (hookMap, hasContext = true) => {
|
|
102
|
+
const setupHook = createSyncHook();
|
|
103
|
+
const _hookMap = Object.assign(Object.assign({}, copyHookMap(hookMap)), { setup: setupHook });
|
|
104
|
+
let _plugins = [];
|
|
105
|
+
let _hookHandlers = {};
|
|
106
|
+
let _internalRunners = {};
|
|
107
|
+
let _context;
|
|
108
|
+
let _initiated = false;
|
|
109
|
+
const init = () => {
|
|
110
|
+
load();
|
|
111
|
+
const setupRunner = getRunner('setup');
|
|
112
|
+
setupRunner({ addHooks });
|
|
113
|
+
};
|
|
114
|
+
const createPlugin = (pluginHandlers, options = {}) => {
|
|
115
|
+
return Object.assign(Object.assign(Object.assign(Object.assign({}, DEFAULT_OPTIONS), { name: `plugin-id-${uuid()}` }), options), { handlers: pluginHandlers, SYNC_PLUGIN_SYMBOL });
|
|
116
|
+
};
|
|
117
|
+
const usePlugin = (...plugins) => {
|
|
118
|
+
if (_initiated) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
_plugins.push(...plugins);
|
|
122
|
+
};
|
|
123
|
+
const load = () => {
|
|
124
|
+
let plugins = _plugins;
|
|
125
|
+
plugins = sortPlugins(plugins);
|
|
126
|
+
checkPlugins(plugins);
|
|
127
|
+
plugins.forEach(plugin => {
|
|
128
|
+
const handlers = plugin.handlers;
|
|
129
|
+
let hookName;
|
|
130
|
+
for (hookName in handlers) {
|
|
131
|
+
if (!_hookHandlers[hookName]) {
|
|
132
|
+
_hookHandlers[hookName] = [];
|
|
133
|
+
}
|
|
134
|
+
_hookHandlers[hookName].push(handlers[hookName]);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
const setContext = (context) => {
|
|
139
|
+
_context = context;
|
|
140
|
+
};
|
|
141
|
+
const hooks = _hookMap;
|
|
142
|
+
const clear = () => {
|
|
143
|
+
Object.values(_hookMap).forEach(cur => {
|
|
144
|
+
cur.clear();
|
|
145
|
+
});
|
|
146
|
+
_plugins = [];
|
|
147
|
+
_hookHandlers = {};
|
|
148
|
+
_internalRunners = {};
|
|
149
|
+
_initiated = false;
|
|
150
|
+
};
|
|
151
|
+
const addHooks = (extraHookMap) => {
|
|
152
|
+
const extraHookMapNew = copyHookMap(extraHookMap);
|
|
153
|
+
for (const hookName in extraHookMapNew) {
|
|
154
|
+
// connot override existed hooks
|
|
155
|
+
if (!_hookMap[hookName]) {
|
|
156
|
+
//@ts-ignore
|
|
157
|
+
_hookMap[hookName] = extraHookMapNew[hookName];
|
|
158
|
+
if (_internalRunners[hookName]) {
|
|
159
|
+
delete _internalRunners[hookName];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.log('has been added', hookName);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const getRunner = (hookName) => {
|
|
168
|
+
if (_internalRunners[hookName]) {
|
|
169
|
+
return _internalRunners[hookName];
|
|
170
|
+
}
|
|
171
|
+
const currentRunner = getSingerRunner(hookName);
|
|
172
|
+
_internalRunners[hookName] = currentRunner;
|
|
173
|
+
return currentRunner;
|
|
174
|
+
};
|
|
175
|
+
const getSingerRunner = (hookName) => {
|
|
176
|
+
let used = false;
|
|
177
|
+
const hook = _hookMap[hookName];
|
|
178
|
+
const handlers = _hookHandlers[hookName] || [];
|
|
179
|
+
if (!hook)
|
|
180
|
+
return () => { };
|
|
181
|
+
const isSetupHook = hookName === 'setup';
|
|
182
|
+
if (isSetupHook) {
|
|
183
|
+
return (util) => {
|
|
184
|
+
let setupDone = false;
|
|
185
|
+
if (!used) {
|
|
186
|
+
hook.use(...handlers);
|
|
187
|
+
// every time setup hook runs, set setupDone to true at the end
|
|
188
|
+
// to make sure util methods cannot be used outside of the hook
|
|
189
|
+
hook.use(() => {
|
|
190
|
+
setupDone = true;
|
|
191
|
+
});
|
|
192
|
+
used = true;
|
|
193
|
+
}
|
|
194
|
+
const getDisposableFunctionProxy = (func) => new Proxy(func, {
|
|
195
|
+
apply(target, thisArg, argArray) {
|
|
196
|
+
if (setupDone) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
return target.apply(thisArg, argArray);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
const wrappedUtil = Object.assign({}, util);
|
|
203
|
+
for (let key in wrappedUtil) {
|
|
204
|
+
if (typeof wrappedUtil[key] === 'function') {
|
|
205
|
+
wrappedUtil[key] = getDisposableFunctionProxy(wrappedUtil[key]);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// @ts-ignore
|
|
209
|
+
return hook.run(wrappedUtil);
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return (...args) => {
|
|
213
|
+
if (!used) {
|
|
214
|
+
hook.use(...handlers);
|
|
215
|
+
used = true;
|
|
216
|
+
}
|
|
217
|
+
if (hasContext && !_context) {
|
|
218
|
+
throw new Error(`Context not set. Hook ${String(hookName)} running failed.`);
|
|
219
|
+
}
|
|
220
|
+
// @ts-ignore
|
|
221
|
+
return hook.run(...args, _context);
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
const runnerProxy = new Proxy({}, {
|
|
225
|
+
get(_, prop) {
|
|
226
|
+
if (!_initiated) {
|
|
227
|
+
init();
|
|
228
|
+
_initiated = true;
|
|
229
|
+
}
|
|
230
|
+
return getRunner(prop);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
createPlugin,
|
|
235
|
+
usePlugin,
|
|
236
|
+
runner: runnerProxy,
|
|
237
|
+
clear,
|
|
238
|
+
addHooks,
|
|
239
|
+
hooks,
|
|
240
|
+
setContext,
|
|
241
|
+
getPlugins: () => _plugins
|
|
242
|
+
};
|
|
243
|
+
};
|
package/esm/hooks.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export declare type HookRunnerFromHandler<T> = T extends (...args: infer A) => infer R ? void extends R ? (...args: A) => void : (...args: A) => R[] : T;
|
|
2
|
+
export declare type RemoveVoidParameter<T> = T extends (initalValue: infer I, extraArg: infer E) => infer R ? null extends I ? null extends E ? (initialValue: I, extraArg: E) => R : void extends E ? (initialValue: I) => R : (initialValue: I, extraArg: E) => R : void extends I ? null extends E ? (extraArg: E) => R : void extends E ? () => R : (extraArg: E) => R : null extends E ? (initialValue: I, extraArg: E) => R : void extends E ? (initialValue: I) => R : (initialValue: I, extraArg: E) => R : T;
|
|
3
|
+
export declare type RemoveVoidParameterBackup<T> = T extends (initalValue: infer I, extraArg: infer E) => infer R ? I extends void ? I extends void ? E extends void ? E extends void ? () => R : (extraArg: E) => R : (extraArg: E) => R : E extends void ? E extends void ? () => R : (initalValue: I, extraArg: E) => R : (initalValue: I, extraArg: E) => R : E extends void ? E extends void ? (initalValue: I) => R : (initalValue: I, extradddArg: E) => R : (initalValue: I, extraArg: E) => R : T;
|
|
4
|
+
export declare type Remove3VoidParameter<T> = T extends (initalValue: infer I, extraArg: infer E, context: infer C) => infer R ? I extends void ? I extends void ? E extends void ? E extends void ? C extends void ? C extends void ? 'C无' : 'C为any' : 'C有' : (extraArg: E) => R : (extraArg: E) => R : E extends void ? E extends void ? () => R : (initalValue: I, extraArg: E) => R : (initalValue: I, extraArg: E) => R : 'I有' : T;
|
|
5
|
+
export declare type SyncHookHandler<I, E, R> = (initalValue: I, extraArg: E) => R;
|
|
6
|
+
export declare type SyncBailHookHandler<I, E, R> = (initalValue: I, extraArg: E) => R | undefined | void;
|
|
7
|
+
export declare type SyncWaterfallHookHandler<I, E> = (initalValue: I, extraArgs: E) => I;
|
|
8
|
+
export declare type AsyncSeriesWaterfallHookHandler<I, E> = (initalValue: I, extraArg: E) => Promise<I> | I;
|
|
9
|
+
export declare type AsyncParallelHookHandler<I, E, R> = (initalValue: I, extraArgs: E) => Promise<R> | R;
|
|
10
|
+
/** Normal hook. */
|
|
11
|
+
export declare type SyncHook<I = void, E = void, R = void> = {
|
|
12
|
+
use: (...handlers: RemoveVoidParameter<SyncHookHandler<I, E, R>>[]) => void;
|
|
13
|
+
run: RemoveVoidParameter<(initalValue: I, extraArg: E) => R[]>;
|
|
14
|
+
clear: () => void;
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
/** Has return value with `any` type */
|
|
18
|
+
export declare type SyncBailHook<I = void, E = void, R = I> = {
|
|
19
|
+
use: (...handlers: RemoveVoidParameter<SyncBailHookHandler<I, E, R>>[]) => void;
|
|
20
|
+
run: RemoveVoidParameter<SyncBailHookHandler<I, E, R>>;
|
|
21
|
+
clear: () => void;
|
|
22
|
+
type: string;
|
|
23
|
+
};
|
|
24
|
+
/** Has return value with given type */
|
|
25
|
+
export declare type SyncWaterfallHook<I, E = void> = {
|
|
26
|
+
use: (...handlers: RemoveVoidParameter<SyncWaterfallHookHandler<I, E>>[]) => void;
|
|
27
|
+
run: RemoveVoidParameter<SyncWaterfallHookHandler<I, E>>;
|
|
28
|
+
clear: () => void;
|
|
29
|
+
type: string;
|
|
30
|
+
};
|
|
31
|
+
/** Normal async hook. No return value
|
|
32
|
+
*
|
|
33
|
+
* RemoveVoidParameter<(
|
|
34
|
+
null extends R ?
|
|
35
|
+
(R extends void ? ((initalValue: I, extraArg: E) => Promise<R[]>) :
|
|
36
|
+
((initalValue: I, extraArg: E) => Promise<R[]>)) :
|
|
37
|
+
((initalValue: I, extraArg: E) => Promise<R[]>)
|
|
38
|
+
)>
|
|
39
|
+
*/
|
|
40
|
+
export declare type AsyncParallelHook<I = void, E = void, R = void> = {
|
|
41
|
+
use: (...handlers: RemoveVoidParameter<AsyncParallelHookHandler<I, E, R>>[]) => void;
|
|
42
|
+
run: RemoveVoidParameter<(initalValue: I, extraArg: E) => Promise<R[]>>;
|
|
43
|
+
clear: () => void;
|
|
44
|
+
type: string;
|
|
45
|
+
};
|
|
46
|
+
/** Has return value with given type */
|
|
47
|
+
export declare type AsyncSeriesWaterfallHook<I = void, E = void> = {
|
|
48
|
+
use: (...handlers: RemoveVoidParameter<AsyncSeriesWaterfallHookHandler<I, E>>[]) => void;
|
|
49
|
+
run: RemoveVoidParameter<(initalValue: I, extraArgs: E) => Promise<I>>;
|
|
50
|
+
clear: () => void;
|
|
51
|
+
type: string;
|
|
52
|
+
};
|
|
53
|
+
export declare const createSyncHook: <I = void, E = void, R = void>() => SyncHook<I, E, R>;
|
|
54
|
+
export declare const createSyncBailHook: <I = void, E = void, R = I>() => SyncBailHook<I, E, R>;
|
|
55
|
+
export declare const createSyncWaterfallHook: <I = void, E = void>() => SyncWaterfallHook<I, E>;
|
|
56
|
+
export declare const createAsyncParallelHook: <I = void, E = void, R = void>() => AsyncParallelHook<I, E, R>;
|
|
57
|
+
export declare const createAsyncSeriesWaterfallHook: <I = void, E = void>() => AsyncSeriesWaterfallHook<I, E>;
|
package/esm/hooks.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// 钩子参数来源(void,固定值,前一个钩子的返回值) 钩子同步异步 钩子调用顺序() 钩子返回值
|
|
2
|
+
// 普通型钩子handler均无返回值(如果有,则是一个数组,但是似乎没啥用,如果对返回值有要求,那么应该用waterfall钩子)
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
export const createSyncHook = () => {
|
|
13
|
+
let _handlers = [];
|
|
14
|
+
const use = (...handlers) => {
|
|
15
|
+
_handlers.push(...handlers);
|
|
16
|
+
};
|
|
17
|
+
const run = (...args) => {
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
return _handlers.map(handler => handler(...args));
|
|
20
|
+
};
|
|
21
|
+
const clear = () => {
|
|
22
|
+
_handlers = [];
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
use,
|
|
26
|
+
run,
|
|
27
|
+
clear,
|
|
28
|
+
type: 'SyncHook'
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export const createSyncBailHook = () => {
|
|
32
|
+
let _handlers = [];
|
|
33
|
+
const use = (...handlers) => {
|
|
34
|
+
_handlers.push(...handlers);
|
|
35
|
+
};
|
|
36
|
+
const run = (...args) => {
|
|
37
|
+
for (let i = 0; i < _handlers.length; i++) {
|
|
38
|
+
const handler = _handlers[i];
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
const result = handler(...args);
|
|
41
|
+
if (result)
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
};
|
|
46
|
+
const clear = () => {
|
|
47
|
+
_handlers = [];
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
use,
|
|
51
|
+
run,
|
|
52
|
+
clear,
|
|
53
|
+
type: 'SyncBailHook'
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export const createSyncWaterfallHook = () => {
|
|
57
|
+
let _handlers = [];
|
|
58
|
+
const use = (...handlers) => {
|
|
59
|
+
_handlers.push(...handlers);
|
|
60
|
+
};
|
|
61
|
+
const run = (...args) => {
|
|
62
|
+
let [currentParam, ...otherArgs] = args;
|
|
63
|
+
for (let i = 0; i < _handlers.length; i++) {
|
|
64
|
+
const handler = _handlers[i];
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
currentParam = handler(currentParam, ...otherArgs);
|
|
67
|
+
}
|
|
68
|
+
return currentParam;
|
|
69
|
+
};
|
|
70
|
+
const clear = () => {
|
|
71
|
+
_handlers = [];
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
use,
|
|
75
|
+
run,
|
|
76
|
+
clear,
|
|
77
|
+
type: 'SyncWaterfallHook'
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
export const createAsyncParallelHook = () => {
|
|
81
|
+
let _handlers = [];
|
|
82
|
+
const use = (...handlers) => {
|
|
83
|
+
_handlers.push(...handlers);
|
|
84
|
+
};
|
|
85
|
+
const run = (...args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
return yield Promise.all(_handlers.map(
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
handler => handler(...args)));
|
|
89
|
+
});
|
|
90
|
+
const clear = () => {
|
|
91
|
+
_handlers = [];
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
use,
|
|
95
|
+
run,
|
|
96
|
+
clear,
|
|
97
|
+
type: 'AsyncParallelHook'
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
export const createAsyncSeriesWaterfallHook = () => {
|
|
101
|
+
let _handlers = [];
|
|
102
|
+
const use = (...handlers) => {
|
|
103
|
+
_handlers.push(...handlers);
|
|
104
|
+
};
|
|
105
|
+
const run = (...args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
|
+
let [currentParam, ...otherArgs] = args;
|
|
107
|
+
for (let i = 0; i < _handlers.length; i++) {
|
|
108
|
+
const handler = _handlers[i];
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
currentParam = yield handler(currentParam, ...otherArgs);
|
|
111
|
+
}
|
|
112
|
+
return currentParam;
|
|
113
|
+
});
|
|
114
|
+
const clear = () => {
|
|
115
|
+
_handlers = [];
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
use,
|
|
119
|
+
run,
|
|
120
|
+
clear,
|
|
121
|
+
type: 'AsyncSeriesWaterfallHook'
|
|
122
|
+
};
|
|
123
|
+
};
|
package/esm/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export * from './types';
|
|
1
|
+
export * from './hooks';
|
|
2
|
+
export * from './hookGroup';
|
package/esm/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
export * from './hooks';
|
|
2
|
+
export * from './hookGroup';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SyncHook, SyncBailHook, SyncWaterfallHook, AsyncParallelHook, AsyncSeriesWaterfallHook, SyncHookHandler, SyncBailHookHandler, SyncWaterfallHookHandler, AsyncParallelHookHandler, AsyncSeriesWaterfallHookHandler } from './hooks';
|
|
2
|
+
export declare type PatchPluginParameter<T, C> = RemoveManagerVoidParameter<AddContextParameter<T, C>>;
|
|
3
|
+
export declare type AddContextParameter<T, C> = T extends (initalValue: infer I, extraArg: infer E) => infer R ? (initalValue: I, extraArg: E, context: C) => R : T;
|
|
4
|
+
export declare type AnyHook = SyncHook<any, any, any> | SyncBailHook<any, any, any> | SyncWaterfallHook<any, any> | AsyncParallelHook<any, any, any> | AsyncSeriesWaterfallHook<any, any>;
|
|
5
|
+
export interface HookMap {
|
|
6
|
+
[x: string]: AnyHook;
|
|
7
|
+
}
|
|
8
|
+
export declare type Setup<EHM> = (utils: {
|
|
9
|
+
addHooks: (hook: Partial<EHM>) => void;
|
|
10
|
+
}) => void;
|
|
11
|
+
export declare type CreatePlugin<HM extends HookMap, C, EHM extends HookMap> = (pluginHandlers: IPluginHandlers<HM & EHM, C> & {
|
|
12
|
+
setup?: Setup<EHM>;
|
|
13
|
+
}, options?: PluginOptions) => IPluginInstance<HM & EHM, C>;
|
|
14
|
+
export declare type HookManager<HM extends HookMap, C, EHM extends HookMap> = {
|
|
15
|
+
createPlugin: (pluginHandlers: IPluginHandlers<HM & EHM, C> & {
|
|
16
|
+
setup?: Setup<EHM>;
|
|
17
|
+
}, options?: PluginOptions) => IPluginInstance<HM & EHM, C>;
|
|
18
|
+
usePlugin: (...plugins: IPluginInstance<HM & EHM, C>[]) => void;
|
|
19
|
+
runner: RunnerType<HM, EHM>;
|
|
20
|
+
setContext: (context: C) => void;
|
|
21
|
+
clear: () => void;
|
|
22
|
+
addHooks: (hook: Partial<EHM>) => void;
|
|
23
|
+
hooks: HM | (HM & EHM);
|
|
24
|
+
getPlugins: () => IPluginInstance<HM & EHM, C>[];
|
|
25
|
+
};
|
|
26
|
+
export declare type RunnerType<HM, EHM> = {
|
|
27
|
+
[K in keyof (HM & EHM)]: HookRunnerType<(HM & EHM)[K]>;
|
|
28
|
+
} & {
|
|
29
|
+
setup: Setup<EHM>;
|
|
30
|
+
};
|
|
31
|
+
export declare type HookRunnerType<H> = H extends SyncHook<infer T, infer E, infer R> ? SyncHook<T, E, R>['run'] : H extends SyncBailHook<infer T, infer E, infer R> ? SyncBailHook<T, E, R>['run'] : H extends SyncWaterfallHook<infer T, infer E> ? SyncWaterfallHook<T, E>['run'] : H extends AsyncParallelHook<infer T, infer E, infer R> ? AsyncParallelHook<T, E, R>['run'] : H extends AsyncSeriesWaterfallHook<infer T, infer E> ? AsyncSeriesWaterfallHook<T, E>['run'] : never;
|
|
32
|
+
export declare type IPluginInstance<HM, C> = {
|
|
33
|
+
handlers: IPluginHandlers<HM, C>;
|
|
34
|
+
SYNC_PLUGIN_SYMBOL: 'SYNC_PLUGIN_SYMBOL';
|
|
35
|
+
} & PluginOptions;
|
|
36
|
+
export declare type IPluginHandlers<HM, C> = Partial<IPluginHandlersFullMap<HM, C>>;
|
|
37
|
+
export declare type IPluginHandlersFullMap<HM, C> = {
|
|
38
|
+
[K in keyof HM]: HM[K] extends SyncHook<infer T, infer E, infer R> ? PatchPluginParameter<SyncHookHandler<T, E, R>, C> : HM[K] extends SyncBailHook<infer T, infer E, infer R> ? PatchPluginParameter<SyncBailHookHandler<T, E, R>, C> : HM[K] extends SyncWaterfallHook<infer T, infer E> ? PatchPluginParameter<SyncWaterfallHookHandler<T, E>, C> : HM[K] extends AsyncParallelHook<infer T, infer E, infer R> ? PatchPluginParameter<AsyncParallelHookHandler<T, E, R>, C> : HM[K] extends AsyncSeriesWaterfallHook<infer T, infer E> ? PatchPluginParameter<AsyncSeriesWaterfallHookHandler<T, E>, C> : never;
|
|
39
|
+
};
|
|
40
|
+
export declare type PluginOptions = {
|
|
41
|
+
name?: string;
|
|
42
|
+
pre?: string[];
|
|
43
|
+
post?: string[];
|
|
44
|
+
rivals?: string[];
|
|
45
|
+
required?: string[];
|
|
46
|
+
order?: number;
|
|
47
|
+
[x: string]: any;
|
|
48
|
+
};
|
|
49
|
+
export declare const DEFAULT_OPTIONS: Required<PluginOptions>;
|
|
50
|
+
export declare const SYNC_PLUGIN_SYMBOL = "SYNC_PLUGIN_SYMBOL";
|
|
51
|
+
export declare const isPluginInstance: (plugin: any) => any;
|
|
52
|
+
export declare type ArrayElements<T extends {}> = {
|
|
53
|
+
[K in keyof T]: T[K][];
|
|
54
|
+
};
|
|
55
|
+
export declare const createHookManager: <HM extends HookMap, C = void, EHM extends HookMap = {}>(hookMap: HM, hasContext?: boolean) => HookManager<HM, C, EHM>;
|
|
56
|
+
export declare type RemoveManagerVoidParameter<T> = T extends (initalValue: infer I, extraArg: infer E, context: infer C) => infer R ? null extends I ? null extends E ? null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : void extends E ? null extends C ? (initialValue: I, context: C) => R : void extends C ? (initialValue: I) => R : (initialValue: I, context: C) => R : null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : void extends I ? null extends E ? null extends C ? (extraArg: E, context: C) => R : void extends C ? (extraArg: E) => R : (extraArg: E, context: C) => R : void extends E ? null extends C ? (context: C) => R : void extends C ? () => R : (context: C) => R : null extends C ? (extraArg: E, context: C) => R : void extends C ? (extraArg: E) => R : (extraArg: E, context: C) => R : null extends E ? null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : void extends E ? null extends C ? (initialValue: I, context: C) => R : void extends C ? (initialValue: I) => R : (initialValue: I, context: C) => R : null extends C ? (initialValue: I, extraArg: E, context: C) => R : void extends C ? (initialValue: I, extraArg: E) => R : (initialValue: I, extraArg: E, context: C) => R : T;
|