@particle-academy/fancy-flow 0.14.0 → 0.15.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/README.md +48 -0
- package/dist/{capabilities-D-V9Rxv1.d.cts → capabilities-BEbLqnJU.d.cts} +1 -1
- package/dist/{capabilities-B6r1Snfj.d.ts → capabilities-CI3gw0C7.d.ts} +1 -1
- package/dist/chunk-UEOE6B52.js +39 -0
- package/dist/chunk-UEOE6B52.js.map +1 -0
- package/dist/{chunk-7U3EP4Q5.js → chunk-ZQBWPYTI.js} +5 -2
- package/dist/chunk-ZQBWPYTI.js.map +1 -0
- package/dist/engine.cjs +299 -0
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +205 -27
- package/dist/engine.d.ts +205 -27
- package/dist/engine.js +258 -2
- package/dist/engine.js.map +1 -1
- package/dist/index.cjs +45 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/llm/vercel-ai.d.cts +2 -2
- package/dist/llm/vercel-ai.d.ts +2 -2
- package/dist/pause-9iT4tCEV.d.cts +96 -0
- package/dist/pause-9iT4tCEV.d.ts +96 -0
- package/dist/registry/index.d.cts +6 -5
- package/dist/registry/index.d.ts +6 -5
- package/dist/registry.cjs +45 -0
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +2 -1
- package/dist/run-flow-ChBi6q-W.d.ts +35 -0
- package/dist/run-flow-VKm57Hcj.d.cts +35 -0
- package/dist/runtime/index.d.cts +3 -3
- package/dist/runtime/index.d.ts +3 -3
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/{types-H60tQAxr.d.cts → types-D_jOR3Z2.d.cts} +12 -1
- package/dist/{types-CnnKPnpt.d.ts → types-NerkPtHS.d.ts} +12 -1
- package/dist/{types-fc0fFKkf.d.cts → types-sOmpCitB.d.cts} +1 -1
- package/dist/{types-fc0fFKkf.d.ts → types-sOmpCitB.d.ts} +1 -1
- package/dist/ux.d.cts +3 -2
- package/dist/ux.d.ts +3 -2
- package/package.json +1 -1
- package/dist/chunk-7U3EP4Q5.js.map +0 -1
package/dist/engine.d.cts
CHANGED
|
@@ -1,37 +1,215 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-VKm57Hcj.cjs';
|
|
2
|
+
import { N as NodeExecutor } from './types-sOmpCitB.cjs';
|
|
3
|
+
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, E as ExecutorRegistry, a as FlowEdge, F as FlowGraph, b as FlowNode, c as FlowNodeData, d as FlowNodeKind, e as NodeRunStatus, f as NoteNodeData, O as OutputNodeData, P as PortDescriptor, R as RunEvent, S as SubgraphNodeData, T as TriggerNodeData } from './types-sOmpCitB.cjs';
|
|
4
|
+
import { P as PauseAwaiting } from './pause-9iT4tCEV.cjs';
|
|
5
|
+
export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.cjs';
|
|
3
6
|
import '@xyflow/react';
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The node package manifest — what a marketplace node declares about itself.
|
|
10
|
+
*
|
|
11
|
+
* A node is not one artifact. It is a kind definition (palette entry, config
|
|
12
|
+
* schema, ports, canvas renderer) plus an executor for EACH runtime the
|
|
13
|
+
* consumer actually runs. A package shipping only a TS executor is unusable to
|
|
14
|
+
* anyone executing on PHP, and today that is invisible until a run fails.
|
|
15
|
+
*
|
|
16
|
+
* So the manifest states which runtimes it implements, and the CLI checks that
|
|
17
|
+
* against the host before installing rather than after. Requested by the MOIC
|
|
18
|
+
* Suite consumer (fancy-flow#2 §2), who runs the editor in TS and executes in
|
|
19
|
+
* PHP and hit exactly this.
|
|
20
|
+
*
|
|
21
|
+
* The manifest is data, not code: the registry, the CLI, and the MCP all read
|
|
22
|
+
* it without executing anything a package author wrote.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** The current manifest schema version. Bump only on a breaking shape change. */
|
|
26
|
+
declare const NODE_MANIFEST_SCHEMA_VERSION = 1;
|
|
27
|
+
/**
|
|
28
|
+
* A runtime a node can implement.
|
|
29
|
+
*
|
|
30
|
+
* Open rather than a closed union — the PHP and Node twins are what exist
|
|
31
|
+
* today, but the point of a manifest is that a runtime we haven't written can
|
|
32
|
+
* declare itself without a release here.
|
|
33
|
+
*/
|
|
34
|
+
type NodeRuntimeId = "ts" | "php" | (string & {});
|
|
35
|
+
type NodePackageManifest = {
|
|
36
|
+
/** Must equal `NODE_MANIFEST_SCHEMA_VERSION`. */
|
|
37
|
+
schemaVersion: number;
|
|
38
|
+
/** Package name, as installed (`@acme/fancy-flow-salesforce`). */
|
|
39
|
+
name: string;
|
|
40
|
+
/**
|
|
41
|
+
* The canonical kind id this package provides — namespaced, and the string
|
|
42
|
+
* that gets persisted into every document using it.
|
|
43
|
+
*/
|
|
44
|
+
kind: string;
|
|
45
|
+
/** Semver range of fancy-flow this node's contract targets. */
|
|
46
|
+
fancyFlow: string;
|
|
47
|
+
/**
|
|
48
|
+
* Per-runtime entrypoints. TS is a module path within the package; PHP is a
|
|
49
|
+
* Composer requirement, because the two ecosystems install differently and
|
|
50
|
+
* pretending otherwise just moves the problem into the CLI.
|
|
51
|
+
*/
|
|
52
|
+
runtimes: Partial<Record<NodeRuntimeId, string>>;
|
|
53
|
+
/**
|
|
54
|
+
* Host capabilities this node needs wired before it can run — `llm`,
|
|
55
|
+
* `workflow_resolver`, `document`, or a host-specific one.
|
|
56
|
+
*
|
|
57
|
+
* Declared so the CLI can tell an author what to wire BEFORE install, rather
|
|
58
|
+
* than the node silently no-opping or crashing mid-run.
|
|
59
|
+
*/
|
|
60
|
+
capabilities?: string[];
|
|
61
|
+
/**
|
|
62
|
+
* Path to this node's golden fixtures, relative to the package root.
|
|
63
|
+
*
|
|
64
|
+
* REQUIRED. Every runtime the package claims runs these same cases, which is
|
|
65
|
+
* what makes "behaves identically on both runtimes" verified rather than
|
|
66
|
+
* asserted. See `./fixtures`.
|
|
67
|
+
*/
|
|
68
|
+
fixtures: string;
|
|
69
|
+
/** Declares the node halts for a person. Mirrors `NodeKindDefinition`. */
|
|
70
|
+
pausesForHuman?: PauseAwaiting;
|
|
71
|
+
/** One-line summary — what `search_nodes` matches against. */
|
|
72
|
+
description?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Assigned by the registry, never by the author. Present in a manifest being
|
|
75
|
+
* submitted for publication, it is a claim to a trust signal the author does
|
|
76
|
+
* not get to make.
|
|
77
|
+
*/
|
|
78
|
+
verified?: boolean;
|
|
79
|
+
};
|
|
80
|
+
type ManifestProblem = {
|
|
81
|
+
level: "error" | "warning";
|
|
82
|
+
field: string;
|
|
83
|
+
message: string;
|
|
84
|
+
};
|
|
85
|
+
type ManifestValidation = {
|
|
86
|
+
/** True when there are no `error`-level problems. Warnings do not block. */
|
|
16
87
|
ok: boolean;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/** Error captured if any node threw. */
|
|
20
|
-
error?: string;
|
|
88
|
+
manifest?: NodePackageManifest;
|
|
89
|
+
problems: ManifestProblem[];
|
|
21
90
|
};
|
|
22
91
|
/**
|
|
23
|
-
*
|
|
92
|
+
* Validate a manifest read from disk or a registry.
|
|
93
|
+
*
|
|
94
|
+
* Returns every problem rather than throwing on the first, because an author
|
|
95
|
+
* fixing a package wants the whole list — a validator that reveals one error
|
|
96
|
+
* per run turns a five-minute fix into five round trips.
|
|
97
|
+
*/
|
|
98
|
+
declare function validateNodeManifest(input: unknown): ManifestValidation;
|
|
99
|
+
/**
|
|
100
|
+
* Check a node against the runtimes a host actually executes on.
|
|
101
|
+
*
|
|
102
|
+
* This is what makes a TS-only package visible to someone running PHP BEFORE
|
|
103
|
+
* they install it rather than at the first run. A missing runtime is an error,
|
|
104
|
+
* not a warning: the node genuinely cannot execute there.
|
|
105
|
+
*/
|
|
106
|
+
declare function checkRuntimeSupport(manifest: Pick<NodePackageManifest, "kind" | "runtimes">, hostRuntimes: readonly string[]): ManifestProblem[];
|
|
107
|
+
/**
|
|
108
|
+
* Check that every capability a node needs is actually wired.
|
|
109
|
+
*
|
|
110
|
+
* Pass `capabilityStatus()` from the host. Unwired capabilities are a warning
|
|
111
|
+
* rather than an error — install is the right time to learn what to wire, not
|
|
112
|
+
* a reason to refuse, since wiring usually happens after install.
|
|
113
|
+
*/
|
|
114
|
+
declare function checkCapabilities(manifest: Pick<NodePackageManifest, "kind" | "capabilities">, available: Readonly<Record<string, boolean>>): ManifestProblem[];
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Golden fixtures — the parity guarantee, and a publishing requirement.
|
|
118
|
+
*
|
|
119
|
+
* Every runtime a node package claims runs these same JSON cases. That is what
|
|
120
|
+
* makes "this node behaves identically on TS and PHP" verified rather than
|
|
121
|
+
* asserted, and it is the one thing a loose collection of repos can never
|
|
122
|
+
* offer.
|
|
123
|
+
*
|
|
124
|
+
* WHY IT IS REQUIRED RATHER THAN ENCOURAGED: cross-runtime drift does not fail
|
|
125
|
+
* loudly. The 0.9.0 port-resolution divergence produced flows that routed
|
|
126
|
+
* correctly in the editor and silently down one path on the server — status
|
|
127
|
+
* `completed`, no error, no exception, nothing to alert on. A guarantee that
|
|
128
|
+
* only holds when an author opts in is not a guarantee.
|
|
24
129
|
*
|
|
25
|
-
*
|
|
26
|
-
* connected ports. Decision nodes (or any executor that returns `{ branch:
|
|
27
|
-
* 'true' }`) can short-circuit specific output ports — only edges leaving
|
|
28
|
-
* an "active" port propagate to downstream nodes.
|
|
130
|
+
* WHAT A CASE ASSERTS, and why it matters more than it looks:
|
|
29
131
|
*
|
|
30
|
-
*
|
|
132
|
+
* A fixture asserts THE DOWNSTREAM NODE EXECUTED — not the port the node
|
|
133
|
+
* recorded. The distinction is the whole lesson of that incident. A test
|
|
134
|
+
* reading back `outputs.router.__port` stays green while no edge fires and
|
|
135
|
+
* the run halts at the branch: the node faithfully recorded its choice, and
|
|
136
|
+
* nothing downstream ever ran. So the runner wires a real probe to every
|
|
137
|
+
* declared port and reports which probes actually executed.
|
|
138
|
+
*
|
|
139
|
+
* The format is plain JSON with no expressions or callbacks, so the PHP runner
|
|
140
|
+
* executes byte-identical cases without an embedded JS engine.
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/** What a case expects to have happened. */
|
|
144
|
+
type FixtureExpectation = {
|
|
145
|
+
/**
|
|
146
|
+
* Output ports whose downstream node must have executed — the assertion that
|
|
147
|
+
* catches routing drift. Order-insensitive; the set must match exactly, so a
|
|
148
|
+
* node that fires an extra port fails just as loudly as one that fires none.
|
|
149
|
+
*/
|
|
150
|
+
ports?: string[];
|
|
151
|
+
/** The value carried downstream, deep-compared when present. */
|
|
152
|
+
value?: unknown;
|
|
153
|
+
/** The run halted for a person. */
|
|
154
|
+
pause?: {
|
|
155
|
+
awaiting: PauseAwaiting;
|
|
156
|
+
detail?: unknown;
|
|
157
|
+
};
|
|
158
|
+
/** The run failed, and the message contains this substring. */
|
|
159
|
+
error?: string;
|
|
160
|
+
};
|
|
161
|
+
type FixtureCase = {
|
|
162
|
+
/** Human-readable, and what a failure report names. */
|
|
163
|
+
name: string;
|
|
164
|
+
/** Config for the node under test — drives config-derived ports. */
|
|
165
|
+
config?: Record<string, unknown>;
|
|
166
|
+
/**
|
|
167
|
+
* The node's resolved output ports, stated rather than derived.
|
|
168
|
+
*
|
|
169
|
+
* NOT a convenience. TS derives config-driven ports by running a JavaScript
|
|
170
|
+
* function (`switch_case`'s cases, `llm_router`'s routes); PHP cannot, and
|
|
171
|
+
* falls back to the kind's static declaration. Left there, the identical
|
|
172
|
+
* fixture would build a DIFFERENT graph on each runtime — the fixtures would
|
|
173
|
+
* silently stop comparing like with like, which is the exact failure they
|
|
174
|
+
* exist to catch.
|
|
175
|
+
*
|
|
176
|
+
* So a case states its ports the same way an exported document does (see
|
|
177
|
+
* 0.10.1, "serialize resolved ports"), and both runners honour it. Omit it
|
|
178
|
+
* only for a node whose ports are static.
|
|
179
|
+
*/
|
|
180
|
+
ports?: string[];
|
|
181
|
+
/** Inputs delivered on the node's input ports. */
|
|
182
|
+
inputs?: Record<string, unknown>;
|
|
183
|
+
expect: FixtureExpectation;
|
|
184
|
+
};
|
|
185
|
+
type FixtureFile = {
|
|
186
|
+
/** The kind under test. Must match the manifest's `kind`. */
|
|
187
|
+
kind: string;
|
|
188
|
+
cases: FixtureCase[];
|
|
189
|
+
};
|
|
190
|
+
type FixtureFailure = {
|
|
191
|
+
case: string;
|
|
192
|
+
message: string;
|
|
193
|
+
};
|
|
194
|
+
type FixtureRunResult = {
|
|
195
|
+
ok: boolean;
|
|
196
|
+
passed: number;
|
|
197
|
+
failures: FixtureFailure[];
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Run one fixture file against a kind's executor.
|
|
201
|
+
*
|
|
202
|
+
* `executor` is the node's own; everything else in the graph is supplied here,
|
|
203
|
+
* so a case exercises the node and nothing but the node.
|
|
204
|
+
*/
|
|
205
|
+
declare function runFixtures(file: FixtureFile, executor: NodeExecutor): Promise<FixtureRunResult>;
|
|
206
|
+
/**
|
|
207
|
+
* Validate a fixture file's shape before running it.
|
|
31
208
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
209
|
+
* A package that publishes an empty or malformed fixture file has satisfied the
|
|
210
|
+
* letter of the requirement and none of its purpose, so this is checked at
|
|
211
|
+
* publish rather than trusted.
|
|
34
212
|
*/
|
|
35
|
-
declare function
|
|
213
|
+
declare function validateFixtureFile(input: unknown, expectedKind?: string): string[];
|
|
36
214
|
|
|
37
|
-
export {
|
|
215
|
+
export { type FixtureCase, type FixtureExpectation, type FixtureFailure, type FixtureFile, type FixtureRunResult, type ManifestProblem, type ManifestValidation, NODE_MANIFEST_SCHEMA_VERSION, NodeExecutor, type NodePackageManifest, type NodeRuntimeId, PauseAwaiting, checkCapabilities, checkRuntimeSupport, runFixtures, validateFixtureFile, validateNodeManifest };
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,37 +1,215 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-ChBi6q-W.js';
|
|
2
|
+
import { N as NodeExecutor } from './types-sOmpCitB.js';
|
|
3
|
+
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, E as ExecutorRegistry, a as FlowEdge, F as FlowGraph, b as FlowNode, c as FlowNodeData, d as FlowNodeKind, e as NodeRunStatus, f as NoteNodeData, O as OutputNodeData, P as PortDescriptor, R as RunEvent, S as SubgraphNodeData, T as TriggerNodeData } from './types-sOmpCitB.js';
|
|
4
|
+
import { P as PauseAwaiting } from './pause-9iT4tCEV.js';
|
|
5
|
+
export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.js';
|
|
3
6
|
import '@xyflow/react';
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The node package manifest — what a marketplace node declares about itself.
|
|
10
|
+
*
|
|
11
|
+
* A node is not one artifact. It is a kind definition (palette entry, config
|
|
12
|
+
* schema, ports, canvas renderer) plus an executor for EACH runtime the
|
|
13
|
+
* consumer actually runs. A package shipping only a TS executor is unusable to
|
|
14
|
+
* anyone executing on PHP, and today that is invisible until a run fails.
|
|
15
|
+
*
|
|
16
|
+
* So the manifest states which runtimes it implements, and the CLI checks that
|
|
17
|
+
* against the host before installing rather than after. Requested by the MOIC
|
|
18
|
+
* Suite consumer (fancy-flow#2 §2), who runs the editor in TS and executes in
|
|
19
|
+
* PHP and hit exactly this.
|
|
20
|
+
*
|
|
21
|
+
* The manifest is data, not code: the registry, the CLI, and the MCP all read
|
|
22
|
+
* it without executing anything a package author wrote.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** The current manifest schema version. Bump only on a breaking shape change. */
|
|
26
|
+
declare const NODE_MANIFEST_SCHEMA_VERSION = 1;
|
|
27
|
+
/**
|
|
28
|
+
* A runtime a node can implement.
|
|
29
|
+
*
|
|
30
|
+
* Open rather than a closed union — the PHP and Node twins are what exist
|
|
31
|
+
* today, but the point of a manifest is that a runtime we haven't written can
|
|
32
|
+
* declare itself without a release here.
|
|
33
|
+
*/
|
|
34
|
+
type NodeRuntimeId = "ts" | "php" | (string & {});
|
|
35
|
+
type NodePackageManifest = {
|
|
36
|
+
/** Must equal `NODE_MANIFEST_SCHEMA_VERSION`. */
|
|
37
|
+
schemaVersion: number;
|
|
38
|
+
/** Package name, as installed (`@acme/fancy-flow-salesforce`). */
|
|
39
|
+
name: string;
|
|
40
|
+
/**
|
|
41
|
+
* The canonical kind id this package provides — namespaced, and the string
|
|
42
|
+
* that gets persisted into every document using it.
|
|
43
|
+
*/
|
|
44
|
+
kind: string;
|
|
45
|
+
/** Semver range of fancy-flow this node's contract targets. */
|
|
46
|
+
fancyFlow: string;
|
|
47
|
+
/**
|
|
48
|
+
* Per-runtime entrypoints. TS is a module path within the package; PHP is a
|
|
49
|
+
* Composer requirement, because the two ecosystems install differently and
|
|
50
|
+
* pretending otherwise just moves the problem into the CLI.
|
|
51
|
+
*/
|
|
52
|
+
runtimes: Partial<Record<NodeRuntimeId, string>>;
|
|
53
|
+
/**
|
|
54
|
+
* Host capabilities this node needs wired before it can run — `llm`,
|
|
55
|
+
* `workflow_resolver`, `document`, or a host-specific one.
|
|
56
|
+
*
|
|
57
|
+
* Declared so the CLI can tell an author what to wire BEFORE install, rather
|
|
58
|
+
* than the node silently no-opping or crashing mid-run.
|
|
59
|
+
*/
|
|
60
|
+
capabilities?: string[];
|
|
61
|
+
/**
|
|
62
|
+
* Path to this node's golden fixtures, relative to the package root.
|
|
63
|
+
*
|
|
64
|
+
* REQUIRED. Every runtime the package claims runs these same cases, which is
|
|
65
|
+
* what makes "behaves identically on both runtimes" verified rather than
|
|
66
|
+
* asserted. See `./fixtures`.
|
|
67
|
+
*/
|
|
68
|
+
fixtures: string;
|
|
69
|
+
/** Declares the node halts for a person. Mirrors `NodeKindDefinition`. */
|
|
70
|
+
pausesForHuman?: PauseAwaiting;
|
|
71
|
+
/** One-line summary — what `search_nodes` matches against. */
|
|
72
|
+
description?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Assigned by the registry, never by the author. Present in a manifest being
|
|
75
|
+
* submitted for publication, it is a claim to a trust signal the author does
|
|
76
|
+
* not get to make.
|
|
77
|
+
*/
|
|
78
|
+
verified?: boolean;
|
|
79
|
+
};
|
|
80
|
+
type ManifestProblem = {
|
|
81
|
+
level: "error" | "warning";
|
|
82
|
+
field: string;
|
|
83
|
+
message: string;
|
|
84
|
+
};
|
|
85
|
+
type ManifestValidation = {
|
|
86
|
+
/** True when there are no `error`-level problems. Warnings do not block. */
|
|
16
87
|
ok: boolean;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/** Error captured if any node threw. */
|
|
20
|
-
error?: string;
|
|
88
|
+
manifest?: NodePackageManifest;
|
|
89
|
+
problems: ManifestProblem[];
|
|
21
90
|
};
|
|
22
91
|
/**
|
|
23
|
-
*
|
|
92
|
+
* Validate a manifest read from disk or a registry.
|
|
93
|
+
*
|
|
94
|
+
* Returns every problem rather than throwing on the first, because an author
|
|
95
|
+
* fixing a package wants the whole list — a validator that reveals one error
|
|
96
|
+
* per run turns a five-minute fix into five round trips.
|
|
97
|
+
*/
|
|
98
|
+
declare function validateNodeManifest(input: unknown): ManifestValidation;
|
|
99
|
+
/**
|
|
100
|
+
* Check a node against the runtimes a host actually executes on.
|
|
101
|
+
*
|
|
102
|
+
* This is what makes a TS-only package visible to someone running PHP BEFORE
|
|
103
|
+
* they install it rather than at the first run. A missing runtime is an error,
|
|
104
|
+
* not a warning: the node genuinely cannot execute there.
|
|
105
|
+
*/
|
|
106
|
+
declare function checkRuntimeSupport(manifest: Pick<NodePackageManifest, "kind" | "runtimes">, hostRuntimes: readonly string[]): ManifestProblem[];
|
|
107
|
+
/**
|
|
108
|
+
* Check that every capability a node needs is actually wired.
|
|
109
|
+
*
|
|
110
|
+
* Pass `capabilityStatus()` from the host. Unwired capabilities are a warning
|
|
111
|
+
* rather than an error — install is the right time to learn what to wire, not
|
|
112
|
+
* a reason to refuse, since wiring usually happens after install.
|
|
113
|
+
*/
|
|
114
|
+
declare function checkCapabilities(manifest: Pick<NodePackageManifest, "kind" | "capabilities">, available: Readonly<Record<string, boolean>>): ManifestProblem[];
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Golden fixtures — the parity guarantee, and a publishing requirement.
|
|
118
|
+
*
|
|
119
|
+
* Every runtime a node package claims runs these same JSON cases. That is what
|
|
120
|
+
* makes "this node behaves identically on TS and PHP" verified rather than
|
|
121
|
+
* asserted, and it is the one thing a loose collection of repos can never
|
|
122
|
+
* offer.
|
|
123
|
+
*
|
|
124
|
+
* WHY IT IS REQUIRED RATHER THAN ENCOURAGED: cross-runtime drift does not fail
|
|
125
|
+
* loudly. The 0.9.0 port-resolution divergence produced flows that routed
|
|
126
|
+
* correctly in the editor and silently down one path on the server — status
|
|
127
|
+
* `completed`, no error, no exception, nothing to alert on. A guarantee that
|
|
128
|
+
* only holds when an author opts in is not a guarantee.
|
|
24
129
|
*
|
|
25
|
-
*
|
|
26
|
-
* connected ports. Decision nodes (or any executor that returns `{ branch:
|
|
27
|
-
* 'true' }`) can short-circuit specific output ports — only edges leaving
|
|
28
|
-
* an "active" port propagate to downstream nodes.
|
|
130
|
+
* WHAT A CASE ASSERTS, and why it matters more than it looks:
|
|
29
131
|
*
|
|
30
|
-
*
|
|
132
|
+
* A fixture asserts THE DOWNSTREAM NODE EXECUTED — not the port the node
|
|
133
|
+
* recorded. The distinction is the whole lesson of that incident. A test
|
|
134
|
+
* reading back `outputs.router.__port` stays green while no edge fires and
|
|
135
|
+
* the run halts at the branch: the node faithfully recorded its choice, and
|
|
136
|
+
* nothing downstream ever ran. So the runner wires a real probe to every
|
|
137
|
+
* declared port and reports which probes actually executed.
|
|
138
|
+
*
|
|
139
|
+
* The format is plain JSON with no expressions or callbacks, so the PHP runner
|
|
140
|
+
* executes byte-identical cases without an embedded JS engine.
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/** What a case expects to have happened. */
|
|
144
|
+
type FixtureExpectation = {
|
|
145
|
+
/**
|
|
146
|
+
* Output ports whose downstream node must have executed — the assertion that
|
|
147
|
+
* catches routing drift. Order-insensitive; the set must match exactly, so a
|
|
148
|
+
* node that fires an extra port fails just as loudly as one that fires none.
|
|
149
|
+
*/
|
|
150
|
+
ports?: string[];
|
|
151
|
+
/** The value carried downstream, deep-compared when present. */
|
|
152
|
+
value?: unknown;
|
|
153
|
+
/** The run halted for a person. */
|
|
154
|
+
pause?: {
|
|
155
|
+
awaiting: PauseAwaiting;
|
|
156
|
+
detail?: unknown;
|
|
157
|
+
};
|
|
158
|
+
/** The run failed, and the message contains this substring. */
|
|
159
|
+
error?: string;
|
|
160
|
+
};
|
|
161
|
+
type FixtureCase = {
|
|
162
|
+
/** Human-readable, and what a failure report names. */
|
|
163
|
+
name: string;
|
|
164
|
+
/** Config for the node under test — drives config-derived ports. */
|
|
165
|
+
config?: Record<string, unknown>;
|
|
166
|
+
/**
|
|
167
|
+
* The node's resolved output ports, stated rather than derived.
|
|
168
|
+
*
|
|
169
|
+
* NOT a convenience. TS derives config-driven ports by running a JavaScript
|
|
170
|
+
* function (`switch_case`'s cases, `llm_router`'s routes); PHP cannot, and
|
|
171
|
+
* falls back to the kind's static declaration. Left there, the identical
|
|
172
|
+
* fixture would build a DIFFERENT graph on each runtime — the fixtures would
|
|
173
|
+
* silently stop comparing like with like, which is the exact failure they
|
|
174
|
+
* exist to catch.
|
|
175
|
+
*
|
|
176
|
+
* So a case states its ports the same way an exported document does (see
|
|
177
|
+
* 0.10.1, "serialize resolved ports"), and both runners honour it. Omit it
|
|
178
|
+
* only for a node whose ports are static.
|
|
179
|
+
*/
|
|
180
|
+
ports?: string[];
|
|
181
|
+
/** Inputs delivered on the node's input ports. */
|
|
182
|
+
inputs?: Record<string, unknown>;
|
|
183
|
+
expect: FixtureExpectation;
|
|
184
|
+
};
|
|
185
|
+
type FixtureFile = {
|
|
186
|
+
/** The kind under test. Must match the manifest's `kind`. */
|
|
187
|
+
kind: string;
|
|
188
|
+
cases: FixtureCase[];
|
|
189
|
+
};
|
|
190
|
+
type FixtureFailure = {
|
|
191
|
+
case: string;
|
|
192
|
+
message: string;
|
|
193
|
+
};
|
|
194
|
+
type FixtureRunResult = {
|
|
195
|
+
ok: boolean;
|
|
196
|
+
passed: number;
|
|
197
|
+
failures: FixtureFailure[];
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Run one fixture file against a kind's executor.
|
|
201
|
+
*
|
|
202
|
+
* `executor` is the node's own; everything else in the graph is supplied here,
|
|
203
|
+
* so a case exercises the node and nothing but the node.
|
|
204
|
+
*/
|
|
205
|
+
declare function runFixtures(file: FixtureFile, executor: NodeExecutor): Promise<FixtureRunResult>;
|
|
206
|
+
/**
|
|
207
|
+
* Validate a fixture file's shape before running it.
|
|
31
208
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
209
|
+
* A package that publishes an empty or malformed fixture file has satisfied the
|
|
210
|
+
* letter of the requirement and none of its purpose, so this is checked at
|
|
211
|
+
* publish rather than trusted.
|
|
34
212
|
*/
|
|
35
|
-
declare function
|
|
213
|
+
declare function validateFixtureFile(input: unknown, expectedKind?: string): string[];
|
|
36
214
|
|
|
37
|
-
export {
|
|
215
|
+
export { type FixtureCase, type FixtureExpectation, type FixtureFailure, type FixtureFile, type FixtureRunResult, type ManifestProblem, type ManifestValidation, NODE_MANIFEST_SCHEMA_VERSION, NodeExecutor, type NodePackageManifest, type NodeRuntimeId, PauseAwaiting, checkCapabilities, checkRuntimeSupport, runFixtures, validateFixtureFile, validateNodeManifest };
|