@duplojs/utils 1.5.15 → 1.6.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/dist/clean/primitive/operations/equal.d.ts +3 -3
- package/dist/common/kind.cjs +2 -1
- package/dist/common/kind.d.ts +1 -0
- package/dist/common/kind.mjs +2 -1
- package/dist/flow/breakIf.cjs +14 -0
- package/dist/flow/breakIf.d.ts +50 -0
- package/dist/flow/breakIf.mjs +12 -0
- package/dist/flow/defer.cjs +12 -0
- package/dist/flow/defer.d.ts +47 -0
- package/dist/flow/defer.mjs +10 -0
- package/dist/flow/exec.cjs +125 -0
- package/dist/flow/exec.d.ts +83 -0
- package/dist/flow/exec.mjs +123 -0
- package/dist/flow/exitIf.cjs +14 -0
- package/dist/flow/exitIf.d.ts +67 -0
- package/dist/flow/exitIf.mjs +12 -0
- package/dist/flow/finalizer.cjs +12 -0
- package/dist/flow/finalizer.d.ts +47 -0
- package/dist/flow/finalizer.mjs +10 -0
- package/dist/flow/index.cjs +50 -0
- package/dist/flow/index.d.ts +12 -0
- package/dist/flow/index.mjs +18 -0
- package/dist/flow/initializer.cjs +38 -0
- package/dist/flow/initializer.d.ts +75 -0
- package/dist/flow/initializer.mjs +36 -0
- package/dist/flow/inject.cjs +19 -0
- package/dist/flow/inject.d.ts +46 -0
- package/dist/flow/inject.mjs +17 -0
- package/dist/flow/kind.cjs +9 -0
- package/dist/flow/kind.d.ts +1 -0
- package/dist/flow/kind.mjs +7 -0
- package/dist/flow/run.cjs +139 -0
- package/dist/flow/run.d.ts +80 -0
- package/dist/flow/run.mjs +136 -0
- package/dist/flow/step.cjs +23 -0
- package/dist/flow/step.d.ts +39 -0
- package/dist/flow/step.mjs +21 -0
- package/dist/flow/theFlow/break.cjs +11 -0
- package/dist/flow/theFlow/break.d.ts +7 -0
- package/dist/flow/theFlow/break.mjs +8 -0
- package/dist/flow/theFlow/defer.cjs +11 -0
- package/dist/flow/theFlow/defer.d.ts +5 -0
- package/dist/flow/theFlow/defer.mjs +8 -0
- package/dist/flow/theFlow/dependence.cjs +17 -0
- package/dist/flow/theFlow/dependence.d.ts +50 -0
- package/dist/flow/theFlow/dependence.mjs +14 -0
- package/dist/flow/theFlow/exit.cjs +11 -0
- package/dist/flow/theFlow/exit.d.ts +7 -0
- package/dist/flow/theFlow/exit.mjs +8 -0
- package/dist/flow/theFlow/finalizer.cjs +11 -0
- package/dist/flow/theFlow/finalizer.d.ts +5 -0
- package/dist/flow/theFlow/finalizer.mjs +8 -0
- package/dist/flow/theFlow/index.cjs +14 -0
- package/dist/flow/theFlow/index.d.ts +85 -0
- package/dist/flow/theFlow/index.mjs +11 -0
- package/dist/flow/theFlow/injection.cjs +11 -0
- package/dist/flow/theFlow/injection.d.ts +10 -0
- package/dist/flow/theFlow/injection.mjs +8 -0
- package/dist/flow/theFlow/step.cjs +11 -0
- package/dist/flow/theFlow/step.d.ts +5 -0
- package/dist/flow/theFlow/step.mjs +8 -0
- package/dist/flow/types/index.d.ts +1 -0
- package/dist/index.cjs +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +3 -0
- package/dist/metadata.json +189 -0
- package/dist/object/types/requireAtLeastOne.d.ts +2 -1
- package/package.json +6 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Finalizer } from "./theFlow";
|
|
2
|
+
/**
|
|
3
|
+
* Registers a final callback handled by the flow runner.
|
|
4
|
+
*
|
|
5
|
+
* **Supported call styles:**
|
|
6
|
+
* - Classic: `finalizer(theFunction)` -> yields a finalizer effect
|
|
7
|
+
*
|
|
8
|
+
* `finalizer` registers logic that is executed by the flow runner when the flow completes.
|
|
9
|
+
* It is useful for cleanup or post-processing that should stay inside the flow effect system.
|
|
10
|
+
* Use it inside `F.run(...)` or inside subflows executed by `F.exec(...)`.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* F.run(
|
|
14
|
+
* function *() {
|
|
15
|
+
* yield *F.finalizer(() => void console.log("close connection"));
|
|
16
|
+
* return "done";
|
|
17
|
+
* },
|
|
18
|
+
* ); // "done"
|
|
19
|
+
*
|
|
20
|
+
* F.run(
|
|
21
|
+
* function *() {
|
|
22
|
+
* yield *F.finalizer(() => void console.log("clear cache"));
|
|
23
|
+
* yield *F.breakIf(2, (value) => value === 2);
|
|
24
|
+
* return "done";
|
|
25
|
+
* },
|
|
26
|
+
* ); // 2
|
|
27
|
+
*
|
|
28
|
+
* await F.run(
|
|
29
|
+
* async function *() {
|
|
30
|
+
* yield *F.finalizer(async() => {
|
|
31
|
+
* await Promise.resolve();
|
|
32
|
+
* });
|
|
33
|
+
* return Promise.resolve("done");
|
|
34
|
+
* },
|
|
35
|
+
* ); // Promise<"done">
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* - Finalizers are collected by the flow runner and executed after the flow ends
|
|
40
|
+
*
|
|
41
|
+
* @see [`F.defer`](https://utils.duplojs.dev/en/v1/api/flow/defer) For another cleanup-oriented effect
|
|
42
|
+
* @see https://utils.duplojs.dev/en/v1/api/flow/finalizer
|
|
43
|
+
*
|
|
44
|
+
* @namespace F
|
|
45
|
+
*
|
|
46
|
+
*/
|
|
47
|
+
export declare function finalizer<GenericOutput extends unknown>(theFunction: () => GenericOutput): (Generator<Finalizer<GenericOutput>, undefined> | (GenericOutput extends Promise<unknown> ? AsyncGenerator<Finalizer<GenericOutput>, undefined> : never));
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var run = require('./run.cjs');
|
|
4
|
+
var index = require('./theFlow/index.cjs');
|
|
5
|
+
var breakIf = require('./breakIf.cjs');
|
|
6
|
+
var defer$1 = require('./defer.cjs');
|
|
7
|
+
var exec = require('./exec.cjs');
|
|
8
|
+
var exitIf = require('./exitIf.cjs');
|
|
9
|
+
var finalizer$1 = require('./finalizer.cjs');
|
|
10
|
+
var inject = require('./inject.cjs');
|
|
11
|
+
var step$1 = require('./step.cjs');
|
|
12
|
+
var initializer = require('./initializer.cjs');
|
|
13
|
+
var kind = require('./kind.cjs');
|
|
14
|
+
var step = require('./theFlow/step.cjs');
|
|
15
|
+
var exit = require('./theFlow/exit.cjs');
|
|
16
|
+
var _break = require('./theFlow/break.cjs');
|
|
17
|
+
var injection = require('./theFlow/injection.cjs');
|
|
18
|
+
var defer = require('./theFlow/defer.cjs');
|
|
19
|
+
var finalizer = require('./theFlow/finalizer.cjs');
|
|
20
|
+
var dependence = require('./theFlow/dependence.cjs');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
exports.MissingDependenceError = run.MissingDependenceError;
|
|
25
|
+
exports.run = run.run;
|
|
26
|
+
exports.create = index.create;
|
|
27
|
+
exports.theFlowKind = index.theFlowKind;
|
|
28
|
+
exports.breakIf = breakIf.breakIf;
|
|
29
|
+
exports.defer = defer$1.defer;
|
|
30
|
+
exports.exec = exec.exec;
|
|
31
|
+
exports.exitIf = exitIf.exitIf;
|
|
32
|
+
exports.finalizer = finalizer$1.finalizer;
|
|
33
|
+
exports.inject = inject.inject;
|
|
34
|
+
exports.step = step$1.step;
|
|
35
|
+
exports.createInitializer = initializer.createInitializer;
|
|
36
|
+
exports.createFlowKind = kind.createFlowKind;
|
|
37
|
+
exports.createStep = step.createStep;
|
|
38
|
+
exports.stepKind = step.stepKind;
|
|
39
|
+
exports.createExit = exit.createExit;
|
|
40
|
+
exports.exitKind = exit.exitKind;
|
|
41
|
+
exports.breakKind = _break.breakKind;
|
|
42
|
+
exports.createBreak = _break.createBreak;
|
|
43
|
+
exports.createInjection = injection.createInjection;
|
|
44
|
+
exports.injectionKind = injection.injectionKind;
|
|
45
|
+
exports.createDefer = defer.createDefer;
|
|
46
|
+
exports.deferKind = defer.deferKind;
|
|
47
|
+
exports.createFinalizer = finalizer.createFinalizer;
|
|
48
|
+
exports.finalizerKind = finalizer.finalizerKind;
|
|
49
|
+
exports.createDependence = dependence.createDependence;
|
|
50
|
+
exports.dependenceHandlerKind = dependence.dependenceHandlerKind;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./run";
|
|
3
|
+
export * from "./theFlow";
|
|
4
|
+
export * from "./breakIf";
|
|
5
|
+
export * from "./defer";
|
|
6
|
+
export * from "./exec";
|
|
7
|
+
export * from "./exitIf";
|
|
8
|
+
export * from "./finalizer";
|
|
9
|
+
export * from "./inject";
|
|
10
|
+
export * from "./step";
|
|
11
|
+
export * from "./initializer";
|
|
12
|
+
export * from "./kind";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { MissingDependenceError, run } from './run.mjs';
|
|
2
|
+
export { create, theFlowKind } from './theFlow/index.mjs';
|
|
3
|
+
export { breakIf } from './breakIf.mjs';
|
|
4
|
+
export { defer } from './defer.mjs';
|
|
5
|
+
export { exec } from './exec.mjs';
|
|
6
|
+
export { exitIf } from './exitIf.mjs';
|
|
7
|
+
export { finalizer } from './finalizer.mjs';
|
|
8
|
+
export { inject } from './inject.mjs';
|
|
9
|
+
export { step } from './step.mjs';
|
|
10
|
+
export { createInitializer } from './initializer.mjs';
|
|
11
|
+
export { createFlowKind } from './kind.mjs';
|
|
12
|
+
export { createStep, stepKind } from './theFlow/step.mjs';
|
|
13
|
+
export { createExit, exitKind } from './theFlow/exit.mjs';
|
|
14
|
+
export { breakKind, createBreak } from './theFlow/break.mjs';
|
|
15
|
+
export { createInjection, injectionKind } from './theFlow/injection.mjs';
|
|
16
|
+
export { createDefer, deferKind } from './theFlow/defer.mjs';
|
|
17
|
+
export { createFinalizer, finalizerKind } from './theFlow/finalizer.mjs';
|
|
18
|
+
export { createDependence, dependenceHandlerKind } from './theFlow/dependence.mjs';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var defer = require('./theFlow/defer.cjs');
|
|
4
|
+
var finalizer = require('./theFlow/finalizer.cjs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* {@include flow/createInitializer/index.md}
|
|
8
|
+
*/
|
|
9
|
+
function createInitializer(initializer, params) {
|
|
10
|
+
return (...args) => {
|
|
11
|
+
const result = initializer(...args);
|
|
12
|
+
const defer$1 = params.defer;
|
|
13
|
+
const finalizer$1 = params.finalizer;
|
|
14
|
+
if (result instanceof Promise) {
|
|
15
|
+
return (async function* () {
|
|
16
|
+
const awaitedResult = await result;
|
|
17
|
+
if (defer$1) {
|
|
18
|
+
yield defer.createDefer(() => defer$1(awaitedResult));
|
|
19
|
+
}
|
|
20
|
+
if (finalizer$1) {
|
|
21
|
+
yield finalizer.createFinalizer(() => finalizer$1(awaitedResult));
|
|
22
|
+
}
|
|
23
|
+
return awaitedResult;
|
|
24
|
+
})();
|
|
25
|
+
}
|
|
26
|
+
return (function* () {
|
|
27
|
+
if (defer$1) {
|
|
28
|
+
yield defer.createDefer(() => defer$1(result));
|
|
29
|
+
}
|
|
30
|
+
if (finalizer$1) {
|
|
31
|
+
yield finalizer.createFinalizer(() => finalizer$1(result));
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
})();
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exports.createInitializer = createInitializer;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type AnyFunction, type IsExtends, type Or } from "../common";
|
|
2
|
+
import { type RequireAtLeastOne } from "../object";
|
|
3
|
+
import { type Defer, type Finalizer } from "./theFlow";
|
|
4
|
+
export interface CreateInitializerParams<GenericOutput extends unknown = unknown> {
|
|
5
|
+
defer?(output: Awaited<GenericOutput>): unknown;
|
|
6
|
+
finalizer?(output: Awaited<GenericOutput>): unknown;
|
|
7
|
+
}
|
|
8
|
+
export type Initializer<GenericArgs extends unknown[], GenericOutput extends unknown, GenericParams extends CreateInitializerParams<GenericOutput>> = Extract<(...args: GenericArgs) => (((GenericParams["finalizer"] extends AnyFunction ? Finalizer<ReturnType<GenericParams["finalizer"]>> : never) | (GenericParams["defer"] extends AnyFunction ? Defer<ReturnType<GenericParams["defer"]>> : never)) extends infer InferredEffect ? (Generator<InferredEffect, Awaited<GenericOutput>> | (Or<[
|
|
9
|
+
IsExtends<GenericOutput, Promise<unknown>>,
|
|
10
|
+
IsExtends<InferredEffect, Finalizer<Promise<unknown>>>,
|
|
11
|
+
IsExtends<InferredEffect, Defer<Promise<unknown>>>
|
|
12
|
+
]> extends true ? AsyncGenerator<InferredEffect, Awaited<GenericOutput>> : never)) : never), any>;
|
|
13
|
+
/**
|
|
14
|
+
* Creates an initializer that returns a value and automatically registers flow cleanup effects.
|
|
15
|
+
*
|
|
16
|
+
* **Supported call styles:**
|
|
17
|
+
* - Classic: `createInitializer(initializer, params)` -> returns a function that can be yielded inside a flow
|
|
18
|
+
*
|
|
19
|
+
* `createInitializer` wraps an initializer function and turns its result into a flow-friendly generator.
|
|
20
|
+
* Depending on the provided options, it can register a `defer` callback, a `finalizer` callback, or both, using the produced value.
|
|
21
|
+
* The returned initializer can then be executed inside `F.run(...)` like any other flow generator.
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const userInitializer = F.createInitializer(
|
|
25
|
+
* (name: string) => ({ name }),
|
|
26
|
+
* { defer: (user) => void console.log(`close:${user.name}`) },
|
|
27
|
+
* );
|
|
28
|
+
*
|
|
29
|
+
* F.run(
|
|
30
|
+
* function *() {
|
|
31
|
+
* return yield *userInitializer("Ada");
|
|
32
|
+
* },
|
|
33
|
+
* ); // { name: "Ada" }
|
|
34
|
+
*
|
|
35
|
+
* const finalizerLogs: string[] = [];
|
|
36
|
+
* const tokenInitializer = F.createInitializer(
|
|
37
|
+
* (id: number) => `token-${id}`,
|
|
38
|
+
* { finalizer: (token) => finalizerLogs.push(token) },
|
|
39
|
+
* );
|
|
40
|
+
*
|
|
41
|
+
* F.run(
|
|
42
|
+
* function *() {
|
|
43
|
+
* return yield *tokenInitializer(42);
|
|
44
|
+
* },
|
|
45
|
+
* ); // "token-42"
|
|
46
|
+
*
|
|
47
|
+
* const asyncInitializer = F.createInitializer(
|
|
48
|
+
* (name: string) => Promise.resolve({
|
|
49
|
+
* name,
|
|
50
|
+
* ready: true,
|
|
51
|
+
* }),
|
|
52
|
+
* { defer: (user) => void console.log(`async:${user.name}`) },
|
|
53
|
+
* );
|
|
54
|
+
*
|
|
55
|
+
* void await F.run(
|
|
56
|
+
* async function *() {
|
|
57
|
+
* const value = yield *asyncInitializer("Linus");
|
|
58
|
+
* // Promise<{ name: string; ready: true }>
|
|
59
|
+
*
|
|
60
|
+
* return;
|
|
61
|
+
* },
|
|
62
|
+
* );
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* - `createInitializer` is useful when a setup step should also declare matching cleanup logic
|
|
67
|
+
*
|
|
68
|
+
* @see [`F.defer`](https://utils.duplojs.dev/en/v1/api/flow/defer) For cleanup callbacks
|
|
69
|
+
* @see [`F.finalizer`](https://utils.duplojs.dev/en/v1/api/flow/finalizer) For final callbacks
|
|
70
|
+
* @see https://utils.duplojs.dev/en/v1/api/flow/createInitializer
|
|
71
|
+
*
|
|
72
|
+
* @namespace F
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
export declare function createInitializer<GenericArgs extends unknown[], GenericOutput extends unknown, GenericParams extends CreateInitializerParams<GenericOutput>>(initializer: (...args: GenericArgs) => GenericOutput, params: GenericParams & RequireAtLeastOne<GenericParams, keyof CreateInitializerParams>): Initializer<GenericArgs, GenericOutput, GenericParams>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createDefer } from './theFlow/defer.mjs';
|
|
2
|
+
import { createFinalizer } from './theFlow/finalizer.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* {@include flow/createInitializer/index.md}
|
|
6
|
+
*/
|
|
7
|
+
function createInitializer(initializer, params) {
|
|
8
|
+
return (...args) => {
|
|
9
|
+
const result = initializer(...args);
|
|
10
|
+
const defer = params.defer;
|
|
11
|
+
const finalizer = params.finalizer;
|
|
12
|
+
if (result instanceof Promise) {
|
|
13
|
+
return (async function* () {
|
|
14
|
+
const awaitedResult = await result;
|
|
15
|
+
if (defer) {
|
|
16
|
+
yield createDefer(() => defer(awaitedResult));
|
|
17
|
+
}
|
|
18
|
+
if (finalizer) {
|
|
19
|
+
yield createFinalizer(() => finalizer(awaitedResult));
|
|
20
|
+
}
|
|
21
|
+
return awaitedResult;
|
|
22
|
+
})();
|
|
23
|
+
}
|
|
24
|
+
return (function* () {
|
|
25
|
+
if (defer) {
|
|
26
|
+
yield createDefer(() => defer(result));
|
|
27
|
+
}
|
|
28
|
+
if (finalizer) {
|
|
29
|
+
yield createFinalizer(() => finalizer(result));
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
})();
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { createInitializer };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var injection = require('./theFlow/injection.cjs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* {@include flow/inject/index.md}
|
|
7
|
+
*/
|
|
8
|
+
function* inject(dependenceHandler) {
|
|
9
|
+
let dependence = undefined;
|
|
10
|
+
yield injection.createInjection({
|
|
11
|
+
dependenceHandler,
|
|
12
|
+
inject: (value) => {
|
|
13
|
+
dependence = value;
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
return dependence;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
exports.inject = inject;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type DependenceHandler, type Injection } from "./theFlow";
|
|
2
|
+
/**
|
|
3
|
+
* Requests a dependency from the flow runner.
|
|
4
|
+
*
|
|
5
|
+
* **Supported call styles:**
|
|
6
|
+
* - Classic: `inject(dependenceHandler)` -> yields an injection effect and returns the injected value
|
|
7
|
+
*
|
|
8
|
+
* `inject` lets a flow declare that it needs a dependency by using a dependence handler created with `F.createDependence(...)`.
|
|
9
|
+
* When `F.run(...)` or `F.exec(...)` receives matching dependencies, the requested value is injected back into the flow.
|
|
10
|
+
* If the dependency is missing, the runner throws a missing dependence error.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const database = F.createDependence("database")<string>;
|
|
14
|
+
*
|
|
15
|
+
* F.run(
|
|
16
|
+
* function *() {
|
|
17
|
+
* const connection = yield *F.inject(database);
|
|
18
|
+
* return connection;
|
|
19
|
+
* },
|
|
20
|
+
* { dependencies: { database: "main-db" } },
|
|
21
|
+
* ); // "main-db"
|
|
22
|
+
*
|
|
23
|
+
* F.run(
|
|
24
|
+
* function *() {
|
|
25
|
+
* return yield *F.exec(
|
|
26
|
+
* function *() {
|
|
27
|
+
* const connection = yield *F.inject(database);
|
|
28
|
+
* return connection;
|
|
29
|
+
* },
|
|
30
|
+
* { dependencies: { database: "replica-db" } },
|
|
31
|
+
* );
|
|
32
|
+
* },
|
|
33
|
+
* { dependencies: { database: "main-db" } },
|
|
34
|
+
* ); // "replica-db"
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* - `inject` keeps dependencies explicit in flow definitions
|
|
39
|
+
*
|
|
40
|
+
* @see [`F.run`](https://utils.duplojs.dev/en/v1/api/flow/run) For providing dependencies
|
|
41
|
+
* @see https://utils.duplojs.dev/en/v1/api/flow/inject
|
|
42
|
+
*
|
|
43
|
+
* @namespace F
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
export declare function inject<GenericDependenceHandler extends DependenceHandler>(dependenceHandler: GenericDependenceHandler): Generator<Injection<GenericDependenceHandler>, ReturnType<GenericDependenceHandler>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createInjection } from './theFlow/injection.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* {@include flow/inject/index.md}
|
|
5
|
+
*/
|
|
6
|
+
function* inject(dependenceHandler) {
|
|
7
|
+
let dependence = undefined;
|
|
8
|
+
yield createInjection({
|
|
9
|
+
dependenceHandler,
|
|
10
|
+
inject: (value) => {
|
|
11
|
+
dependence = value;
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
return dependence;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { inject };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const createFlowKind: <GenericName extends string, GenericKindValue extends unknown = unknown>(name: GenericName & import("../string").ForbiddenString<GenericName, "@" | "/">) => import("../common").KindHandler<import("../common").KindDefinition<`@DuplojsUtilsFlow/${GenericName}`, GenericKindValue>>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./theFlow/index.cjs');
|
|
4
|
+
var defer = require('./theFlow/defer.cjs');
|
|
5
|
+
var finalizer = require('./theFlow/finalizer.cjs');
|
|
6
|
+
var kind$1 = require('./kind.cjs');
|
|
7
|
+
var dependence = require('./theFlow/dependence.cjs');
|
|
8
|
+
var _break = require('./theFlow/break.cjs');
|
|
9
|
+
var exit = require('./theFlow/exit.cjs');
|
|
10
|
+
var step = require('./theFlow/step.cjs');
|
|
11
|
+
var injection = require('./theFlow/injection.cjs');
|
|
12
|
+
var justExec = require('../common/justExec.cjs');
|
|
13
|
+
var kind = require('../common/kind.cjs');
|
|
14
|
+
|
|
15
|
+
class MissingDependenceError extends kind.kindHeritage("missing-dependence-error", kind$1.createFlowKind("missing-dependence-error"), Error) {
|
|
16
|
+
dependenceHandler;
|
|
17
|
+
constructor(dependenceHandler) {
|
|
18
|
+
super({}, [`Missing dependence : ${dependence.dependenceHandlerKind.getValue(dependenceHandler)}`]);
|
|
19
|
+
this.dependenceHandler = dependenceHandler;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* {@include flow/run/index.md}
|
|
24
|
+
*/
|
|
25
|
+
function run(theFlow, ...[params]) {
|
|
26
|
+
let result = undefined;
|
|
27
|
+
let deferFunctions = undefined;
|
|
28
|
+
let steps = undefined;
|
|
29
|
+
const generator = typeof theFlow === "function"
|
|
30
|
+
? theFlow(params?.input)
|
|
31
|
+
: index.theFlowKind.getValue(theFlow).run(params?.input);
|
|
32
|
+
if (Symbol.asyncIterator in generator) {
|
|
33
|
+
return (async function () {
|
|
34
|
+
try {
|
|
35
|
+
do {
|
|
36
|
+
result = await generator.next();
|
|
37
|
+
if (result.done === true) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
else if (_break.breakKind.has(result.value)) {
|
|
41
|
+
result = await generator.return(_break.breakKind.getValue(result.value).value);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
else if (exit.exitKind.has(result.value)) {
|
|
45
|
+
result = await generator.return(exit.exitKind.getValue(result.value).value);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
else if (defer.deferKind.has(result.value)) {
|
|
49
|
+
deferFunctions ??= [];
|
|
50
|
+
deferFunctions.push(defer.deferKind.getValue(result.value));
|
|
51
|
+
}
|
|
52
|
+
else if (finalizer.finalizerKind.has(result.value)) {
|
|
53
|
+
deferFunctions ??= [];
|
|
54
|
+
deferFunctions.push(finalizer.finalizerKind.getValue(result.value));
|
|
55
|
+
}
|
|
56
|
+
else if (params?.includeDetails === true
|
|
57
|
+
&& step.stepKind.has(result.value)) {
|
|
58
|
+
steps ??= [];
|
|
59
|
+
steps.push(step.stepKind.getValue(result.value));
|
|
60
|
+
}
|
|
61
|
+
else if (injection.injectionKind.has(result.value)) {
|
|
62
|
+
const injectionProperties = injection.injectionKind.getValue(result.value);
|
|
63
|
+
const dependenceName = dependence.dependenceHandlerKind.getValue(injectionProperties.dependenceHandler);
|
|
64
|
+
if (!params?.dependencies
|
|
65
|
+
|| !(dependenceName in params.dependencies)) {
|
|
66
|
+
throw new MissingDependenceError(injectionProperties.dependenceHandler);
|
|
67
|
+
}
|
|
68
|
+
injectionProperties.inject(params.dependencies[dependenceName]);
|
|
69
|
+
}
|
|
70
|
+
} while (true);
|
|
71
|
+
return params?.includeDetails === true
|
|
72
|
+
? {
|
|
73
|
+
result: result.value,
|
|
74
|
+
steps: steps ?? [],
|
|
75
|
+
}
|
|
76
|
+
: result.value;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
await generator.return(undefined);
|
|
80
|
+
if (deferFunctions) {
|
|
81
|
+
await Promise.all(deferFunctions.map(justExec.justExec));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
do {
|
|
88
|
+
result = generator.next();
|
|
89
|
+
if (result.done === true) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
else if (_break.breakKind.has(result.value)) {
|
|
93
|
+
result = generator.return(_break.breakKind.getValue(result.value).value);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
else if (exit.exitKind.has(result.value)) {
|
|
97
|
+
result = generator.return(exit.exitKind.getValue(result.value).value);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
else if (defer.deferKind.has(result.value)) {
|
|
101
|
+
deferFunctions ??= [];
|
|
102
|
+
deferFunctions.push(defer.deferKind.getValue(result.value));
|
|
103
|
+
}
|
|
104
|
+
else if (finalizer.finalizerKind.has(result.value)) {
|
|
105
|
+
deferFunctions ??= [];
|
|
106
|
+
deferFunctions.push(finalizer.finalizerKind.getValue(result.value));
|
|
107
|
+
}
|
|
108
|
+
else if (params?.includeDetails === true
|
|
109
|
+
&& step.stepKind.has(result.value)) {
|
|
110
|
+
steps ??= [];
|
|
111
|
+
steps.push(step.stepKind.getValue(result.value));
|
|
112
|
+
}
|
|
113
|
+
else if (injection.injectionKind.has(result.value)) {
|
|
114
|
+
const injectionProperties = injection.injectionKind.getValue(result.value);
|
|
115
|
+
const dependenceName = dependence.dependenceHandlerKind.getValue(injectionProperties.dependenceHandler);
|
|
116
|
+
if (!params?.dependencies
|
|
117
|
+
|| !(dependenceName in params.dependencies)) {
|
|
118
|
+
throw new MissingDependenceError(injectionProperties.dependenceHandler);
|
|
119
|
+
}
|
|
120
|
+
injectionProperties.inject(params.dependencies[dependenceName]);
|
|
121
|
+
}
|
|
122
|
+
} while (true);
|
|
123
|
+
return (params?.includeDetails === true
|
|
124
|
+
? {
|
|
125
|
+
result: result.value,
|
|
126
|
+
steps: steps ?? [],
|
|
127
|
+
}
|
|
128
|
+
: result.value);
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
generator.return(undefined);
|
|
132
|
+
if (deferFunctions) {
|
|
133
|
+
deferFunctions.map(justExec.justExec);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
exports.MissingDependenceError = MissingDependenceError;
|
|
139
|
+
exports.run = run;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type SimplifyTopLevel, type IsEqual, type IsExtends, type Or } from "../common";
|
|
2
|
+
import { type TheFlow, type TheFlowFunction, type FlowInput, type WrapFlow, type TheFlowGenerator, type Exit, type Break, type Step, type FlowDependencies, type DependenceHandler, type ExtractFlowGenerator } from "./theFlow";
|
|
3
|
+
type ComputeRunParams<GenericInput extends unknown, GenericDependencies extends Record<string, unknown>> = SimplifyTopLevel<(Or<[
|
|
4
|
+
IsEqual<GenericInput, unknown>,
|
|
5
|
+
IsEqual<GenericInput, never>,
|
|
6
|
+
IsExtends<GenericInput, undefined>
|
|
7
|
+
]> extends true ? {
|
|
8
|
+
input?: GenericInput;
|
|
9
|
+
} : {
|
|
10
|
+
input: GenericInput;
|
|
11
|
+
}) & {
|
|
12
|
+
includeDetails?: boolean;
|
|
13
|
+
} & ({} extends GenericDependencies ? {
|
|
14
|
+
dependencies?: GenericDependencies;
|
|
15
|
+
} : {
|
|
16
|
+
dependencies: GenericDependencies;
|
|
17
|
+
})>;
|
|
18
|
+
export interface FlowDetails<GenericValue extends unknown, GenericStepName extends string> {
|
|
19
|
+
result: GenericValue;
|
|
20
|
+
steps: GenericStepName[];
|
|
21
|
+
}
|
|
22
|
+
export type RunResult<GenericFlow extends TheFlow, GenericIncludeDetails extends boolean = false> = (GenericFlow extends TheFlow<infer InferredFunction> ? InferredFunction extends TheFlowFunction<any, infer InferredGenerator> ? InferredGenerator extends TheFlowGenerator<infer InferredOutput, infer InferredEffect> ? ((InferredEffect extends Exit<infer InferredValue> ? InferredValue : InferredEffect extends Break<infer InferredValue> ? InferredValue : never) | InferredOutput) extends infer InferredResult ? IsEqual<GenericIncludeDetails, true> extends true ? FlowDetails<InferredResult, InferredEffect extends Step<infer InferredName> ? InferredName : never> : InferredResult : never : never : never : never) extends infer InferredResult ? ExtractFlowGenerator<GenericFlow> extends AsyncGenerator ? Promise<InferredResult> : InferredResult : never;
|
|
23
|
+
declare const MissingDependenceError_base: new (params: {
|
|
24
|
+
"@DuplojsUtilsFlow/missing-dependence-error"?: unknown;
|
|
25
|
+
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("../common").Kind<import("../common").KindDefinition<"missing-dependence-error", unknown>, unknown> & import("../common").Kind<import("../common").KindDefinition<"@DuplojsUtilsFlow/missing-dependence-error", unknown>, unknown>;
|
|
26
|
+
export declare class MissingDependenceError extends MissingDependenceError_base {
|
|
27
|
+
dependenceHandler: DependenceHandler;
|
|
28
|
+
constructor(dependenceHandler: DependenceHandler);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Runs a flow and resolves its final result.
|
|
32
|
+
*
|
|
33
|
+
* **Supported call styles:**
|
|
34
|
+
* - Classic with a flow function: `run(theFlow, params?)` -> executes the provided flow function
|
|
35
|
+
* - Classic with a flow instance: `run(theFlow, params?)` -> executes a flow created with `F.create(...)`
|
|
36
|
+
*
|
|
37
|
+
* `run` is the entry point of the flow system.
|
|
38
|
+
* It executes synchronous or asynchronous flows, handles break and exit effects, collects steps when `includeDetails` is enabled, runs deferred and finalizer callbacks, and injects declared dependencies.
|
|
39
|
+
* Use `run` to start a top-level flow and get its final value.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* F.run(
|
|
43
|
+
* function *(input: string) {
|
|
44
|
+
* return input.toUpperCase();
|
|
45
|
+
* },
|
|
46
|
+
* { input: "hello" },
|
|
47
|
+
* ); // "HELLO"
|
|
48
|
+
*
|
|
49
|
+
* F.run(
|
|
50
|
+
* function *() {
|
|
51
|
+
* yield *F.step("check cache");
|
|
52
|
+
* yield *F.breakIf(2, (value) => value === 2);
|
|
53
|
+
* return "done";
|
|
54
|
+
* },
|
|
55
|
+
* { includeDetails: true },
|
|
56
|
+
* ); // { result: 2, steps: ["check cache"] }
|
|
57
|
+
*
|
|
58
|
+
* const service = F.createDependence("service")<string>;
|
|
59
|
+
*
|
|
60
|
+
* F.run(
|
|
61
|
+
* function *() {
|
|
62
|
+
* const currentService = yield *F.inject(service);
|
|
63
|
+
* yield *F.finalizer(() => currentService.toUpperCase());
|
|
64
|
+
* return currentService;
|
|
65
|
+
* },
|
|
66
|
+
* { dependencies: { service: "api" } },
|
|
67
|
+
* ); // "api"
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* - `run` returns a `Promise` when the executed flow is asynchronous
|
|
72
|
+
*
|
|
73
|
+
* @see [`F.exec`](https://utils.duplojs.dev/en/v1/api/flow/exec) To run a nested flow from inside another flow
|
|
74
|
+
* @see https://utils.duplojs.dev/en/v1/api/flow/run
|
|
75
|
+
*
|
|
76
|
+
* @namespace F
|
|
77
|
+
*
|
|
78
|
+
*/
|
|
79
|
+
export declare function run<GenericFlow extends (TheFlowFunction | TheFlow), GenericWrapFlow extends WrapFlow<GenericFlow>, const GenericParams extends ComputeRunParams<FlowInput<GenericWrapFlow>, FlowDependencies<GenericWrapFlow>>>(theFlow: GenericFlow, ...[params]: ({} extends GenericParams ? [params?: GenericParams] : [params: GenericParams])): RunResult<GenericWrapFlow, IsEqual<GenericParams["includeDetails"], true>>;
|
|
80
|
+
export {};
|