@modern-js/plugin 1.2.0 → 1.2.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/CHANGELOG.md +6 -0
- package/dist/js/modern/waterfall/async.js +4 -4
- package/dist/js/node/waterfall/async.js +4 -4
- package/dist/js/treeshaking/waterfall/async.js +4 -4
- package/dist/types/waterfall/async.d.ts +2 -2
- package/package.json +1 -1
- package/src/index.ts +0 -5
- package/src/manager/async.ts +0 -248
- package/src/manager/index.ts +0 -3
- package/src/manager/runner.ts +0 -15
- package/src/manager/sync.ts +0 -458
- package/src/waterfall/async.ts +0 -109
- package/src/waterfall/index.ts +0 -2
- package/src/waterfall/sync.ts +0 -110
- package/src/workflow/async.ts +0 -96
- package/src/workflow/index.ts +0 -3
- package/src/workflow/parallel.ts +0 -97
- package/src/workflow/sync.ts +0 -82
package/CHANGELOG.md
CHANGED
@@ -9,8 +9,8 @@ const ASYNC_WATERFALL_SYMBOL = Symbol('ASYNC_WATERFALL_SYMBOL');
|
|
9
9
|
export const getAsyncBrook = input => {
|
10
10
|
if (typeof input === 'function') {
|
11
11
|
return input;
|
12
|
-
} else if (input && typeof input.
|
13
|
-
return input.
|
12
|
+
} else if (input && typeof input.middleware === 'function') {
|
13
|
+
return input.middleware;
|
14
14
|
} // eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
15
15
|
|
16
16
|
|
@@ -30,7 +30,7 @@ export const createAsyncWaterfall = () => {
|
|
30
30
|
onLast: input => input
|
31
31
|
}));
|
32
32
|
|
33
|
-
const
|
33
|
+
const middleware = input => {
|
34
34
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
35
35
|
const container = useContainer(); // eslint-disable-next-line @typescript-eslint/no-shadow
|
36
36
|
|
@@ -43,7 +43,7 @@ export const createAsyncWaterfall = () => {
|
|
43
43
|
const waterfall = _objectSpread(_objectSpread({}, pipeline), {}, {
|
44
44
|
use,
|
45
45
|
run,
|
46
|
-
|
46
|
+
middleware,
|
47
47
|
[ASYNC_WATERFALL_SYMBOL]: true
|
48
48
|
});
|
49
49
|
|
@@ -18,8 +18,8 @@ const ASYNC_WATERFALL_SYMBOL = Symbol('ASYNC_WATERFALL_SYMBOL');
|
|
18
18
|
const getAsyncBrook = input => {
|
19
19
|
if (typeof input === 'function') {
|
20
20
|
return input;
|
21
|
-
} else if (input && typeof input.
|
22
|
-
return input.
|
21
|
+
} else if (input && typeof input.middleware === 'function') {
|
22
|
+
return input.middleware;
|
23
23
|
} // eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
24
24
|
|
25
25
|
|
@@ -42,7 +42,7 @@ const createAsyncWaterfall = () => {
|
|
42
42
|
onLast: input => input
|
43
43
|
}));
|
44
44
|
|
45
|
-
const
|
45
|
+
const middleware = input => {
|
46
46
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
47
47
|
const container = (0, _farrowPipeline.useContainer)(); // eslint-disable-next-line @typescript-eslint/no-shadow
|
48
48
|
|
@@ -55,7 +55,7 @@ const createAsyncWaterfall = () => {
|
|
55
55
|
const waterfall = _objectSpread(_objectSpread({}, pipeline), {}, {
|
56
56
|
use,
|
57
57
|
run,
|
58
|
-
|
58
|
+
middleware,
|
59
59
|
[ASYNC_WATERFALL_SYMBOL]: true
|
60
60
|
});
|
61
61
|
|
@@ -27,8 +27,8 @@ var ASYNC_WATERFALL_SYMBOL = Symbol('ASYNC_WATERFALL_SYMBOL');
|
|
27
27
|
export var getAsyncBrook = function getAsyncBrook(input) {
|
28
28
|
if (typeof input === 'function') {
|
29
29
|
return input;
|
30
|
-
} else if (input && typeof input.
|
31
|
-
return input.
|
30
|
+
} else if (input && typeof input.middleware === 'function') {
|
31
|
+
return input.middleware;
|
32
32
|
} // eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
33
33
|
|
34
34
|
|
@@ -57,7 +57,7 @@ export var createAsyncWaterfall = function createAsyncWaterfall() {
|
|
57
57
|
);
|
58
58
|
};
|
59
59
|
|
60
|
-
var
|
60
|
+
var middleware = function middleware(input) {
|
61
61
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
62
62
|
var container = useContainer(); // eslint-disable-next-line @typescript-eslint/no-shadow
|
63
63
|
|
@@ -72,7 +72,7 @@ export var createAsyncWaterfall = function createAsyncWaterfall() {
|
|
72
72
|
var waterfall = _objectSpread(_objectSpread({}, pipeline), {}, _defineProperty({
|
73
73
|
use: use,
|
74
74
|
run: run,
|
75
|
-
|
75
|
+
middleware: middleware
|
76
76
|
}, ASYNC_WATERFALL_SYMBOL, true));
|
77
77
|
|
78
78
|
return waterfall;
|
@@ -2,7 +2,7 @@ import { MaybeAsync, Container } from 'farrow-pipeline';
|
|
2
2
|
declare const ASYNC_WATERFALL_SYMBOL: unique symbol;
|
3
3
|
export declare type AsyncBrook<I = unknown> = (I: I) => MaybeAsync<I>;
|
4
4
|
export declare type AsyncBrookInput<I = unknown> = AsyncBrook<I> | {
|
5
|
-
|
5
|
+
middleware: AsyncBrook<I>;
|
6
6
|
};
|
7
7
|
export declare type AsyncBrooks<I = unknown> = AsyncBrook<I>[];
|
8
8
|
export declare type AsyncBrookInputs<I = unknown> = AsyncBrookInput<I>[];
|
@@ -14,7 +14,7 @@ export declare type RunAsyncWaterfallOptions<I = unknown> = {
|
|
14
14
|
export declare type AsyncWaterfall<I> = {
|
15
15
|
run: (input: I, options?: RunAsyncWaterfallOptions<I>) => MaybeAsync<I>;
|
16
16
|
use: (...I: AsyncBrookInputs<I>) => AsyncWaterfall<I>;
|
17
|
-
|
17
|
+
middleware: AsyncBrook<I>;
|
18
18
|
[ASYNC_WATERFALL_SYMBOL]: true;
|
19
19
|
};
|
20
20
|
export declare type AsyncWaterfall2AsyncBrook<P extends AsyncWaterfall<any>> = P extends AsyncWaterfall<infer I> ? AsyncBrook<I> : never;
|
package/package.json
CHANGED
package/src/index.ts
DELETED
package/src/manager/async.ts
DELETED
@@ -1,248 +0,0 @@
|
|
1
|
-
import { runWithContainer, createContainer } from 'farrow-pipeline';
|
2
|
-
import {
|
3
|
-
ProgressRecord,
|
4
|
-
Progresses2Threads,
|
5
|
-
Progresses2Runners,
|
6
|
-
PluginOptions,
|
7
|
-
ClearDraftProgress,
|
8
|
-
InitOptions,
|
9
|
-
generateRunner,
|
10
|
-
hasOwnProperty,
|
11
|
-
DEFAULT_OPTIONS,
|
12
|
-
} from './sync';
|
13
|
-
import { useRunner } from './runner';
|
14
|
-
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
16
|
-
export type AsyncInitializer<O> = () => void | O | Promise<O | void>;
|
17
|
-
|
18
|
-
const ASYNC_PLUGIN_SYMBOL = 'ASYNC_PLUGIN_SYMBOL';
|
19
|
-
|
20
|
-
export type AsyncPlugin<O> = {
|
21
|
-
initializer: AsyncInitializer<O>;
|
22
|
-
ASYNC_PLUGIN_SYMBOL: typeof ASYNC_PLUGIN_SYMBOL;
|
23
|
-
} & Required<PluginOptions>;
|
24
|
-
|
25
|
-
export type IndexAsyncPlugin<O> = AsyncPlugin<O> & {
|
26
|
-
index: number;
|
27
|
-
};
|
28
|
-
|
29
|
-
export type AsyncPlugins<O> = AsyncPlugin<O>[];
|
30
|
-
export type AsyncIndexPlugins<O> = IndexAsyncPlugin<O>[];
|
31
|
-
|
32
|
-
export type AsyncPluginFromAsyncManager<M extends AsyncManager<any, any>> =
|
33
|
-
M extends AsyncManager<infer EP, infer PR>
|
34
|
-
? AsyncPlugin<Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>>
|
35
|
-
: never;
|
36
|
-
|
37
|
-
export type PluginFromAsyncManager<M extends AsyncManager<any, any>> =
|
38
|
-
M extends AsyncManager<infer EP, infer PR>
|
39
|
-
? AsyncPlugin<Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>>
|
40
|
-
: never;
|
41
|
-
|
42
|
-
export type AsyncManager<
|
43
|
-
EP extends Record<string, any>,
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
45
|
-
PR extends ProgressRecord | void = void,
|
46
|
-
> = {
|
47
|
-
createPlugin: (
|
48
|
-
initializer: AsyncInitializer<
|
49
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
50
|
-
>,
|
51
|
-
options?: PluginOptions,
|
52
|
-
) => AsyncPlugin<Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>>;
|
53
|
-
isPlugin: (
|
54
|
-
input: Record<string, unknown>,
|
55
|
-
) => input is AsyncPlugin<
|
56
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
57
|
-
>;
|
58
|
-
usePlugin: (
|
59
|
-
...input: AsyncPlugins<
|
60
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
61
|
-
>
|
62
|
-
) => AsyncManager<EP, PR>;
|
63
|
-
init: (
|
64
|
-
options?: InitOptions,
|
65
|
-
) => Promise<Progresses2Runners<PR & ClearDraftProgress<EP>>>;
|
66
|
-
run: <O>(cb: () => O, options?: InitOptions) => O;
|
67
|
-
registe: (newShape: Partial<EP>) => void;
|
68
|
-
clone: () => AsyncManager<EP, PR>;
|
69
|
-
clear: () => void;
|
70
|
-
useRunner: () => Progresses2Runners<PR & ClearDraftProgress<EP>>;
|
71
|
-
};
|
72
|
-
|
73
|
-
export const createAsyncManager = <
|
74
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
75
|
-
EP extends Record<string, any> = {},
|
76
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
77
|
-
PR extends ProgressRecord | void = void,
|
78
|
-
>(
|
79
|
-
processes?: PR,
|
80
|
-
): AsyncManager<EP, PR> => {
|
81
|
-
let index = 0;
|
82
|
-
const createPlugin: AsyncManager<EP, PR>['createPlugin'] = (
|
83
|
-
initializer,
|
84
|
-
options = {},
|
85
|
-
) => ({
|
86
|
-
...DEFAULT_OPTIONS,
|
87
|
-
name: `No.${index++} plugin`,
|
88
|
-
...options,
|
89
|
-
ASYNC_PLUGIN_SYMBOL,
|
90
|
-
initializer,
|
91
|
-
});
|
92
|
-
|
93
|
-
const isPlugin: AsyncManager<EP, PR>['isPlugin'] = (
|
94
|
-
input,
|
95
|
-
): input is AsyncPlugin<
|
96
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
97
|
-
> =>
|
98
|
-
hasOwnProperty(input, ASYNC_PLUGIN_SYMBOL) &&
|
99
|
-
input[ASYNC_PLUGIN_SYMBOL] === ASYNC_PLUGIN_SYMBOL;
|
100
|
-
|
101
|
-
const registe: AsyncManager<EP, PR>['registe'] = extraProcesses => {
|
102
|
-
// eslint-disable-next-line no-param-reassign
|
103
|
-
processes = {
|
104
|
-
...extraProcesses,
|
105
|
-
...processes,
|
106
|
-
} as any;
|
107
|
-
};
|
108
|
-
|
109
|
-
const clone = () => {
|
110
|
-
let plugins: AsyncIndexPlugins<
|
111
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
112
|
-
> = [];
|
113
|
-
|
114
|
-
const usePlugin: AsyncManager<EP, PR>['usePlugin'] = (...input) => {
|
115
|
-
for (const plugin of input) {
|
116
|
-
if (isPlugin(plugin)) {
|
117
|
-
if (!includeAsyncPlugin(plugins, plugin)) {
|
118
|
-
plugins.push({
|
119
|
-
...plugin,
|
120
|
-
index: plugins.length,
|
121
|
-
});
|
122
|
-
}
|
123
|
-
} else {
|
124
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
125
|
-
// @ts-expect-error
|
126
|
-
console.warn(`Unknown plugin: ${plugin.name}`);
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
|
-
return manager;
|
131
|
-
};
|
132
|
-
|
133
|
-
const clear = () => {
|
134
|
-
plugins = [];
|
135
|
-
};
|
136
|
-
|
137
|
-
const currentContainer = createContainer();
|
138
|
-
|
139
|
-
const init: AsyncManager<EP, PR>['init'] = async options => {
|
140
|
-
const container = options?.container || currentContainer;
|
141
|
-
|
142
|
-
const sortedPlugins = sortAsyncPlugins(plugins);
|
143
|
-
|
144
|
-
checkAsyncPlugins(sortedPlugins);
|
145
|
-
|
146
|
-
const hooksList = await Promise.all(
|
147
|
-
sortedPlugins.map(plugin =>
|
148
|
-
runWithContainer(() => plugin.initializer(), container),
|
149
|
-
),
|
150
|
-
);
|
151
|
-
|
152
|
-
return generateRunner<EP, PR>(hooksList, container, processes);
|
153
|
-
};
|
154
|
-
|
155
|
-
const run: AsyncManager<EP, PR>['run'] = (cb, options) => {
|
156
|
-
const container = options?.container || currentContainer;
|
157
|
-
|
158
|
-
return runWithContainer(cb, container);
|
159
|
-
};
|
160
|
-
|
161
|
-
const manager = {
|
162
|
-
createPlugin,
|
163
|
-
isPlugin,
|
164
|
-
usePlugin,
|
165
|
-
init,
|
166
|
-
run,
|
167
|
-
clear,
|
168
|
-
clone,
|
169
|
-
registe,
|
170
|
-
useRunner,
|
171
|
-
};
|
172
|
-
|
173
|
-
return manager;
|
174
|
-
};
|
175
|
-
|
176
|
-
return clone();
|
177
|
-
};
|
178
|
-
|
179
|
-
const includeAsyncPlugin = <O>(
|
180
|
-
plugins: AsyncPlugins<O>,
|
181
|
-
input: AsyncPlugin<O>,
|
182
|
-
): boolean => {
|
183
|
-
for (const plugin of plugins) {
|
184
|
-
if (plugin.name === input.name) {
|
185
|
-
return true;
|
186
|
-
}
|
187
|
-
}
|
188
|
-
|
189
|
-
return false;
|
190
|
-
};
|
191
|
-
|
192
|
-
const sortAsyncPlugins = <O>(
|
193
|
-
input: AsyncIndexPlugins<O>,
|
194
|
-
): AsyncIndexPlugins<O> => {
|
195
|
-
let plugins = input.slice();
|
196
|
-
|
197
|
-
for (let i = 0; i < plugins.length; i++) {
|
198
|
-
const plugin = plugins[i];
|
199
|
-
|
200
|
-
for (const pre of plugin.pre) {
|
201
|
-
for (let j = i + 1; j < plugins.length; j++) {
|
202
|
-
if (plugins[j].name === pre) {
|
203
|
-
plugins = [
|
204
|
-
...plugins.slice(0, i),
|
205
|
-
plugins[j],
|
206
|
-
...plugins.slice(i, j),
|
207
|
-
...plugins.slice(j + 1, plugins.length),
|
208
|
-
];
|
209
|
-
}
|
210
|
-
}
|
211
|
-
}
|
212
|
-
|
213
|
-
for (const post of plugin.post) {
|
214
|
-
for (let j = 0; j < i; j++) {
|
215
|
-
if (plugins[j].name === post) {
|
216
|
-
plugins = [
|
217
|
-
...plugins.slice(0, j),
|
218
|
-
...plugins.slice(j + 1, i + 1),
|
219
|
-
plugins[j],
|
220
|
-
...plugins.slice(i + 1, plugins.length),
|
221
|
-
];
|
222
|
-
}
|
223
|
-
}
|
224
|
-
}
|
225
|
-
}
|
226
|
-
|
227
|
-
return plugins;
|
228
|
-
};
|
229
|
-
|
230
|
-
const checkAsyncPlugins = <O>(plugins: AsyncIndexPlugins<O>) => {
|
231
|
-
for (const origin of plugins) {
|
232
|
-
for (const rival of origin.rivals) {
|
233
|
-
for (const plugin of plugins) {
|
234
|
-
if (rival === plugin.name) {
|
235
|
-
throw new Error(`${origin.name} has rival ${plugin.name}`);
|
236
|
-
}
|
237
|
-
}
|
238
|
-
}
|
239
|
-
|
240
|
-
for (const required of origin.required) {
|
241
|
-
if (!plugins.some(plugin => plugin.name === required)) {
|
242
|
-
throw new Error(
|
243
|
-
`The plugin: ${required} is required when plugin: ${origin.name} is exist.`,
|
244
|
-
);
|
245
|
-
}
|
246
|
-
}
|
247
|
-
}
|
248
|
-
};
|
package/src/manager/index.ts
DELETED
package/src/manager/runner.ts
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
import { createContext } from 'farrow-pipeline';
|
2
|
-
|
3
|
-
export const RunnerContext = createContext<any>(null);
|
4
|
-
|
5
|
-
export const useRunner = () => {
|
6
|
-
const runner = RunnerContext.use().value;
|
7
|
-
|
8
|
-
if (!runner) {
|
9
|
-
throw new Error(
|
10
|
-
`Can't call useRunner out of scope, it should be placed in hooks of plugin`,
|
11
|
-
);
|
12
|
-
}
|
13
|
-
|
14
|
-
return runner;
|
15
|
-
};
|
package/src/manager/sync.ts
DELETED
@@ -1,458 +0,0 @@
|
|
1
|
-
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
2
|
-
/* eslint-disable max-lines */
|
3
|
-
import {
|
4
|
-
Middleware,
|
5
|
-
Pipeline,
|
6
|
-
isPipeline,
|
7
|
-
createPipeline,
|
8
|
-
AsyncPipeline,
|
9
|
-
MaybeAsync,
|
10
|
-
runWithContainer,
|
11
|
-
createContainer,
|
12
|
-
Container,
|
13
|
-
} from 'farrow-pipeline';
|
14
|
-
import {
|
15
|
-
Waterfall,
|
16
|
-
Brook,
|
17
|
-
isWaterfall,
|
18
|
-
createWaterfall,
|
19
|
-
AsyncWaterfall,
|
20
|
-
AsyncBrook,
|
21
|
-
isAsyncWaterfall,
|
22
|
-
createAsyncWaterfall,
|
23
|
-
} from '../waterfall';
|
24
|
-
import {
|
25
|
-
Worker,
|
26
|
-
Workflow,
|
27
|
-
isWorkflow,
|
28
|
-
createWorkflow,
|
29
|
-
AsyncWorker,
|
30
|
-
AsyncWorkflow,
|
31
|
-
isAsyncWorkflow,
|
32
|
-
createAsyncWorkflow,
|
33
|
-
ParallelWorkflow,
|
34
|
-
isParallelWorkflow,
|
35
|
-
createParallelWorkflow,
|
36
|
-
} from '../workflow';
|
37
|
-
import { RunnerContext, useRunner } from './runner';
|
38
|
-
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
40
|
-
export type Initializer<O> = () => O | void;
|
41
|
-
|
42
|
-
const SYNC_PLUGIN_SYMBOL = 'SYNC_PLUGIN_SYMBOL';
|
43
|
-
|
44
|
-
export type Plugin<O> = {
|
45
|
-
initializer: Initializer<O>;
|
46
|
-
SYNC_PLUGIN_SYMBOL: typeof SYNC_PLUGIN_SYMBOL;
|
47
|
-
} & Required<PluginOptions>;
|
48
|
-
|
49
|
-
export type IndexPlugin<O> = Plugin<O> & {
|
50
|
-
index: number;
|
51
|
-
};
|
52
|
-
|
53
|
-
export type Plugins<O> = Plugin<O>[];
|
54
|
-
export type IndexPlugins<O> = IndexPlugin<O>[];
|
55
|
-
|
56
|
-
export type PluginOptions = {
|
57
|
-
name?: string;
|
58
|
-
pre?: string[];
|
59
|
-
post?: string[];
|
60
|
-
rivals?: string[];
|
61
|
-
required?: string[];
|
62
|
-
};
|
63
|
-
|
64
|
-
export type Progress =
|
65
|
-
| Waterfall<any>
|
66
|
-
| AsyncWaterfall<any>
|
67
|
-
| Workflow<any, any>
|
68
|
-
| AsyncWorkflow<any, any>
|
69
|
-
| ParallelWorkflow<any>
|
70
|
-
| Pipeline<any, any>
|
71
|
-
| AsyncPipeline<any, any>;
|
72
|
-
|
73
|
-
export type Progress2Thread<P extends Progress> = P extends Workflow<
|
74
|
-
infer I,
|
75
|
-
infer O
|
76
|
-
>
|
77
|
-
? Worker<I, O>
|
78
|
-
: P extends AsyncWorkflow<infer I, infer O>
|
79
|
-
? AsyncWorker<I, O>
|
80
|
-
: P extends ParallelWorkflow<infer I, infer O>
|
81
|
-
? AsyncWorker<I, O>
|
82
|
-
: P extends Waterfall<infer I>
|
83
|
-
? Brook<I>
|
84
|
-
: P extends AsyncWaterfall<infer I>
|
85
|
-
? AsyncBrook<I>
|
86
|
-
: P extends Pipeline<infer I, infer O>
|
87
|
-
? Middleware<I, O>
|
88
|
-
: P extends AsyncPipeline<infer I, infer O>
|
89
|
-
? Middleware<I, MaybeAsync<O>>
|
90
|
-
: never;
|
91
|
-
|
92
|
-
export type ProgressRecord = Record<string, Progress>;
|
93
|
-
|
94
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
95
|
-
export type Progresses2Threads<PS extends ProgressRecord | void> = {
|
96
|
-
[K in keyof PS]: PS[K] extends Progress
|
97
|
-
? Progress2Thread<PS[K]>
|
98
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
99
|
-
PS[K] extends void
|
100
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
101
|
-
void
|
102
|
-
: never;
|
103
|
-
};
|
104
|
-
|
105
|
-
export type RunnerFromProgress<P extends Progress> = P extends Waterfall<
|
106
|
-
infer I
|
107
|
-
>
|
108
|
-
? Waterfall<I>['run']
|
109
|
-
: P extends AsyncWaterfall<infer I>
|
110
|
-
? AsyncWaterfall<I>['run']
|
111
|
-
: P extends Workflow<infer I, infer O>
|
112
|
-
? Workflow<I, O>['run']
|
113
|
-
: P extends AsyncWorkflow<infer I, infer O>
|
114
|
-
? AsyncWorkflow<I, O>['run']
|
115
|
-
: P extends ParallelWorkflow<infer I, infer O>
|
116
|
-
? ParallelWorkflow<I, O>['run']
|
117
|
-
: P extends Pipeline<infer I, infer O>
|
118
|
-
? Pipeline<I, O>['run']
|
119
|
-
: P extends AsyncPipeline<infer I, infer O>
|
120
|
-
? AsyncPipeline<I, O>['run']
|
121
|
-
: never;
|
122
|
-
|
123
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
124
|
-
export type Progresses2Runners<PS extends ProgressRecord | void> = {
|
125
|
-
[K in keyof PS]: PS[K] extends Progress
|
126
|
-
? RunnerFromProgress<PS[K]>
|
127
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
128
|
-
PS[K] extends void
|
129
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
130
|
-
void
|
131
|
-
: never;
|
132
|
-
};
|
133
|
-
|
134
|
-
export type ClearDraftProgress<I extends Record<string, any>> = {
|
135
|
-
[K in keyof I]: I[K] extends Progress ? I[K] : never;
|
136
|
-
};
|
137
|
-
|
138
|
-
export type PluginFromManager<M extends Manager<any, any>> = M extends Manager<
|
139
|
-
infer EP,
|
140
|
-
infer PR
|
141
|
-
>
|
142
|
-
? Plugin<Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>>
|
143
|
-
: never;
|
144
|
-
export type InitOptions = {
|
145
|
-
container?: Container;
|
146
|
-
};
|
147
|
-
export type Manager<
|
148
|
-
EP extends Record<string, any>,
|
149
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
150
|
-
PR extends ProgressRecord | void = void,
|
151
|
-
> = {
|
152
|
-
createPlugin: (
|
153
|
-
initializer: Initializer<
|
154
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
155
|
-
>,
|
156
|
-
options?: PluginOptions,
|
157
|
-
) => Plugin<Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>>;
|
158
|
-
isPlugin: (
|
159
|
-
input: Record<string, unknown>,
|
160
|
-
) => input is Plugin<
|
161
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
162
|
-
>;
|
163
|
-
usePlugin: (
|
164
|
-
...input: Plugins<Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>>
|
165
|
-
) => Manager<EP, PR>;
|
166
|
-
init: (
|
167
|
-
options?: InitOptions,
|
168
|
-
) => Progresses2Runners<PR & ClearDraftProgress<EP>>;
|
169
|
-
run: <O>(cb: () => O, options?: InitOptions) => O;
|
170
|
-
registe: (newShape: Partial<EP>) => void;
|
171
|
-
clear: () => void;
|
172
|
-
clone: () => Manager<EP, PR>;
|
173
|
-
useRunner: () => Progresses2Runners<PR & ClearDraftProgress<EP>>;
|
174
|
-
};
|
175
|
-
|
176
|
-
export const DEFAULT_OPTIONS: Required<PluginOptions> = {
|
177
|
-
name: 'untitled',
|
178
|
-
pre: [],
|
179
|
-
post: [],
|
180
|
-
rivals: [],
|
181
|
-
required: [],
|
182
|
-
};
|
183
|
-
|
184
|
-
export const createManager = <
|
185
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
186
|
-
EP extends Record<string, any> = {},
|
187
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
188
|
-
PR extends ProgressRecord | void = void,
|
189
|
-
>(
|
190
|
-
processes?: PR,
|
191
|
-
): Manager<EP, PR> => {
|
192
|
-
let index = 0;
|
193
|
-
const createPlugin: Manager<EP, PR>['createPlugin'] = (
|
194
|
-
initializer,
|
195
|
-
options = {},
|
196
|
-
) => ({
|
197
|
-
...DEFAULT_OPTIONS,
|
198
|
-
name: `No.${index++} plugin`,
|
199
|
-
...options,
|
200
|
-
SYNC_PLUGIN_SYMBOL,
|
201
|
-
initializer,
|
202
|
-
});
|
203
|
-
|
204
|
-
const isPlugin: Manager<EP, PR>['isPlugin'] = (
|
205
|
-
input,
|
206
|
-
): input is Plugin<
|
207
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
208
|
-
> =>
|
209
|
-
hasOwnProperty(input, SYNC_PLUGIN_SYMBOL) &&
|
210
|
-
input[SYNC_PLUGIN_SYMBOL] === SYNC_PLUGIN_SYMBOL;
|
211
|
-
|
212
|
-
const registe: Manager<EP, PR>['registe'] = extraProcesses => {
|
213
|
-
// eslint-disable-next-line no-param-reassign
|
214
|
-
processes = {
|
215
|
-
...extraProcesses,
|
216
|
-
...processes,
|
217
|
-
} as any;
|
218
|
-
};
|
219
|
-
|
220
|
-
const clone = () => {
|
221
|
-
let plugins: IndexPlugins<
|
222
|
-
Partial<Progresses2Threads<PR & ClearDraftProgress<EP>>>
|
223
|
-
> = [];
|
224
|
-
|
225
|
-
const usePlugin: Manager<EP, PR>['usePlugin'] = (...input) => {
|
226
|
-
for (const plugin of input) {
|
227
|
-
if (isPlugin(plugin)) {
|
228
|
-
if (!includePlugin(plugins, plugin)) {
|
229
|
-
plugins.push({
|
230
|
-
...plugin,
|
231
|
-
index: plugins.length,
|
232
|
-
});
|
233
|
-
}
|
234
|
-
} else {
|
235
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
236
|
-
// @ts-expect-error
|
237
|
-
console.warn(`Unknown plugin: ${plugin.name}`);
|
238
|
-
}
|
239
|
-
}
|
240
|
-
|
241
|
-
return {
|
242
|
-
createPlugin,
|
243
|
-
isPlugin,
|
244
|
-
usePlugin,
|
245
|
-
init,
|
246
|
-
run,
|
247
|
-
clear,
|
248
|
-
registe,
|
249
|
-
useRunner,
|
250
|
-
clone,
|
251
|
-
};
|
252
|
-
};
|
253
|
-
|
254
|
-
const clear = () => {
|
255
|
-
plugins = [];
|
256
|
-
};
|
257
|
-
|
258
|
-
const currentContainer = createContainer();
|
259
|
-
|
260
|
-
const init: Manager<EP, PR>['init'] = options => {
|
261
|
-
const container = options?.container || currentContainer;
|
262
|
-
|
263
|
-
const sortedPlugins = sortPlugins(plugins);
|
264
|
-
|
265
|
-
checkPlugins(sortedPlugins);
|
266
|
-
|
267
|
-
const hooksList = sortedPlugins.map(plugin =>
|
268
|
-
runWithContainer(() => plugin.initializer(), container),
|
269
|
-
);
|
270
|
-
|
271
|
-
return generateRunner<EP, PR>(hooksList, container, processes);
|
272
|
-
};
|
273
|
-
|
274
|
-
const run: Manager<EP, PR>['run'] = (cb, options) => {
|
275
|
-
const container = options?.container || currentContainer;
|
276
|
-
|
277
|
-
return runWithContainer(cb, container);
|
278
|
-
};
|
279
|
-
|
280
|
-
return {
|
281
|
-
createPlugin,
|
282
|
-
isPlugin,
|
283
|
-
usePlugin,
|
284
|
-
init,
|
285
|
-
clear,
|
286
|
-
run,
|
287
|
-
registe,
|
288
|
-
useRunner,
|
289
|
-
clone,
|
290
|
-
};
|
291
|
-
};
|
292
|
-
|
293
|
-
return clone();
|
294
|
-
};
|
295
|
-
|
296
|
-
export const generateRunner = <
|
297
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
298
|
-
EP extends Record<string, any> = {},
|
299
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
300
|
-
PR extends ProgressRecord | void = void,
|
301
|
-
>(
|
302
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
303
|
-
hooksList: (void | Partial<
|
304
|
-
Progresses2Threads<PR & ClearDraftProgress<EP>>
|
305
|
-
>)[],
|
306
|
-
container: Container,
|
307
|
-
processes?: PR,
|
308
|
-
): Progresses2Runners<PR & ClearDraftProgress<EP>> => {
|
309
|
-
const runner = {};
|
310
|
-
const cloneShape = cloneProgressRecord(processes);
|
311
|
-
|
312
|
-
if (processes) {
|
313
|
-
for (const key in cloneShape) {
|
314
|
-
for (const hooks of hooksList) {
|
315
|
-
if (!hooks) {
|
316
|
-
continue;
|
317
|
-
}
|
318
|
-
if (hooks[key]) {
|
319
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
320
|
-
// @ts-expect-error
|
321
|
-
cloneShape[key].use(hooks[key]);
|
322
|
-
}
|
323
|
-
}
|
324
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
325
|
-
// @ts-expect-error
|
326
|
-
runner[key] = (input: any, options: any) =>
|
327
|
-
(cloneShape[key] as any).run(input, {
|
328
|
-
container,
|
329
|
-
...options,
|
330
|
-
});
|
331
|
-
}
|
332
|
-
}
|
333
|
-
|
334
|
-
container.write(RunnerContext, runner);
|
335
|
-
return runner as any;
|
336
|
-
};
|
337
|
-
|
338
|
-
export const cloneProgress = (progress: Progress): Progress => {
|
339
|
-
if (isWaterfall(progress)) {
|
340
|
-
return createWaterfall();
|
341
|
-
}
|
342
|
-
|
343
|
-
if (isAsyncWaterfall(progress)) {
|
344
|
-
return createAsyncWaterfall();
|
345
|
-
}
|
346
|
-
|
347
|
-
if (isWorkflow(progress)) {
|
348
|
-
return createWorkflow();
|
349
|
-
}
|
350
|
-
|
351
|
-
if (isAsyncWorkflow(progress)) {
|
352
|
-
return createAsyncWorkflow();
|
353
|
-
}
|
354
|
-
|
355
|
-
if (isParallelWorkflow(progress)) {
|
356
|
-
return createParallelWorkflow();
|
357
|
-
}
|
358
|
-
|
359
|
-
if (isPipeline(progress)) {
|
360
|
-
return createPipeline();
|
361
|
-
}
|
362
|
-
|
363
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
364
|
-
throw new Error(`Unknown progress: ${progress}`);
|
365
|
-
};
|
366
|
-
|
367
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
368
|
-
export const cloneProgressRecord = <PR extends ProgressRecord | void>(
|
369
|
-
record: PR,
|
370
|
-
): PR => {
|
371
|
-
if (!record) {
|
372
|
-
return record;
|
373
|
-
}
|
374
|
-
|
375
|
-
const result: PR = {} as any;
|
376
|
-
|
377
|
-
for (const key in record) {
|
378
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
379
|
-
// @ts-expect-error
|
380
|
-
result[key] = cloneProgress(record[key]);
|
381
|
-
}
|
382
|
-
|
383
|
-
return result;
|
384
|
-
};
|
385
|
-
|
386
|
-
const includePlugin = <O>(plugins: Plugins<O>, input: Plugin<O>): boolean => {
|
387
|
-
for (const plugin of plugins) {
|
388
|
-
if (plugin.name === input.name) {
|
389
|
-
return true;
|
390
|
-
}
|
391
|
-
}
|
392
|
-
|
393
|
-
return false;
|
394
|
-
};
|
395
|
-
|
396
|
-
const sortPlugins = <O>(input: IndexPlugins<O>): IndexPlugins<O> => {
|
397
|
-
let plugins = input.slice();
|
398
|
-
|
399
|
-
for (let i = 0; i < plugins.length; i++) {
|
400
|
-
const plugin = plugins[i];
|
401
|
-
|
402
|
-
for (const pre of plugin.pre) {
|
403
|
-
for (let j = i + 1; j < plugins.length; j++) {
|
404
|
-
if (plugins[j].name === pre) {
|
405
|
-
plugins = [
|
406
|
-
...plugins.slice(0, i),
|
407
|
-
plugins[j],
|
408
|
-
...plugins.slice(i, j),
|
409
|
-
...plugins.slice(j + 1, plugins.length),
|
410
|
-
];
|
411
|
-
}
|
412
|
-
}
|
413
|
-
}
|
414
|
-
|
415
|
-
for (const post of plugin.post) {
|
416
|
-
for (let j = 0; j < i; j++) {
|
417
|
-
if (plugins[j].name === post) {
|
418
|
-
plugins = [
|
419
|
-
...plugins.slice(0, j),
|
420
|
-
...plugins.slice(j + 1, i + 1),
|
421
|
-
plugins[j],
|
422
|
-
...plugins.slice(i + 1, plugins.length),
|
423
|
-
];
|
424
|
-
}
|
425
|
-
}
|
426
|
-
}
|
427
|
-
}
|
428
|
-
|
429
|
-
return plugins;
|
430
|
-
};
|
431
|
-
|
432
|
-
const checkPlugins = <O>(plugins: Plugins<O>) => {
|
433
|
-
for (const origin of plugins) {
|
434
|
-
for (const rival of origin.rivals) {
|
435
|
-
for (const plugin of plugins) {
|
436
|
-
if (rival === plugin.name) {
|
437
|
-
throw new Error(`${origin.name} has rival ${plugin.name}`);
|
438
|
-
}
|
439
|
-
}
|
440
|
-
}
|
441
|
-
|
442
|
-
for (const required of origin.required) {
|
443
|
-
if (!plugins.some(plugin => plugin.name === required)) {
|
444
|
-
throw new Error(
|
445
|
-
`The plugin: ${required} is required when plugin: ${origin.name} is exist.`,
|
446
|
-
);
|
447
|
-
}
|
448
|
-
}
|
449
|
-
}
|
450
|
-
};
|
451
|
-
|
452
|
-
export const hasOwnProperty = <
|
453
|
-
X extends Record<string, unknown>,
|
454
|
-
Y extends PropertyKey,
|
455
|
-
>(
|
456
|
-
obj: X,
|
457
|
-
prop: Y,
|
458
|
-
): obj is X & Record<Y, unknown> => obj.hasOwnProperty(prop);
|
package/src/waterfall/async.ts
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
createAsyncPipeline,
|
3
|
-
Middleware,
|
4
|
-
MaybeAsync,
|
5
|
-
Container,
|
6
|
-
useContainer,
|
7
|
-
} from 'farrow-pipeline';
|
8
|
-
|
9
|
-
const ASYNC_WATERFALL_SYMBOL = Symbol('ASYNC_WATERFALL_SYMBOL');
|
10
|
-
|
11
|
-
export type AsyncBrook<I = unknown> = (I: I) => MaybeAsync<I>;
|
12
|
-
export type AsyncBrookInput<I = unknown> =
|
13
|
-
| AsyncBrook<I>
|
14
|
-
| { middlware: AsyncBrook<I> };
|
15
|
-
export type AsyncBrooks<I = unknown> = AsyncBrook<I>[];
|
16
|
-
export type AsyncBrookInputs<I = unknown> = AsyncBrookInput<I>[];
|
17
|
-
|
18
|
-
export const getAsyncBrook = <I>(input: AsyncBrookInput<I>) => {
|
19
|
-
if (typeof input === 'function') {
|
20
|
-
return input;
|
21
|
-
} else if (input && typeof input.middlware === 'function') {
|
22
|
-
return input.middlware;
|
23
|
-
}
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
25
|
-
throw new Error(`${input} is not a AsyncBrook or { brook: AsyncBrook }`);
|
26
|
-
};
|
27
|
-
|
28
|
-
export type RunAsyncWaterfallOptions<I = unknown> = {
|
29
|
-
container?: Container;
|
30
|
-
onLast?: AsyncBrook<I>;
|
31
|
-
};
|
32
|
-
|
33
|
-
export type AsyncWaterfall<I> = {
|
34
|
-
run: (input: I, options?: RunAsyncWaterfallOptions<I>) => MaybeAsync<I>;
|
35
|
-
use: (...I: AsyncBrookInputs<I>) => AsyncWaterfall<I>;
|
36
|
-
middlware: AsyncBrook<I>;
|
37
|
-
[ASYNC_WATERFALL_SYMBOL]: true;
|
38
|
-
};
|
39
|
-
|
40
|
-
export type AsyncWaterfall2AsyncBrook<P extends AsyncWaterfall<any>> =
|
41
|
-
P extends AsyncWaterfall<infer I> ? AsyncBrook<I> : never;
|
42
|
-
|
43
|
-
export type AsyncWaterfallRecord = Record<string, AsyncWaterfall<any>>;
|
44
|
-
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
46
|
-
export type AsyncWaterfalls2Brooks<PS extends AsyncWaterfallRecord | void> = {
|
47
|
-
[K in keyof PS]: PS[K] extends AsyncWaterfall<any>
|
48
|
-
? AsyncWaterfall2AsyncBrook<PS[K]>
|
49
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
50
|
-
PS[K] extends void
|
51
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
52
|
-
void
|
53
|
-
: never;
|
54
|
-
};
|
55
|
-
|
56
|
-
export type RunnerFromAsyncWaterfall<M extends AsyncWaterfall<any>> =
|
57
|
-
M extends AsyncWaterfall<infer VS> ? AsyncWaterfall<VS>['run'] : never;
|
58
|
-
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
60
|
-
export type AsyncWaterfalls2Runners<PS extends AsyncWaterfallRecord | void> = {
|
61
|
-
[K in keyof PS]: PS[K] extends AsyncWaterfall<any>
|
62
|
-
? RunnerFromAsyncWaterfall<PS[K]>
|
63
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
64
|
-
PS[K] extends void
|
65
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
66
|
-
void
|
67
|
-
: never;
|
68
|
-
};
|
69
|
-
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
71
|
-
export const createAsyncWaterfall = <I = void>(): AsyncWaterfall<I> => {
|
72
|
-
const pipeline = createAsyncPipeline<I, I>();
|
73
|
-
|
74
|
-
const use: AsyncWaterfall<I>['use'] = (...input) => {
|
75
|
-
pipeline.use(
|
76
|
-
...input.map(getAsyncBrook).map(mapAsyncBrookToAsyncMiddleware),
|
77
|
-
);
|
78
|
-
return waterfall;
|
79
|
-
};
|
80
|
-
|
81
|
-
const run: AsyncWaterfall<I>['run'] = (input, options) =>
|
82
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
83
|
-
pipeline.run(input, { ...options, onLast: input => input });
|
84
|
-
|
85
|
-
const middlware: AsyncWaterfall<I>['middlware'] = input => {
|
86
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
87
|
-
const container = useContainer();
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
89
|
-
return pipeline.run(input, { container, onLast: input => input });
|
90
|
-
};
|
91
|
-
|
92
|
-
const waterfall: AsyncWaterfall<I> = {
|
93
|
-
...pipeline,
|
94
|
-
use,
|
95
|
-
run,
|
96
|
-
middlware,
|
97
|
-
[ASYNC_WATERFALL_SYMBOL]: true as const,
|
98
|
-
};
|
99
|
-
|
100
|
-
return waterfall;
|
101
|
-
};
|
102
|
-
|
103
|
-
export const isAsyncWaterfall = (input: any): input is AsyncWaterfall<any> =>
|
104
|
-
Boolean(input?.[ASYNC_WATERFALL_SYMBOL]);
|
105
|
-
|
106
|
-
const mapAsyncBrookToAsyncMiddleware =
|
107
|
-
<I>(brook: AsyncBrook<I>): Middleware<I, MaybeAsync<I>> =>
|
108
|
-
async (input, next) =>
|
109
|
-
next(await brook(input));
|
package/src/waterfall/index.ts
DELETED
package/src/waterfall/sync.ts
DELETED
@@ -1,110 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Container,
|
3
|
-
useContainer,
|
4
|
-
createPipeline,
|
5
|
-
Middleware,
|
6
|
-
} from 'farrow-pipeline';
|
7
|
-
|
8
|
-
const WATERFALL_SYMBOL = Symbol('WATERFALL_SYMBOL');
|
9
|
-
|
10
|
-
export type Brook<I = unknown> = (I: I) => I;
|
11
|
-
export type BrookInput<I = unknown> = Brook<I> | { middleware: Brook<I> };
|
12
|
-
export type Brooks<I = unknown> = Brook<I>[];
|
13
|
-
export type BrookInputs<I = unknown> = BrookInput<I>[];
|
14
|
-
|
15
|
-
export const getBrook = <I>(input: BrookInput<I>) => {
|
16
|
-
if (typeof input === 'function') {
|
17
|
-
return input;
|
18
|
-
} else if (input && typeof input.middleware === 'function') {
|
19
|
-
return input.middleware;
|
20
|
-
}
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
22
|
-
throw new Error(`${input} is not a Brook or { brook: Brook }`);
|
23
|
-
};
|
24
|
-
|
25
|
-
export type RunWaterfallOptions<I = unknown> = {
|
26
|
-
container?: Container;
|
27
|
-
onLast?: Brook<I>;
|
28
|
-
};
|
29
|
-
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
31
|
-
export type Waterfall<I = void> = {
|
32
|
-
run: (input: I, options?: RunWaterfallOptions<I>) => I;
|
33
|
-
use: (...I: BrookInputs<I>) => Waterfall<I>;
|
34
|
-
middleware: Brook<I>;
|
35
|
-
[WATERFALL_SYMBOL]: true;
|
36
|
-
};
|
37
|
-
|
38
|
-
export type Waterfall2Brook<P extends Waterfall<any>> = P extends Waterfall<
|
39
|
-
infer I
|
40
|
-
>
|
41
|
-
? Brook<I>
|
42
|
-
: never;
|
43
|
-
|
44
|
-
export type WaterfallRecord = Record<string, Waterfall<any>>;
|
45
|
-
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
47
|
-
export type Waterfalls2Brooks<PS extends WaterfallRecord | void> = {
|
48
|
-
[K in keyof PS]: PS[K] extends Waterfall<any>
|
49
|
-
? Waterfall2Brook<PS[K]>
|
50
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
51
|
-
PS[K] extends void
|
52
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
53
|
-
void
|
54
|
-
: never;
|
55
|
-
};
|
56
|
-
|
57
|
-
export type RunnerFromWaterfall<M extends Waterfall<any>> = M extends Waterfall<
|
58
|
-
infer VS
|
59
|
-
>
|
60
|
-
? Waterfall<VS>['run']
|
61
|
-
: never;
|
62
|
-
|
63
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
64
|
-
export type Waterfalls2Runners<PS extends WaterfallRecord | void> = {
|
65
|
-
[K in keyof PS]: PS[K] extends Waterfall<any>
|
66
|
-
? RunnerFromWaterfall<PS[K]>
|
67
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
68
|
-
PS[K] extends void
|
69
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
70
|
-
void
|
71
|
-
: never;
|
72
|
-
};
|
73
|
-
|
74
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
75
|
-
export const createWaterfall = <I = void>(): Waterfall<I> => {
|
76
|
-
const pipeline = createPipeline<I, I>();
|
77
|
-
|
78
|
-
const use: Waterfall<I>['use'] = (...brooks) => {
|
79
|
-
pipeline.use(...brooks.map(getBrook).map(mapBrookToMiddleware));
|
80
|
-
return waterfall;
|
81
|
-
};
|
82
|
-
|
83
|
-
const run: Waterfall<I>['run'] = (input, options) =>
|
84
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
85
|
-
pipeline.run(input, { ...options, onLast: input => input });
|
86
|
-
|
87
|
-
const middleware: Waterfall<I>['middleware'] = input => {
|
88
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
89
|
-
const container = useContainer();
|
90
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
91
|
-
return pipeline.run(input, { container, onLast: input => input });
|
92
|
-
};
|
93
|
-
|
94
|
-
const waterfall: Waterfall<I> = {
|
95
|
-
...pipeline,
|
96
|
-
use,
|
97
|
-
run,
|
98
|
-
middleware,
|
99
|
-
[WATERFALL_SYMBOL]: true,
|
100
|
-
};
|
101
|
-
return waterfall;
|
102
|
-
};
|
103
|
-
|
104
|
-
export const isWaterfall = (input: any): input is Waterfall<any> =>
|
105
|
-
Boolean(input?.[WATERFALL_SYMBOL]);
|
106
|
-
|
107
|
-
const mapBrookToMiddleware =
|
108
|
-
<I>(brook: Brook<I>): Middleware<I, I> =>
|
109
|
-
(input, next) =>
|
110
|
-
next(brook(input));
|
package/src/workflow/async.ts
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
import { MaybeAsync, createAsyncPipeline, Middleware } from 'farrow-pipeline';
|
2
|
-
import type { RunWorkflowOptions } from './sync';
|
3
|
-
|
4
|
-
const ASYNC_WORKFLOW_SYMBOL = Symbol('ASYNC_WORKFLOW_SYMBOL');
|
5
|
-
|
6
|
-
export type AsyncWorker<I, O> = (I: I) => MaybeAsync<O>;
|
7
|
-
export type AsyncWorkers<I, O> = AsyncWorker<I, O>[];
|
8
|
-
|
9
|
-
export type AsyncWorkflow<I, O> = {
|
10
|
-
run: (input: I, options?: RunWorkflowOptions) => MaybeAsync<O[]>;
|
11
|
-
use: (...I: AsyncWorkers<I, O>) => AsyncWorkflow<I, O>;
|
12
|
-
[ASYNC_WORKFLOW_SYMBOL]: true;
|
13
|
-
};
|
14
|
-
|
15
|
-
export type AsyncWorkflow2AsyncWorker<W extends AsyncWorkflow<any, any>> =
|
16
|
-
W extends AsyncWorkflow<infer I, infer O> ? AsyncWorker<I, O> : never;
|
17
|
-
|
18
|
-
export type AsyncWorkflowRecord = Record<string, AsyncWorkflow<any, any>>;
|
19
|
-
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
21
|
-
export type AsyncWorkflows2AsyncWorkers<PS extends AsyncWorkflowRecord | void> =
|
22
|
-
{
|
23
|
-
[K in keyof PS]: PS[K] extends AsyncWorkflow<any, any>
|
24
|
-
? AsyncWorkflow2AsyncWorker<PS[K]>
|
25
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
26
|
-
PS[K] extends void
|
27
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
28
|
-
void
|
29
|
-
: never;
|
30
|
-
};
|
31
|
-
|
32
|
-
export type RunnerFromAsyncWorkflow<W extends AsyncWorkflow<any, any>> =
|
33
|
-
W extends AsyncWorkflow<infer I, infer O>
|
34
|
-
? AsyncWorkflow<I, O>['run']
|
35
|
-
: never;
|
36
|
-
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
38
|
-
export type AsyncWorkflows2Runners<PS extends AsyncWorkflowRecord | void> = {
|
39
|
-
[K in keyof PS]: PS[K] extends AsyncWorkflow<any, any>
|
40
|
-
? RunnerFromAsyncWorkflow<PS[K]>
|
41
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
42
|
-
PS[K] extends void
|
43
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
44
|
-
void
|
45
|
-
: never;
|
46
|
-
};
|
47
|
-
|
48
|
-
export const isAsyncWorkflow = (input: any): input is AsyncWorkflow<any, any> =>
|
49
|
-
Boolean(input?.[ASYNC_WORKFLOW_SYMBOL]);
|
50
|
-
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
52
|
-
export const createAsyncWorkflow = <I = void, O = unknown>(): AsyncWorkflow<
|
53
|
-
I,
|
54
|
-
O
|
55
|
-
> => {
|
56
|
-
const pipeline = createAsyncPipeline<I, O[]>();
|
57
|
-
|
58
|
-
const use: AsyncWorkflow<I, O>['use'] = (...input) => {
|
59
|
-
pipeline.use(...input.map(mapAsyncWorkerToAsyncMiddleware));
|
60
|
-
return workflow;
|
61
|
-
};
|
62
|
-
|
63
|
-
const run: AsyncWorkflow<I, O>['run'] = async (input, options) => {
|
64
|
-
const result = pipeline.run(input, { ...options, onLast: () => [] });
|
65
|
-
if (isPromise(result)) {
|
66
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow,promise/prefer-await-to-then
|
67
|
-
return result.then(result => result.filter(Boolean));
|
68
|
-
} else {
|
69
|
-
return result.filter(Boolean);
|
70
|
-
}
|
71
|
-
};
|
72
|
-
|
73
|
-
const workflow: AsyncWorkflow<I, O> = {
|
74
|
-
...pipeline,
|
75
|
-
use,
|
76
|
-
run,
|
77
|
-
[ASYNC_WORKFLOW_SYMBOL]: true as const,
|
78
|
-
};
|
79
|
-
|
80
|
-
return workflow;
|
81
|
-
};
|
82
|
-
|
83
|
-
const mapAsyncWorkerToAsyncMiddleware =
|
84
|
-
<I, O>(worker: AsyncWorker<I, O>): Middleware<I, MaybeAsync<O[]>> =>
|
85
|
-
async (input, next) =>
|
86
|
-
[await worker(input), ...(await next(input))];
|
87
|
-
|
88
|
-
function isPromise(obj: any): obj is Promise<any> {
|
89
|
-
/* eslint-disable promise/prefer-await-to-then */
|
90
|
-
return (
|
91
|
-
Boolean(obj) &&
|
92
|
-
(typeof obj === 'object' || typeof obj === 'function') &&
|
93
|
-
typeof obj.then === 'function'
|
94
|
-
);
|
95
|
-
/* eslint-enable promise/prefer-await-to-then */
|
96
|
-
}
|
package/src/workflow/index.ts
DELETED
package/src/workflow/parallel.ts
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
import { MaybeAsync, createPipeline, Middleware } from 'farrow-pipeline';
|
2
|
-
import type { AsyncWorker, AsyncWorkers } from './async';
|
3
|
-
import type { RunWorkflowOptions } from './sync';
|
4
|
-
|
5
|
-
const PARALLEL_WORKFLOW_SYMBOL = Symbol('PARALLEL_WORKFLOW_SYMBOL');
|
6
|
-
|
7
|
-
export type ParallelWorkflow<I, O = any> = {
|
8
|
-
run: (input: I, options?: RunWorkflowOptions) => Promise<O[]>;
|
9
|
-
use: (...I: AsyncWorkers<I, O>) => ParallelWorkflow<I, O>;
|
10
|
-
[PARALLEL_WORKFLOW_SYMBOL]: true;
|
11
|
-
};
|
12
|
-
|
13
|
-
export type ParallelWorkflow2Worker<W extends ParallelWorkflow<any>> =
|
14
|
-
W extends ParallelWorkflow<infer CS, infer O> ? AsyncWorker<CS, O> : never;
|
15
|
-
|
16
|
-
export type ParallelWorkflowRecord = Record<string, ParallelWorkflow<any>>;
|
17
|
-
|
18
|
-
export type ParallelWorkflows2Workers<
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
20
|
-
PS extends ParallelWorkflowRecord | void,
|
21
|
-
> = {
|
22
|
-
[K in keyof PS]: PS[K] extends ParallelWorkflow<any>
|
23
|
-
? ParallelWorkflow2Worker<PS[K]>
|
24
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
25
|
-
PS[K] extends void
|
26
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
27
|
-
void
|
28
|
-
: never;
|
29
|
-
};
|
30
|
-
|
31
|
-
export type ParallelWorkflows2AsyncWorkers<
|
32
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
33
|
-
PS extends ParallelWorkflowRecord | void,
|
34
|
-
> = {
|
35
|
-
[K in keyof PS]: PS[K] extends ParallelWorkflow<any>
|
36
|
-
? ParallelWorkflow2Worker<PS[K]>
|
37
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
38
|
-
PS[K] extends void
|
39
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
40
|
-
void
|
41
|
-
: never;
|
42
|
-
};
|
43
|
-
|
44
|
-
export type RunnerFromParallelWorkflow<W extends ParallelWorkflow<any>> =
|
45
|
-
W extends ParallelWorkflow<infer CS, infer O>
|
46
|
-
? ParallelWorkflow<CS, O>['run']
|
47
|
-
: never;
|
48
|
-
|
49
|
-
export type ParallelWorkflows2Runners<
|
50
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
51
|
-
PS extends ParallelWorkflowRecord | void,
|
52
|
-
> = {
|
53
|
-
[K in keyof PS]: PS[K] extends ParallelWorkflow<any>
|
54
|
-
? RunnerFromParallelWorkflow<PS[K]>
|
55
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
56
|
-
PS[K] extends void
|
57
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
58
|
-
void
|
59
|
-
: never;
|
60
|
-
};
|
61
|
-
|
62
|
-
export const isParallelWorkflow = (
|
63
|
-
input: any,
|
64
|
-
): input is ParallelWorkflow<any> => Boolean(input?.[PARALLEL_WORKFLOW_SYMBOL]);
|
65
|
-
|
66
|
-
export const createParallelWorkflow = <
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
68
|
-
I = void,
|
69
|
-
O = unknown,
|
70
|
-
>(): ParallelWorkflow<I, O> => {
|
71
|
-
const pipeline = createPipeline<I, MaybeAsync<O>[]>();
|
72
|
-
|
73
|
-
const use: ParallelWorkflow<I, O>['use'] = (...input) => {
|
74
|
-
pipeline.use(...input.map(mapParallelWorkerToAsyncMiddleware));
|
75
|
-
return workflow;
|
76
|
-
};
|
77
|
-
|
78
|
-
const run: ParallelWorkflow<I, O>['run'] = async (input, options) =>
|
79
|
-
// eslint-disable-next-line promise/prefer-await-to-then
|
80
|
-
Promise.all(pipeline.run(input, { ...options, onLast: () => [] })).then(
|
81
|
-
result => result.filter(Boolean),
|
82
|
-
);
|
83
|
-
|
84
|
-
const workflow: ParallelWorkflow<I, O> = {
|
85
|
-
...pipeline,
|
86
|
-
run,
|
87
|
-
use,
|
88
|
-
[PARALLEL_WORKFLOW_SYMBOL]: true as const,
|
89
|
-
};
|
90
|
-
|
91
|
-
return workflow;
|
92
|
-
};
|
93
|
-
|
94
|
-
const mapParallelWorkerToAsyncMiddleware =
|
95
|
-
<I, O>(worker: AsyncWorker<I, O>): Middleware<I, MaybeAsync<O>[]> =>
|
96
|
-
(input, next) =>
|
97
|
-
[worker(input), ...next(input)];
|
package/src/workflow/sync.ts
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
import { Container, createPipeline, Middleware } from 'farrow-pipeline';
|
2
|
-
|
3
|
-
const WORKFLOW_SYMBOL = Symbol('WORKFLOW_SYMBOL');
|
4
|
-
|
5
|
-
export type Worker<I, O> = (I: I) => O;
|
6
|
-
export type Workers<I, O> = Worker<I, O>[];
|
7
|
-
|
8
|
-
export type RunWorkflowOptions = {
|
9
|
-
container?: Container;
|
10
|
-
};
|
11
|
-
|
12
|
-
export type Workflow<I, O> = {
|
13
|
-
run: (input: I, options?: RunWorkflowOptions) => void;
|
14
|
-
use: (...I: Workers<I, O>) => Workflow<I, O>;
|
15
|
-
[WORKFLOW_SYMBOL]: true;
|
16
|
-
};
|
17
|
-
|
18
|
-
export type Workflow2Worker<W extends Workflow<any, any>> = W extends Workflow<
|
19
|
-
infer I,
|
20
|
-
infer O
|
21
|
-
>
|
22
|
-
? Worker<I, O>
|
23
|
-
: never;
|
24
|
-
|
25
|
-
export type WorkflowRecord = Record<string, Workflow<any, any>>;
|
26
|
-
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
28
|
-
export type Workflows2Workers<PS extends WorkflowRecord | void> = {
|
29
|
-
[K in keyof PS]: PS[K] extends Workflow<any, any>
|
30
|
-
? Workflow2Worker<PS[K]>
|
31
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
32
|
-
PS[K] extends void
|
33
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
34
|
-
void
|
35
|
-
: never;
|
36
|
-
};
|
37
|
-
|
38
|
-
export type RunnerFromWorkflow<W extends Workflow<any, any>> =
|
39
|
-
W extends Workflow<infer I, infer O> ? Workflow<I, O>['run'] : never;
|
40
|
-
|
41
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
42
|
-
export type Workflows2Runners<PS extends WorkflowRecord | void> = {
|
43
|
-
[K in keyof PS]: PS[K] extends Workflow<any, any>
|
44
|
-
? RunnerFromWorkflow<PS[K]>
|
45
|
-
: // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
46
|
-
PS[K] extends void
|
47
|
-
? // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
48
|
-
void
|
49
|
-
: never;
|
50
|
-
};
|
51
|
-
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
53
|
-
export const createWorkflow = <I = void, O = unknown>(): Workflow<I, O> => {
|
54
|
-
const pipeline = createPipeline<I, O[]>();
|
55
|
-
|
56
|
-
const use: Workflow<I, O>['use'] = (...input) => {
|
57
|
-
pipeline.use(...input.map(mapWorkerToMiddleware));
|
58
|
-
return workflow;
|
59
|
-
};
|
60
|
-
|
61
|
-
const run: Workflow<I, O>['run'] = async (input, options) => {
|
62
|
-
const result = pipeline.run(input, { ...options, onLast: () => [] });
|
63
|
-
return result.filter(Boolean);
|
64
|
-
};
|
65
|
-
|
66
|
-
const workflow: Workflow<I, O> = {
|
67
|
-
...pipeline,
|
68
|
-
use,
|
69
|
-
run,
|
70
|
-
[WORKFLOW_SYMBOL]: true as const,
|
71
|
-
};
|
72
|
-
|
73
|
-
return workflow;
|
74
|
-
};
|
75
|
-
|
76
|
-
export const isWorkflow = (input: any): input is Workflow<unknown, unknown> =>
|
77
|
-
Boolean(input?.[WORKFLOW_SYMBOL]);
|
78
|
-
|
79
|
-
const mapWorkerToMiddleware =
|
80
|
-
<I, O>(worker: Worker<I, O>): Middleware<I, O[]> =>
|
81
|
-
(input, next) =>
|
82
|
-
[worker(input), ...next(input)];
|