@bian-womp/spark-graph 0.2.14 → 0.2.15
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 +86 -75
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/types.d.ts +12 -0
- package/lib/cjs/src/core/types.d.ts.map +1 -1
- package/lib/cjs/src/misc/base.d.ts.map +1 -1
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +2 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/index.js +86 -75
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/types.d.ts +12 -0
- package/lib/esm/src/core/types.d.ts.map +1 -1
- package/lib/esm/src/misc/base.d.ts.map +1 -1
- package/lib/esm/src/runtime/GraphRuntime.d.ts +2 -0
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -433,6 +433,8 @@ class GraphRuntime {
|
|
|
433
433
|
static create(def, registry, opts) {
|
|
434
434
|
const gr = new GraphRuntime();
|
|
435
435
|
gr.environment = opts?.environment ?? {};
|
|
436
|
+
// Precompute per-node resolved handles (use def-provided overrides; do not compute dynamically here)
|
|
437
|
+
const resolvedByNode = GraphRuntime.computeResolvedHandleMap(def, registry);
|
|
436
438
|
// Instantiate nodes
|
|
437
439
|
for (const n of def.nodes) {
|
|
438
440
|
const desc = registry.nodes.get(n.typeId);
|
|
@@ -472,46 +474,7 @@ class GraphRuntime {
|
|
|
472
474
|
gr.nodes.set(n.nodeId, rn);
|
|
473
475
|
}
|
|
474
476
|
// Instantiate edges
|
|
475
|
-
gr.edges =
|
|
476
|
-
// infer type from source output if missing
|
|
477
|
-
const srcNode = def.nodes.find((n) => n.nodeId === e.source.nodeId);
|
|
478
|
-
const dstNode = def.nodes.find((n) => n.nodeId === e.target.nodeId);
|
|
479
|
-
let effectiveTypeId = e.typeId;
|
|
480
|
-
let srcDeclared;
|
|
481
|
-
let dstDeclared;
|
|
482
|
-
if (srcNode) {
|
|
483
|
-
const srcDesc = registry.nodes.get(srcNode.typeId);
|
|
484
|
-
if (srcDesc) {
|
|
485
|
-
srcDeclared = srcDesc.outputs[e.source.handle];
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
if (!effectiveTypeId) {
|
|
489
|
-
effectiveTypeId = Array.isArray(srcDeclared)
|
|
490
|
-
? srcDeclared[0]
|
|
491
|
-
: srcDeclared;
|
|
492
|
-
}
|
|
493
|
-
if (dstNode) {
|
|
494
|
-
const dstDesc = registry.nodes.get(dstNode.typeId);
|
|
495
|
-
if (dstDesc) {
|
|
496
|
-
dstDeclared = getInputTypeId(dstDesc.inputs, e.target.handle);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
// Attach dynamic convert/convertAsync aware of union sources and typed outputs
|
|
500
|
-
const { convert, convertAsync } = GraphRuntime.buildEdgeConverters(srcDeclared, dstDeclared, registry);
|
|
501
|
-
return {
|
|
502
|
-
id: e.id,
|
|
503
|
-
source: { ...e.source },
|
|
504
|
-
target: { ...e.target },
|
|
505
|
-
typeId: effectiveTypeId ?? "untyped",
|
|
506
|
-
convert,
|
|
507
|
-
convertAsync,
|
|
508
|
-
srcUnionTypes: Array.isArray(srcDeclared)
|
|
509
|
-
? [...srcDeclared]
|
|
510
|
-
: undefined,
|
|
511
|
-
dstDeclared,
|
|
512
|
-
stats: { runs: 0, inFlight: false, progress: 0 },
|
|
513
|
-
};
|
|
514
|
-
});
|
|
477
|
+
gr.edges = GraphRuntime.buildEdges(def, registry, resolvedByNode);
|
|
515
478
|
// After nodes and edges exist, seed registry- and graph-level defaults
|
|
516
479
|
for (const n of def.nodes) {
|
|
517
480
|
const node = gr.nodes.get(n.nodeId);
|
|
@@ -941,6 +904,61 @@ class GraphRuntime {
|
|
|
941
904
|
}
|
|
942
905
|
}
|
|
943
906
|
}
|
|
907
|
+
// Helper: build map of resolved handles per node from def (prefer def.resolvedHandles, otherwise registry statics)
|
|
908
|
+
static computeResolvedHandleMap(def, registry) {
|
|
909
|
+
const out = new Map();
|
|
910
|
+
for (const n of def.nodes) {
|
|
911
|
+
const desc = registry.nodes.get(n.typeId);
|
|
912
|
+
if (!desc)
|
|
913
|
+
continue;
|
|
914
|
+
const overrideInputs = n.resolvedHandles?.inputs;
|
|
915
|
+
const overrideOutputs = n.resolvedHandles?.outputs;
|
|
916
|
+
// Merge base with overrides (allow partial resolvedHandles)
|
|
917
|
+
const inputs = { ...desc.inputs, ...overrideInputs };
|
|
918
|
+
const outputs = { ...desc.outputs, ...overrideOutputs };
|
|
919
|
+
out.set(n.nodeId, { inputs, outputs });
|
|
920
|
+
}
|
|
921
|
+
return out;
|
|
922
|
+
}
|
|
923
|
+
// Helper: build runtime edges with coercions using resolved handles
|
|
924
|
+
static buildEdges(def, registry, resolvedByNode) {
|
|
925
|
+
return def.edges.map((e) => {
|
|
926
|
+
const srcNode = def.nodes.find((n) => n.nodeId === e.source.nodeId);
|
|
927
|
+
const dstNode = def.nodes.find((n) => n.nodeId === e.target.nodeId);
|
|
928
|
+
let effectiveTypeId = e.typeId;
|
|
929
|
+
let srcDeclared;
|
|
930
|
+
let dstDeclared;
|
|
931
|
+
if (srcNode) {
|
|
932
|
+
const resolved = resolvedByNode.get(srcNode.nodeId);
|
|
933
|
+
if (resolved)
|
|
934
|
+
srcDeclared = resolved.outputs[e.source.handle];
|
|
935
|
+
}
|
|
936
|
+
if (!effectiveTypeId) {
|
|
937
|
+
effectiveTypeId = Array.isArray(srcDeclared)
|
|
938
|
+
? srcDeclared[0]
|
|
939
|
+
: srcDeclared;
|
|
940
|
+
}
|
|
941
|
+
if (dstNode) {
|
|
942
|
+
const resolved = resolvedByNode.get(dstNode.nodeId);
|
|
943
|
+
if (resolved)
|
|
944
|
+
dstDeclared = getInputTypeId(resolved.inputs, e.target.handle);
|
|
945
|
+
}
|
|
946
|
+
const { convert, convertAsync } = GraphRuntime.buildEdgeConverters(srcDeclared, dstDeclared, registry);
|
|
947
|
+
return {
|
|
948
|
+
id: e.id,
|
|
949
|
+
source: { ...e.source },
|
|
950
|
+
target: { ...e.target },
|
|
951
|
+
typeId: effectiveTypeId ?? "untyped",
|
|
952
|
+
convert,
|
|
953
|
+
convertAsync,
|
|
954
|
+
srcUnionTypes: Array.isArray(srcDeclared)
|
|
955
|
+
? [...srcDeclared]
|
|
956
|
+
: undefined,
|
|
957
|
+
dstDeclared,
|
|
958
|
+
stats: { runs: 0, inFlight: false, progress: 0 },
|
|
959
|
+
};
|
|
960
|
+
});
|
|
961
|
+
}
|
|
944
962
|
reemitNodeOutputs(nodeId) {
|
|
945
963
|
const node = this.nodes.get(nodeId);
|
|
946
964
|
if (!node)
|
|
@@ -1241,42 +1259,10 @@ class GraphRuntime {
|
|
|
1241
1259
|
tmap.set(e.source.handle, tset);
|
|
1242
1260
|
prevOutTargets.set(e.source.nodeId, tmap);
|
|
1243
1261
|
}
|
|
1262
|
+
// Precompute per-node resolved handles for updated graph
|
|
1263
|
+
const resolvedByNode = GraphRuntime.computeResolvedHandleMap(def, registry);
|
|
1244
1264
|
// Rebuild edges mapping with coercions
|
|
1245
|
-
this.edges =
|
|
1246
|
-
const srcNode = def.nodes.find((nn) => nn.nodeId === e.source.nodeId);
|
|
1247
|
-
const dstNode = def.nodes.find((nn) => nn.nodeId === e.target.nodeId);
|
|
1248
|
-
let effectiveTypeId = e.typeId;
|
|
1249
|
-
let srcDeclared;
|
|
1250
|
-
let dstDeclared;
|
|
1251
|
-
if (srcNode) {
|
|
1252
|
-
const srcDesc = registry.nodes.get(srcNode.typeId);
|
|
1253
|
-
if (srcDesc) {
|
|
1254
|
-
srcDeclared = srcDesc.outputs[e.source.handle];
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
if (!effectiveTypeId) {
|
|
1258
|
-
effectiveTypeId = Array.isArray(srcDeclared)
|
|
1259
|
-
? srcDeclared[0]
|
|
1260
|
-
: srcDeclared;
|
|
1261
|
-
}
|
|
1262
|
-
if (dstNode) {
|
|
1263
|
-
const dstDesc = registry.nodes.get(dstNode.typeId);
|
|
1264
|
-
if (dstDesc) {
|
|
1265
|
-
dstDeclared = getInputTypeId(dstDesc.inputs, e.target.handle);
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
const { convert, convertAsync } = GraphRuntime.buildEdgeConverters(srcDeclared, dstDeclared, registry);
|
|
1269
|
-
return {
|
|
1270
|
-
id: e.id,
|
|
1271
|
-
source: { ...e.source },
|
|
1272
|
-
target: { ...e.target },
|
|
1273
|
-
typeId: effectiveTypeId ?? "untyped",
|
|
1274
|
-
convert,
|
|
1275
|
-
convertAsync,
|
|
1276
|
-
dstDeclared,
|
|
1277
|
-
stats: { runs: 0, inFlight: false, progress: 0 },
|
|
1278
|
-
};
|
|
1279
|
-
});
|
|
1265
|
+
this.edges = GraphRuntime.buildEdges(def, registry, resolvedByNode);
|
|
1280
1266
|
// Build new inbound map
|
|
1281
1267
|
const nextInbound = new Map();
|
|
1282
1268
|
for (const e of this.edges) {
|
|
@@ -2643,6 +2629,31 @@ function setupBasicGraphRegistry() {
|
|
|
2643
2629
|
return { Result: arr.slice(s, e) };
|
|
2644
2630
|
},
|
|
2645
2631
|
});
|
|
2632
|
+
// Compose array from dynamic item inputs
|
|
2633
|
+
registry.registerNode({
|
|
2634
|
+
id: "base.array.compose",
|
|
2635
|
+
categoryId: "compute",
|
|
2636
|
+
inputs: { Length: "base.float" },
|
|
2637
|
+
outputs: { Items: "base.object" },
|
|
2638
|
+
resolveHandles: ({ params }) => {
|
|
2639
|
+
const maxLen = 64;
|
|
2640
|
+
const raw = params?.Length;
|
|
2641
|
+
const n = Math.max(0, Math.min(maxLen, Math.trunc(Number(raw ?? 0))));
|
|
2642
|
+
if (!Number.isFinite(n))
|
|
2643
|
+
return { inputs: {} };
|
|
2644
|
+
const dyn = {};
|
|
2645
|
+
for (let i = 0; i < n; i++)
|
|
2646
|
+
dyn[`Item${i}`] = { typeId: "base.object" };
|
|
2647
|
+
return { inputs: dyn };
|
|
2648
|
+
},
|
|
2649
|
+
inputDefaults: { Length: 0 },
|
|
2650
|
+
impl: (ins) => {
|
|
2651
|
+
const length = Math.max(0, Math.trunc(Number(ins.Length ?? 0)));
|
|
2652
|
+
if (!Number.isFinite(length))
|
|
2653
|
+
return { Items: [] };
|
|
2654
|
+
return { Items: Array.from({ length }, (_, i) => ins[`Item${i}`]) };
|
|
2655
|
+
},
|
|
2656
|
+
});
|
|
2646
2657
|
// Select
|
|
2647
2658
|
registry.registerNode({
|
|
2648
2659
|
id: "base.select",
|