@bian-womp/spark-graph 0.2.34 → 0.2.36
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 +71 -114
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +1 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/index.js +71 -114
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/runtime/GraphRuntime.d.ts +1 -0
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -31,6 +31,7 @@ export declare class GraphRuntime {
|
|
|
31
31
|
private static buildEdgeConverters;
|
|
32
32
|
private scheduleInputsChanged;
|
|
33
33
|
private allInboundHaveValue;
|
|
34
|
+
private getEffectiveInputs;
|
|
34
35
|
private invalidateDownstream;
|
|
35
36
|
private propagate;
|
|
36
37
|
private static computeResolvedHandleMap;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphRuntime.d.ts","sourceRoot":"","sources":["../../../../src/runtime/GraphRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,eAAe,EAIhB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAIV,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAQvB,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,IAAI,CAC7D,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,KAClB,IAAI,CAAC;AAUV,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;CACrB;AA+BD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAE5B,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,SAAS,CAGb;IACJ,OAAO,CAAC,WAAW,CAA+B;IAElD,OAAO,CAAC,oBAAoB,CAA6B;IACzD,OAAO,CAAC,MAAM,CAAS;IAIvB,OAAO,CAAC,iBAAiB,CAGrB;IAGJ,OAAO,CAAC,WAAW;IAanB,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,QAAQ,EAClB,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAC/C,YAAY;
|
|
1
|
+
{"version":3,"file":"GraphRuntime.d.ts","sourceRoot":"","sources":["../../../../src/runtime/GraphRuntime.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/index.js
CHANGED
|
@@ -483,41 +483,12 @@ class GraphRuntime {
|
|
|
483
483
|
queued: 0,
|
|
484
484
|
progress: 0,
|
|
485
485
|
},
|
|
486
|
+
initialInputs: n.initialInputs ?? {},
|
|
486
487
|
};
|
|
487
488
|
gr.nodes.set(n.nodeId, rn);
|
|
488
489
|
}
|
|
489
490
|
// Instantiate edges
|
|
490
491
|
gr.edges = GraphRuntime.buildEdges(def, registry, gr.resolvedByNode);
|
|
491
|
-
// After nodes and edges exist, seed registry-, dynamic- and graph-level defaults
|
|
492
|
-
for (const n of def.nodes) {
|
|
493
|
-
const node = gr.nodes.get(n.nodeId);
|
|
494
|
-
const desc = registry.nodes.get(n.typeId);
|
|
495
|
-
if (!node || !desc)
|
|
496
|
-
continue;
|
|
497
|
-
// Resolve registry-level defaults and dynamic (resolved) defaults
|
|
498
|
-
const regDefaults = desc.inputDefaults ?? {};
|
|
499
|
-
const dynDefaults = gr.resolvedByNode.get(n.nodeId)?.inputDefaults ?? {};
|
|
500
|
-
const graphDefaults = n.initialInputs ?? {};
|
|
501
|
-
// Apply precedence: graph-level overrides dynamic, which overrides registry-level
|
|
502
|
-
const merged = {
|
|
503
|
-
...regDefaults,
|
|
504
|
-
...dynDefaults,
|
|
505
|
-
...graphDefaults,
|
|
506
|
-
};
|
|
507
|
-
for (const [handle, value] of Object.entries(merged)) {
|
|
508
|
-
// Only seed if input has no inbound wiring
|
|
509
|
-
const hasInbound = gr.edges.some((e) => e.target.nodeId === n.nodeId && e.target.handle === handle);
|
|
510
|
-
if (hasInbound)
|
|
511
|
-
continue;
|
|
512
|
-
if (value === undefined)
|
|
513
|
-
continue;
|
|
514
|
-
// Clone to avoid accidental shared references
|
|
515
|
-
node.inputs[handle] =
|
|
516
|
-
typeof structuredClone === "function"
|
|
517
|
-
? structuredClone(value)
|
|
518
|
-
: JSON.parse(JSON.stringify(value));
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
492
|
// Schedule async recompute only for nodes that indicated Promise-based resolveHandles
|
|
522
493
|
for (const nodeId of initial.pending)
|
|
523
494
|
gr.scheduleRecomputeHandles(nodeId);
|
|
@@ -641,6 +612,8 @@ class GraphRuntime {
|
|
|
641
612
|
return;
|
|
642
613
|
const now = Date.now();
|
|
643
614
|
const policy = node.policy ?? {};
|
|
615
|
+
// Compute effective inputs (real inputs + defaults) for this execution
|
|
616
|
+
const effectiveInputs = this.getEffectiveInputs(nodeId);
|
|
644
617
|
if (policy.debounceMs &&
|
|
645
618
|
node.lastScheduledAt &&
|
|
646
619
|
now - node.lastScheduledAt < policy.debounceMs) {
|
|
@@ -648,7 +621,7 @@ class GraphRuntime {
|
|
|
648
621
|
node.queue.splice(0, node.queue.length);
|
|
649
622
|
node.runSeq += 1;
|
|
650
623
|
const rid = `${nodeId}:${node.runSeq}:${now}`;
|
|
651
|
-
node.queue.push({ runId: rid, inputs:
|
|
624
|
+
node.queue.push({ runId: rid, inputs: effectiveInputs });
|
|
652
625
|
return;
|
|
653
626
|
}
|
|
654
627
|
node.lastScheduledAt = now;
|
|
@@ -754,7 +727,7 @@ class GraphRuntime {
|
|
|
754
727
|
return;
|
|
755
728
|
if (mode === "queue") {
|
|
756
729
|
const maxQ = policy.maxQueue ?? 8;
|
|
757
|
-
node.queue.push({ runId: rid, inputs:
|
|
730
|
+
node.queue.push({ runId: rid, inputs: effectiveInputs });
|
|
758
731
|
if (node.queue.length > maxQ)
|
|
759
732
|
node.queue.shift();
|
|
760
733
|
const processNext = () => {
|
|
@@ -773,7 +746,7 @@ class GraphRuntime {
|
|
|
773
746
|
return;
|
|
774
747
|
}
|
|
775
748
|
// switch or merge
|
|
776
|
-
startRun(rid,
|
|
749
|
+
startRun(rid, effectiveInputs);
|
|
777
750
|
}
|
|
778
751
|
// Returns true if all inbound handles for the node currently have a value
|
|
779
752
|
allInboundHaveValue(nodeId) {
|
|
@@ -789,6 +762,62 @@ class GraphRuntime {
|
|
|
789
762
|
}
|
|
790
763
|
return true;
|
|
791
764
|
}
|
|
765
|
+
// Computes effective inputs for a node by merging real inputs with defaults
|
|
766
|
+
// Defaults are applied only for unbound handles that have no explicit value
|
|
767
|
+
// This method does NOT mutate node.inputs - defaults remain virtual
|
|
768
|
+
// Dynamic handles (from resolveHandles) do NOT get defaults applied - they are metadata-only
|
|
769
|
+
getEffectiveInputs(nodeId) {
|
|
770
|
+
const node = this.nodes.get(nodeId);
|
|
771
|
+
if (!node)
|
|
772
|
+
return {};
|
|
773
|
+
const registry = this.registry;
|
|
774
|
+
if (!registry)
|
|
775
|
+
return {};
|
|
776
|
+
const desc = registry.nodes.get(node.typeId);
|
|
777
|
+
if (!desc)
|
|
778
|
+
return {};
|
|
779
|
+
const resolved = this.resolvedByNode.get(nodeId);
|
|
780
|
+
const regDefaults = desc.inputDefaults ?? {};
|
|
781
|
+
const dynDefaults = resolved?.inputDefaults ?? {};
|
|
782
|
+
const graphDefaults = node.initialInputs ?? {};
|
|
783
|
+
// Identify which handles are dynamically resolved (not in registry statics)
|
|
784
|
+
// Dynamic handles are metadata-only and should not receive defaults in execution
|
|
785
|
+
const staticHandles = new Set(Object.keys(desc.inputs ?? {}));
|
|
786
|
+
const dynamicHandles = new Set(Object.keys(resolved?.inputs ?? {}).filter((h) => !staticHandles.has(h)));
|
|
787
|
+
// Precedence: graph > dynamic > registry
|
|
788
|
+
const mergedDefaults = {
|
|
789
|
+
...regDefaults,
|
|
790
|
+
...dynDefaults,
|
|
791
|
+
...graphDefaults,
|
|
792
|
+
};
|
|
793
|
+
// Start with real inputs only (no defaults)
|
|
794
|
+
const effective = { ...node.inputs };
|
|
795
|
+
// Build set of inbound handles (wired inputs)
|
|
796
|
+
const inbound = new Set(this.edges
|
|
797
|
+
.filter((e) => e.target.nodeId === nodeId)
|
|
798
|
+
.map((e) => e.target.handle));
|
|
799
|
+
// Apply defaults only for:
|
|
800
|
+
// 1. Unbound handles that have no explicit value
|
|
801
|
+
// 2. Static handles (not dynamically resolved)
|
|
802
|
+
// This prevents dynamic handles (like geo:*) from getting defaults in execution
|
|
803
|
+
// Dynamic handles are metadata-only for UI display, not execution values
|
|
804
|
+
for (const [handle, defaultValue] of Object.entries(mergedDefaults)) {
|
|
805
|
+
if (defaultValue === undefined)
|
|
806
|
+
continue;
|
|
807
|
+
if (inbound.has(handle))
|
|
808
|
+
continue; // Don't override wired inputs
|
|
809
|
+
if (effective[handle] !== undefined)
|
|
810
|
+
continue; // Already has value
|
|
811
|
+
if (dynamicHandles.has(handle))
|
|
812
|
+
continue; // Skip defaults for dynamic handles
|
|
813
|
+
// Clone to avoid shared references
|
|
814
|
+
effective[handle] =
|
|
815
|
+
typeof structuredClone === "function"
|
|
816
|
+
? structuredClone(defaultValue)
|
|
817
|
+
: JSON.parse(JSON.stringify(defaultValue));
|
|
818
|
+
}
|
|
819
|
+
return effective;
|
|
820
|
+
}
|
|
792
821
|
invalidateDownstream(nodeId) {
|
|
793
822
|
// Notifies dependents; for now we propagate current outputs
|
|
794
823
|
for (const e of this.edges.filter((e) => e.source.nodeId === nodeId)) {
|
|
@@ -1090,12 +1119,13 @@ class GraphRuntime {
|
|
|
1090
1119
|
// call onActivated for nodes that implement it
|
|
1091
1120
|
for (const node of this.nodes.values()) {
|
|
1092
1121
|
const ctrl = new AbortController();
|
|
1122
|
+
const effectiveInputs = this.getEffectiveInputs(node.nodeId);
|
|
1093
1123
|
const ctx = {
|
|
1094
1124
|
state: node.state,
|
|
1095
1125
|
setState: (next) => Object.assign(node.state, next),
|
|
1096
1126
|
emit: (handle, value) => this.propagate(node.nodeId, handle, value),
|
|
1097
1127
|
invalidateDownstream: () => this.invalidateDownstream(node.nodeId),
|
|
1098
|
-
getInput: (handle) =>
|
|
1128
|
+
getInput: (handle) => effectiveInputs[handle],
|
|
1099
1129
|
environment: this.environment,
|
|
1100
1130
|
runId: `${node.nodeId}:activation`,
|
|
1101
1131
|
abortSignal: ctrl.signal,
|
|
@@ -1123,12 +1153,13 @@ class GraphRuntime {
|
|
|
1123
1153
|
if (!node)
|
|
1124
1154
|
return;
|
|
1125
1155
|
const ctrl = new AbortController();
|
|
1156
|
+
const effectiveInputs = this.getEffectiveInputs(nodeId);
|
|
1126
1157
|
const ctx = {
|
|
1127
1158
|
state: node.state,
|
|
1128
1159
|
setState: (next) => Object.assign(node.state, next),
|
|
1129
1160
|
emit: (handle, value) => this.propagate(nodeId, handle, value),
|
|
1130
1161
|
invalidateDownstream: () => this.invalidateDownstream(nodeId),
|
|
1131
|
-
getInput: (handle) =>
|
|
1162
|
+
getInput: (handle) => effectiveInputs[handle],
|
|
1132
1163
|
environment: this.environment,
|
|
1133
1164
|
runId: `${nodeId}:external`,
|
|
1134
1165
|
abortSignal: ctrl.signal,
|
|
@@ -1385,16 +1416,18 @@ class GraphRuntime {
|
|
|
1385
1416
|
queued: 0,
|
|
1386
1417
|
progress: 0,
|
|
1387
1418
|
},
|
|
1419
|
+
initialInputs: n.initialInputs ?? {},
|
|
1388
1420
|
};
|
|
1389
1421
|
this.nodes.set(n.nodeId, rn);
|
|
1390
1422
|
// Activate new node
|
|
1391
1423
|
const ctrl = new AbortController();
|
|
1424
|
+
const effectiveInputs = this.getEffectiveInputs(rn.nodeId);
|
|
1392
1425
|
const ctx = {
|
|
1393
1426
|
state: rn.state,
|
|
1394
1427
|
setState: (next) => Object.assign(rn.state, next),
|
|
1395
1428
|
emit: (handle, value) => this.propagate(rn.nodeId, handle, value),
|
|
1396
1429
|
invalidateDownstream: () => this.invalidateDownstream(rn.nodeId),
|
|
1397
|
-
getInput: (handle) =>
|
|
1430
|
+
getInput: (handle) => effectiveInputs[handle],
|
|
1398
1431
|
environment: this.environment,
|
|
1399
1432
|
runId: `${rn.nodeId}:activation`,
|
|
1400
1433
|
abortSignal: ctrl.signal,
|
|
@@ -1407,8 +1440,9 @@ class GraphRuntime {
|
|
|
1407
1440
|
rn.runtime.onActivated?.(ctx);
|
|
1408
1441
|
}
|
|
1409
1442
|
else {
|
|
1410
|
-
// update params/policy
|
|
1443
|
+
// update params/policy and initialInputs
|
|
1411
1444
|
existing.params = n.params;
|
|
1445
|
+
existing.initialInputs = n.initialInputs ?? {};
|
|
1412
1446
|
if (!existing.stats) {
|
|
1413
1447
|
existing.stats = {
|
|
1414
1448
|
runs: 0,
|
|
@@ -1462,32 +1496,7 @@ class GraphRuntime {
|
|
|
1462
1496
|
}
|
|
1463
1497
|
}
|
|
1464
1498
|
}
|
|
1465
|
-
// If input lost inbound, try to re-seed from defaults
|
|
1466
1499
|
if (changed) {
|
|
1467
|
-
const defNode = def.nodes.find((n) => n.nodeId === nodeId);
|
|
1468
|
-
if (defNode) {
|
|
1469
|
-
const desc = registry.nodes.get(defNode.typeId);
|
|
1470
|
-
if (desc) {
|
|
1471
|
-
const regDefaults = desc.inputDefaults ?? {};
|
|
1472
|
-
const dynDefaults = this.resolvedByNode.get(defNode.nodeId)?.inputDefaults ?? {};
|
|
1473
|
-
const graphDefaults = defNode.initialInputs ?? {};
|
|
1474
|
-
const merged = {
|
|
1475
|
-
...regDefaults,
|
|
1476
|
-
...dynDefaults,
|
|
1477
|
-
...graphDefaults,
|
|
1478
|
-
};
|
|
1479
|
-
for (const h of Array.from(prevSet)) {
|
|
1480
|
-
if (!currSet.has(h) && node.inputs[h] === undefined) {
|
|
1481
|
-
const v = merged[h];
|
|
1482
|
-
if (v !== undefined)
|
|
1483
|
-
node.inputs[h] =
|
|
1484
|
-
typeof structuredClone === "function"
|
|
1485
|
-
? structuredClone(v)
|
|
1486
|
-
: JSON.parse(JSON.stringify(v));
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
1500
|
// Clear buckets for handles that lost inbound
|
|
1492
1501
|
const bucketsForNode = this.arrayInputBuckets.get(nodeId);
|
|
1493
1502
|
if (bucketsForNode) {
|
|
@@ -1545,34 +1554,6 @@ class GraphRuntime {
|
|
|
1545
1554
|
}
|
|
1546
1555
|
}
|
|
1547
1556
|
}
|
|
1548
|
-
// Seed defaults for nodes (new or existing) where inputs are still undefined and not inbound
|
|
1549
|
-
for (const n of def.nodes) {
|
|
1550
|
-
const node = this.nodes.get(n.nodeId);
|
|
1551
|
-
const desc = registry.nodes.get(n.typeId);
|
|
1552
|
-
if (!node || !desc)
|
|
1553
|
-
continue;
|
|
1554
|
-
const regDefaults = desc.inputDefaults ?? {};
|
|
1555
|
-
const dynDefaults = this.resolvedByNode.get(n.nodeId)?.inputDefaults ?? {};
|
|
1556
|
-
const graphDefaults = n.initialInputs ?? {};
|
|
1557
|
-
const merged = {
|
|
1558
|
-
...regDefaults,
|
|
1559
|
-
...dynDefaults,
|
|
1560
|
-
...graphDefaults,
|
|
1561
|
-
};
|
|
1562
|
-
const inboundSet = nextInbound.get(n.nodeId) ?? new Set();
|
|
1563
|
-
for (const [handle, value] of Object.entries(merged)) {
|
|
1564
|
-
if (value === undefined)
|
|
1565
|
-
continue;
|
|
1566
|
-
if (inboundSet.has(handle))
|
|
1567
|
-
continue;
|
|
1568
|
-
if (node.inputs[handle] !== undefined)
|
|
1569
|
-
continue;
|
|
1570
|
-
node.inputs[handle] =
|
|
1571
|
-
typeof structuredClone === "function"
|
|
1572
|
-
? structuredClone(value)
|
|
1573
|
-
: JSON.parse(JSON.stringify(value));
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
1557
|
// Prune array bucket contributions for edges that no longer exist
|
|
1577
1558
|
const validPerTarget = new Map();
|
|
1578
1559
|
for (const ed of this.edges) {
|
|
@@ -1651,30 +1632,6 @@ class GraphRuntime {
|
|
|
1651
1632
|
return;
|
|
1652
1633
|
this.resolvedByNode.set(nodeId, next);
|
|
1653
1634
|
this.updateNodeHandles(nodeId, next, registry);
|
|
1654
|
-
// Seed defaults for newly introduced inputs that are not inbound
|
|
1655
|
-
const inbound = this.edges
|
|
1656
|
-
.filter((e) => e.target.nodeId === nodeId)
|
|
1657
|
-
.map((e) => e.target.handle);
|
|
1658
|
-
for (const [handle, value] of Object.entries(inputDefaults)) {
|
|
1659
|
-
if (value === undefined)
|
|
1660
|
-
continue;
|
|
1661
|
-
if (inbound.includes(handle))
|
|
1662
|
-
continue;
|
|
1663
|
-
if (node.inputs[handle] === undefined) {
|
|
1664
|
-
node.inputs[handle] =
|
|
1665
|
-
typeof structuredClone === "function"
|
|
1666
|
-
? structuredClone(value)
|
|
1667
|
-
: JSON.parse(JSON.stringify(value));
|
|
1668
|
-
// Emit input value event for seeded defaults
|
|
1669
|
-
this.emit("value", {
|
|
1670
|
-
nodeId,
|
|
1671
|
-
handle,
|
|
1672
|
-
value: node.inputs[handle],
|
|
1673
|
-
io: "input",
|
|
1674
|
-
runtimeTypeId: getTypedOutputTypeId(node.inputs[handle]),
|
|
1675
|
-
});
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
1635
|
// Notify graph updated for UI parity
|
|
1679
1636
|
this.emit("invalidate", { reason: "graph-updated" });
|
|
1680
1637
|
}
|