@bian-womp/spark-graph 0.3.3 → 0.3.5

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
@@ -1528,10 +1528,16 @@ class NodeExecutor {
1528
1528
  invalidateDownstream: () => {
1529
1529
  this.edgePropagator.invalidateDownstream(nodeId);
1530
1530
  },
1531
- execute: () => {
1531
+ execute: (resolve, opts) => {
1532
1532
  if (this.graph.allInboundHaveValue(nodeId)) {
1533
- // Preserve run-context IDs when scheduling from execution context
1534
- this.execute(nodeId, runContextIds);
1533
+ let runContextIdsToUse = this.runtime.getRunMode() === "auto" ? undefined : runContextIds;
1534
+ if (this.runtime.getRunMode() === "manual" &&
1535
+ (!runContextIds || runContextIds.size === 0)) {
1536
+ runContextIdsToUse = new Set([
1537
+ this.runContextManager.createRunContext(nodeId, resolve, opts),
1538
+ ]);
1539
+ }
1540
+ this.execute(nodeId, runContextIdsToUse);
1535
1541
  }
1536
1542
  },
1537
1543
  getInput: (handle) => inputs[handle],
@@ -1554,12 +1560,21 @@ class NodeExecutor {
1554
1560
  console.warn("NodeExecutor.execute: no runMode, skipping execution");
1555
1561
  return;
1556
1562
  }
1563
+ // In manual mode, require runContextIds unless autoRun policy is set
1557
1564
  if (runMode === "manual" && (!runContextIds || runContextIds.size === 0)) {
1558
- console.warn("NodeExecutor.execute: no runContextIds provided, skipping execution");
1559
- return;
1565
+ // If autoRun is true, auto-generate a run context (similar to createExecutionContext pattern)
1566
+ if (node.policy?.autoRun === true) {
1567
+ runContextIds = new Set([
1568
+ this.runContextManager.createRunContext(nodeId),
1569
+ ]);
1570
+ }
1571
+ else {
1572
+ console.warn("NodeExecutor.execute: no runContextIds provided in manual mode, skipping execution");
1573
+ return;
1574
+ }
1560
1575
  }
1561
1576
  if (runMode === "auto" && runContextIds && runContextIds.size > 0) {
1562
- console.warn("NodeExecutor.execute: runContextIds provided in auto-mode, ignoring");
1577
+ console.warn("NodeExecutor.execute: runContextIds provided in auto mode, ignoring");
1563
1578
  runContextIds = undefined;
1564
1579
  }
1565
1580
  // Early validation for auto-mode paused state
@@ -2103,9 +2118,12 @@ class GraphRuntime {
2103
2118
  }
2104
2119
  }
2105
2120
  // In auto mode, input updates can trigger execution; in manual mode they never should.
2121
+ // However, if autoRun policy is set, nodes run automatically even in manual mode.
2106
2122
  if (anyChanged) {
2107
2123
  this.handleResolver.scheduleRecomputeHandles(nodeId);
2108
- if (this.runMode === "auto" && this.graph.allInboundHaveValue(nodeId)) {
2124
+ const node = this.graph.getNode(nodeId);
2125
+ const shouldAutoRun = this.runMode === "auto" || node?.policy?.autoRun === true;
2126
+ if (shouldAutoRun && this.graph.allInboundHaveValue(nodeId)) {
2109
2127
  this.execute(nodeId);
2110
2128
  }
2111
2129
  }
@@ -2379,6 +2397,14 @@ class GraphRuntime {
2379
2397
  }
2380
2398
  else {
2381
2399
  existing.params = n.params;
2400
+ // Re-merge policy when params change (params.policy can override descriptor/category policy)
2401
+ const desc = registry.nodes.get(existing.typeId);
2402
+ const cat = registry.categories.get(desc?.categoryId ?? "");
2403
+ existing.policy = {
2404
+ ...cat?.policy,
2405
+ ...desc?.policy,
2406
+ ...n.params?.policy,
2407
+ };
2382
2408
  if (!existing.stats) {
2383
2409
  existing.stats = {
2384
2410
  runs: 0,
@@ -3236,6 +3262,7 @@ function setupBasicGraphRegistry(id) {
3236
3262
  categoryId: "compute",
3237
3263
  inputs: { Value: "base.float" },
3238
3264
  outputs: { Result: "base.float" },
3265
+ policy: { autoRun: true },
3239
3266
  impl: (ins) => ({ Result: Number(ins.Value) }),
3240
3267
  });
3241
3268
  registry.registerNode({
@@ -3243,6 +3270,7 @@ function setupBasicGraphRegistry(id) {
3243
3270
  categoryId: "compute",
3244
3271
  inputs: { Value: "base.string" },
3245
3272
  outputs: { Result: "base.string" },
3273
+ policy: { autoRun: true },
3246
3274
  impl: (ins) => ({ Result: String(ins.Value) }),
3247
3275
  });
3248
3276
  registry.registerNode({
@@ -3250,6 +3278,7 @@ function setupBasicGraphRegistry(id) {
3250
3278
  categoryId: "compute",
3251
3279
  inputs: { Value: "base.bool" },
3252
3280
  outputs: { Result: "base.bool" },
3281
+ policy: { autoRun: true },
3253
3282
  impl: (ins) => ({ Result: Boolean(ins.Value) }),
3254
3283
  });
3255
3284
  registry.registerNode({
@@ -3257,6 +3286,7 @@ function setupBasicGraphRegistry(id) {
3257
3286
  categoryId: "compute",
3258
3287
  inputs: { Value: "base.object" },
3259
3288
  outputs: { Result: "base.object" },
3289
+ policy: { autoRun: true },
3260
3290
  impl: (ins) => ({ Result: ins.Value }),
3261
3291
  });
3262
3292
  registry.registerNode({
@@ -3264,6 +3294,7 @@ function setupBasicGraphRegistry(id) {
3264
3294
  categoryId: "compute",
3265
3295
  inputs: { Value: "base.vec3" },
3266
3296
  outputs: { Result: "base.vec3" },
3297
+ policy: { autoRun: true },
3267
3298
  impl: (ins) => ({ Result: ins.Value }),
3268
3299
  });
3269
3300
  // JSON parser node: base.stringToObject