@xyne/workflow-ui 1.3.6 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/builder/v3/LoopContainer.d.ts +3 -1
- package/dist/components/builder/v3/LoopContainer.d.ts.map +1 -1
- package/dist/components/builder/v3/LoopContainer.js +2 -2
- package/dist/components/builder/v3/LoopContainer.js.map +1 -1
- package/dist/components/builder/v3/WorkflowTree.d.ts.map +1 -1
- package/dist/components/builder/v3/WorkflowTree.js +7 -3
- package/dist/components/builder/v3/WorkflowTree.js.map +1 -1
- package/dist/components/execution/ExecutionJourney.d.ts +5 -2
- package/dist/components/execution/ExecutionJourney.d.ts.map +1 -1
- package/dist/components/execution/ExecutionJourney.js +85 -17
- package/dist/components/execution/ExecutionJourney.js.map +1 -1
- package/dist/components/execution/ExecutionTree.d.ts +13 -2
- package/dist/components/execution/ExecutionTree.d.ts.map +1 -1
- package/dist/components/execution/ExecutionTree.js +9 -4
- package/dist/components/execution/ExecutionTree.js.map +1 -1
- package/dist/components/execution/ExecutionViewer.d.ts.map +1 -1
- package/dist/components/execution/ExecutionViewer.js +31 -9
- package/dist/components/execution/ExecutionViewer.js.map +1 -1
- package/dist/components/execution/MapContainer.d.ts +29 -0
- package/dist/components/execution/MapContainer.d.ts.map +1 -0
- package/dist/components/execution/MapContainer.js +24 -0
- package/dist/components/execution/MapContainer.js.map +1 -0
- package/dist/components/execution/StepDetailPanel.d.ts +2 -1
- package/dist/components/execution/StepDetailPanel.d.ts.map +1 -1
- package/dist/components/execution/StepDetailPanel.js.map +1 -1
- package/dist/hooks/use-execution-viewer.d.ts +2 -35
- package/dist/hooks/use-execution-viewer.d.ts.map +1 -1
- package/dist/hooks/use-execution-viewer.js +31 -260
- package/dist/hooks/use-execution-viewer.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/iterations.d.ts +48 -0
- package/dist/utils/iterations.d.ts.map +1 -0
- package/dist/utils/iterations.js +79 -0
- package/dist/utils/iterations.js.map +1 -0
- package/dist/utils/map-lanes.d.ts +35 -0
- package/dist/utils/map-lanes.d.ts.map +1 -0
- package/dist/utils/map-lanes.js +48 -0
- package/dist/utils/map-lanes.js.map +1 -0
- package/dist/utils/step-state.d.ts +71 -0
- package/dist/utils/step-state.d.ts.map +1 -0
- package/dist/utils/step-state.js +267 -0
- package/dist/utils/step-state.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step-execution state model — the shared vocabulary the whole execution view is
|
|
3
|
+
* built on. Pure (no React): types + functions that turn raw `ExecutionDetail`
|
|
4
|
+
* step records (node-path keyed) into per-step UI state.
|
|
5
|
+
*
|
|
6
|
+
* Lives here (not in the viewer hook) because every surface depends on it — the
|
|
7
|
+
* graph (`ExecutionTree`/`MapContainer`), the Journey, the detail panel, and the
|
|
8
|
+
* iteration grouping (`utils/iterations.ts`). Keeping it in `utils` also avoids a
|
|
9
|
+
* util→hook dependency.
|
|
10
|
+
*/
|
|
11
|
+
import type { ExecutionDetail } from '@xyne/workflow-sdk/client';
|
|
12
|
+
import type { PauseState } from '@xyne/workflow-sdk';
|
|
13
|
+
import type { WorkflowStepConfig } from '@xyne/workflow-sdk/builder';
|
|
14
|
+
export type StepExecutionStatus = 'pending' | 'running' | 'completed' | 'failed' | 'paused' | 'skipped';
|
|
15
|
+
export interface StepExecutionState {
|
|
16
|
+
stepName: string;
|
|
17
|
+
stepType: string;
|
|
18
|
+
status: StepExecutionStatus;
|
|
19
|
+
input?: Record<string, unknown>;
|
|
20
|
+
output?: Record<string, unknown>;
|
|
21
|
+
error?: string;
|
|
22
|
+
duration?: number;
|
|
23
|
+
pauseState?: PauseState;
|
|
24
|
+
/**
|
|
25
|
+
* Full node-path record key of the underlying step (e.g.
|
|
26
|
+
* `parallel_x:swot#0/gate`). `stepName` is reduced to the bare config id for
|
|
27
|
+
* graph/timeline matching; this retains the precise key needed to resume a
|
|
28
|
+
* specific gate. When several records collapse to one id, this is the paused
|
|
29
|
+
* one's path (paused outranks the rest in aggregation).
|
|
30
|
+
*/
|
|
31
|
+
nodePath?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function mapStepStatus(rawStatus: string): StepExecutionStatus;
|
|
34
|
+
/** Merge two states for the same bare step id, keeping the higher-ranked status. */
|
|
35
|
+
export declare function aggregateStepState(a: StepExecutionState, b: StepExecutionState): StepExecutionState;
|
|
36
|
+
/**
|
|
37
|
+
* Build step states map from execution detail's step rows, keyed by the BARE
|
|
38
|
+
* config step id so it matches graph nodes and SSE events.
|
|
39
|
+
*
|
|
40
|
+
* Step records are keyed by node-path (`ctrl:branch#iter/.../stepId` for nested
|
|
41
|
+
* steps; bare id for top-level). We reduce each to its leaf config id via
|
|
42
|
+
* `leafStepId`. Multiple records can collapse to one id (a LOOP body across
|
|
43
|
+
* iterations, or same-id steps in sibling branches) — those are aggregated by
|
|
44
|
+
* status precedence (see `aggregateStepState`).
|
|
45
|
+
*
|
|
46
|
+
* `synthesizeNestedStates` then fills states for nested steps that have NOT yet
|
|
47
|
+
* produced a record (e.g. children of a still-running control step), inheriting
|
|
48
|
+
* the parent's status — a fallback for in-progress visualization only.
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildStepStates(detail: ExecutionDetail): Map<string, StepExecutionState>;
|
|
51
|
+
/**
|
|
52
|
+
* Build a step-states map from a set of raw step records (keyed by bare leaf
|
|
53
|
+
* config id, aggregated by status precedence). `buildStepStates` passes the
|
|
54
|
+
* whole execution; iteration lanes pass one iteration's frame-stripped records
|
|
55
|
+
* so each lane gets its own per-iteration states.
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildStepStatesFromRecords(records: ExecutionDetail['steps'], configSteps?: WorkflowStepConfig[]): Map<string, StepExecutionState>;
|
|
58
|
+
/**
|
|
59
|
+
* Upsert one node-path record in `execution.steps` from an incremental SSE event.
|
|
60
|
+
* Finds the record by `nodePath` (exact node-path key, e.g. `map1:item#0/validate`;
|
|
61
|
+
* equals the bare id for top-level steps) and merges the new `status` + `data`
|
|
62
|
+
* fields; appends a fresh record if this is the step's first event. Returns a new
|
|
63
|
+
* detail object (or the same one if there's no execution yet) so React re-renders
|
|
64
|
+
* and the derived `stepStates` / iteration lanes pick up the change.
|
|
65
|
+
*/
|
|
66
|
+
export declare function patchExecutionStep(detail: ExecutionDetail | undefined, nodePath: string, patch: {
|
|
67
|
+
status?: string;
|
|
68
|
+
executorType?: string;
|
|
69
|
+
dataMerge?: Record<string, unknown>;
|
|
70
|
+
}): ExecutionDetail | undefined;
|
|
71
|
+
//# sourceMappingURL=step-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-state.d.ts","sourceRoot":"","sources":["../../src/utils/step-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAIrE,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAExG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAWpE;AAaD,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,CAsBnG;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,EACjC,WAAW,CAAC,EAAE,kBAAkB,EAAE,GACjC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAsEjC;AAiGD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,eAAe,GAAG,SAAS,EACnC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACrF,eAAe,GAAG,SAAS,CAsB7B"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step-execution state model — the shared vocabulary the whole execution view is
|
|
3
|
+
* built on. Pure (no React): types + functions that turn raw `ExecutionDetail`
|
|
4
|
+
* step records (node-path keyed) into per-step UI state.
|
|
5
|
+
*
|
|
6
|
+
* Lives here (not in the viewer hook) because every surface depends on it — the
|
|
7
|
+
* graph (`ExecutionTree`/`MapContainer`), the Journey, the detail panel, and the
|
|
8
|
+
* iteration grouping (`utils/iterations.ts`). Keeping it in `utils` also avoids a
|
|
9
|
+
* util→hook dependency.
|
|
10
|
+
*/
|
|
11
|
+
import { leafStepId } from '@xyne/workflow-sdk/common';
|
|
12
|
+
// ─── Raw status → UI status ───
|
|
13
|
+
export function mapStepStatus(rawStatus) {
|
|
14
|
+
switch (rawStatus) {
|
|
15
|
+
case 'COMPLETED': return 'completed';
|
|
16
|
+
case 'FAILED': return 'failed';
|
|
17
|
+
case 'RUNNING': return 'running';
|
|
18
|
+
case 'PAUSED':
|
|
19
|
+
case 'EXTERNAL_WAIT':
|
|
20
|
+
case 'REVIEW_WAIT': return 'paused';
|
|
21
|
+
case 'SKIPPED': return 'skipped';
|
|
22
|
+
default: return 'pending';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// ─── Aggregation (many records → one bare id) ───
|
|
26
|
+
/**
|
|
27
|
+
* Aggregation precedence when several records collapse to the same bare step id
|
|
28
|
+
* (a LOOP body step across iterations, or same-id steps in different branches —
|
|
29
|
+
* one config node, many records). The most attention-worthy status wins.
|
|
30
|
+
*/
|
|
31
|
+
const STATUS_RANK = {
|
|
32
|
+
running: 5, paused: 4, failed: 3, completed: 2, skipped: 1, pending: 0,
|
|
33
|
+
};
|
|
34
|
+
/** Merge two states for the same bare step id, keeping the higher-ranked status. */
|
|
35
|
+
export function aggregateStepState(a, b) {
|
|
36
|
+
const winner = STATUS_RANK[b.status] >= STATUS_RANK[a.status] ? b : a;
|
|
37
|
+
const loser = winner === b ? a : b;
|
|
38
|
+
const merged = {
|
|
39
|
+
stepName: winner.stepName,
|
|
40
|
+
stepType: winner.stepType || loser.stepType,
|
|
41
|
+
status: winner.status,
|
|
42
|
+
};
|
|
43
|
+
const input = winner.input ?? loser.input;
|
|
44
|
+
if (input)
|
|
45
|
+
merged.input = input;
|
|
46
|
+
const output = winner.output ?? loser.output;
|
|
47
|
+
if (output)
|
|
48
|
+
merged.output = output;
|
|
49
|
+
const error = winner.error ?? loser.error;
|
|
50
|
+
if (error)
|
|
51
|
+
merged.error = error;
|
|
52
|
+
// Prefer a pauseState from whichever record is actually paused.
|
|
53
|
+
const pauseState = winner.pauseState ?? loser.pauseState;
|
|
54
|
+
if (pauseState)
|
|
55
|
+
merged.pauseState = pauseState;
|
|
56
|
+
// Keep the winner's node-path (the paused record's, since paused outranks) so
|
|
57
|
+
// resume can target the right gate.
|
|
58
|
+
const nodePath = winner.nodePath ?? loser.nodePath;
|
|
59
|
+
if (nodePath)
|
|
60
|
+
merged.nodePath = nodePath;
|
|
61
|
+
return merged;
|
|
62
|
+
}
|
|
63
|
+
// ─── Records → states ───
|
|
64
|
+
/**
|
|
65
|
+
* Build step states map from execution detail's step rows, keyed by the BARE
|
|
66
|
+
* config step id so it matches graph nodes and SSE events.
|
|
67
|
+
*
|
|
68
|
+
* Step records are keyed by node-path (`ctrl:branch#iter/.../stepId` for nested
|
|
69
|
+
* steps; bare id for top-level). We reduce each to its leaf config id via
|
|
70
|
+
* `leafStepId`. Multiple records can collapse to one id (a LOOP body across
|
|
71
|
+
* iterations, or same-id steps in sibling branches) — those are aggregated by
|
|
72
|
+
* status precedence (see `aggregateStepState`).
|
|
73
|
+
*
|
|
74
|
+
* `synthesizeNestedStates` then fills states for nested steps that have NOT yet
|
|
75
|
+
* produced a record (e.g. children of a still-running control step), inheriting
|
|
76
|
+
* the parent's status — a fallback for in-progress visualization only.
|
|
77
|
+
*/
|
|
78
|
+
export function buildStepStates(detail) {
|
|
79
|
+
return buildStepStatesFromRecords(detail.steps ?? [], detail.config?.steps);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build a step-states map from a set of raw step records (keyed by bare leaf
|
|
83
|
+
* config id, aggregated by status precedence). `buildStepStates` passes the
|
|
84
|
+
* whole execution; iteration lanes pass one iteration's frame-stripped records
|
|
85
|
+
* so each lane gets its own per-iteration states.
|
|
86
|
+
*/
|
|
87
|
+
export function buildStepStatesFromRecords(records, configSteps) {
|
|
88
|
+
const map = new Map();
|
|
89
|
+
if (!records)
|
|
90
|
+
return map;
|
|
91
|
+
// ─── LEGACY (safe to remove once no pre-id-keying executions remain) ─────────
|
|
92
|
+
// Older executor builds keyed TOP-LEVEL records positionally (`step_0`,
|
|
93
|
+
// `step_1`, …) instead of by the config step's `id`. The current executor keys
|
|
94
|
+
// every record by `step.id` / node-path (nothing writes `step_N` anymore — see
|
|
95
|
+
// workflow-executor.ts emitting `stepName: step.id`), so this map only joins
|
|
96
|
+
// history persisted before that switch. It is viewer-only — it never affects
|
|
97
|
+
// execution/resume — but dropping it makes those old records render orphaned
|
|
98
|
+
// (their steps show as pending). NOTE: it maps by POSITION, so it mis-joins if
|
|
99
|
+
// the config was reordered after the run.
|
|
100
|
+
//
|
|
101
|
+
// TO REMOVE: delete this `stepKeyMap` block AND drop the `stepKeyMap.get(...) ??`
|
|
102
|
+
// prefix on the `bareId` line below (leaving just `leafStepId(step.stepName)`).
|
|
103
|
+
// Only do this once no in-flight/browsable execution can still carry `step_N`
|
|
104
|
+
// records. Then `configSteps` is used solely by `synthesizeNestedStates`.
|
|
105
|
+
const stepKeyMap = new Map();
|
|
106
|
+
if (configSteps) {
|
|
107
|
+
for (let i = 0; i < configSteps.length; i++) {
|
|
108
|
+
stepKeyMap.set(`step_${i}`, configSteps[i].id);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// ─── end LEGACY ──────────────────────────────────────────────────────────────
|
|
112
|
+
for (const step of records) {
|
|
113
|
+
let stepData;
|
|
114
|
+
if (step.data) {
|
|
115
|
+
try {
|
|
116
|
+
stepData = JSON.parse(step.data);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Ignore parse errors
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Record keys are node-path qualified for nested steps and bare config ids
|
|
123
|
+
// for top-level steps. Reduce to the bare config id so they match graph
|
|
124
|
+
// nodes / SSE events. `stepKeyMap.get(...)` is the LEGACY `step_N` fallback
|
|
125
|
+
// (see block above) — remove it with that block; keep `leafStepId(...)`.
|
|
126
|
+
const bareId = stepKeyMap.get(step.stepName) ?? leafStepId(step.stepName);
|
|
127
|
+
const incoming = {
|
|
128
|
+
stepName: bareId,
|
|
129
|
+
stepType: step.executorType,
|
|
130
|
+
status: mapStepStatus(step.status),
|
|
131
|
+
};
|
|
132
|
+
const input = stepData?.['input'];
|
|
133
|
+
if (input)
|
|
134
|
+
incoming.input = input;
|
|
135
|
+
const output = stepData?.['output'];
|
|
136
|
+
if (output)
|
|
137
|
+
incoming.output = output;
|
|
138
|
+
const err = stepData?.['error'];
|
|
139
|
+
if (err)
|
|
140
|
+
incoming.error = err;
|
|
141
|
+
const pauseStateRaw = stepData?.['pauseState'];
|
|
142
|
+
if (pauseStateRaw)
|
|
143
|
+
incoming.pauseState = pauseStateRaw;
|
|
144
|
+
// Retain the full record key so a paused gate can be resumed precisely.
|
|
145
|
+
incoming.nodePath = step.stepName;
|
|
146
|
+
// Many records can collapse to one bare id (loop iterations / same-id branch
|
|
147
|
+
// steps) — aggregate by status precedence rather than last-write-wins.
|
|
148
|
+
const existing = map.get(bareId);
|
|
149
|
+
map.set(bareId, existing ? aggregateStepState(existing, incoming) : incoming);
|
|
150
|
+
}
|
|
151
|
+
// Synthesize states for nested steps (branch sub-steps, loop bodies, etc.)
|
|
152
|
+
if (configSteps) {
|
|
153
|
+
synthesizeNestedStates(configSteps, map);
|
|
154
|
+
}
|
|
155
|
+
return map;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Recursively walk config steps and synthesize execution states for
|
|
159
|
+
* nested steps that the executor doesn't emit as separate rows.
|
|
160
|
+
*
|
|
161
|
+
* Works at any depth: parallel → loop → parallel → … etc.
|
|
162
|
+
* If a parent step has a known state, its children inherit accordingly.
|
|
163
|
+
* For PARALLEL branches we also inspect the per-branch result to
|
|
164
|
+
* distinguish fulfilled vs rejected sub-steps and attach output to
|
|
165
|
+
* the last step in each branch.
|
|
166
|
+
*/
|
|
167
|
+
function synthesizeNestedStates(steps, map, inheritedStatus) {
|
|
168
|
+
for (const step of steps) {
|
|
169
|
+
const state = map.get(step.id);
|
|
170
|
+
const effectiveStatus = state?.status ?? inheritedStatus;
|
|
171
|
+
const cfg = step.config;
|
|
172
|
+
if (!cfg)
|
|
173
|
+
continue;
|
|
174
|
+
// ─── Multi-branch containers (PARALLEL, CONDITIONAL, etc.) ───
|
|
175
|
+
const branches = cfg['branches'];
|
|
176
|
+
if (branches && typeof branches === 'object' && !Array.isArray(branches)) {
|
|
177
|
+
// Per-branch results from the parent's output (allSettled shape)
|
|
178
|
+
const outputBranches = state?.output?.['branches'];
|
|
179
|
+
for (const [branchName, branchSteps] of Object.entries(branches)) {
|
|
180
|
+
if (!Array.isArray(branchSteps))
|
|
181
|
+
continue;
|
|
182
|
+
const typed = branchSteps;
|
|
183
|
+
const branchResult = outputBranches?.[branchName];
|
|
184
|
+
for (let i = 0; i < typed.length; i++) {
|
|
185
|
+
const sub = typed[i];
|
|
186
|
+
if (!map.has(sub.id) && effectiveStatus) {
|
|
187
|
+
const synth = effectiveStatus === 'completed'
|
|
188
|
+
? (branchResult?.status === 'rejected' ? 'failed' : 'completed')
|
|
189
|
+
: effectiveStatus === 'running' ? 'running'
|
|
190
|
+
: effectiveStatus === 'failed' ? 'failed'
|
|
191
|
+
: undefined;
|
|
192
|
+
if (synth) {
|
|
193
|
+
const subState = {
|
|
194
|
+
stepName: sub.id,
|
|
195
|
+
stepType: sub.type,
|
|
196
|
+
status: synth,
|
|
197
|
+
};
|
|
198
|
+
// Attach branch value as the last step's output
|
|
199
|
+
if (synth === 'completed' && i === typed.length - 1 && branchResult?.value) {
|
|
200
|
+
subState.output = branchResult.value;
|
|
201
|
+
}
|
|
202
|
+
map.set(sub.id, subState);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Recurse into branch steps for deeper nesting
|
|
207
|
+
synthesizeNestedStates(typed, map, effectiveStatus);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// ─── Single-branch containers (LOOP, etc.) ───
|
|
211
|
+
const body = cfg['body'];
|
|
212
|
+
if (Array.isArray(body)) {
|
|
213
|
+
const bodySteps = body;
|
|
214
|
+
for (const sub of bodySteps) {
|
|
215
|
+
if (!map.has(sub.id) && effectiveStatus) {
|
|
216
|
+
const synth = effectiveStatus === 'completed' ? 'completed'
|
|
217
|
+
: effectiveStatus === 'running' ? 'running'
|
|
218
|
+
: effectiveStatus === 'failed' ? 'failed'
|
|
219
|
+
: undefined;
|
|
220
|
+
if (synth) {
|
|
221
|
+
map.set(sub.id, {
|
|
222
|
+
stepName: sub.id,
|
|
223
|
+
stepType: sub.type,
|
|
224
|
+
status: synth,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Recurse into body steps for deeper nesting
|
|
230
|
+
synthesizeNestedStates(bodySteps, map, effectiveStatus);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// ─── Incremental patch (live SSE updates) ───
|
|
235
|
+
/**
|
|
236
|
+
* Upsert one node-path record in `execution.steps` from an incremental SSE event.
|
|
237
|
+
* Finds the record by `nodePath` (exact node-path key, e.g. `map1:item#0/validate`;
|
|
238
|
+
* equals the bare id for top-level steps) and merges the new `status` + `data`
|
|
239
|
+
* fields; appends a fresh record if this is the step's first event. Returns a new
|
|
240
|
+
* detail object (or the same one if there's no execution yet) so React re-renders
|
|
241
|
+
* and the derived `stepStates` / iteration lanes pick up the change.
|
|
242
|
+
*/
|
|
243
|
+
export function patchExecutionStep(detail, nodePath, patch) {
|
|
244
|
+
if (!detail)
|
|
245
|
+
return detail; // events before the first snapshot are a no-op
|
|
246
|
+
const steps = (detail.steps ?? []);
|
|
247
|
+
const idx = steps.findIndex((s) => s.stepName === nodePath);
|
|
248
|
+
const prev = idx >= 0 ? steps[idx] : undefined;
|
|
249
|
+
let data = {};
|
|
250
|
+
if (prev?.data) {
|
|
251
|
+
try {
|
|
252
|
+
data = JSON.parse(prev.data);
|
|
253
|
+
}
|
|
254
|
+
catch { /* keep {} */ }
|
|
255
|
+
}
|
|
256
|
+
if (patch.dataMerge)
|
|
257
|
+
data = { ...data, ...patch.dataMerge };
|
|
258
|
+
const nextRecord = {
|
|
259
|
+
...(prev ?? { stepName: nodePath, executorType: patch.executorType ?? '' }),
|
|
260
|
+
stepName: nodePath,
|
|
261
|
+
status: patch.status ?? prev?.status ?? 'RUNNING',
|
|
262
|
+
data: JSON.stringify(data),
|
|
263
|
+
};
|
|
264
|
+
const nextSteps = idx >= 0 ? steps.map((s, i) => (i === idx ? nextRecord : s)) : [...steps, nextRecord];
|
|
265
|
+
return { ...detail, steps: nextSteps };
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=step-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-state.js","sourceRoot":"","sources":["../../src/utils/step-state.ts"],"names":[],"mappings":"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"}
|