@bian-womp/spark-graph 0.2.45 → 0.2.47

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/lib/cjs/index.cjs CHANGED
@@ -639,6 +639,30 @@ class GraphRuntime {
639
639
  },
640
640
  };
641
641
  }
642
+ createExecutionContext(nodeId, node, inputs, runId, abortSignal, options) {
643
+ const emitHandler = options?.emitHandler ??
644
+ ((handle, value) => this.propagate(nodeId, handle, value));
645
+ const reportProgress = options?.reportProgress ??
646
+ ((p) => {
647
+ node.stats.progress = Math.max(0, Math.min(1, Number(p) || 0));
648
+ });
649
+ return {
650
+ state: node.state,
651
+ setState: (next) => Object.assign(node.state, next),
652
+ emit: emitHandler,
653
+ invalidateDownstream: () => this.invalidateDownstream(nodeId),
654
+ scheduleInputsChanged: () => {
655
+ if (this.allInboundHaveValue(nodeId)) {
656
+ this.scheduleInputsChanged(nodeId);
657
+ }
658
+ },
659
+ getInput: (handle) => inputs[handle],
660
+ environment: this.environment,
661
+ runId,
662
+ abortSignal,
663
+ reportProgress,
664
+ };
665
+ }
642
666
  scheduleInputsChanged(nodeId) {
643
667
  const node = this.nodes.get(nodeId);
644
668
  if (!node)
@@ -681,21 +705,13 @@ class GraphRuntime {
681
705
  if (policy.timeoutMs && policy.timeoutMs > 0) {
682
706
  timeoutId = setTimeout(() => controller.abort("timeout"), policy.timeoutMs);
683
707
  }
684
- const ctx = {
685
- state: node.state,
686
- setState: (next) => Object.assign(node.state, next),
687
- emit: (handle, value) => {
708
+ const ctx = this.createExecutionContext(nodeId, node, capturedInputs, runId, controller.signal, {
709
+ emitHandler: (handle, value) => {
688
710
  const m = policy.asyncConcurrency ?? "switch";
689
711
  if (m !== "merge" && runId !== node.latestRunId)
690
712
  return;
691
713
  this.propagate(nodeId, handle, value);
692
714
  },
693
- invalidateDownstream: () => this.invalidateDownstream(nodeId),
694
- getInput: (handle) => capturedInputs[handle],
695
- environment: this.environment,
696
- runId: runId,
697
- abortSignal: controller.signal,
698
- createAbortController: () => new AbortController(),
699
715
  reportProgress: (p) => {
700
716
  node.stats.progress = Math.max(0, Math.min(1, Number(p) || 0));
701
717
  this.emit("stats", {
@@ -705,10 +721,11 @@ class GraphRuntime {
705
721
  progress: node.stats.progress,
706
722
  });
707
723
  },
708
- };
724
+ });
709
725
  const exec = async (attempt) => {
710
726
  let hadError = false;
711
727
  try {
728
+ node.lifecycle?.prepare?.(node.params ?? {}, ctx);
712
729
  await node.runtime.onInputsChanged?.(capturedInputs, ctx);
713
730
  }
714
731
  catch (err) {
@@ -1150,27 +1167,11 @@ class GraphRuntime {
1150
1167
  launch(invalidate = false) {
1151
1168
  // call onActivated for nodes that implement it
1152
1169
  for (const node of this.nodes.values()) {
1153
- const ctrl = new AbortController();
1154
1170
  const effectiveInputs = this.getEffectiveInputs(node.nodeId);
1155
- const ctx = {
1156
- state: node.state,
1157
- setState: (next) => Object.assign(node.state, next),
1158
- emit: (handle, value) => this.propagate(node.nodeId, handle, value),
1159
- invalidateDownstream: () => this.invalidateDownstream(node.nodeId),
1160
- getInput: (handle) => effectiveInputs[handle],
1161
- environment: this.environment,
1162
- runId: `${node.nodeId}:activation`,
1163
- abortSignal: ctrl.signal,
1164
- createAbortController: () => new AbortController(),
1165
- reportProgress: (p) => {
1166
- node.stats.progress = Math.max(0, Math.min(1, Number(p) || 0));
1167
- },
1168
- };
1169
- node.lifecycle?.init?.(node.params ?? {}, {
1170
- state: node.state,
1171
- setState: (next) => Object.assign(node.state, next),
1172
- });
1173
- node.runtime.onActivated?.(ctx);
1171
+ const ctrl = new AbortController();
1172
+ const ctx = this.createExecutionContext(node.nodeId, node, effectiveInputs, `${node.nodeId}:init`, ctrl.signal);
1173
+ node.lifecycle?.prepare?.(node.params ?? {}, ctx);
1174
+ node.runtime.onActivated?.();
1174
1175
  }
1175
1176
  if (invalidate) {
1176
1177
  // After activation, schedule nodes that have all inbound inputs present
@@ -1184,22 +1185,6 @@ class GraphRuntime {
1184
1185
  const node = this.nodes.get(nodeId);
1185
1186
  if (!node)
1186
1187
  return;
1187
- const ctrl = new AbortController();
1188
- const effectiveInputs = this.getEffectiveInputs(nodeId);
1189
- const ctx = {
1190
- state: node.state,
1191
- setState: (next) => Object.assign(node.state, next),
1192
- emit: (handle, value) => this.propagate(nodeId, handle, value),
1193
- invalidateDownstream: () => this.invalidateDownstream(nodeId),
1194
- getInput: (handle) => effectiveInputs[handle],
1195
- environment: this.environment,
1196
- runId: `${nodeId}:external`,
1197
- abortSignal: ctrl.signal,
1198
- createAbortController: () => new AbortController(),
1199
- reportProgress: (p) => {
1200
- node.stats.progress = Math.max(0, Math.min(1, Number(p) || 0));
1201
- },
1202
- };
1203
1188
  // Built-in support: invalidate event reruns or re-emits without per-node wiring
1204
1189
  if (event &&
1205
1190
  typeof event === "object" &&
@@ -1210,7 +1195,7 @@ class GraphRuntime {
1210
1195
  this.invalidateDownstream(nodeId);
1211
1196
  }
1212
1197
  else {
1213
- node.runtime.onExternalEvent?.(event, ctx);
1198
+ node.runtime.onExternalEvent?.(event, node.state);
1214
1199
  }
1215
1200
  }
1216
1201
  dispose() {
@@ -1428,24 +1413,11 @@ class GraphRuntime {
1428
1413
  };
1429
1414
  this.nodes.set(n.nodeId, rn);
1430
1415
  // Activate new node
1431
- const ctrl = new AbortController();
1432
1416
  const effectiveInputs = this.getEffectiveInputs(rn.nodeId);
1433
- const ctx = {
1434
- state: rn.state,
1435
- setState: (next) => Object.assign(rn.state, next),
1436
- emit: (handle, value) => this.propagate(rn.nodeId, handle, value),
1437
- invalidateDownstream: () => this.invalidateDownstream(rn.nodeId),
1438
- getInput: (handle) => effectiveInputs[handle],
1439
- environment: this.environment,
1440
- runId: `${rn.nodeId}:activation`,
1441
- abortSignal: ctrl.signal,
1442
- createAbortController: () => new AbortController(),
1443
- };
1444
- rn.lifecycle?.init?.(rn.params ?? {}, {
1445
- state: rn.state,
1446
- setState: (next) => Object.assign(rn.state, next),
1447
- });
1448
- rn.runtime.onActivated?.(ctx);
1417
+ const ctrl = new AbortController();
1418
+ const ctx = this.createExecutionContext(rn.nodeId, rn, effectiveInputs, `${rn.nodeId}:init`, ctrl.signal);
1419
+ rn.lifecycle?.prepare?.(rn.params ?? {}, ctx);
1420
+ rn.runtime.onActivated?.();
1449
1421
  }
1450
1422
  else {
1451
1423
  // update params/policy and initialInputs
@@ -2088,13 +2060,13 @@ const ComputeCategory = {
2088
2060
  ctx.emit(h, v);
2089
2061
  }
2090
2062
  },
2091
- onExternalEvent(event, ctx) {
2063
+ onExternalEvent(event, state) {
2092
2064
  try {
2093
2065
  const e = event;
2094
- // Preferred: call a function on ctx.state keyed by e.action
2066
+ // Preferred: call a function on state keyed by e.action
2095
2067
  const action = e?.action;
2096
- if (action && typeof ctx.state?.[action] === "function") {
2097
- const fn = ctx.state[action];
2068
+ if (action && typeof state?.[action] === "function") {
2069
+ const fn = state[action];
2098
2070
  // Normalize args: prefer explicit args array, else wrap single value;
2099
2071
  let args = [];
2100
2072
  if (Array.isArray(e?.args))