@w6w/ui 0.2.0 → 0.2.54
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 +146 -2
- package/README.md +28 -10
- package/dist/AppPicker.d.ts +58 -2
- package/dist/CanvasContextMenu.d.ts +19 -0
- package/dist/CanvasLayer.d.ts +38 -0
- package/dist/{CodeBlock-Dot3Pd7P.js → CodeBlock-C-oIIYfC.js} +1436 -555
- package/dist/CodeBlock-C-oIIYfC.js.map +1 -0
- package/dist/CodeBlock-CymlfyeA.cjs +15 -0
- package/dist/CodeBlock-CymlfyeA.cjs.map +1 -0
- package/dist/CodeEditor.d.ts +4 -1
- package/dist/ConditionEditor.d.ts +11 -0
- package/dist/EditConnectionModal.d.ts +6 -1
- package/dist/JsonEditor.d.ts +20 -0
- package/dist/Markdown.d.ts +25 -0
- package/dist/ParamCustomization.d.ts +5 -0
- package/dist/ParamsForm.d.ts +18 -4
- package/dist/RouterEditor.d.ts +5 -0
- package/dist/StepBuilderModal.d.ts +103 -15
- package/dist/StepNameEditor.d.ts +11 -0
- package/dist/StopEditor.d.ts +5 -0
- package/dist/TriggerFillForm.d.ts +14 -1
- package/dist/WebhookListenPanel.d.ts +28 -0
- package/dist/WorkflowConnections.d.ts +29 -0
- package/dist/WorkflowFlowEditor.d.ts +74 -7
- package/dist/app-pages.d.ts +2 -0
- package/dist/assets/script-completion.worker-DDJKkj5M.js +8290 -0
- package/dist/assets/script-completion.worker-DDJKkj5M.js.map +1 -0
- package/dist/canvas-context-menu.d.ts +27 -0
- package/dist/canvas-types.d.ts +36 -0
- package/dist/canvas-utils.d.ts +44 -0
- package/dist/code.cjs +1 -1
- package/dist/code.mjs +3 -4
- package/dist/code.mjs.map +1 -1
- package/dist/components/AnchoredFlyout.d.ts +7 -0
- package/dist/components/AuthFieldsForm.d.ts +11 -0
- package/dist/components/BudgetMeter.d.ts +15 -0
- package/dist/components/CallableList.d.ts +3 -2
- package/dist/components/ColumnsEditor.d.ts +27 -0
- package/dist/components/Combobox.d.ts +19 -1
- package/dist/components/ConnectionList.d.ts +2 -3
- package/dist/components/CredentialPicker.d.ts +35 -0
- package/dist/components/CsvPanel.d.ts +21 -0
- package/dist/components/DataEntryEditor.d.ts +38 -0
- package/dist/components/DataEntryList.d.ts +33 -0
- package/dist/components/DataStoreList.d.ts +33 -0
- package/dist/components/DataTable.d.ts +27 -0
- package/dist/components/DataTableGrid.d.ts +46 -0
- package/dist/components/EmptyState.d.ts +9 -0
- package/dist/components/EventbriteTriggerPicker.d.ts +7 -0
- package/dist/components/ExecutionDetail.d.ts +17 -1
- package/dist/components/ExecutionList.d.ts +19 -1
- package/dist/components/ExecutionLogPanel.d.ts +61 -3
- package/dist/components/ExpressionEditorModal.d.ts +33 -10
- package/dist/components/ExpressionOptions.d.ts +101 -15
- package/dist/components/HtmlPreview.d.ts +7 -0
- package/dist/components/JsonTree.d.ts +32 -0
- package/dist/components/ResolvedParams.d.ts +6 -1
- package/dist/components/ResultViewer.d.ts +46 -0
- package/dist/components/ScriptBindingsNotice.d.ts +31 -0
- package/dist/components/ScriptCodeField.d.ts +13 -0
- package/dist/components/StepStatusPill.d.ts +7 -0
- package/dist/components/expression-authoring.d.ts +13 -0
- package/dist/components/expression-dom.d.ts +17 -2
- package/dist/components/expression-template.d.ts +25 -3
- package/dist/components/icons.d.ts +1 -1
- package/dist/components/json-compose.d.ts +53 -0
- package/dist/components/result-format.d.ts +13 -0
- package/dist/condition-editor.d.ts +44 -0
- package/dist/data-stores/data-store-view.d.ts +371 -0
- package/dist/dynamic-fields.d.ts +60 -0
- package/dist/editor-theme.d.ts +24 -0
- package/dist/eventbrite-trigger-selection.d.ts +13 -0
- package/dist/flow-connect.d.ts +22 -16
- package/dist/flow-delete.d.ts +16 -0
- package/dist/flow-fanout.d.ts +2 -2
- package/dist/flow-history.d.ts +75 -0
- package/dist/flow-layout.d.ts +13 -0
- package/dist/flow-loop-colors.d.ts +39 -0
- package/dist/flow-loop.d.ts +98 -0
- package/dist/flow-node-flags.d.ts +14 -0
- package/dist/flow-problems.d.ts +69 -0
- package/dist/flow-state.d.ts +20 -0
- package/dist/flow-types.d.ts +155 -10
- package/dist/flow-utils.d.ts +33 -12
- package/dist/flow.cjs +4 -2
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.d.ts +15 -2
- package/dist/flow.mjs +3737 -1350
- package/dist/flow.mjs.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +43 -5
- package/dist/index.mjs +2855 -1333
- package/dist/index.mjs.map +1 -1
- package/dist/node-samples-ChdyMBnJ.cjs +22 -0
- package/dist/node-samples-ChdyMBnJ.cjs.map +1 -0
- package/dist/node-samples-DkJL07EX.js +12302 -0
- package/dist/node-samples-DkJL07EX.js.map +1 -0
- package/dist/node-samples.d.ts +80 -0
- package/dist/note-markdown.d.ts +22 -0
- package/dist/output-shape.d.ts +30 -14
- package/dist/param-customization.d.ts +7 -0
- package/dist/provider.d.ts +174 -13
- package/dist/resolve-params.d.ts +50 -11
- package/dist/run-visuals.d.ts +18 -22
- package/dist/script-bindings.d.ts +63 -0
- package/dist/script-completion-service.d.ts +9 -0
- package/dist/script-completion.worker.d.ts +1 -0
- package/dist/script-completions.d.ts +2 -0
- package/dist/state-shape.d.ts +38 -0
- package/dist/step-preview-state.d.ts +155 -6
- package/dist/step-problems.d.ts +64 -0
- package/dist/test-inputs.d.ts +25 -0
- package/dist/trigger-registration.d.ts +28 -0
- package/dist/types.d.ts +179 -11
- package/dist/use-app-action-defs.d.ts +9 -1
- package/dist/use-dynamic-fields.d.ts +23 -0
- package/dist/use-test-input.d.ts +18 -0
- package/dist/workflow-connections.d.ts +30 -0
- package/package.json +18 -7
- package/src/code.css +60 -6
- package/src/styles/_budget-meter.scss +46 -0
- package/src/styles/_callable-list.scss +15 -6
- package/src/styles/_canvas.scss +353 -0
- package/src/styles/_code-editor.scss +35 -0
- package/src/styles/_code.scss +6 -5
- package/src/styles/_connections.scss +2 -14
- package/src/styles/_copyable.scss +24 -0
- package/src/styles/_data-stores.scss +138 -0
- package/src/styles/_data-table.scss +55 -0
- package/src/styles/_data-vars.scss +17 -6
- package/src/styles/_empty-state.scss +21 -0
- package/src/styles/_execution-history.scss +73 -0
- package/src/styles/_execution-log.scss +145 -1
- package/src/styles/_expression-modal.scss +106 -16
- package/src/styles/_fields.scss +11 -0
- package/src/styles/_flow.scss +171 -0
- package/src/styles/_fx.scss +26 -1
- package/src/styles/_incoming-state.scss +33 -0
- package/src/styles/_layout.scss +10 -0
- package/src/styles/_markdown.scss +20 -0
- package/src/styles/_modal.scss +12 -0
- package/src/styles/_multiselect.scss +35 -0
- package/src/styles/_sections.scss +36 -0
- package/src/styles/_step-builder.scss +145 -0
- package/src/styles/_tester.scss +57 -14
- package/src/styles/_tokens.scss +27 -1
- package/src/styles.css +1861 -115
- package/src/styles.scss +7 -0
- package/dist/CodeBlock-CZu4TFSi.cjs +0 -15
- package/dist/CodeBlock-CZu4TFSi.cjs.map +0 -1
- package/dist/CodeBlock-Dot3Pd7P.js.map +0 -1
- package/dist/ConfirmModal-ChoiGy2K.cjs +0 -11
- package/dist/ConfirmModal-ChoiGy2K.cjs.map +0 -1
- package/dist/ConfirmModal-Wx3i8F1n.js +0 -6359
- package/dist/ConfirmModal-Wx3i8F1n.js.map +0 -1
- package/dist/Copyable-1niV9gUa.js +0 -771
- package/dist/Copyable-1niV9gUa.js.map +0 -1
- package/dist/Copyable-CYZU1o4X.cjs +0 -2
- package/dist/Copyable-CYZU1o4X.cjs.map +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted node samples — the server's record of the last output SHAPE (and, when small enough,
|
|
3
|
+
* the value) each node produced, from a step Test, a node run or a full run
|
|
4
|
+
* (`GET /workflows/:id/node-samples`). The editor loads them once per workflow so the picker,
|
|
5
|
+
* the ƒx previews and the Test tab still offer an upstream node's keys after a reload, a reopen or
|
|
6
|
+
* another browser, without re-running anything.
|
|
7
|
+
*
|
|
8
|
+
* They are a FALLBACK under what the editor already holds: a fresh in-memory output (a saved
|
|
9
|
+
* step-test's `lastRunOutput`) wins, unless the persisted sample is strictly newer. Field
|
|
10
|
+
* inference (`inferOutputFields`) is the same either way — a skeleton carries the same keys as
|
|
11
|
+
* the real value it was taken from.
|
|
12
|
+
*
|
|
13
|
+
* Pure and JSX-free so `node --test` exercises it directly.
|
|
14
|
+
*/
|
|
15
|
+
/** A node output's structural shape, as the server records it. */
|
|
16
|
+
export type NodeShape = {
|
|
17
|
+
type: "string" | "number" | "boolean" | "null" | "unknown";
|
|
18
|
+
} | {
|
|
19
|
+
type: "object";
|
|
20
|
+
fields: Record<string, NodeShape>;
|
|
21
|
+
} | {
|
|
22
|
+
type: "array";
|
|
23
|
+
items?: NodeShape;
|
|
24
|
+
};
|
|
25
|
+
/** One persisted node sample (`GET /workflows/:id/node-samples` → `nodeSamples[]`). */
|
|
26
|
+
export interface NodeSample {
|
|
27
|
+
nodeId: string;
|
|
28
|
+
shape: NodeShape;
|
|
29
|
+
/** The output itself, when the server kept it (omitted when too large — `sampleOmitted`). */
|
|
30
|
+
sample?: unknown;
|
|
31
|
+
sampleOmitted?: true;
|
|
32
|
+
source: "step_test" | "node_run" | "run";
|
|
33
|
+
runId?: string;
|
|
34
|
+
/** ISO timestamp of the write. */
|
|
35
|
+
updatedAt: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A representative value of `shape`: `""`, `0`, `false`, `null`, an object of its fields, an
|
|
39
|
+
* array of one item skeleton (`[]` when the item shape is unknown). `unknown` is `null`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function shapeToSkeleton(shape: NodeShape | undefined): unknown;
|
|
42
|
+
/** Index `samples` by node id (the last entry for a repeated id wins). */
|
|
43
|
+
export declare function indexNodeSamples(samples: readonly NodeSample[] | undefined): Record<string, NodeSample>;
|
|
44
|
+
/**
|
|
45
|
+
* One node's effective output for SHAPE inference: the fresh in-memory output wins (unless the
|
|
46
|
+
* persisted sample is strictly newer than `freshAt`), else the persisted `sample`, else
|
|
47
|
+
* {@link shapeToSkeleton} of its shape. `undefined` when neither exists.
|
|
48
|
+
*/
|
|
49
|
+
export declare function effectiveNodeOutput(nodeId: string, fresh: Record<string, unknown>, persisted: Record<string, NodeSample>, freshAt?: Record<string, string | null | undefined>): unknown;
|
|
50
|
+
/**
|
|
51
|
+
* {@link effectiveNodeOutput} for every node with a fresh or persisted output — the map the
|
|
52
|
+
* editor hands `StepShapeContext.testOutputs`, so a downstream node's picker offers the
|
|
53
|
+
* persisted keys after a reload.
|
|
54
|
+
*/
|
|
55
|
+
export declare function effectiveNodeOutputs(fresh: Record<string, unknown>, persisted: Record<string, NodeSample>, freshAt?: Record<string, string | null | undefined>): Record<string, unknown>;
|
|
56
|
+
/**
|
|
57
|
+
* The outputs the Result PREVIEWS read: real values only — never a skeleton, which would preview
|
|
58
|
+
* a made-up `""`/`0`. Same precedence as {@link effectiveNodeOutput}; a newer persisted sample
|
|
59
|
+
* with no value falls back to the fresh one.
|
|
60
|
+
*/
|
|
61
|
+
export declare function previewNodeOutputs(fresh: Record<string, unknown>, persisted: Record<string, NodeSample>, freshAt?: Record<string, string | null | undefined>): Record<string, unknown>;
|
|
62
|
+
/**
|
|
63
|
+
* {@link effectiveNodeOutputs} split into its two tiers, so the editor can hand the picker
|
|
64
|
+
* `testOutputs` (fresh) and `persistedOutputs` (persisted) SEPARATELY and show the right hint.
|
|
65
|
+
* A persisted sample wins only when there is no fresh output or it is strictly newer than
|
|
66
|
+
* `freshAt`; then the fresh entry is dropped from `fresh` and the persisted shape (its kept
|
|
67
|
+
* value, else its skeleton) goes in `persisted`. Elsewhere `fresh` is the fresh map unchanged.
|
|
68
|
+
*/
|
|
69
|
+
export declare function splitNodeOutputs(fresh: Record<string, unknown>, persisted: Record<string, NodeSample>, freshAt?: Record<string, string | null | undefined>): {
|
|
70
|
+
fresh: Record<string, unknown>;
|
|
71
|
+
persisted: Record<string, unknown>;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* {@link previewNodeOutputs} split into tiers: `persisted` holds only REAL kept values of the
|
|
75
|
+
* persisted samples that win (never a skeleton); `fresh` is the fresh map minus those ids.
|
|
76
|
+
*/
|
|
77
|
+
export declare function splitPreviewOutputs(fresh: Record<string, unknown>, persisted: Record<string, NodeSample>, freshAt?: Record<string, string | null | undefined>): {
|
|
78
|
+
fresh: Record<string, unknown>;
|
|
79
|
+
persisted: Record<string, unknown>;
|
|
80
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The note editor's Markdown round-trip. A note is edited in place as a `contentEditable` block
|
|
3
|
+
* (no textarea); these two functions convert between its stored Markdown and that editable DOM.
|
|
4
|
+
*
|
|
5
|
+
* The editable model is line-based and covers exactly what the note toolbar writes: a heading
|
|
6
|
+
* level per line (`#`…`######`) and `**bold**` runs. Everything else (links, lists, `code`, …) is
|
|
7
|
+
* kept as literal text while editing and rendered by `Markdown` when not, so a line the toolbar
|
|
8
|
+
* never touched round-trips byte-for-byte.
|
|
9
|
+
*
|
|
10
|
+
* The DOM is built with `createElement` + text nodes only — note content is imported,
|
|
11
|
+
* attacker-controllable text and must never reach `innerHTML`.
|
|
12
|
+
*/
|
|
13
|
+
/** Build the editable DOM for `content` into `root` (its children are replaced). */
|
|
14
|
+
export declare function renderEditable(root: HTMLElement, content: string): void;
|
|
15
|
+
/** Serialize the editable DOM under `root` back to Markdown. */
|
|
16
|
+
export declare function editableToMarkdown(root: HTMLElement): string;
|
|
17
|
+
/**
|
|
18
|
+
* The content handed to `Markdown` for display. A note is typed line by line, so a single
|
|
19
|
+
* newline must show as a line break — Markdown would fold it into a space. A soft break between
|
|
20
|
+
* two non-empty lines becomes a hard break (two trailing spaces); the stored content is untouched.
|
|
21
|
+
*/
|
|
22
|
+
export declare function noteDisplayMarkdown(content: string): string;
|
package/dist/output-shape.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* An upstream step's output SHAPE — the field paths a later step can pick —
|
|
3
|
-
* from the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* 3. **Test run** — the step's last saved test output, when the action
|
|
10
|
-
* declares neither. With none of the three, the author has to run a test.
|
|
3
|
+
* from the places one can come from. A real shape (a fresh test output, else
|
|
4
|
+
* the persisted one) is the BASE and keeps every key; the app's declared
|
|
5
|
+
* `output` (`core/rfcs/action.md` `OutputField[]`) annotates it and adds its
|
|
6
|
+
* declared-only keys (muted). With no real shape the declared `output` drives
|
|
7
|
+
* the keys alone, then keys inferred from the action's `sample`. With none of
|
|
8
|
+
* these, the author has to run a test.
|
|
11
9
|
*
|
|
12
10
|
* Every field is a dot-separated PATH (`start.utc`), the spec's own notation
|
|
13
11
|
* for nesting (`OutputField.key`: "Dot notation for nested paths"). That is
|
|
@@ -24,15 +22,28 @@ export interface OutputFieldRef {
|
|
|
24
22
|
label?: string;
|
|
25
23
|
/** `true` — `key` is a dot path whose segments are checked one by one. */
|
|
26
24
|
path: true;
|
|
25
|
+
/**
|
|
26
|
+
* `true` when a real (fresh/persisted) shape exists and this key came ONLY from the app's
|
|
27
|
+
* declaration — the picker adds it muted, "declared by the app".
|
|
28
|
+
*/
|
|
29
|
+
declaredOnly?: true;
|
|
27
30
|
}
|
|
28
|
-
/**
|
|
29
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Where a step's offered fields came from: a fresh test output, the persisted test shape,
|
|
33
|
+
* the app's declared `output`, or keys inferred from the app's `sample`.
|
|
34
|
+
*/
|
|
35
|
+
export type OutputShapeSource = "fresh" | "persisted" | "declared" | "sample";
|
|
30
36
|
/**
|
|
31
37
|
* The fields an action's `output` declares, or `undefined` when it declares
|
|
32
38
|
* none. A `DynamicOutput` (`{ source }`) is resolved by a hook the editor does
|
|
33
39
|
* not run, so it counts as "nothing declared" and the test-run fallback applies.
|
|
34
40
|
*/
|
|
35
41
|
export declare function declaredOutputFields(output: unknown): OutputFieldRef[] | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* The item keys a declared array field's `items` lists (`undefined` when the key is not a
|
|
44
|
+
* declared array field with items) — what a never-run For each over that array iterates.
|
|
45
|
+
*/
|
|
46
|
+
export declare function declaredItemFields(output: unknown, key: string): OutputFieldRef[] | undefined;
|
|
36
47
|
/**
|
|
37
48
|
* Field paths inferred from a concrete value (an action's `sample` or a test
|
|
38
49
|
* run's output): every key of a plain object, recursing into nested plain
|
|
@@ -48,11 +59,16 @@ export interface ActionShapeDef {
|
|
|
48
59
|
sample?: unknown;
|
|
49
60
|
}
|
|
50
61
|
/**
|
|
51
|
-
* Resolve a step's offered fields
|
|
52
|
-
*
|
|
53
|
-
*
|
|
62
|
+
* Resolve a step's offered fields. KEYS MERGE and never hide:
|
|
63
|
+
* - with a real shape (the fresh test output, else the persisted one) every real key is
|
|
64
|
+
* offered; the app's declared `output` annotates matching keys (label) and its
|
|
65
|
+
* declared-only keys are appended with `declaredOnly: true`;
|
|
66
|
+
* - with no real shape, the declared `output` drives the keys alone (`declared`), else
|
|
67
|
+
* the keys inferred from `sample` (`sample`).
|
|
68
|
+
* `action` is the app action/trigger definition (`undefined` while its app is loading);
|
|
69
|
+
* `fresh` / `persisted` are SEPARATE inputs so the tier stays visible.
|
|
54
70
|
*/
|
|
55
|
-
export declare function resolveOutputShape(action: ActionShapeDef | undefined,
|
|
71
|
+
export declare function resolveOutputShape(action: ActionShapeDef | undefined, fresh: unknown, persisted?: unknown): {
|
|
56
72
|
fields: OutputFieldRef[];
|
|
57
73
|
from: OutputShapeSource;
|
|
58
74
|
} | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ResolveScope } from './resolve-params.ts';
|
|
2
|
+
/** Authored JSON customization is kept apart from the editable form values. */
|
|
3
|
+
export declare function hasParamCustomization(values: Record<string, unknown>): boolean;
|
|
4
|
+
/** null: invalid; undefined: a binding whose fields can only be checked at runtime. */
|
|
5
|
+
export declare function customizedParamValues(values: Record<string, unknown>): Record<string, unknown> | undefined | null;
|
|
6
|
+
/** Resolve authored children only. A substituted object is data, not another template. */
|
|
7
|
+
export declare function previewCustomization(value: unknown, scope: ResolveScope, literalKeys?: readonly string[]): unknown;
|
package/dist/provider.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { NodeSample } from './node-samples.ts';
|
|
3
|
+
import { NodeTestInput } from './test-inputs.ts';
|
|
4
|
+
import { ActionDef, ApiCallRecord, AppSummary, AuthDef, ConnectionBinding, ConnectionSummary, CreateConnectionBody, CredentialDependents, CredentialSummary, CredentialTestResult, FunctionDetail, FunctionSummary, ResolveFieldsBody, ResolveFieldsResult, SavedTest, SubscriptionSummary, ThemeMode, TriggerSummary, WebhookListenSession, WorkflowDetail, WorkflowSummary } from './types.ts';
|
|
3
5
|
/**
|
|
4
6
|
* A single tester-run summary from the unified `run_log` ledger, keyed to a
|
|
5
7
|
* connection. Thin by design — the full result payload stays server-side in
|
|
@@ -75,6 +77,14 @@ export interface StepStartState {
|
|
|
75
77
|
trigger?: {
|
|
76
78
|
event?: unknown;
|
|
77
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* The iteration scope of a step inside a For each body → `foreach.item` / `foreach.index`
|
|
82
|
+
* (on the wire `state.foreach = { item, index }`, index defaulting to 0).
|
|
83
|
+
*/
|
|
84
|
+
foreach?: {
|
|
85
|
+
item?: unknown;
|
|
86
|
+
index?: number;
|
|
87
|
+
};
|
|
78
88
|
}
|
|
79
89
|
/**
|
|
80
90
|
* A caller-supplied override merged into an app action's outbound request at
|
|
@@ -111,6 +121,10 @@ export interface ListAppsPageOptions {
|
|
|
111
121
|
q?: string;
|
|
112
122
|
/** Server-side category filter (e.g. `"ai"`). */
|
|
113
123
|
category?: string;
|
|
124
|
+
/** Server-side filter to apps declaring at least one trigger (`GET /apps?hasTriggers=true`); `total` is then the filtered total. */
|
|
125
|
+
hasTriggers?: boolean;
|
|
126
|
+
/** Server-side id allow-list (`GET /apps?ids=a,b`); `total` is then the filtered total. */
|
|
127
|
+
ids?: string[];
|
|
114
128
|
/** Opaque pagination cursor from a prior {@link AppsPageResult.nextCursor}. */
|
|
115
129
|
cursor?: string;
|
|
116
130
|
/** Page size; a host may clamp this to its own bounds. */
|
|
@@ -135,6 +149,20 @@ export interface AppsPageResult {
|
|
|
135
149
|
limit?: number;
|
|
136
150
|
expiresAt?: string;
|
|
137
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* One page of a data store's entries for the `data-store-key` picker
|
|
154
|
+
* ({@link W6WApi.listDataStoreEntries}). `value` is the stored JSON, which the
|
|
155
|
+
* picker shortens to a one-line preview; `updatedAt` is an ISO timestamp.
|
|
156
|
+
*/
|
|
157
|
+
export interface DataStoreEntryOptions {
|
|
158
|
+
items: {
|
|
159
|
+
key: string;
|
|
160
|
+
value?: unknown;
|
|
161
|
+
updatedAt?: string;
|
|
162
|
+
}[];
|
|
163
|
+
/** True when further matching entries exist past this page. */
|
|
164
|
+
more?: boolean;
|
|
165
|
+
}
|
|
138
166
|
export interface W6WApi {
|
|
139
167
|
/**
|
|
140
168
|
* List registered apps to pick from in the connection modal.
|
|
@@ -174,15 +202,59 @@ export interface W6WApi {
|
|
|
174
202
|
listAppsByIds?(ids: readonly string[], options?: {
|
|
175
203
|
signal?: AbortSignal;
|
|
176
204
|
}): Promise<AppSummary[]>;
|
|
205
|
+
/**
|
|
206
|
+
* OPTIONAL: the tenant's model routes, for the `model-route` step-param
|
|
207
|
+
* picker (`@w6w/model` `complete`). Absent, the param renders as a plain text
|
|
208
|
+
* input and this is never called. A `broken` route is still selectable.
|
|
209
|
+
* `project` is the editor's own project (`WorkflowProjectProvider`) when it
|
|
210
|
+
* has one — a host should list THAT project's routes, not guess one from its
|
|
211
|
+
* URL; `undefined` leaves the choice to the host.
|
|
212
|
+
*/
|
|
213
|
+
listModelRoutes?(project?: string): Promise<{
|
|
214
|
+
name: string;
|
|
215
|
+
model: string;
|
|
216
|
+
status: "active" | "broken";
|
|
217
|
+
}[]>;
|
|
218
|
+
/**
|
|
219
|
+
* OPTIONAL: the project's data stores, for the `data-store` step-param
|
|
220
|
+
* picker (`@w6w/store`). Absent, the param renders as a plain text input and
|
|
221
|
+
* this is never called. Archived stores are not listed by the host.
|
|
222
|
+
* `project` is the editor's own project (`WorkflowProjectProvider`) when it
|
|
223
|
+
* has one — a host should list THAT project's stores, not guess one from its
|
|
224
|
+
* URL; `undefined` leaves the choice to the host.
|
|
225
|
+
*/
|
|
226
|
+
listDataStores?(project?: string): Promise<{
|
|
227
|
+
name: string;
|
|
228
|
+
kind: string;
|
|
229
|
+
}[]>;
|
|
230
|
+
/**
|
|
231
|
+
* OPTIONAL: ONE page of a data store's entries, for the `data-store-key`
|
|
232
|
+
* step-param picker (`@w6w/store` get/set/delete/increment). Absent, the key
|
|
233
|
+
* renders as a plain text input and this is never called.
|
|
234
|
+
* `store` is the store's NAME (what the step's `store` param holds) — the
|
|
235
|
+
* host resolves it to its own id. `prefix` is the server-side key search
|
|
236
|
+
* (the host's `GET /data-stores/:id/entries?prefix=`); `limit` caps the page,
|
|
237
|
+
* so a picker never loads a whole store. `more` is true when the store holds
|
|
238
|
+
* further matches past this page. `project` follows the `listDataStores` rule.
|
|
239
|
+
*/
|
|
240
|
+
listDataStoreEntries?(store: string, opts: {
|
|
241
|
+
project?: string;
|
|
242
|
+
prefix?: string;
|
|
243
|
+
limit?: number;
|
|
244
|
+
signal?: AbortSignal;
|
|
245
|
+
}): Promise<DataStoreEntryOptions>;
|
|
246
|
+
/**
|
|
247
|
+
* OPTIONAL: resolve the choices of `options: { source: "resolveFields" }`
|
|
248
|
+
* params from the current form (`POST` to the host). Absent, those params
|
|
249
|
+
* render as plain inputs and this is never called.
|
|
250
|
+
*/
|
|
251
|
+
resolveActionFields?(appId: string, actionKey: string, body: ResolveFieldsBody, opts?: {
|
|
252
|
+
signal?: AbortSignal;
|
|
253
|
+
}): Promise<ResolveFieldsResult>;
|
|
177
254
|
/** Load auth methods declared by an app's manifest, with availability flags. */
|
|
178
255
|
getAppAuth(appId: string): Promise<AuthDef[]>;
|
|
179
256
|
/** Create a non-OAuth connection with a user-supplied credential. */
|
|
180
|
-
createConnection(appId: string, body:
|
|
181
|
-
authKey: string;
|
|
182
|
-
credential: Record<string, unknown>;
|
|
183
|
-
displayName?: string;
|
|
184
|
-
profile?: Record<string, unknown>;
|
|
185
|
-
}): Promise<ConnectionSummary>;
|
|
257
|
+
createConnection(appId: string, body: CreateConnectionBody): Promise<ConnectionSummary>;
|
|
186
258
|
/**
|
|
187
259
|
* Rename a connection and/or replace some of its credential fields (`PATCH /connections/:id`).
|
|
188
260
|
* Send only the fields being changed: the server merges a partial `credential` over the stored
|
|
@@ -191,8 +263,34 @@ export interface W6WApi {
|
|
|
191
263
|
*/
|
|
192
264
|
updateConnection?(id: string, body: {
|
|
193
265
|
displayName?: string;
|
|
266
|
+
binding?: ConnectionBinding;
|
|
267
|
+
credentialId?: string;
|
|
194
268
|
credential?: Record<string, unknown>;
|
|
195
269
|
}): Promise<ConnectionSummary>;
|
|
270
|
+
/** List stored credentials, optionally narrowed (`GET /credentials`). */
|
|
271
|
+
listCredentials?(filter?: {
|
|
272
|
+
contract?: string;
|
|
273
|
+
appId?: string;
|
|
274
|
+
authKey?: string;
|
|
275
|
+
}): Promise<CredentialSummary[]>;
|
|
276
|
+
/** Store a new credential (`POST /credentials`). `source` is the auth's field-value record. */
|
|
277
|
+
createCredential?(body: {
|
|
278
|
+
name: string;
|
|
279
|
+
contract: string;
|
|
280
|
+
source: Record<string, unknown>;
|
|
281
|
+
}): Promise<CredentialSummary>;
|
|
282
|
+
getCredential?(id: string): Promise<CredentialSummary>;
|
|
283
|
+
/** Replace a credential's secret (`POST /credentials/:id/rotate`). */
|
|
284
|
+
rotateCredential?(id: string, body: {
|
|
285
|
+
source: Record<string, unknown>;
|
|
286
|
+
}): Promise<CredentialSummary>;
|
|
287
|
+
/** Disable (`/disable`) or re-enable (`/enable`) a credential. */
|
|
288
|
+
setCredentialStatus?(id: string, status: "active" | "disabled"): Promise<CredentialSummary>;
|
|
289
|
+
/** Mint-level health check; distinct from a connection's app-access test. */
|
|
290
|
+
testCredential?(id: string): Promise<CredentialTestResult>;
|
|
291
|
+
credentialDependents?(id: string): Promise<CredentialDependents>;
|
|
292
|
+
/** Rejects with `ApiError` code `credential_in_use` (body.error.dependents) when in use. */
|
|
293
|
+
deleteCredential?(id: string): Promise<void>;
|
|
196
294
|
/**
|
|
197
295
|
* Start an OAuth 2.0 flow. Server builds the provider's authorize URL and
|
|
198
296
|
* returns it; the caller opens it in a popup and awaits the server's
|
|
@@ -231,6 +329,11 @@ export interface W6WApi {
|
|
|
231
329
|
project?: string;
|
|
232
330
|
state?: StepStartState;
|
|
233
331
|
overrides?: RequestOverrides;
|
|
332
|
+
/**
|
|
333
|
+
* The workflow the step belongs to, so the host resolves `nodes.<id>.config` (e.g. a
|
|
334
|
+
* webhook node's `url`) as on a run. The host reads only the caller's own workflows.
|
|
335
|
+
*/
|
|
336
|
+
workflowId?: string;
|
|
234
337
|
}): Promise<{
|
|
235
338
|
value: unknown;
|
|
236
339
|
logs?: string[];
|
|
@@ -310,6 +413,28 @@ export interface W6WApi {
|
|
|
310
413
|
* `/workflows/:workflowId/steps/:stepId/tests`.
|
|
311
414
|
*/
|
|
312
415
|
listStepTests(workflowId: string, stepId: string): Promise<StepTest[]>;
|
|
416
|
+
/**
|
|
417
|
+
* OPTIONAL. The workflow's persisted node samples — each node's last output shape (and value,
|
|
418
|
+
* when kept) from a step Test, a node run or a full run, written server-side on every one of
|
|
419
|
+
* them. The flow editor loads them once per workflow so upstream keys survive a reload
|
|
420
|
+
* (`node-samples.ts`); a host without it behaves exactly as before. GETs
|
|
421
|
+
* `/workflows/:workflowId/node-samples` → `{ nodeSamples }`.
|
|
422
|
+
*/
|
|
423
|
+
loadNodeSamples?(workflowId: string): Promise<NodeSample[]>;
|
|
424
|
+
/**
|
|
425
|
+
* OPTIONAL. The test input each node of the workflow last ran with in the editor (a trigger's
|
|
426
|
+
* filled fields, any other node's incoming state) — so the Run node modal, the Test tabs and the
|
|
427
|
+
* header Run reopen prefilled (`test-inputs.ts`). Server-side, never in the workflow definition.
|
|
428
|
+
* GETs `/workflows/:workflowId/test-inputs` → `{ testInputs }`. A host without it falls back to
|
|
429
|
+
* the latest step-test fixture, as before.
|
|
430
|
+
*/
|
|
431
|
+
loadTestInputs?(workflowId: string): Promise<NodeTestInput[]>;
|
|
432
|
+
/**
|
|
433
|
+
* OPTIONAL. Remember the node's test input (newest wins; `{}` is a CLEAR). The server drops
|
|
434
|
+
* sealed envelopes; the caller drops literal secrets first (`rememberableInput`). PUTs
|
|
435
|
+
* `/workflows/:workflowId/nodes/:nodeId/test-input` `{ input }`.
|
|
436
|
+
*/
|
|
437
|
+
saveTestInput?(workflowId: string, nodeId: string, input: Record<string, unknown>): Promise<void>;
|
|
313
438
|
/**
|
|
314
439
|
* List the caller's registered Functions (core rfcs/function.md) — drives
|
|
315
440
|
* the step builder's Functions tab (F-2.0). GETs `/functions`.
|
|
@@ -359,11 +484,11 @@ export interface W6WApi {
|
|
|
359
484
|
}>;
|
|
360
485
|
/**
|
|
361
486
|
* List apps that declare at least one trigger — the Triggers tab's
|
|
362
|
-
*
|
|
363
|
-
* apps
|
|
487
|
+
* Apps filtered by `triggerCount > 0`. UNUSED by the step builder: the Triggers
|
|
488
|
+
* tab resolves connected apps via `listAppsByIds` and searches via
|
|
489
|
+
* `listAppsPage({ hasTriggers: true })`. The member stays on the public surface.
|
|
364
490
|
*
|
|
365
|
-
* OPTIONAL, like `listTestRuns?` above
|
|
366
|
-
* still typechecks and simply doesn't render the App-triggers section.
|
|
491
|
+
* OPTIONAL, like `listTestRuns?` above.
|
|
367
492
|
*/
|
|
368
493
|
listTriggerApps?(): Promise<AppSummary[]>;
|
|
369
494
|
/**
|
|
@@ -376,6 +501,31 @@ export interface W6WApi {
|
|
|
376
501
|
* `/workflows/:id/subscriptions`.
|
|
377
502
|
*/
|
|
378
503
|
listSubscriptionsForWorkflow?(workflowId: string): Promise<SubscriptionSummary[]>;
|
|
504
|
+
/**
|
|
505
|
+
* "Listen for test event" on a `@w6w/webhook` subscription: opens a short-lived session in
|
|
506
|
+
* which the receive URL captures the next request, even for an unpublished workflow. POSTs
|
|
507
|
+
* `/subscriptions/:id/listen`.
|
|
508
|
+
*/
|
|
509
|
+
startWebhookListen?(subscriptionId: string): Promise<{
|
|
510
|
+
session: WebhookListenSession;
|
|
511
|
+
webhookUrl: string;
|
|
512
|
+
}>;
|
|
513
|
+
/**
|
|
514
|
+
* Long-poll a listen session (`GET /subscriptions/:id/listen/:sessionId?wait=`). Resolves as
|
|
515
|
+
* soon as a request is captured or the session expires, else after `waitSeconds` (max 25).
|
|
516
|
+
*/
|
|
517
|
+
pollWebhookListen?(subscriptionId: string, sessionId: string, opts?: {
|
|
518
|
+
waitSeconds?: number;
|
|
519
|
+
signal?: AbortSignal;
|
|
520
|
+
}): Promise<WebhookListenSession>;
|
|
521
|
+
/** Stop listening (`DELETE /subscriptions/:id/listen/:sessionId`). */
|
|
522
|
+
stopWebhookListen?(subscriptionId: string, sessionId: string): Promise<void>;
|
|
523
|
+
/**
|
|
524
|
+
* Retry a failed trigger registration. POSTs
|
|
525
|
+
* `/subscriptions/:id/retry-registration`; resolves the updated Subscription.
|
|
526
|
+
* Absent => the trigger node offers no Retry.
|
|
527
|
+
*/
|
|
528
|
+
retrySubscriptionRegistration?(subscriptionId: string): Promise<SubscriptionSummary>;
|
|
379
529
|
/**
|
|
380
530
|
* Create a Subscription binding an app trigger to a workflow — the one
|
|
381
531
|
* explicit user action both the Triggers-tab app section (T-0) and the
|
|
@@ -431,10 +581,21 @@ export declare function W6WUIProvider({ api, theme, children }: W6WUIProviderPro
|
|
|
431
581
|
* `<W6WUIProvider>` — the common mistake is forgetting to wrap the app root.
|
|
432
582
|
*/
|
|
433
583
|
export declare function useW6WApi(): W6WApi;
|
|
434
|
-
/**
|
|
435
|
-
|
|
584
|
+
/**
|
|
585
|
+
* Like {@link useW6WApi} but returns `undefined` outside a provider instead of
|
|
586
|
+
* throwing — for optional enhancements (e.g. the `model-route` picker).
|
|
587
|
+
*/
|
|
588
|
+
export declare function useOptionalW6WApi(): W6WApi | undefined;
|
|
589
|
+
/**
|
|
590
|
+
* Scopes test-invokes under it to `project`, and names `workflowId` on them; the editor wraps
|
|
591
|
+
* its body with this.
|
|
592
|
+
*/
|
|
593
|
+
export declare function WorkflowProjectProvider({ project, workflowId, children, }: {
|
|
436
594
|
project?: string;
|
|
595
|
+
workflowId?: string;
|
|
437
596
|
children: ReactNode;
|
|
438
597
|
}): import("react").JSX.Element;
|
|
439
598
|
/** The selected workflow project id in scope, or `undefined` outside the editor. */
|
|
440
599
|
export declare function useWorkflowProject(): string | undefined;
|
|
600
|
+
/** The edited workflow's id in scope, or `undefined` outside the editor. */
|
|
601
|
+
export declare function useWorkflowId(): string | undefined;
|
package/dist/resolve-params.d.ts
CHANGED
|
@@ -18,6 +18,16 @@ export type ResolvedSegment = {
|
|
|
18
18
|
} | {
|
|
19
19
|
status: "unresolved";
|
|
20
20
|
ref: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A `nodes.<id>.meta.config.<key>` (alias `nodes.<id>.config.<key>`) ref this client cannot
|
|
24
|
+
* know — a key no node configures here, or one the host fills only at run time — or a
|
|
25
|
+
* `nodes.<id>.meta.<key>` its static meta lacks (a `version` the canvas does not know). Neutral, not a failure: the engine
|
|
26
|
+
* resolves it on the run.
|
|
27
|
+
*/
|
|
28
|
+
| {
|
|
29
|
+
status: "at-run";
|
|
30
|
+
ref: string;
|
|
21
31
|
} | {
|
|
22
32
|
status: "not-evaluated";
|
|
23
33
|
ref?: string;
|
|
@@ -29,18 +39,39 @@ export type ResolvedSegment = {
|
|
|
29
39
|
* The scope a param's `var` refs resolve against. Built by {@link buildResolveScope}
|
|
30
40
|
* from the SAME two things `StepEditModal` already computes: `testStartState`
|
|
31
41
|
* (for `steps.*`/`trigger.*` — the object literally sent as the test's `state`)
|
|
32
|
-
* and `sampleValues` (for `
|
|
42
|
+
* and `sampleValues` (for `var.*`/`documents.*`/`const.*`).
|
|
43
|
+
*
|
|
44
|
+
* The fields mirror the engine's `RunScope` (`vars`, `constants`); the roots a ref
|
|
45
|
+
* names are what the engine's data root exposes — `var.*` (with `vars.*` as its
|
|
46
|
+
* permanent alias) and `const.*`. {@link resolveRef} maps one onto the other.
|
|
33
47
|
*/
|
|
34
48
|
export interface ResolveScope {
|
|
35
49
|
vars: Record<string, unknown>;
|
|
50
|
+
/** The SAME object as {@link vars}: `state`, `var` and `vars` are one tree (optional: hand-built scopes omit it). */
|
|
51
|
+
state?: Record<string, unknown>;
|
|
36
52
|
documents: Record<string, unknown>;
|
|
53
|
+
/** Account constants, read as `const.<name>`. */
|
|
54
|
+
constants?: Record<string, unknown>;
|
|
37
55
|
steps: Record<string, {
|
|
38
56
|
output?: unknown;
|
|
39
57
|
meta?: StepMeta;
|
|
40
58
|
}>;
|
|
59
|
+
/** `nodes.<id>…` root — the SAME object as `steps` (one state, two roots). */
|
|
60
|
+
nodes?: Record<string, {
|
|
61
|
+
output?: unknown;
|
|
62
|
+
meta?: StepMeta;
|
|
63
|
+
}>;
|
|
41
64
|
trigger: {
|
|
42
65
|
event?: unknown;
|
|
43
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* The For each iteration scope (`foreach.item` / `foreach.index`), present only when
|
|
69
|
+
* `sampleValues` carries a `foreach.*` key. Mirrors the engine's inner scope.
|
|
70
|
+
*/
|
|
71
|
+
foreach?: {
|
|
72
|
+
item?: unknown;
|
|
73
|
+
index?: number;
|
|
74
|
+
};
|
|
44
75
|
/**
|
|
45
76
|
* The original flat `sampleValues` map, keyed by full ref string — checked
|
|
46
77
|
* BEFORE the nested walk in {@link resolveRef}. `documentSampleValues`
|
|
@@ -54,8 +85,8 @@ export interface ResolveScope {
|
|
|
54
85
|
* never reach either shape. An exact flat-key hit here resolves any ref
|
|
55
86
|
* `sampleValues` names directly, regardless of how many segments it has;
|
|
56
87
|
* the nested walk stays the fallback for a ref whose own reconstructed
|
|
57
|
-
* value happens to be an object (`
|
|
58
|
-
* into it for `
|
|
88
|
+
* value happens to be an object (`var.address` = `{ city: "X" }`, walking
|
|
89
|
+
* into it for `var.address.city`), which is a value shape `sampleValues`
|
|
59
90
|
* never produces a matching flat key for in the first place.
|
|
60
91
|
*
|
|
61
92
|
* Optional: a `ResolveScope` built by hand (as most tests in
|
|
@@ -64,6 +95,16 @@ export interface ResolveScope {
|
|
|
64
95
|
* `buildResolveScope` populates it.
|
|
65
96
|
*/
|
|
66
97
|
flat?: Record<string, unknown>;
|
|
98
|
+
/**
|
|
99
|
+
* Each node's static configuration ({@link ExpressionOptions.nodeConfig}), laid over `nodes`
|
|
100
|
+
* at `meta.config` and the `config` alias exactly as the engine's `withConfig` does.
|
|
101
|
+
*/
|
|
102
|
+
config?: Record<string, Record<string, unknown>>;
|
|
103
|
+
/**
|
|
104
|
+
* Each node's static metadata ({@link ExpressionOptions.nodeMeta}), laid under the state's own
|
|
105
|
+
* `meta` (which wins key by key) exactly as the engine's `withConfig` does.
|
|
106
|
+
*/
|
|
107
|
+
meta?: Record<string, Record<string, unknown>>;
|
|
67
108
|
}
|
|
68
109
|
/**
|
|
69
110
|
* Build a {@link ResolveScope} from the two sources scope fidelity requires
|
|
@@ -72,15 +113,13 @@ export interface ResolveScope {
|
|
|
72
113
|
* - `steps`/`trigger` come from `testStartState` — the exact object the test
|
|
73
114
|
* invoke sends as `state`, so a `steps.<id>.output.<field>` ref resolves to
|
|
74
115
|
* what the test will ACTUALLY see, not a design-time sample.
|
|
75
|
-
* - `vars`/`documents` come from `sampleValues` (`useExpressionOptions()`), a
|
|
76
|
-
* FLAT map keyed by full ref (`"
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* resolves `vars.address.city` correctly, because the walk continues INTO
|
|
81
|
-
* the reconstructed value rather than doing a second flat-key lookup.
|
|
116
|
+
* - `vars`/`documents`/`constants` come from `sampleValues` (`useExpressionOptions()`), a
|
|
117
|
+
* FLAT map keyed by full ref (`"var.from_email"`, `"documents.<key>"`, `"const.<name>"`).
|
|
118
|
+
* State paths are reconstructed into one nested tree; whole-object samples
|
|
119
|
+
* take precedence over their indexed descendants. The original flat map
|
|
120
|
+
* remains available for exact field lookups, including parsed document fields.
|
|
82
121
|
*/
|
|
83
|
-
export declare function buildResolveScope(sampleValues: Record<string, unknown> | undefined, testStartState: StepStartState | undefined): ResolveScope;
|
|
122
|
+
export declare function buildResolveScope(sampleValues: Record<string, unknown> | undefined, testStartState: StepStartState | undefined, config?: Record<string, Record<string, unknown>>, meta?: Record<string, Record<string, unknown>>): ResolveScope;
|
|
84
123
|
/** A hand-authored whole-value path marker: `{ "$": "<path>" }`, exactly one key. */
|
|
85
124
|
export declare function isDollarPath(v: unknown): v is {
|
|
86
125
|
$: unknown;
|
package/dist/run-visuals.d.ts
CHANGED
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Pure derivation of a live run's canvas visuals (T1.1.1) — step node styling
|
|
3
|
-
* and main-graph edge taken/skipped/untouched state. Plain functions of (run
|
|
4
|
-
* state, step/edge identity) → visual state, with **no React import**, so
|
|
5
|
-
* `node --test` exercises them directly (A7) the same way `flow-connect.ts`'s
|
|
6
|
-
* connection rules do.
|
|
7
|
-
*
|
|
8
|
-
* `RunStatus`/`StepStatus`/`RunState`/`StepExecution` below are thin LOCAL
|
|
9
|
-
* copies of the shapes `@w6w/workflow-types` declares
|
|
10
|
-
* (`packages/w6w-workflow/packages/types/mod.ts`) — the same house idiom
|
|
11
|
-
* `components/HealthStatusPill.tsx`'s `HealthPillState` uses, and the same
|
|
12
|
-
* design note `flow-types.ts`'s own header already states for
|
|
13
|
-
* `FlowWorkflow`/`FlowStep`: `packages/ui/package.json` has no dependency on
|
|
14
|
-
* `@w6w/workflow-types` and must not gain one, so this module stays a
|
|
15
|
-
* pure-presentation leaf with no transport/spec coupling. A caller who
|
|
16
|
-
* already has the real `RunState`/`StepExecution` is structurally compatible
|
|
17
|
-
* for free.
|
|
18
|
-
*/
|
|
1
|
+
import { CanvasLane } from './flow-types.ts';
|
|
19
2
|
/** Mirrors `RunStatus` in `@w6w/workflow-types`. */
|
|
20
3
|
export type RunStatus = "queued" | "running" | "succeeded" | "failed" | "canceled";
|
|
21
4
|
/** Mirrors `StepStatus` in `@w6w/workflow-types`. */
|
|
@@ -23,12 +6,24 @@ export type StepStatus = "pending" | "running" | "succeeded" | "failed" | "skipp
|
|
|
23
6
|
/** The slice of `StepExecution` this module reads. */
|
|
24
7
|
export interface StepExecution {
|
|
25
8
|
status: StepStatus;
|
|
9
|
+
/** Why a `skipped` step did not run; `"not_on_path"` = never part of this run (no paint). */
|
|
10
|
+
skipReason?: string;
|
|
11
|
+
output?: unknown;
|
|
12
|
+
/** For each only (I3): per-iteration body-step records, keyed by body-step id. */
|
|
13
|
+
iterations?: ReadonlyArray<{
|
|
14
|
+
nodes?: Record<string, {
|
|
15
|
+
status: StepStatus;
|
|
16
|
+
}>;
|
|
17
|
+
}>;
|
|
26
18
|
}
|
|
27
19
|
/** The slice of `RunState` this module reads — steps keyed by step id, same
|
|
28
20
|
* as the engine's own `RunState.steps`. */
|
|
29
21
|
export interface RunState {
|
|
30
22
|
status: RunStatus;
|
|
31
|
-
|
|
23
|
+
/** Canonical per-node records (D2). */
|
|
24
|
+
nodes?: Record<string, StepExecution>;
|
|
25
|
+
/** Legacy alias of `nodes`; read as `nodes ?? steps` (un-upgraded server). */
|
|
26
|
+
steps?: Record<string, StepExecution>;
|
|
32
27
|
}
|
|
33
28
|
/**
|
|
34
29
|
* A step node's rendered state — exactly the five {@link StepStatus} values
|
|
@@ -43,9 +38,10 @@ export type StepVisualState = "no-run" | StepStatus;
|
|
|
43
38
|
* The rendered state for step `stepId` under `runState` — the StepStatus
|
|
44
39
|
* half of A3's RunStatus × StepStatus mapping. Pure function of the run's own
|
|
45
40
|
* step records; no additional data needed (`GET /runs/:id` already returns
|
|
46
|
-
* everything this reads).
|
|
41
|
+
* everything this reads). A step whose record says `skipReason: "not_on_path"` (or whose
|
|
42
|
+
* enclosing loop's does) was never part of the run: `"no-run"`, the unpainted look.
|
|
47
43
|
*/
|
|
48
|
-
export declare function stepVisualState(runState: RunState | undefined, stepId: string): StepVisualState;
|
|
44
|
+
export declare function stepVisualState(runState: RunState | undefined, stepId: string, loops?: readonly string[]): StepVisualState;
|
|
49
45
|
/** One node's non-persisted, run-aware look. Colour is never the only signal
|
|
50
46
|
* (the house rule `HealthStatusPill`'s own doc comment states) — every
|
|
51
47
|
* non-default state also differs from the default (`"no-run"`) in
|
|
@@ -87,4 +83,4 @@ export type EdgeRunState = "taken" | "skipped";
|
|
|
87
83
|
* - `from` is **running**, or has no record at all (not yet reached): the
|
|
88
84
|
* edge's fate isn't decided yet ⇒ `undefined`.
|
|
89
85
|
*/
|
|
90
|
-
export declare function edgeRunState(runState: RunState | undefined, from: string, when:
|
|
86
|
+
export declare function edgeRunState(runState: RunState | undefined, from: string, when: CanvasLane | undefined, route?: string, to?: string): EdgeRunState | undefined;
|