@kindgi/flow 0.0.0-bootstrap.0 → 0.1.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/LICENSE +201 -0
- package/README.md +262 -2
- package/dist/define.d.ts +36 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +29 -0
- package/dist/define.js.map +1 -0
- package/dist/errors.d.ts +252 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator.d.ts +69 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +220 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/flow.schema.json +517 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +43 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +1051 -0
- package/dist/loader.js.map +1 -0
- package/dist/scheduler.d.ts +91 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +187 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/types.d.ts +792 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +71 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -4
- package/src/define.ts +44 -0
- package/src/errors.ts +306 -0
- package/src/evaluator.ts +254 -0
- package/src/flow.schema.json +517 -0
- package/src/index.ts +85 -0
- package/src/loader.ts +1382 -0
- package/src/scheduler.ts +274 -0
- package/src/types.ts +853 -0
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import type { EdgeId, FlowId, NodeId } from '@kindgi/types';
|
|
2
|
+
/**
|
|
3
|
+
* Every flow error carries a discriminating `code` so callers can pattern
|
|
4
|
+
* match without inspecting messages. Messages are intended for logs and are
|
|
5
|
+
* not part of the API contract.
|
|
6
|
+
*/
|
|
7
|
+
export type FlowError = SchemaValidationError | DuplicateNodeError | DuplicateEdgeError | UnknownNodeReferenceError | ReservedIdError | CycleError | InvalidPredicateError | InvalidEdgePolicyError | MissingStartEdgeError | LoopBodyMissingStartError | LoopBodyCycleError | LoopBodyEdgeReferenceError | LoopMaxIterationsError | LoopOutputSchemaError | LoopVariantMismatchError | LoopConcurrencyError | InvalidFanoutNodeError | InvalidSubflowNodeError | InvalidMappingError | InvalidFlowOutputError;
|
|
8
|
+
export interface SchemaValidationError {
|
|
9
|
+
readonly code: 'schema-validation-failed';
|
|
10
|
+
readonly message: string;
|
|
11
|
+
readonly flowId?: FlowId;
|
|
12
|
+
/** Ajv-style path list — one per validation failure. */
|
|
13
|
+
readonly issues: readonly {
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
export interface DuplicateNodeError {
|
|
19
|
+
readonly code: 'duplicate-node-id';
|
|
20
|
+
readonly message: string;
|
|
21
|
+
readonly flowId: FlowId;
|
|
22
|
+
readonly nodeId: NodeId;
|
|
23
|
+
}
|
|
24
|
+
export interface DuplicateEdgeError {
|
|
25
|
+
readonly code: 'duplicate-edge-id';
|
|
26
|
+
readonly message: string;
|
|
27
|
+
readonly flowId: FlowId;
|
|
28
|
+
readonly edgeId: EdgeId;
|
|
29
|
+
}
|
|
30
|
+
export interface UnknownNodeReferenceError {
|
|
31
|
+
readonly code: 'unknown-node-reference';
|
|
32
|
+
readonly message: string;
|
|
33
|
+
readonly flowId: FlowId;
|
|
34
|
+
readonly edgeId: EdgeId;
|
|
35
|
+
readonly endpoint: 'from' | 'to';
|
|
36
|
+
readonly referencedId: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ReservedIdError {
|
|
39
|
+
readonly code: 'reserved-id';
|
|
40
|
+
readonly message: string;
|
|
41
|
+
readonly flowId: FlowId;
|
|
42
|
+
readonly nodeId: NodeId;
|
|
43
|
+
}
|
|
44
|
+
export interface CycleError {
|
|
45
|
+
readonly code: 'cycle-detected';
|
|
46
|
+
readonly message: string;
|
|
47
|
+
readonly flowId: FlowId;
|
|
48
|
+
/** Node ids in the cycle, in traversal order. */
|
|
49
|
+
readonly cycle: readonly NodeId[];
|
|
50
|
+
}
|
|
51
|
+
export interface InvalidPredicateError {
|
|
52
|
+
readonly code: 'invalid-predicate';
|
|
53
|
+
readonly message: string;
|
|
54
|
+
readonly flowId: FlowId;
|
|
55
|
+
readonly edgeId: EdgeId;
|
|
56
|
+
readonly reason: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A `FlowEdge.policy` field is structurally valid JSON-schema-wise but
|
|
60
|
+
* violates one of the semantic rules `loadFlow` enforces — e.g.
|
|
61
|
+
* `retry.maxAttempts` out of the `[1, 10]` band, negative `delayMs`, or
|
|
62
|
+
* `backoff: 'exponential'` without a `maxDelayMs` ceiling.
|
|
63
|
+
*
|
|
64
|
+
* The schema layer catches shape errors (wrong types, unknown fields);
|
|
65
|
+
* this error surfaces the semantic ones the schema can't express.
|
|
66
|
+
*/
|
|
67
|
+
export interface InvalidEdgePolicyError {
|
|
68
|
+
readonly code: 'invalid-edge-policy';
|
|
69
|
+
readonly message: string;
|
|
70
|
+
readonly flowId: FlowId;
|
|
71
|
+
readonly edgeId: EdgeId;
|
|
72
|
+
readonly field: 'retry.maxAttempts' | 'retry.delayMs' | 'retry.backoff' | 'retry.maxDelayMs' | 'timeoutMs' | 'concurrencyKey' | 'priority';
|
|
73
|
+
readonly reason: string;
|
|
74
|
+
}
|
|
75
|
+
export interface MissingStartEdgeError {
|
|
76
|
+
readonly code: 'missing-start-edge';
|
|
77
|
+
readonly message: string;
|
|
78
|
+
readonly flowId: FlowId;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A loop node's body has no edge originating at `$loop-start`. Analogous to
|
|
82
|
+
* `MissingStartEdgeError` but scoped to a specific loop body.
|
|
83
|
+
*/
|
|
84
|
+
export interface LoopBodyMissingStartError {
|
|
85
|
+
readonly code: 'loop-body-missing-start-edge';
|
|
86
|
+
readonly message: string;
|
|
87
|
+
readonly flowId: FlowId;
|
|
88
|
+
readonly loopNodeId: NodeId;
|
|
89
|
+
}
|
|
90
|
+
/** A cycle was detected inside a loop node's body sub-flow. */
|
|
91
|
+
export interface LoopBodyCycleError {
|
|
92
|
+
readonly code: 'loop-body-cycle-detected';
|
|
93
|
+
readonly message: string;
|
|
94
|
+
readonly flowId: FlowId;
|
|
95
|
+
readonly loopNodeId: NodeId;
|
|
96
|
+
readonly cycle: readonly NodeId[];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* An edge inside a loop body references an endpoint that isn't a known
|
|
100
|
+
* body node or a `$loop-start` / `$loop-end` sentinel.
|
|
101
|
+
*/
|
|
102
|
+
export interface LoopBodyEdgeReferenceError {
|
|
103
|
+
readonly code: 'loop-body-unknown-node-reference';
|
|
104
|
+
readonly message: string;
|
|
105
|
+
readonly flowId: FlowId;
|
|
106
|
+
readonly loopNodeId: NodeId;
|
|
107
|
+
readonly edgeId: EdgeId;
|
|
108
|
+
readonly endpoint: 'from' | 'to';
|
|
109
|
+
readonly referencedId: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A loop node's `maxIterations` is out of the allowed range. Checked by
|
|
113
|
+
* `loadFlow` in addition to the schema-level bounds.
|
|
114
|
+
*/
|
|
115
|
+
export interface LoopMaxIterationsError {
|
|
116
|
+
readonly code: 'loop-invalid-max-iterations';
|
|
117
|
+
readonly message: string;
|
|
118
|
+
readonly flowId: FlowId;
|
|
119
|
+
readonly loopNodeId: NodeId;
|
|
120
|
+
readonly value: number;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A loop node's `outputSchema` is missing or is not a valid JSON Schema
|
|
124
|
+
* (draft 2020-12). Every loop declares a typed escape contract; a
|
|
125
|
+
* malformed schema is caught at load time so no execution-time surprise
|
|
126
|
+
* ever surfaces to the caller.
|
|
127
|
+
*/
|
|
128
|
+
export interface LoopOutputSchemaError {
|
|
129
|
+
readonly code: 'loop-invalid-output-schema';
|
|
130
|
+
readonly message: string;
|
|
131
|
+
readonly flowId: FlowId;
|
|
132
|
+
readonly loopNodeId: NodeId;
|
|
133
|
+
/** Meta-schema validation issues (Ajv-style path + message). */
|
|
134
|
+
readonly issues: readonly {
|
|
135
|
+
readonly path: string;
|
|
136
|
+
readonly message: string;
|
|
137
|
+
}[];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* A loop node declares fields that belong to the wrong variant. Examples:
|
|
141
|
+
* - `loopKind: 'foreach'` with an `exitCondition` present.
|
|
142
|
+
* - `loopKind: 'while'` with an `iterateOver` present.
|
|
143
|
+
* - `loopKind: 'foreach'` missing `iterateOver`.
|
|
144
|
+
* - `loopKind: 'while'` missing `exitCondition`.
|
|
145
|
+
*
|
|
146
|
+
* Enforced at load time so the executor can trust the discriminated union.
|
|
147
|
+
*/
|
|
148
|
+
export interface LoopVariantMismatchError {
|
|
149
|
+
readonly code: 'loop-variant-mismatch';
|
|
150
|
+
readonly message: string;
|
|
151
|
+
readonly flowId: FlowId;
|
|
152
|
+
readonly loopNodeId: NodeId;
|
|
153
|
+
readonly loopKind: 'while' | 'foreach';
|
|
154
|
+
readonly problem: 'while-missing-exit-condition' | 'while-has-iterate-over' | 'while-has-invalid-evaluation-timing' | 'while-has-concurrency' | 'foreach-missing-iterate-over' | 'foreach-has-exit-condition' | 'foreach-has-evaluation-timing';
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* A foreach loop's `concurrency` field is out of the allowed band. Bounds:
|
|
158
|
+
* - Must be a positive integer.
|
|
159
|
+
* - `1 ≤ concurrency ≤ 32` — the upper cap is a safety limit.
|
|
160
|
+
* - `concurrency ≤ maxIterations` — otherwise pointless.
|
|
161
|
+
*
|
|
162
|
+
* The 32 cap prevents accidents (a stray `concurrency: 1000` spawning a
|
|
163
|
+
* thousand simultaneous handlers). The cap is fixed; adaptive or
|
|
164
|
+
* rate-aware concurrency is not part of this primitive.
|
|
165
|
+
*/
|
|
166
|
+
export interface LoopConcurrencyError {
|
|
167
|
+
readonly code: 'loop-invalid-concurrency';
|
|
168
|
+
readonly message: string;
|
|
169
|
+
readonly flowId: FlowId;
|
|
170
|
+
readonly loopNodeId: NodeId;
|
|
171
|
+
readonly value: number;
|
|
172
|
+
readonly reason: 'not-integer' | 'below-minimum' | 'exceeds-max-iterations' | 'exceeds-cap';
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* A `subgraph` node is structurally valid JSON-schema-wise but violates
|
|
176
|
+
* one of the semantic rules `loadFlow` enforces — e.g. malformed `flowRef`,
|
|
177
|
+
* non-exact semver, an `inputMapping` value that isn't a valid Operand,
|
|
178
|
+
* an `outputSchema` that fails to compile against the draft-2020-12
|
|
179
|
+
* meta-schema, or an unknown `convergence` mode.
|
|
180
|
+
*
|
|
181
|
+
* `field` narrows the location of the failure so callers can attribute
|
|
182
|
+
* without matching on the message.
|
|
183
|
+
*/
|
|
184
|
+
export interface InvalidSubflowNodeError {
|
|
185
|
+
readonly code: 'invalid-subgraph-node';
|
|
186
|
+
readonly message: string;
|
|
187
|
+
readonly flowId: FlowId;
|
|
188
|
+
readonly subgraphNodeId: NodeId;
|
|
189
|
+
readonly field: 'flowRef' | 'flowRef.flowId' | 'flowRef.version' | 'inputMapping' | 'output-schema' | 'convergence';
|
|
190
|
+
readonly reason: string;
|
|
191
|
+
/** Meta-schema issues, when `field === 'output-schema'`. */
|
|
192
|
+
readonly issues?: readonly {
|
|
193
|
+
readonly path: string;
|
|
194
|
+
readonly message: string;
|
|
195
|
+
}[];
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* A `fanout` node is structurally valid JSON-schema-wise but violates one
|
|
199
|
+
* of the semantic rules `loadFlow` enforces — e.g. duplicate `branchId`,
|
|
200
|
+
* concurrency out of `[1, branches.length]`, an unknown convergence mode,
|
|
201
|
+
* or a per-branch `outputSchema` that fails to compile against the
|
|
202
|
+
* draft-2020-12 meta-schema.
|
|
203
|
+
*
|
|
204
|
+
* `field` narrows the location of the failure so callers can attribute
|
|
205
|
+
* without matching on the message.
|
|
206
|
+
*/
|
|
207
|
+
export interface InvalidFanoutNodeError {
|
|
208
|
+
readonly code: 'invalid-fanout-node';
|
|
209
|
+
readonly message: string;
|
|
210
|
+
readonly flowId: FlowId;
|
|
211
|
+
readonly fanoutNodeId: NodeId;
|
|
212
|
+
readonly field: 'branches' | 'branch-id' | 'branch-handler' | 'branch-output-schema' | 'concurrency' | 'convergence';
|
|
213
|
+
readonly reason: string;
|
|
214
|
+
/** Branch id at fault, when the failure attribution is per-branch. */
|
|
215
|
+
readonly branchId?: string;
|
|
216
|
+
/** Meta-schema issues, when `field === 'branch-output-schema'`. */
|
|
217
|
+
readonly issues?: readonly {
|
|
218
|
+
readonly path: string;
|
|
219
|
+
readonly message: string;
|
|
220
|
+
}[];
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* A leaf `inputMapping` or the flow `output.mapping` entry can't be
|
|
224
|
+
* resolved as written (schema-version 1.8.0+): its path names a node the
|
|
225
|
+
* flow doesn't have, maps the node's own output, or uses a loop-only root
|
|
226
|
+
* (`iterationIndex` / `iterationOutput`). A path with an unknown root
|
|
227
|
+
* fails the schema step instead (`schema-validation-failed`).
|
|
228
|
+
*/
|
|
229
|
+
export interface InvalidMappingError {
|
|
230
|
+
readonly code: 'invalid-mapping';
|
|
231
|
+
readonly message: string;
|
|
232
|
+
readonly flowId: FlowId;
|
|
233
|
+
/** The leaf node whose `inputMapping` is invalid; absent for the flow's `output`. */
|
|
234
|
+
readonly nodeId?: NodeId;
|
|
235
|
+
/** The mapping key whose operand is invalid. */
|
|
236
|
+
readonly key: string;
|
|
237
|
+
readonly reason: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* A flow's `output.schema` is not a valid JSON Schema (draft 2020-12).
|
|
241
|
+
*/
|
|
242
|
+
export interface InvalidFlowOutputError {
|
|
243
|
+
readonly code: 'invalid-flow-output';
|
|
244
|
+
readonly message: string;
|
|
245
|
+
readonly flowId: FlowId;
|
|
246
|
+
/** Meta-schema validation issues (Ajv-style path + message). */
|
|
247
|
+
readonly issues: readonly {
|
|
248
|
+
readonly path: string;
|
|
249
|
+
readonly message: string;
|
|
250
|
+
}[];
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { NodeId } from '@kindgi/types';
|
|
2
|
+
import type { Expr, Mapping } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The evaluation environment. Passed by the kernel at edge dispatch time —
|
|
5
|
+
* one instance per edge evaluation — and when resolving a `Mapping`.
|
|
6
|
+
* Consumers should treat every branch as read-only.
|
|
7
|
+
*
|
|
8
|
+
* Every root is optional at construction; a missing root resolves any
|
|
9
|
+
* dependent path to MISSING (`MISSING_PATH`), which composes cleanly with
|
|
10
|
+
* `exists` and `notExists` predicates.
|
|
11
|
+
*/
|
|
12
|
+
export interface EvalEnv {
|
|
13
|
+
readonly runInput?: unknown;
|
|
14
|
+
readonly state?: unknown;
|
|
15
|
+
/**
|
|
16
|
+
* Outputs of previously-completed nodes, keyed by NodeId. Only nodes whose
|
|
17
|
+
* `step.completed` entry exists in the journal appear here — a fan-in edge
|
|
18
|
+
* whose predicate references a not-yet-completed sibling resolves that
|
|
19
|
+
* path to MISSING.
|
|
20
|
+
*/
|
|
21
|
+
readonly nodeOutputs?: ReadonlyMap<NodeId, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Only populated when evaluating a loop node's `exitCondition`. `undefined`
|
|
24
|
+
* outside that context; predicates referencing this root then resolve to
|
|
25
|
+
* MISSING (composes cleanly with `exists` / `notExists`).
|
|
26
|
+
*/
|
|
27
|
+
readonly iterationIndex?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Only populated when evaluating a loop node's `exitCondition`. Holds
|
|
30
|
+
* the just-completed iteration's `$loop-end` output (or the previous
|
|
31
|
+
* iteration's output for while+before at iteration i>0; null for
|
|
32
|
+
* while+before iteration 0).
|
|
33
|
+
*/
|
|
34
|
+
readonly iterationOutput?: unknown;
|
|
35
|
+
}
|
|
36
|
+
/** Distinguishing "resolved to `undefined`" from "path does not exist". */
|
|
37
|
+
declare const MISSING: unique symbol;
|
|
38
|
+
type Resolved = unknown | typeof MISSING;
|
|
39
|
+
/**
|
|
40
|
+
* Evaluate a predicate expression against an environment.
|
|
41
|
+
*
|
|
42
|
+
* Semantics summary:
|
|
43
|
+
* - Comparisons on missing operands (path resolves to MISSING) → false.
|
|
44
|
+
* - `exists` on MISSING → false; on `undefined` value at a real path → true.
|
|
45
|
+
* - `truthy` / `falsy` use the JS truthiness rules on the resolved value;
|
|
46
|
+
* MISSING is treated as falsy.
|
|
47
|
+
* - `in` / `notIn` require `set` to be an array; a non-array `set` → false.
|
|
48
|
+
* - `and` / `or` are short-circuiting; empty children are rejected at load time.
|
|
49
|
+
*
|
|
50
|
+
* The evaluator is intentionally total — it never throws for a well-formed
|
|
51
|
+
* expression, so kernel edge evaluation cannot fail due to predicate execution.
|
|
52
|
+
*/
|
|
53
|
+
export declare function evaluateExpr(expr: Expr, env: EvalEnv): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve a `Mapping` against an environment: literals as given, paths
|
|
56
|
+
* via `resolvePath`. A path that doesn't resolve omits its key — the
|
|
57
|
+
* result never carries a mapped key whose value is missing. Total, like
|
|
58
|
+
* `evaluateExpr`: it never throws for a well-formed mapping.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveMapping(mapping: Mapping, env: EvalEnv): Record<string, unknown>;
|
|
61
|
+
export declare function resolvePath(path: string, env: EvalEnv): Resolved;
|
|
62
|
+
/**
|
|
63
|
+
* Distinguishes "path resolved but value was undefined" from "path did not
|
|
64
|
+
* exist at all". Exported so tests and downstream diagnostics can identify
|
|
65
|
+
* the missing marker without depending on a private symbol.
|
|
66
|
+
*/
|
|
67
|
+
export declare const MISSING_PATH: typeof MISSING;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../src/evaluator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,IAAI,EAAkB,OAAO,EAAW,MAAM,YAAY,CAAC;AAEzE;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,2EAA2E;AAC3E,QAAA,MAAM,OAAO,eAAmC,CAAC;AACjD,KAAK,QAAQ,GAAG,OAAO,GAAG,OAAO,OAAO,CAAC;AAEzC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CA2B9D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOtF;AAwED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,CA4BhE;AA+CD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,OAAiB,CAAC"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
/** Distinguishing "resolved to `undefined`" from "path does not exist". */
|
|
4
|
+
const MISSING = Symbol('flow.evaluator.missing');
|
|
5
|
+
/**
|
|
6
|
+
* Evaluate a predicate expression against an environment.
|
|
7
|
+
*
|
|
8
|
+
* Semantics summary:
|
|
9
|
+
* - Comparisons on missing operands (path resolves to MISSING) → false.
|
|
10
|
+
* - `exists` on MISSING → false; on `undefined` value at a real path → true.
|
|
11
|
+
* - `truthy` / `falsy` use the JS truthiness rules on the resolved value;
|
|
12
|
+
* MISSING is treated as falsy.
|
|
13
|
+
* - `in` / `notIn` require `set` to be an array; a non-array `set` → false.
|
|
14
|
+
* - `and` / `or` are short-circuiting; empty children are rejected at load time.
|
|
15
|
+
*
|
|
16
|
+
* The evaluator is intentionally total — it never throws for a well-formed
|
|
17
|
+
* expression, so kernel edge evaluation cannot fail due to predicate execution.
|
|
18
|
+
*/
|
|
19
|
+
export function evaluateExpr(expr, env) {
|
|
20
|
+
switch (expr.op) {
|
|
21
|
+
case 'eq':
|
|
22
|
+
case 'ne':
|
|
23
|
+
case 'lt':
|
|
24
|
+
case 'lte':
|
|
25
|
+
case 'gt':
|
|
26
|
+
case 'gte':
|
|
27
|
+
return compare(expr.op, resolveOperand(expr.left, env), resolveOperand(expr.right, env));
|
|
28
|
+
case 'in':
|
|
29
|
+
case 'notIn':
|
|
30
|
+
return evalMembership(expr.op, expr, env);
|
|
31
|
+
case 'exists':
|
|
32
|
+
return resolveOperand(expr.value, env) !== MISSING;
|
|
33
|
+
case 'notExists':
|
|
34
|
+
return resolveOperand(expr.value, env) === MISSING;
|
|
35
|
+
case 'truthy':
|
|
36
|
+
return evalTruthy(resolveOperand(expr.value, env));
|
|
37
|
+
case 'falsy':
|
|
38
|
+
return evalFalsy(resolveOperand(expr.value, env));
|
|
39
|
+
case 'and':
|
|
40
|
+
return expr.children.every((c) => evaluateExpr(c, env));
|
|
41
|
+
case 'or':
|
|
42
|
+
return expr.children.some((c) => evaluateExpr(c, env));
|
|
43
|
+
case 'not':
|
|
44
|
+
return !evaluateExpr(expr.child, env);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a `Mapping` against an environment: literals as given, paths
|
|
49
|
+
* via `resolvePath`. A path that doesn't resolve omits its key — the
|
|
50
|
+
* result never carries a mapped key whose value is missing. Total, like
|
|
51
|
+
* `evaluateExpr`: it never throws for a well-formed mapping.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveMapping(mapping, env) {
|
|
54
|
+
const out = {};
|
|
55
|
+
for (const [key, operand] of Object.entries(mapping)) {
|
|
56
|
+
const value = resolveOperand(operand, env);
|
|
57
|
+
if (value !== MISSING)
|
|
58
|
+
out[key] = value;
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
function evalMembership(op, expr, env) {
|
|
63
|
+
const value = resolveOperand(expr.value, env);
|
|
64
|
+
const set = resolveOperand(expr.set, env);
|
|
65
|
+
if (value === MISSING || set === MISSING)
|
|
66
|
+
return false;
|
|
67
|
+
if (!Array.isArray(set))
|
|
68
|
+
return false;
|
|
69
|
+
const found = set.some((item) => deepEqual(item, value));
|
|
70
|
+
return op === 'in' ? found : !found;
|
|
71
|
+
}
|
|
72
|
+
function evalTruthy(v) {
|
|
73
|
+
if (v === MISSING)
|
|
74
|
+
return false;
|
|
75
|
+
return Boolean(v);
|
|
76
|
+
}
|
|
77
|
+
function evalFalsy(v) {
|
|
78
|
+
if (v === MISSING)
|
|
79
|
+
return true;
|
|
80
|
+
return !v;
|
|
81
|
+
}
|
|
82
|
+
function compare(op, left, right) {
|
|
83
|
+
if (op === 'eq' || op === 'ne')
|
|
84
|
+
return compareEquality(op, left, right);
|
|
85
|
+
return compareOrdering(op, left, right);
|
|
86
|
+
}
|
|
87
|
+
function compareEquality(op, left, right) {
|
|
88
|
+
if (left === MISSING || right === MISSING)
|
|
89
|
+
return op === 'ne' ? left !== right : false;
|
|
90
|
+
const equal = deepEqual(left, right);
|
|
91
|
+
return op === 'eq' ? equal : !equal;
|
|
92
|
+
}
|
|
93
|
+
function compareOrdering(op, left, right) {
|
|
94
|
+
if (left === MISSING || right === MISSING)
|
|
95
|
+
return false;
|
|
96
|
+
if (typeof left !== typeof right)
|
|
97
|
+
return false;
|
|
98
|
+
if (typeof left !== 'number' && typeof left !== 'string')
|
|
99
|
+
return false;
|
|
100
|
+
const l = left;
|
|
101
|
+
const r = right;
|
|
102
|
+
switch (op) {
|
|
103
|
+
case 'lt':
|
|
104
|
+
return l < r;
|
|
105
|
+
case 'lte':
|
|
106
|
+
return l <= r;
|
|
107
|
+
case 'gt':
|
|
108
|
+
return l > r;
|
|
109
|
+
case 'gte':
|
|
110
|
+
return l >= r;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function resolveOperand(operand, env) {
|
|
114
|
+
if (isLiteral(operand))
|
|
115
|
+
return operand.literal;
|
|
116
|
+
return resolvePath(operand.path, env);
|
|
117
|
+
}
|
|
118
|
+
function isLiteral(operand) {
|
|
119
|
+
return 'literal' in operand;
|
|
120
|
+
}
|
|
121
|
+
// Exported for tests and diagnostics; keep small and predictable.
|
|
122
|
+
export function resolvePath(path, env) {
|
|
123
|
+
const segments = path.split('.');
|
|
124
|
+
const [root, ...rest] = segments;
|
|
125
|
+
if (root === undefined)
|
|
126
|
+
return MISSING;
|
|
127
|
+
if (root === 'runInput') {
|
|
128
|
+
return walk(env.runInput, rest);
|
|
129
|
+
}
|
|
130
|
+
if (root === 'state') {
|
|
131
|
+
return walk(env.state, rest);
|
|
132
|
+
}
|
|
133
|
+
if (root === 'nodeOutputs') {
|
|
134
|
+
const [nodeId, ...tail] = rest;
|
|
135
|
+
if (nodeId === undefined || nodeId === '')
|
|
136
|
+
return MISSING;
|
|
137
|
+
if (env.nodeOutputs === undefined)
|
|
138
|
+
return MISSING;
|
|
139
|
+
if (!env.nodeOutputs.has(nodeId))
|
|
140
|
+
return MISSING;
|
|
141
|
+
return walk(env.nodeOutputs.get(nodeId), tail);
|
|
142
|
+
}
|
|
143
|
+
if (root === 'iterationIndex') {
|
|
144
|
+
if (env.iterationIndex === undefined)
|
|
145
|
+
return MISSING;
|
|
146
|
+
if (rest.length > 0)
|
|
147
|
+
return MISSING;
|
|
148
|
+
return env.iterationIndex;
|
|
149
|
+
}
|
|
150
|
+
if (root === 'iterationOutput') {
|
|
151
|
+
if (env.iterationOutput === undefined)
|
|
152
|
+
return MISSING;
|
|
153
|
+
return walk(env.iterationOutput, rest);
|
|
154
|
+
}
|
|
155
|
+
return MISSING;
|
|
156
|
+
}
|
|
157
|
+
function walk(base, segments) {
|
|
158
|
+
let current = base;
|
|
159
|
+
if (segments.length === 0)
|
|
160
|
+
return current === undefined ? MISSING : current;
|
|
161
|
+
for (const seg of segments) {
|
|
162
|
+
if (current === null || current === undefined)
|
|
163
|
+
return MISSING;
|
|
164
|
+
if (typeof current !== 'object')
|
|
165
|
+
return MISSING;
|
|
166
|
+
const asRecord = current;
|
|
167
|
+
if (!(seg in asRecord))
|
|
168
|
+
return MISSING;
|
|
169
|
+
current = asRecord[seg];
|
|
170
|
+
}
|
|
171
|
+
return current === undefined ? MISSING : current;
|
|
172
|
+
}
|
|
173
|
+
/** Structural JSON equality. Handles primitives, arrays, and plain objects. */
|
|
174
|
+
function deepEqual(a, b) {
|
|
175
|
+
if (a === b)
|
|
176
|
+
return true;
|
|
177
|
+
if (a === null || b === null)
|
|
178
|
+
return false;
|
|
179
|
+
if (typeof a !== typeof b)
|
|
180
|
+
return false;
|
|
181
|
+
if (typeof a !== 'object')
|
|
182
|
+
return false;
|
|
183
|
+
if (Array.isArray(a) || Array.isArray(b))
|
|
184
|
+
return arrayEqual(a, b);
|
|
185
|
+
return objectEqual(a, b);
|
|
186
|
+
}
|
|
187
|
+
function arrayEqual(a, b) {
|
|
188
|
+
if (!Array.isArray(a) || !Array.isArray(b))
|
|
189
|
+
return false;
|
|
190
|
+
if (a.length !== b.length)
|
|
191
|
+
return false;
|
|
192
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
193
|
+
if (!deepEqual(a[i], b[i]))
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
function objectEqual(a, b) {
|
|
199
|
+
const ka = Object.keys(a).sort();
|
|
200
|
+
const kb = Object.keys(b).sort();
|
|
201
|
+
if (ka.length !== kb.length)
|
|
202
|
+
return false;
|
|
203
|
+
for (let i = 0; i < ka.length; i += 1)
|
|
204
|
+
if (ka[i] !== kb[i])
|
|
205
|
+
return false;
|
|
206
|
+
const aRec = a;
|
|
207
|
+
const bRec = b;
|
|
208
|
+
for (const k of ka) {
|
|
209
|
+
if (!deepEqual(aRec[k], bRec[k]))
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Distinguishes "path resolved but value was undefined" from "path did not
|
|
216
|
+
* exist at all". Exported so tests and downstream diagnostics can identify
|
|
217
|
+
* the missing marker without depending on a private symbol.
|
|
218
|
+
*/
|
|
219
|
+
export const MISSING_PATH = MISSING;
|
|
220
|
+
//# sourceMappingURL=evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../src/evaluator.ts"],"names":[],"mappings":"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"}
|