@modern-js/plugin 1.0.1 → 1.2.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/CHANGELOG.md +20 -2
- package/dist/js/modern/index.js +2 -3
- package/dist/js/modern/manager/async.js +3 -3
- package/dist/js/modern/manager/runner.js +1 -1
- package/dist/js/modern/manager/sync.js +3 -8
- package/dist/js/modern/waterfall/async.js +28 -34
- package/dist/js/modern/waterfall/sync.js +29 -36
- package/dist/js/modern/workflow/async.js +31 -30
- package/dist/js/modern/workflow/parallel.js +20 -29
- package/dist/js/modern/workflow/sync.js +20 -27
- package/dist/js/node/index.js +12 -25
- package/dist/js/node/manager/async.js +6 -6
- package/dist/js/node/manager/runner.js +2 -2
- package/dist/js/node/manager/sync.js +8 -14
- package/dist/js/node/waterfall/async.js +27 -34
- package/dist/js/node/waterfall/sync.js +29 -36
- package/dist/js/node/workflow/async.js +30 -30
- package/dist/js/node/workflow/parallel.js +19 -29
- package/dist/js/node/workflow/sync.js +19 -27
- package/dist/js/treeshaking/index.js +2 -3
- package/dist/js/treeshaking/manager/async.js +3 -3
- package/dist/js/treeshaking/manager/runner.js +1 -1
- package/dist/js/treeshaking/manager/sync.js +3 -8
- package/dist/js/treeshaking/waterfall/async.js +63 -108
- package/dist/js/treeshaking/waterfall/sync.js +36 -39
- package/dist/js/treeshaking/workflow/async.js +89 -88
- package/dist/js/treeshaking/workflow/parallel.js +42 -66
- package/dist/js/treeshaking/workflow/sync.js +50 -30
- package/dist/types/index.d.ts +2 -3
- package/dist/types/manager/runner.d.ts +1 -1
- package/dist/types/manager/sync.d.ts +2 -3
- package/dist/types/waterfall/async.d.ts +9 -5
- package/dist/types/waterfall/sync.d.ts +4 -4
- package/dist/types/workflow/async.d.ts +3 -2
- package/dist/types/workflow/parallel.d.ts +1 -1
- package/dist/types/workflow/sync.d.ts +1 -1
- package/jest.config.js +8 -0
- package/modern.config.js +1 -9
- package/node.d.ts +1 -1
- package/node.js +1 -1
- package/package.json +13 -7
- package/src/index.ts +2 -2
- package/src/manager/async.ts +1 -1
- package/src/manager/runner.ts +1 -1
- package/src/manager/sync.ts +12 -16
- package/src/waterfall/async.ts +34 -49
- package/src/waterfall/sync.ts +26 -45
- package/src/workflow/async.ts +29 -33
- package/src/workflow/parallel.ts +17 -35
- package/src/workflow/sync.ts +13 -35
- package/tests/async.test.ts +14 -10
- package/tests/fixtures/async/base/fooManager.ts +1 -1
- package/tests/fixtures/async/core/index.ts +1 -1
- package/tests/fixtures/async/dynamic/foo.ts +1 -1
- package/tests/fixtures/sync/base/fooManager.ts +1 -1
- package/tests/fixtures/sync/core/index.ts +1 -1
- package/tests/fixtures/sync/dynamic/foo.ts +1 -1
- package/tests/pipeline.test.ts +6 -16
- package/tests/sync.test.ts +13 -9
- package/tests/tsconfig.json +1 -3
- package/tests/waterfall.test.ts +3 -3
- package/tests/workflow.test.ts +2 -2
- package/tsconfig.json +1 -3
- package/dist/js/modern/asyncHooksImpl.js +0 -63
- package/dist/js/modern/asyncHooksInterface.js +0 -16
- package/dist/js/modern/context.js +0 -130
- package/dist/js/modern/counter.js +0 -40
- package/dist/js/modern/hook.js +0 -47
- package/dist/js/modern/pipeline/async.js +0 -97
- package/dist/js/modern/pipeline/index.js +0 -2
- package/dist/js/modern/pipeline/sync.js +0 -97
- package/dist/js/node/asyncHooksImpl.js +0 -82
- package/dist/js/node/asyncHooksInterface.js +0 -30
- package/dist/js/node/context.js +0 -164
- package/dist/js/node/counter.js +0 -52
- package/dist/js/node/hook.js +0 -57
- package/dist/js/node/pipeline/async.js +0 -110
- package/dist/js/node/pipeline/index.js +0 -31
- package/dist/js/node/pipeline/sync.js +0 -110
- package/dist/js/treeshaking/asyncHooksImpl.js +0 -65
- package/dist/js/treeshaking/asyncHooksInterface.js +0 -16
- package/dist/js/treeshaking/context.js +0 -137
- package/dist/js/treeshaking/counter.js +0 -74
- package/dist/js/treeshaking/hook.js +0 -51
- package/dist/js/treeshaking/pipeline/async.js +0 -165
- package/dist/js/treeshaking/pipeline/index.js +0 -2
- package/dist/js/treeshaking/pipeline/sync.js +0 -118
- package/dist/types/asyncHooksImpl.d.ts +0 -10
- package/dist/types/asyncHooksInterface.d.ts +0 -21
- package/dist/types/context.d.ts +0 -47
- package/dist/types/counter.d.ts +0 -22
- package/dist/types/hook.d.ts +0 -13
- package/dist/types/pipeline/async.d.ts +0 -35
- package/dist/types/pipeline/index.d.ts +0 -2
- package/dist/types/pipeline/sync.d.ts +0 -37
- package/src/asyncHooksImpl.ts +0 -64
- package/src/asyncHooksInterface.ts +0 -34
- package/src/context.ts +0 -184
- package/src/counter.ts +0 -78
- package/src/hook.ts +0 -46
- package/src/pipeline/async.ts +0 -155
- package/src/pipeline/index.ts +0 -2
- package/src/pipeline/sync.ts +0 -152
- package/tests/context.test.ts +0 -114
- package/tests/counter.test.ts +0 -31
- package/tests/hook.test.ts +0 -113
package/src/waterfall/async.ts
CHANGED
@@ -1,39 +1,39 @@
|
|
1
|
-
import { createAsyncCounter } from '../counter';
|
2
1
|
import {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
createAsyncPipeline,
|
3
|
+
Middleware,
|
4
|
+
MaybeAsync,
|
5
|
+
Container,
|
7
6
|
useContainer,
|
8
|
-
} from '
|
9
|
-
import type { RunWaterfallOptions } from './sync';
|
7
|
+
} from 'farrow-pipeline';
|
10
8
|
|
11
9
|
const ASYNC_WATERFALL_SYMBOL = Symbol('ASYNC_WATERFALL_SYMBOL');
|
12
10
|
|
13
|
-
export type AsyncBrook<I = unknown> = (
|
14
|
-
I: I,
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
16
|
-
) => I | Promise<I> | void | Promise<void>;
|
11
|
+
export type AsyncBrook<I = unknown> = (I: I) => MaybeAsync<I>;
|
17
12
|
export type AsyncBrookInput<I = unknown> =
|
18
13
|
| AsyncBrook<I>
|
19
|
-
| {
|
14
|
+
| { middlware: AsyncBrook<I> };
|
20
15
|
export type AsyncBrooks<I = unknown> = AsyncBrook<I>[];
|
21
16
|
export type AsyncBrookInputs<I = unknown> = AsyncBrookInput<I>[];
|
22
17
|
|
23
18
|
export const getAsyncBrook = <I>(input: AsyncBrookInput<I>) => {
|
24
19
|
if (typeof input === 'function') {
|
25
20
|
return input;
|
26
|
-
} else if (input && typeof input.
|
27
|
-
return input.
|
21
|
+
} else if (input && typeof input.middlware === 'function') {
|
22
|
+
return input.middlware;
|
28
23
|
}
|
29
24
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
30
25
|
throw new Error(`${input} is not a AsyncBrook or { brook: AsyncBrook }`);
|
31
26
|
};
|
32
27
|
|
28
|
+
export type RunAsyncWaterfallOptions<I = unknown> = {
|
29
|
+
container?: Container;
|
30
|
+
onLast?: AsyncBrook<I>;
|
31
|
+
};
|
32
|
+
|
33
33
|
export type AsyncWaterfall<I> = {
|
34
|
-
run: (input: I, options?:
|
34
|
+
run: (input: I, options?: RunAsyncWaterfallOptions<I>) => MaybeAsync<I>;
|
35
35
|
use: (...I: AsyncBrookInputs<I>) => AsyncWaterfall<I>;
|
36
|
-
|
36
|
+
middlware: AsyncBrook<I>;
|
37
37
|
[ASYNC_WATERFALL_SYMBOL]: true;
|
38
38
|
};
|
39
39
|
|
@@ -69,51 +69,31 @@ export type AsyncWaterfalls2Runners<PS extends AsyncWaterfallRecord | void> = {
|
|
69
69
|
|
70
70
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
71
71
|
export const createAsyncWaterfall = <I = void>(): AsyncWaterfall<I> => {
|
72
|
-
const
|
73
|
-
|
74
|
-
const createCurrentRunner = (hooks: Hooks) =>
|
75
|
-
createAsyncCounter<I, I>(async (index, input, next) => {
|
76
|
-
if (index >= middlewares.length) {
|
77
|
-
return input;
|
78
|
-
}
|
79
|
-
|
80
|
-
return runHooks(
|
81
|
-
async () => next((await middlewares[index](input)) || input),
|
82
|
-
hooks,
|
83
|
-
);
|
84
|
-
});
|
85
|
-
|
86
|
-
const currentContainer = createContainer();
|
87
|
-
const currentHooks = fromContainer(currentContainer);
|
88
|
-
const currentRunner = createCurrentRunner(currentHooks);
|
72
|
+
const pipeline = createAsyncPipeline<I, I>();
|
89
73
|
|
90
74
|
const use: AsyncWaterfall<I>['use'] = (...input) => {
|
91
|
-
|
75
|
+
pipeline.use(
|
76
|
+
...input.map(getAsyncBrook).map(mapAsyncBrookToAsyncMiddleware),
|
77
|
+
);
|
92
78
|
return waterfall;
|
93
79
|
};
|
94
80
|
|
95
|
-
const run: AsyncWaterfall<I>['run'] =
|
96
|
-
|
97
|
-
|
98
|
-
container === currentContainer ? currentHooks : fromContainer(container);
|
99
|
-
const runner =
|
100
|
-
container === currentContainer
|
101
|
-
? currentRunner
|
102
|
-
: createCurrentRunner(hooks);
|
103
|
-
|
104
|
-
return runner.start(input);
|
105
|
-
};
|
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 });
|
106
84
|
|
107
|
-
const
|
85
|
+
const middlware: AsyncWaterfall<I>['middlware'] = input => {
|
108
86
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
109
87
|
const container = useContainer();
|
110
|
-
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
89
|
+
return pipeline.run(input, { container, onLast: input => input });
|
111
90
|
};
|
112
91
|
|
113
|
-
const waterfall = {
|
92
|
+
const waterfall: AsyncWaterfall<I> = {
|
93
|
+
...pipeline,
|
114
94
|
use,
|
115
95
|
run,
|
116
|
-
|
96
|
+
middlware,
|
117
97
|
[ASYNC_WATERFALL_SYMBOL]: true as const,
|
118
98
|
};
|
119
99
|
|
@@ -122,3 +102,8 @@ export const createAsyncWaterfall = <I = void>(): AsyncWaterfall<I> => {
|
|
122
102
|
|
123
103
|
export const isAsyncWaterfall = (input: any): input is AsyncWaterfall<any> =>
|
124
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/sync.ts
CHANGED
@@ -1,26 +1,22 @@
|
|
1
|
-
import { createCounter } from '../counter';
|
2
1
|
import {
|
3
|
-
Hooks,
|
4
|
-
runHooks,
|
5
|
-
fromContainer,
|
6
2
|
Container,
|
7
|
-
createContainer,
|
8
3
|
useContainer,
|
9
|
-
|
4
|
+
createPipeline,
|
5
|
+
Middleware,
|
6
|
+
} from 'farrow-pipeline';
|
10
7
|
|
11
8
|
const WATERFALL_SYMBOL = Symbol('WATERFALL_SYMBOL');
|
12
9
|
|
13
|
-
|
14
|
-
export type
|
15
|
-
export type BrookInput<I = unknown> = Brook<I> | { brook: Brook<I> };
|
10
|
+
export type Brook<I = unknown> = (I: I) => I;
|
11
|
+
export type BrookInput<I = unknown> = Brook<I> | { middleware: Brook<I> };
|
16
12
|
export type Brooks<I = unknown> = Brook<I>[];
|
17
13
|
export type BrookInputs<I = unknown> = BrookInput<I>[];
|
18
14
|
|
19
15
|
export const getBrook = <I>(input: BrookInput<I>) => {
|
20
16
|
if (typeof input === 'function') {
|
21
17
|
return input;
|
22
|
-
} else if (input && typeof input.
|
23
|
-
return input.
|
18
|
+
} else if (input && typeof input.middleware === 'function') {
|
19
|
+
return input.middleware;
|
24
20
|
}
|
25
21
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
26
22
|
throw new Error(`${input} is not a Brook or { brook: Brook }`);
|
@@ -35,7 +31,7 @@ export type RunWaterfallOptions<I = unknown> = {
|
|
35
31
|
export type Waterfall<I = void> = {
|
36
32
|
run: (input: I, options?: RunWaterfallOptions<I>) => I;
|
37
33
|
use: (...I: BrookInputs<I>) => Waterfall<I>;
|
38
|
-
|
34
|
+
middleware: Brook<I>;
|
39
35
|
[WATERFALL_SYMBOL]: true;
|
40
36
|
};
|
41
37
|
|
@@ -77,53 +73,38 @@ export type Waterfalls2Runners<PS extends WaterfallRecord | void> = {
|
|
77
73
|
|
78
74
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
79
75
|
export const createWaterfall = <I = void>(): Waterfall<I> => {
|
80
|
-
const
|
81
|
-
|
82
|
-
const createCurrentRunner = (hooks: Hooks) =>
|
83
|
-
createCounter<I, I>((index, input, next) => {
|
84
|
-
if (index >= middlewares.length) {
|
85
|
-
return input;
|
86
|
-
}
|
87
|
-
|
88
|
-
return runHooks(() => next(middlewares[index](input) || input), hooks);
|
89
|
-
});
|
90
|
-
|
91
|
-
const currentContainer = createContainer();
|
92
|
-
const currentHooks = fromContainer(currentContainer);
|
93
|
-
const currentRunner = createCurrentRunner(currentHooks);
|
76
|
+
const pipeline = createPipeline<I, I>();
|
94
77
|
|
95
|
-
const use: Waterfall<I>['use'] = (...
|
96
|
-
|
78
|
+
const use: Waterfall<I>['use'] = (...brooks) => {
|
79
|
+
pipeline.use(...brooks.map(getBrook).map(mapBrookToMiddleware));
|
97
80
|
return waterfall;
|
98
81
|
};
|
99
82
|
|
100
|
-
const run: Waterfall<I>['run'] = (input, options) =>
|
101
|
-
|
102
|
-
|
103
|
-
container === currentContainer ? currentHooks : fromContainer(container);
|
104
|
-
const runner =
|
105
|
-
container === currentContainer
|
106
|
-
? currentRunner
|
107
|
-
: createCurrentRunner(hooks);
|
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 });
|
108
86
|
|
109
|
-
|
110
|
-
};
|
111
|
-
|
112
|
-
const brook: Waterfall<I>['brook'] = input => {
|
87
|
+
const middleware: Waterfall<I>['middleware'] = input => {
|
113
88
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
114
89
|
const container = useContainer();
|
115
|
-
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
91
|
+
return pipeline.run(input, { container, onLast: input => input });
|
116
92
|
};
|
117
93
|
|
118
|
-
const waterfall = {
|
94
|
+
const waterfall: Waterfall<I> = {
|
95
|
+
...pipeline,
|
119
96
|
use,
|
120
97
|
run,
|
121
|
-
|
122
|
-
[WATERFALL_SYMBOL]: true
|
98
|
+
middleware,
|
99
|
+
[WATERFALL_SYMBOL]: true,
|
123
100
|
};
|
124
|
-
|
125
101
|
return waterfall;
|
126
102
|
};
|
127
103
|
|
128
104
|
export const isWaterfall = (input: any): input is Waterfall<any> =>
|
129
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
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
import {
|
2
|
-
import { Hooks, runHooks, fromContainer, createContainer } from '../context';
|
1
|
+
import { MaybeAsync, createAsyncPipeline, Middleware } from 'farrow-pipeline';
|
3
2
|
import type { RunWorkflowOptions } from './sync';
|
4
3
|
|
5
4
|
const ASYNC_WORKFLOW_SYMBOL = Symbol('ASYNC_WORKFLOW_SYMBOL');
|
6
5
|
|
7
|
-
export type AsyncWorker<I, O> = (I: I) =>
|
6
|
+
export type AsyncWorker<I, O> = (I: I) => MaybeAsync<O>;
|
8
7
|
export type AsyncWorkers<I, O> = AsyncWorker<I, O>[];
|
9
8
|
|
10
9
|
export type AsyncWorkflow<I, O> = {
|
11
|
-
run: (input: I, options?: RunWorkflowOptions) =>
|
10
|
+
run: (input: I, options?: RunWorkflowOptions) => MaybeAsync<O[]>;
|
12
11
|
use: (...I: AsyncWorkers<I, O>) => AsyncWorkflow<I, O>;
|
13
12
|
[ASYNC_WORKFLOW_SYMBOL]: true;
|
14
13
|
};
|
@@ -54,43 +53,25 @@ export const createAsyncWorkflow = <I = void, O = unknown>(): AsyncWorkflow<
|
|
54
53
|
I,
|
55
54
|
O
|
56
55
|
> => {
|
57
|
-
const
|
58
|
-
|
59
|
-
const createCurrentRunner = (hooks: Hooks) =>
|
60
|
-
createAsyncCounter<I, O[]>(async (index, input, next) => {
|
61
|
-
if (index >= middlewares.length) {
|
62
|
-
return [];
|
63
|
-
}
|
64
|
-
|
65
|
-
const middleware = middlewares[index];
|
66
|
-
return runHooks(async () => {
|
67
|
-
const result = await middleware(input);
|
68
|
-
const rest = await next(input);
|
69
|
-
return [result, ...rest];
|
70
|
-
}, hooks);
|
71
|
-
});
|
72
|
-
const currentContainer = createContainer();
|
73
|
-
const currentHooks = fromContainer(currentContainer);
|
74
|
-
const currentRunner = createCurrentRunner(currentHooks);
|
56
|
+
const pipeline = createAsyncPipeline<I, O[]>();
|
75
57
|
|
76
58
|
const use: AsyncWorkflow<I, O>['use'] = (...input) => {
|
77
|
-
|
59
|
+
pipeline.use(...input.map(mapAsyncWorkerToAsyncMiddleware));
|
78
60
|
return workflow;
|
79
61
|
};
|
80
62
|
|
81
63
|
const run: AsyncWorkflow<I, O>['run'] = async (input, options) => {
|
82
|
-
const
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
return runner.start(input);
|
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
|
+
}
|
91
71
|
};
|
92
72
|
|
93
|
-
const workflow = {
|
73
|
+
const workflow: AsyncWorkflow<I, O> = {
|
74
|
+
...pipeline,
|
94
75
|
use,
|
95
76
|
run,
|
96
77
|
[ASYNC_WORKFLOW_SYMBOL]: true as const,
|
@@ -98,3 +79,18 @@ export const createAsyncWorkflow = <I = void, O = unknown>(): AsyncWorkflow<
|
|
98
79
|
|
99
80
|
return workflow;
|
100
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/parallel.ts
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { AsyncWorker, AsyncWorkers } from './async';
|
1
|
+
import { MaybeAsync, createPipeline, Middleware } from 'farrow-pipeline';
|
2
|
+
import type { AsyncWorker, AsyncWorkers } from './async';
|
4
3
|
import type { RunWorkflowOptions } from './sync';
|
5
4
|
|
6
5
|
const PARALLEL_WORKFLOW_SYMBOL = Symbol('PARALLEL_WORKFLOW_SYMBOL');
|
@@ -69,47 +68,30 @@ export const createParallelWorkflow = <
|
|
69
68
|
I = void,
|
70
69
|
O = unknown,
|
71
70
|
>(): ParallelWorkflow<I, O> => {
|
72
|
-
const
|
73
|
-
|
74
|
-
const createCurrentRunner = (hooks: Hooks) =>
|
75
|
-
createAsyncCounter<I, O[]>((index, input, next) => {
|
76
|
-
if (index >= middlewares.length) {
|
77
|
-
return Promise.resolve<any[]>([]);
|
78
|
-
}
|
79
|
-
|
80
|
-
const middleware = middlewares[index];
|
81
|
-
return runHooks(
|
82
|
-
async () => Promise.all([middleware(input), ...(await next(input))]),
|
83
|
-
hooks,
|
84
|
-
);
|
85
|
-
});
|
86
|
-
|
87
|
-
const currentContainer = createContainer();
|
88
|
-
const currentHooks = fromContainer(currentContainer);
|
89
|
-
const currentRunner = createCurrentRunner(currentHooks);
|
71
|
+
const pipeline = createPipeline<I, MaybeAsync<O>[]>();
|
90
72
|
|
91
73
|
const use: ParallelWorkflow<I, O>['use'] = (...input) => {
|
92
|
-
|
74
|
+
pipeline.use(...input.map(mapParallelWorkerToAsyncMiddleware));
|
93
75
|
return workflow;
|
94
76
|
};
|
95
77
|
|
96
|
-
const run: ParallelWorkflow<I, O>['run'] = async (input, options) =>
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
container === currentContainer
|
102
|
-
? currentRunner
|
103
|
-
: createCurrentRunner(hooks);
|
104
|
-
|
105
|
-
return runner.start(input);
|
106
|
-
};
|
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
|
+
);
|
107
83
|
|
108
|
-
const workflow = {
|
109
|
-
|
84
|
+
const workflow: ParallelWorkflow<I, O> = {
|
85
|
+
...pipeline,
|
110
86
|
run,
|
87
|
+
use,
|
111
88
|
[PARALLEL_WORKFLOW_SYMBOL]: true as const,
|
112
89
|
};
|
113
90
|
|
114
91
|
return workflow;
|
115
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
CHANGED
@@ -1,11 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
Hooks,
|
4
|
-
runHooks,
|
5
|
-
fromContainer,
|
6
|
-
Container,
|
7
|
-
createContainer,
|
8
|
-
} from '../context';
|
1
|
+
import { Container, createPipeline, Middleware } from 'farrow-pipeline';
|
9
2
|
|
10
3
|
const WORKFLOW_SYMBOL = Symbol('WORKFLOW_SYMBOL');
|
11
4
|
|
@@ -58,40 +51,20 @@ export type Workflows2Runners<PS extends WorkflowRecord | void> = {
|
|
58
51
|
|
59
52
|
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
60
53
|
export const createWorkflow = <I = void, O = unknown>(): Workflow<I, O> => {
|
61
|
-
const
|
62
|
-
|
63
|
-
const createCurrentRunner = (hooks: Hooks) =>
|
64
|
-
createCounter<I, O[]>((index, input, next) => {
|
65
|
-
if (index >= middlewares.length) {
|
66
|
-
return [];
|
67
|
-
}
|
68
|
-
|
69
|
-
const middleware = middlewares[index];
|
70
|
-
return runHooks(() => [middleware(input), ...next(input)], hooks);
|
71
|
-
});
|
72
|
-
|
73
|
-
const currentContainer = createContainer();
|
74
|
-
const currentHooks = fromContainer(currentContainer);
|
75
|
-
const currentRunner = createCurrentRunner(currentHooks);
|
54
|
+
const pipeline = createPipeline<I, O[]>();
|
76
55
|
|
77
56
|
const use: Workflow<I, O>['use'] = (...input) => {
|
78
|
-
|
57
|
+
pipeline.use(...input.map(mapWorkerToMiddleware));
|
79
58
|
return workflow;
|
80
59
|
};
|
81
60
|
|
82
|
-
const run: Workflow<I, O>['run'] = (input, options) => {
|
83
|
-
const
|
84
|
-
|
85
|
-
container === currentContainer ? currentHooks : fromContainer(container);
|
86
|
-
const runner =
|
87
|
-
container === currentContainer
|
88
|
-
? currentRunner
|
89
|
-
: createCurrentRunner(hooks);
|
90
|
-
|
91
|
-
return runner.start(input);
|
61
|
+
const run: Workflow<I, O>['run'] = async (input, options) => {
|
62
|
+
const result = pipeline.run(input, { ...options, onLast: () => [] });
|
63
|
+
return result.filter(Boolean);
|
92
64
|
};
|
93
65
|
|
94
|
-
const workflow = {
|
66
|
+
const workflow: Workflow<I, O> = {
|
67
|
+
...pipeline,
|
95
68
|
use,
|
96
69
|
run,
|
97
70
|
[WORKFLOW_SYMBOL]: true as const,
|
@@ -102,3 +75,8 @@ export const createWorkflow = <I = void, O = unknown>(): Workflow<I, O> => {
|
|
102
75
|
|
103
76
|
export const isWorkflow = (input: any): input is Workflow<unknown, unknown> =>
|
104
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)];
|
package/tests/async.test.ts
CHANGED
@@ -1,21 +1,25 @@
|
|
1
1
|
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
2
2
|
/* eslint-disable max-lines */
|
3
|
+
import { enable, disable } from 'farrow-pipeline/asyncHooks.node';
|
4
|
+
import {
|
5
|
+
createPipeline,
|
6
|
+
createAsyncPipeline,
|
7
|
+
createContext,
|
8
|
+
createContainer,
|
9
|
+
} from 'farrow-pipeline';
|
10
|
+
import { createManager, createAsyncManager, useRunner } from '../src/manager';
|
11
|
+
import { createWaterfall, createAsyncWaterfall } from '../src/waterfall';
|
12
|
+
import {
|
13
|
+
createWorkflow,
|
14
|
+
createAsyncWorkflow,
|
15
|
+
createParallelWorkflow,
|
16
|
+
} from '../src/workflow';
|
3
17
|
import { main } from './fixtures/async/core';
|
4
18
|
import foo from './fixtures/async/base/foo';
|
5
19
|
import bar, { getBar } from './fixtures/async/base/bar';
|
6
20
|
import dFoo from './fixtures/async/dynamic/foo';
|
7
21
|
import dBar, { getNumber } from './fixtures/async/dynamic/bar';
|
8
22
|
import { sleep } from './helpers';
|
9
|
-
import { createContext, createContainer } from '@/context';
|
10
|
-
import { createManager, createAsyncManager, useRunner } from '@/manager';
|
11
|
-
import { enable, disable } from '@/asyncHooksImpl';
|
12
|
-
import { createWaterfall, createAsyncWaterfall } from '@/waterfall';
|
13
|
-
import { createPipeline, createAsyncPipeline } from '@/pipeline';
|
14
|
-
import {
|
15
|
-
createWorkflow,
|
16
|
-
createAsyncWorkflow,
|
17
|
-
createParallelWorkflow,
|
18
|
-
} from '@/workflow';
|
19
23
|
|
20
24
|
describe('async manager', () => {
|
21
25
|
it('base usage', async () => {
|
package/tests/pipeline.test.ts
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
2
2
|
/* eslint-disable max-lines */
|
3
|
-
import
|
3
|
+
import * as asyncHooksImpl from 'farrow-pipeline/asyncHooks.node';
|
4
4
|
import {
|
5
5
|
createContext,
|
6
6
|
createContainer,
|
7
7
|
createPipeline,
|
8
8
|
createAsyncPipeline,
|
9
|
-
useAsyncPipeline,
|
10
9
|
usePipeline,
|
11
10
|
useContainer,
|
12
11
|
isPipeline,
|
13
|
-
|
14
|
-
} from '
|
15
|
-
import * as asyncHooksImpl from '@/asyncHooksImpl';
|
12
|
+
} from '../src';
|
13
|
+
import { sleep } from './helpers';
|
16
14
|
|
17
15
|
describe('createPipeline', () => {
|
18
16
|
it('basic usage', async () => {
|
@@ -531,7 +529,7 @@ describe('createPipeline', () => {
|
|
531
529
|
pipeline0.use(async input => `${input} from pipeline0`);
|
532
530
|
|
533
531
|
pipeline1.use(async input => {
|
534
|
-
const runPipeline1 =
|
532
|
+
const runPipeline1 = usePipeline(pipeline0);
|
535
533
|
|
536
534
|
const text = await runPipeline1(' pipeline1');
|
537
535
|
|
@@ -543,15 +541,6 @@ describe('createPipeline', () => {
|
|
543
541
|
expect(result).toEqual(`run pipeline1 from pipeline0`);
|
544
542
|
});
|
545
543
|
|
546
|
-
it('isAsyncPipeline', () => {
|
547
|
-
const pipeline = createAsyncPipeline();
|
548
|
-
|
549
|
-
expect(isAsyncPipeline(pipeline)).toBeTruthy();
|
550
|
-
expect(isAsyncPipeline({})).toBeFalsy();
|
551
|
-
expect(isAsyncPipeline('test')).toBeFalsy();
|
552
|
-
expect(isAsyncPipeline(null)).toBeFalsy();
|
553
|
-
});
|
554
|
-
|
555
544
|
it('support hooks', async () => {
|
556
545
|
const pipeline = createAsyncPipeline<number, number>();
|
557
546
|
|
@@ -599,7 +588,8 @@ describe('createPipeline', () => {
|
|
599
588
|
it('should throw error when all middlewares calling next() and onLast is not exist', async () => {
|
600
589
|
const pipeline = createAsyncPipeline<number, number>();
|
601
590
|
|
602
|
-
|
591
|
+
// eslint-disable-next-line promise/prefer-await-to-then
|
592
|
+
pipeline.use((input, next) => Promise.resolve().then(() => next(input)));
|
603
593
|
|
604
594
|
await expect(() => pipeline.run(0)).rejects.toThrowError();
|
605
595
|
});
|
package/tests/sync.test.ts
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
// eslint-disable-next-line eslint-comments/disable-enable-pair
|
2
2
|
/* eslint-disable max-lines */
|
3
|
+
import {
|
4
|
+
createPipeline,
|
5
|
+
createAsyncPipeline,
|
6
|
+
createContext,
|
7
|
+
createContainer,
|
8
|
+
} from 'farrow-pipeline';
|
9
|
+
import { createManager, createAsyncManager, useRunner } from '../src/manager';
|
10
|
+
import { createWaterfall, createAsyncWaterfall } from '../src/waterfall';
|
11
|
+
import {
|
12
|
+
createWorkflow,
|
13
|
+
createAsyncWorkflow,
|
14
|
+
createParallelWorkflow,
|
15
|
+
} from '../src/workflow';
|
3
16
|
import { main } from './fixtures/sync/core';
|
4
17
|
import foo from './fixtures/sync/base/foo';
|
5
18
|
import bar, { getBar } from './fixtures/sync/base/bar';
|
6
19
|
import dFoo from './fixtures/sync/dynamic/foo';
|
7
20
|
import dBar, { getNumber, setNumber } from './fixtures/sync/dynamic/bar';
|
8
|
-
import { createContext, createContainer } from '@/context';
|
9
|
-
import { createManager, createAsyncManager, useRunner } from '@/manager';
|
10
|
-
import { createWaterfall, createAsyncWaterfall } from '@/waterfall';
|
11
|
-
import { createPipeline, createAsyncPipeline } from '@/pipeline';
|
12
|
-
import {
|
13
|
-
createWorkflow,
|
14
|
-
createAsyncWorkflow,
|
15
|
-
createParallelWorkflow,
|
16
|
-
} from '@/workflow';
|
17
21
|
|
18
22
|
describe('sync manager', () => {
|
19
23
|
it('base useage', () => {
|