@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/pipeline/sync.ts
DELETED
@@ -1,152 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Copyright Lucifier129 and other contributors.
|
3
|
-
*
|
4
|
-
* This source code is licensed under the MIT license found in the
|
5
|
-
* LICENSE file at
|
6
|
-
* https://github.com/farrow-js/farrow/blob/master/LICENSE
|
7
|
-
*
|
8
|
-
*/
|
9
|
-
|
10
|
-
import {
|
11
|
-
createContainer,
|
12
|
-
ContextStorage,
|
13
|
-
Container,
|
14
|
-
fromContainer,
|
15
|
-
runHooks,
|
16
|
-
useContainer,
|
17
|
-
Hooks,
|
18
|
-
} from '../context';
|
19
|
-
|
20
|
-
import { Next, createCounter } from '../counter';
|
21
|
-
|
22
|
-
export type Middleware<I = unknown, O = unknown> = (
|
23
|
-
input: I,
|
24
|
-
next: Next<I, O>,
|
25
|
-
) => O;
|
26
|
-
|
27
|
-
export type Middlewares<I = unknown, O = unknown> = Middleware<I, O>[];
|
28
|
-
|
29
|
-
const PIPELINE_SYMBOL = Symbol('PIPELINE_SYMBOL');
|
30
|
-
export const isPipeline = (input: any): input is Pipeline =>
|
31
|
-
Boolean(input?.[PIPELINE_SYMBOL]);
|
32
|
-
|
33
|
-
export type PipelineOptions = {
|
34
|
-
contexts?: ContextStorage;
|
35
|
-
};
|
36
|
-
|
37
|
-
export type RunPipelineOptions<I = unknown, O = unknown> = {
|
38
|
-
container?: Container;
|
39
|
-
onLast?: (input: I) => O;
|
40
|
-
};
|
41
|
-
|
42
|
-
export type MiddlewareInput<I = unknown, O = unknown> =
|
43
|
-
| Middleware<I, O>
|
44
|
-
| { middleware: Middleware<I, O> };
|
45
|
-
|
46
|
-
export type MiddlewareType<T extends MiddlewareInput> =
|
47
|
-
T extends MiddlewareInput<infer I, infer O> ? Middleware<I, O> : never;
|
48
|
-
|
49
|
-
export const getMiddleware = <I, O>(input: MiddlewareInput<I, O>) => {
|
50
|
-
if (typeof input === 'function') {
|
51
|
-
return input;
|
52
|
-
} else if (input && typeof input.middleware === 'function') {
|
53
|
-
return input.middleware;
|
54
|
-
}
|
55
|
-
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
|
56
|
-
throw new Error(`${input} is not a Middleware or { middleware: Middleware }`);
|
57
|
-
};
|
58
|
-
|
59
|
-
export type Pipeline<I = unknown, O = unknown> = {
|
60
|
-
[PIPELINE_SYMBOL]: true;
|
61
|
-
use: (...inputs: MiddlewareInput<I, O>[]) => Pipeline<I, O>;
|
62
|
-
run: (input: I, options?: RunPipelineOptions<I, O>) => O;
|
63
|
-
middleware: Middleware<I, O>;
|
64
|
-
};
|
65
|
-
|
66
|
-
export const createPipeline = <I, O>(options?: PipelineOptions) => {
|
67
|
-
const config = { ...options };
|
68
|
-
|
69
|
-
const middlewares: Middlewares<I, O> = [];
|
70
|
-
|
71
|
-
const use: Pipeline<I, O>['use'] = (...inputs) => {
|
72
|
-
middlewares.push(...inputs.map(getMiddleware));
|
73
|
-
return pipeline;
|
74
|
-
};
|
75
|
-
|
76
|
-
const createCurrentCounter = (hooks: Hooks, onLast?: (input: I) => O) =>
|
77
|
-
createCounter<I, O>((index, input, next) => {
|
78
|
-
if (index >= middlewares.length) {
|
79
|
-
if (onLast) {
|
80
|
-
return onLast(input);
|
81
|
-
}
|
82
|
-
throw new Error(
|
83
|
-
`Expect returning a value, but all middlewares just calling next()`,
|
84
|
-
);
|
85
|
-
}
|
86
|
-
|
87
|
-
const middleware = middlewares[index];
|
88
|
-
const result = runHooks(() => middleware(input, next), hooks);
|
89
|
-
|
90
|
-
return result;
|
91
|
-
});
|
92
|
-
|
93
|
-
const currentContainer = createContainer(config.contexts);
|
94
|
-
const currentHooks = fromContainer(currentContainer);
|
95
|
-
const currentCounter = createCurrentCounter(currentHooks);
|
96
|
-
|
97
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
98
|
-
const run: Pipeline<I, O>['run'] = (input, options) => {
|
99
|
-
const container = options?.container ?? currentContainer;
|
100
|
-
const hooks =
|
101
|
-
container === currentContainer ? currentHooks : fromContainer(container);
|
102
|
-
let counter =
|
103
|
-
container === currentContainer
|
104
|
-
? currentCounter
|
105
|
-
: createCurrentCounter(hooks);
|
106
|
-
|
107
|
-
if (options?.onLast) {
|
108
|
-
counter = createCurrentCounter(hooks, options.onLast);
|
109
|
-
}
|
110
|
-
|
111
|
-
const result = counter.start(input);
|
112
|
-
|
113
|
-
return result;
|
114
|
-
};
|
115
|
-
|
116
|
-
const middleware: Pipeline<I, O>['middleware'] = (input, next) => {
|
117
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
118
|
-
const container = useContainer();
|
119
|
-
return run(input, {
|
120
|
-
container,
|
121
|
-
onLast: next,
|
122
|
-
});
|
123
|
-
};
|
124
|
-
|
125
|
-
const pipeline: Pipeline<I, O> = {
|
126
|
-
[PIPELINE_SYMBOL]: true,
|
127
|
-
use,
|
128
|
-
run,
|
129
|
-
middleware,
|
130
|
-
};
|
131
|
-
|
132
|
-
return pipeline;
|
133
|
-
};
|
134
|
-
|
135
|
-
export type PipelineInput<T extends Pipeline> = T extends Pipeline<infer I>
|
136
|
-
? I
|
137
|
-
: never;
|
138
|
-
export type PipelineOutput<T extends Pipeline> = T extends Pipeline<
|
139
|
-
any,
|
140
|
-
infer O
|
141
|
-
>
|
142
|
-
? O
|
143
|
-
: never;
|
144
|
-
|
145
|
-
export const usePipeline = <I, O>(pipeline: Pipeline<I, O>) => {
|
146
|
-
const container = useContainer();
|
147
|
-
|
148
|
-
const runPipeline = (input: I, options?: RunPipelineOptions<I, O>): O =>
|
149
|
-
pipeline.run(input, { ...options, container });
|
150
|
-
|
151
|
-
return runPipeline;
|
152
|
-
};
|
package/tests/context.test.ts
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
createContext,
|
3
|
-
createContainer,
|
4
|
-
useContainer,
|
5
|
-
fromContainer,
|
6
|
-
runHooks,
|
7
|
-
isContext,
|
8
|
-
assertContext,
|
9
|
-
isContainer,
|
10
|
-
assertContainer,
|
11
|
-
} from '@/context';
|
12
|
-
|
13
|
-
describe('context', () => {
|
14
|
-
it('different values in Containers with same Context', () => {
|
15
|
-
const Context0 = createContext({ count: 0 });
|
16
|
-
|
17
|
-
const Context1 = createContext({ text: 'test' });
|
18
|
-
|
19
|
-
const container = createContainer();
|
20
|
-
|
21
|
-
expect(container.read(Context0)).toEqual({ count: 0 });
|
22
|
-
|
23
|
-
expect(container.read(Context1)).toEqual({ text: 'test' });
|
24
|
-
|
25
|
-
container.write(Context0, { count: 1 });
|
26
|
-
|
27
|
-
expect(container.read(Context0)).toEqual({ count: 1 });
|
28
|
-
|
29
|
-
container.write(Context1, { text: 'update test' });
|
30
|
-
|
31
|
-
expect(container.read(Context1)).toEqual({ text: 'update test' });
|
32
|
-
});
|
33
|
-
|
34
|
-
it('inject new Context to Container', () => {
|
35
|
-
const Context0 = createContext({ count: 0 });
|
36
|
-
|
37
|
-
const Context1 = createContext({ text: 'test' });
|
38
|
-
|
39
|
-
const container = createContainer({
|
40
|
-
count: Context0.create({ count: 1 }),
|
41
|
-
text: Context1.create({ text: 'new text' }),
|
42
|
-
});
|
43
|
-
|
44
|
-
expect(container.read(Context0)).toEqual({ count: 1 });
|
45
|
-
|
46
|
-
expect(container.read(Context1)).toEqual({ text: 'new text' });
|
47
|
-
});
|
48
|
-
|
49
|
-
it('run hook with container', () => {
|
50
|
-
const Context0 = createContext({ count: 0 });
|
51
|
-
|
52
|
-
const Context1 = createContext({ text: 'test' });
|
53
|
-
|
54
|
-
const container = createContainer({
|
55
|
-
count: Context0.create({ count: 1 }),
|
56
|
-
text: Context1.create({ text: 'new text' }),
|
57
|
-
});
|
58
|
-
|
59
|
-
runHooks(() => {
|
60
|
-
const ctn = useContainer();
|
61
|
-
|
62
|
-
expect(container === ctn).toBeTruthy();
|
63
|
-
|
64
|
-
expect(ctn.read(Context0)).toEqual({ count: 1 });
|
65
|
-
|
66
|
-
expect(ctn.read(Context1)).toEqual({ text: 'new text' });
|
67
|
-
}, fromContainer(container));
|
68
|
-
});
|
69
|
-
|
70
|
-
it('assert Context', () => {
|
71
|
-
const context = createContext<number | null>(null);
|
72
|
-
|
73
|
-
const container = createContainer();
|
74
|
-
|
75
|
-
runHooks(() => {
|
76
|
-
expect(() => context.assert()).toThrowError();
|
77
|
-
|
78
|
-
context.set(0);
|
79
|
-
|
80
|
-
expect(context.assert()).toBe(0);
|
81
|
-
}, fromContainer(container));
|
82
|
-
});
|
83
|
-
|
84
|
-
it('isContext', () => {
|
85
|
-
const context = createContext(0);
|
86
|
-
|
87
|
-
expect(isContext(context)).toBeTruthy();
|
88
|
-
expect(isContext({})).toBeFalsy();
|
89
|
-
});
|
90
|
-
|
91
|
-
it('assertContext', () => {
|
92
|
-
const context = createContext(0);
|
93
|
-
|
94
|
-
assertContext(context);
|
95
|
-
|
96
|
-
expect(() => assertContext({})).toThrowError();
|
97
|
-
});
|
98
|
-
|
99
|
-
it('isContainer', () => {
|
100
|
-
const container = createContainer();
|
101
|
-
|
102
|
-
expect(isContainer(container)).toBeTruthy();
|
103
|
-
expect(isContainer({})).toBeFalsy();
|
104
|
-
expect(isContainer(null)).toBeFalsy();
|
105
|
-
});
|
106
|
-
|
107
|
-
it('assertContainer', () => {
|
108
|
-
const container = createContainer();
|
109
|
-
|
110
|
-
assertContainer(container);
|
111
|
-
|
112
|
-
expect(() => assertContainer({})).toThrowError();
|
113
|
-
});
|
114
|
-
});
|
package/tests/counter.test.ts
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
import { createCounter, createAsyncCounter } from '@/counter';
|
2
|
-
|
3
|
-
describe('counter', () => {
|
4
|
-
describe('sync', () => {
|
5
|
-
it('base usage', () => {
|
6
|
-
const counter = createCounter<number, number>((index, input, next) => {
|
7
|
-
if (index >= 10) {
|
8
|
-
return input;
|
9
|
-
}
|
10
|
-
return next(input * 2);
|
11
|
-
});
|
12
|
-
|
13
|
-
expect(counter.start(1)).toBe(2 ** 10);
|
14
|
-
});
|
15
|
-
});
|
16
|
-
|
17
|
-
describe('async', () => {
|
18
|
-
it('base usage', async () => {
|
19
|
-
const counter = createAsyncCounter<number, number>(
|
20
|
-
async (index, input, next) => {
|
21
|
-
if (index >= 10) {
|
22
|
-
return input;
|
23
|
-
}
|
24
|
-
return next(input * 2);
|
25
|
-
},
|
26
|
-
);
|
27
|
-
|
28
|
-
expect(await counter.start(1)).toBe(2 ** 10);
|
29
|
-
});
|
30
|
-
});
|
31
|
-
});
|
package/tests/hook.test.ts
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
import { sleep } from './helpers';
|
2
|
-
import { enable, disable } from '@/asyncHooksImpl';
|
3
|
-
import { createHooks } from '@/hook';
|
4
|
-
|
5
|
-
describe('hook', () => {
|
6
|
-
it('should support sync runner', () => {
|
7
|
-
type Hooks = {
|
8
|
-
useCount: () => number;
|
9
|
-
};
|
10
|
-
|
11
|
-
const {
|
12
|
-
run,
|
13
|
-
hooks: { useCount },
|
14
|
-
} = createHooks<Hooks>({
|
15
|
-
useCount: () => {
|
16
|
-
throw new Error(`useCount can't not be called after initilizing`);
|
17
|
-
},
|
18
|
-
});
|
19
|
-
|
20
|
-
let count = 0;
|
21
|
-
const implementations: Hooks = { useCount: () => count++ };
|
22
|
-
run(() => {
|
23
|
-
expect(useCount()).toBe(0);
|
24
|
-
expect(useCount()).toBe(1);
|
25
|
-
expect(useCount()).toBe(2);
|
26
|
-
expect(useCount()).toBe(3);
|
27
|
-
}, implementations);
|
28
|
-
});
|
29
|
-
|
30
|
-
it('should support async runner', async () => {
|
31
|
-
type Hooks = {
|
32
|
-
useCount: () => number;
|
33
|
-
};
|
34
|
-
|
35
|
-
const {
|
36
|
-
run,
|
37
|
-
hooks: { useCount },
|
38
|
-
} = createHooks<Hooks>({
|
39
|
-
useCount: () => {
|
40
|
-
throw new Error(`useCount can't not be called after initilizing`);
|
41
|
-
},
|
42
|
-
});
|
43
|
-
|
44
|
-
let count = 0;
|
45
|
-
const implementations: Hooks = { useCount: () => count++ };
|
46
|
-
|
47
|
-
enable();
|
48
|
-
|
49
|
-
await run(async () => {
|
50
|
-
expect(useCount()).toBe(0);
|
51
|
-
await sleep(0);
|
52
|
-
expect(useCount()).toBe(1);
|
53
|
-
await sleep(0);
|
54
|
-
expect(useCount()).toBe(2);
|
55
|
-
await sleep(0);
|
56
|
-
expect(useCount()).toBe(3);
|
57
|
-
}, implementations);
|
58
|
-
|
59
|
-
disable();
|
60
|
-
});
|
61
|
-
|
62
|
-
it('should use default hook with passing new one', () => {
|
63
|
-
type Hooks = {
|
64
|
-
useCount: () => number;
|
65
|
-
};
|
66
|
-
|
67
|
-
const {
|
68
|
-
run,
|
69
|
-
hooks: { useCount },
|
70
|
-
} = createHooks<Hooks>({
|
71
|
-
useCount: () => {
|
72
|
-
throw new Error(`useCount can't not be called after initilizing`);
|
73
|
-
},
|
74
|
-
});
|
75
|
-
|
76
|
-
enable();
|
77
|
-
|
78
|
-
run(() => {
|
79
|
-
expect(useCount).toThrowError(
|
80
|
-
new Error(`useCount can't not be called after initilizing`),
|
81
|
-
);
|
82
|
-
});
|
83
|
-
|
84
|
-
disable();
|
85
|
-
});
|
86
|
-
|
87
|
-
it('should fallback to default hook', () => {
|
88
|
-
type Hooks = {
|
89
|
-
useCount: () => number;
|
90
|
-
};
|
91
|
-
|
92
|
-
const {
|
93
|
-
run,
|
94
|
-
hooks: { useCount },
|
95
|
-
} = createHooks<Hooks>({
|
96
|
-
useCount: () => {
|
97
|
-
throw new Error(`useCount can't not be called after initilizing`);
|
98
|
-
},
|
99
|
-
});
|
100
|
-
|
101
|
-
const implementations: Hooks = { useCount: '' } as any;
|
102
|
-
|
103
|
-
enable();
|
104
|
-
|
105
|
-
run(() => {
|
106
|
-
expect(useCount).toThrowError(
|
107
|
-
new Error(`useCount can't not be called after initilizing`),
|
108
|
-
);
|
109
|
-
}, implementations);
|
110
|
-
|
111
|
-
disable();
|
112
|
-
});
|
113
|
-
});
|