@bian-womp/spark-graph 0.2.22 → 0.2.24
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 +39 -12
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/builder/GraphBuilder.d.ts +2 -1
- package/lib/cjs/src/builder/GraphBuilder.d.ts.map +1 -1
- package/lib/cjs/src/builder/Registry.d.ts +3 -3
- package/lib/cjs/src/builder/Registry.d.ts.map +1 -1
- package/lib/cjs/src/core/types.d.ts +19 -45
- package/lib/cjs/src/core/types.d.ts.map +1 -1
- package/lib/cjs/src/index.d.ts +1 -1
- package/lib/cjs/src/index.d.ts.map +1 -1
- package/lib/cjs/src/misc/base.d.ts +1 -1
- package/lib/cjs/src/misc/base.d.ts.map +1 -1
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +3 -2
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/index.js +39 -12
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/builder/GraphBuilder.d.ts +2 -1
- package/lib/esm/src/builder/GraphBuilder.d.ts.map +1 -1
- package/lib/esm/src/builder/Registry.d.ts +3 -3
- package/lib/esm/src/builder/Registry.d.ts.map +1 -1
- package/lib/esm/src/core/types.d.ts +19 -45
- package/lib/esm/src/core/types.d.ts.map +1 -1
- package/lib/esm/src/index.d.ts +1 -1
- package/lib/esm/src/index.d.ts.map +1 -1
- package/lib/esm/src/misc/base.d.ts +1 -1
- package/lib/esm/src/misc/base.d.ts.map +1 -1
- package/lib/esm/src/runtime/GraphRuntime.d.ts +3 -2
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -402,6 +402,13 @@ class Registry {
|
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
// Helper: typed promise detection and unwrapping for T | Promise<T>
|
|
406
|
+
function isPromise(value) {
|
|
407
|
+
return !!value && typeof value.then === "function";
|
|
408
|
+
}
|
|
409
|
+
async function unwrapMaybePromise(value) {
|
|
410
|
+
return isPromise(value) ? await value : value;
|
|
411
|
+
}
|
|
405
412
|
class GraphRuntime {
|
|
406
413
|
constructor() {
|
|
407
414
|
this.nodes = new Map();
|
|
@@ -410,6 +417,8 @@ class GraphRuntime {
|
|
|
410
417
|
this.resolvedByNode = new Map();
|
|
411
418
|
this.listeners = new Map();
|
|
412
419
|
this.environment = {};
|
|
420
|
+
// Token to guard async resolveHandles recomputes per node
|
|
421
|
+
this.recomputeTokenByNode = new Map();
|
|
413
422
|
this.paused = false;
|
|
414
423
|
// For array-typed target inputs, keep per-edge contributions so successive runs
|
|
415
424
|
// from the same source replace their slice instead of accumulating forever.
|
|
@@ -437,7 +446,8 @@ class GraphRuntime {
|
|
|
437
446
|
gr.registry = registry;
|
|
438
447
|
gr.environment = opts?.environment ?? {};
|
|
439
448
|
// Precompute per-node resolved handles (use def-provided overrides; do not compute dynamically here)
|
|
440
|
-
|
|
449
|
+
const initial = GraphRuntime.computeResolvedHandleMap(def, registry, gr.environment);
|
|
450
|
+
gr.resolvedByNode = initial.map;
|
|
441
451
|
// Instantiate nodes
|
|
442
452
|
for (const n of def.nodes) {
|
|
443
453
|
const desc = registry.nodes.get(n.typeId);
|
|
@@ -510,6 +520,9 @@ class GraphRuntime {
|
|
|
510
520
|
: JSON.parse(JSON.stringify(value));
|
|
511
521
|
}
|
|
512
522
|
}
|
|
523
|
+
// Schedule async recompute only for nodes that indicated Promise-based resolveHandles
|
|
524
|
+
for (const nodeId of initial.pending)
|
|
525
|
+
gr.scheduleRecomputeHandles(nodeId);
|
|
513
526
|
return gr;
|
|
514
527
|
}
|
|
515
528
|
on(event, handler) {
|
|
@@ -916,6 +929,7 @@ class GraphRuntime {
|
|
|
916
929
|
// Helper: build map of resolved handles per node from def (prefer def.resolvedHandles, otherwise registry statics)
|
|
917
930
|
static computeResolvedHandleMap(def, registry, environment) {
|
|
918
931
|
const out = new Map();
|
|
932
|
+
const pending = new Set();
|
|
919
933
|
for (const n of def.nodes) {
|
|
920
934
|
const desc = registry.nodes.get(n.typeId);
|
|
921
935
|
if (!desc)
|
|
@@ -927,11 +941,19 @@ class GraphRuntime {
|
|
|
927
941
|
let dyn = {};
|
|
928
942
|
try {
|
|
929
943
|
if (typeof desc.resolveHandles === "function") {
|
|
930
|
-
|
|
944
|
+
const maybe = desc.resolveHandles({
|
|
931
945
|
environment: environment || {},
|
|
932
946
|
params: n.params,
|
|
933
947
|
inputs: undefined,
|
|
934
948
|
});
|
|
949
|
+
// Only use sync results here; async results are applied via recompute later
|
|
950
|
+
if (isPromise(maybe)) {
|
|
951
|
+
// mark node as pending async recompute
|
|
952
|
+
pending.add(n.nodeId);
|
|
953
|
+
}
|
|
954
|
+
else {
|
|
955
|
+
dyn = maybe || {};
|
|
956
|
+
}
|
|
935
957
|
}
|
|
936
958
|
}
|
|
937
959
|
catch {
|
|
@@ -955,7 +977,7 @@ class GraphRuntime {
|
|
|
955
977
|
};
|
|
956
978
|
out.set(n.nodeId, { inputs, outputs, inputDefaults });
|
|
957
979
|
}
|
|
958
|
-
return out;
|
|
980
|
+
return { map: out, pending };
|
|
959
981
|
}
|
|
960
982
|
// Helper: build runtime edges with coercions using resolved handles
|
|
961
983
|
static buildEdges(def, registry, resolvedByNode) {
|
|
@@ -1357,7 +1379,8 @@ class GraphRuntime {
|
|
|
1357
1379
|
prevOutTargets.set(e.source.nodeId, tmap);
|
|
1358
1380
|
}
|
|
1359
1381
|
// Precompute per-node resolved handles for updated graph (include dynamic)
|
|
1360
|
-
|
|
1382
|
+
const resolved = GraphRuntime.computeResolvedHandleMap(def, registry, this.environment);
|
|
1383
|
+
this.resolvedByNode = resolved.map;
|
|
1361
1384
|
// Rebuild edges mapping with coercions
|
|
1362
1385
|
this.edges = GraphRuntime.buildEdges(def, registry, this.resolvedByNode);
|
|
1363
1386
|
// Build new inbound map
|
|
@@ -1516,6 +1539,9 @@ class GraphRuntime {
|
|
|
1516
1539
|
if (byHandle.size === 0)
|
|
1517
1540
|
this.arrayInputBuckets.delete(nodeId);
|
|
1518
1541
|
}
|
|
1542
|
+
// Schedule async recompute for nodes that indicated Promise-based resolveHandles in this update
|
|
1543
|
+
for (const nodeId of resolved.pending)
|
|
1544
|
+
this.scheduleRecomputeHandles(nodeId);
|
|
1519
1545
|
}
|
|
1520
1546
|
// Schedule a recomputation of dynamic handles for a node (async to avoid mutating during propagation)
|
|
1521
1547
|
scheduleRecomputeHandles(nodeId) {
|
|
@@ -1526,16 +1552,11 @@ class GraphRuntime {
|
|
|
1526
1552
|
if (!node)
|
|
1527
1553
|
return;
|
|
1528
1554
|
setTimeout(() => {
|
|
1529
|
-
|
|
1530
|
-
this.recomputeHandlesForNode(nodeId);
|
|
1531
|
-
}
|
|
1532
|
-
catch {
|
|
1533
|
-
// ignore recompute errors
|
|
1534
|
-
}
|
|
1555
|
+
void this.recomputeHandlesForNode(nodeId);
|
|
1535
1556
|
}, 0);
|
|
1536
1557
|
}
|
|
1537
1558
|
// Recompute dynamic handles for a single node using current inputs/environment
|
|
1538
|
-
recomputeHandlesForNode(nodeId) {
|
|
1559
|
+
async recomputeHandlesForNode(nodeId) {
|
|
1539
1560
|
const registry = this.registry;
|
|
1540
1561
|
const node = this.nodes.get(nodeId);
|
|
1541
1562
|
if (!node)
|
|
@@ -1546,17 +1567,23 @@ class GraphRuntime {
|
|
|
1546
1567
|
const resolveHandles = desc.resolveHandles;
|
|
1547
1568
|
if (typeof resolveHandles !== "function")
|
|
1548
1569
|
return;
|
|
1570
|
+
const token = (this.recomputeTokenByNode.get(nodeId) ?? 0) + 1;
|
|
1571
|
+
this.recomputeTokenByNode.set(nodeId, token);
|
|
1549
1572
|
let r;
|
|
1550
1573
|
try {
|
|
1551
|
-
|
|
1574
|
+
const res = resolveHandles({
|
|
1552
1575
|
environment: this.environment || {},
|
|
1553
1576
|
params: node.params,
|
|
1554
1577
|
inputs: node.inputs || {},
|
|
1555
1578
|
});
|
|
1579
|
+
r = await unwrapMaybePromise(res);
|
|
1556
1580
|
}
|
|
1557
1581
|
catch {
|
|
1558
1582
|
return;
|
|
1559
1583
|
}
|
|
1584
|
+
// If a newer recompute was scheduled, drop this result
|
|
1585
|
+
if ((this.recomputeTokenByNode.get(nodeId) ?? 0) !== token)
|
|
1586
|
+
return;
|
|
1560
1587
|
const inputs = { ...desc.inputs, ...r?.inputs };
|
|
1561
1588
|
const outputs = { ...desc.outputs, ...r?.outputs };
|
|
1562
1589
|
const inputDefaults = { ...desc.inputDefaults, ...r?.inputDefaults };
|