@bian-womp/spark-graph 0.2.54 → 0.2.56
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 +581 -0
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/index.d.ts +3 -1
- package/lib/cjs/src/index.d.ts.map +1 -1
- package/lib/cjs/src/misc/base.d.ts +1 -0
- package/lib/cjs/src/misc/base.d.ts.map +1 -1
- package/lib/cjs/src/misc/utils/json.d.ts +14 -0
- package/lib/cjs/src/misc/utils/json.d.ts.map +1 -0
- package/lib/cjs/src/misc/utils/merge.d.ts +86 -0
- package/lib/cjs/src/misc/utils/merge.d.ts.map +1 -0
- package/lib/esm/index.js +571 -1
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/index.d.ts +3 -1
- package/lib/esm/src/index.d.ts.map +1 -1
- package/lib/esm/src/misc/base.d.ts +1 -0
- package/lib/esm/src/misc/base.d.ts.map +1 -1
- package/lib/esm/src/misc/utils/json.d.ts +14 -0
- package/lib/esm/src/misc/utils/json.d.ts.map +1 -0
- package/lib/esm/src/misc/utils/merge.d.ts +86 -0
- package/lib/esm/src/misc/utils/merge.d.ts.map +1 -0
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -3260,6 +3260,20 @@ function registerProgressNodes(registry) {
|
|
|
3260
3260
|
},
|
|
3261
3261
|
});
|
|
3262
3262
|
}
|
|
3263
|
+
function generateId(prefix, used = new Set()) {
|
|
3264
|
+
let id;
|
|
3265
|
+
let attempts = 0;
|
|
3266
|
+
do {
|
|
3267
|
+
id = `${prefix}${Math.random().toString(36).slice(2, 8)}`;
|
|
3268
|
+
attempts++;
|
|
3269
|
+
if (attempts > 1000) {
|
|
3270
|
+
id = `${prefix}${Date.now().toString(36)}${Math.random()
|
|
3271
|
+
.toString(36)
|
|
3272
|
+
.slice(2, 4)}`;
|
|
3273
|
+
}
|
|
3274
|
+
} while (used.has(id));
|
|
3275
|
+
return id;
|
|
3276
|
+
}
|
|
3263
3277
|
|
|
3264
3278
|
function installLogging(engine) {
|
|
3265
3279
|
engine.on("value", (e) => {
|
|
@@ -3475,6 +3489,562 @@ function createValidationGraphRegistry() {
|
|
|
3475
3489
|
return registry;
|
|
3476
3490
|
}
|
|
3477
3491
|
|
|
3492
|
+
function parseJsonPath(path) {
|
|
3493
|
+
if (typeof path === "string") {
|
|
3494
|
+
return path.split(".").flatMap((segment) => {
|
|
3495
|
+
const arrayMatch = segment.match(/^(.+)\[(\d+)\]$/);
|
|
3496
|
+
if (arrayMatch) {
|
|
3497
|
+
const index = parseInt(arrayMatch[2], 10);
|
|
3498
|
+
return arrayMatch[1] ? [arrayMatch[1], index] : [index];
|
|
3499
|
+
}
|
|
3500
|
+
return [segment];
|
|
3501
|
+
});
|
|
3502
|
+
}
|
|
3503
|
+
return path;
|
|
3504
|
+
}
|
|
3505
|
+
function getValueAtPath(obj, pathSegments) {
|
|
3506
|
+
if (pathSegments.length === 0) {
|
|
3507
|
+
return { value: obj, parent: null, key: "" };
|
|
3508
|
+
}
|
|
3509
|
+
let current = obj;
|
|
3510
|
+
for (let i = 0; i < pathSegments.length - 1; i++) {
|
|
3511
|
+
const segment = pathSegments[i];
|
|
3512
|
+
if (current === null ||
|
|
3513
|
+
current === undefined ||
|
|
3514
|
+
typeof current !== "object") {
|
|
3515
|
+
return null;
|
|
3516
|
+
}
|
|
3517
|
+
if (typeof segment === "string") {
|
|
3518
|
+
if (Array.isArray(current)) {
|
|
3519
|
+
const index = parseInt(segment, 10);
|
|
3520
|
+
if (isNaN(index))
|
|
3521
|
+
return null;
|
|
3522
|
+
current = current[index];
|
|
3523
|
+
}
|
|
3524
|
+
else {
|
|
3525
|
+
current = current[segment];
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
else if (typeof segment === "number") {
|
|
3529
|
+
if (Array.isArray(current)) {
|
|
3530
|
+
if (segment >= 0 && segment < current.length) {
|
|
3531
|
+
current = current[segment];
|
|
3532
|
+
}
|
|
3533
|
+
else {
|
|
3534
|
+
return null;
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
else {
|
|
3538
|
+
return null;
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
else if (segment instanceof RegExp) {
|
|
3542
|
+
if (Array.isArray(current)) {
|
|
3543
|
+
return null;
|
|
3544
|
+
}
|
|
3545
|
+
const obj = current;
|
|
3546
|
+
const matchingKey = Object.keys(obj).find((key) => segment.test(key));
|
|
3547
|
+
if (!matchingKey)
|
|
3548
|
+
return null;
|
|
3549
|
+
current = obj[matchingKey];
|
|
3550
|
+
}
|
|
3551
|
+
else {
|
|
3552
|
+
return null;
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
const lastSegment = pathSegments[pathSegments.length - 1];
|
|
3556
|
+
if (typeof lastSegment === "string") {
|
|
3557
|
+
if (Array.isArray(current)) {
|
|
3558
|
+
const index = parseInt(lastSegment, 10);
|
|
3559
|
+
if (isNaN(index))
|
|
3560
|
+
return null;
|
|
3561
|
+
return { value: current[index], parent: current, key: index };
|
|
3562
|
+
}
|
|
3563
|
+
else if (current !== null &&
|
|
3564
|
+
current !== undefined &&
|
|
3565
|
+
typeof current === "object") {
|
|
3566
|
+
return {
|
|
3567
|
+
value: current[lastSegment],
|
|
3568
|
+
parent: current,
|
|
3569
|
+
key: lastSegment,
|
|
3570
|
+
};
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
else if (typeof lastSegment === "number") {
|
|
3574
|
+
if (Array.isArray(current)) {
|
|
3575
|
+
if (lastSegment >= 0 && lastSegment < current.length) {
|
|
3576
|
+
return {
|
|
3577
|
+
value: current[lastSegment],
|
|
3578
|
+
parent: current,
|
|
3579
|
+
key: lastSegment,
|
|
3580
|
+
};
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
return null;
|
|
3584
|
+
}
|
|
3585
|
+
else if (lastSegment instanceof RegExp) {
|
|
3586
|
+
if (Array.isArray(current)) {
|
|
3587
|
+
return null;
|
|
3588
|
+
}
|
|
3589
|
+
const obj = current;
|
|
3590
|
+
const matchingKey = Object.keys(obj).find((key) => lastSegment.test(key));
|
|
3591
|
+
if (!matchingKey)
|
|
3592
|
+
return null;
|
|
3593
|
+
return { value: obj[matchingKey], parent: current, key: matchingKey };
|
|
3594
|
+
}
|
|
3595
|
+
return null;
|
|
3596
|
+
}
|
|
3597
|
+
function setValueAtPath(obj, pathSegments, newValue) {
|
|
3598
|
+
const result = getValueAtPath(obj, pathSegments);
|
|
3599
|
+
if (!result || result.parent === null)
|
|
3600
|
+
return false;
|
|
3601
|
+
if (Array.isArray(result.parent)) {
|
|
3602
|
+
result.parent[result.key] = newValue;
|
|
3603
|
+
}
|
|
3604
|
+
else {
|
|
3605
|
+
result.parent[result.key] = newValue;
|
|
3606
|
+
}
|
|
3607
|
+
return true;
|
|
3608
|
+
}
|
|
3609
|
+
function findMatchingPaths(obj, pathSegments, currentPath = []) {
|
|
3610
|
+
if (pathSegments.length === 0) {
|
|
3611
|
+
return [{ path: currentPath, value: obj }];
|
|
3612
|
+
}
|
|
3613
|
+
const [currentSegment, ...remainingSegments] = pathSegments;
|
|
3614
|
+
const results = [];
|
|
3615
|
+
if (currentSegment === undefined) {
|
|
3616
|
+
return results;
|
|
3617
|
+
}
|
|
3618
|
+
if (typeof currentSegment === "string") {
|
|
3619
|
+
if (Array.isArray(obj)) {
|
|
3620
|
+
const index = parseInt(currentSegment, 10);
|
|
3621
|
+
if (!isNaN(index) && index >= 0 && index < obj.length) {
|
|
3622
|
+
results.push(...findMatchingPaths(obj[index], remainingSegments, [
|
|
3623
|
+
...currentPath,
|
|
3624
|
+
index,
|
|
3625
|
+
]));
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
else if (obj !== null && obj !== undefined && typeof obj === "object") {
|
|
3629
|
+
const objRecord = obj;
|
|
3630
|
+
if (currentSegment in objRecord) {
|
|
3631
|
+
results.push(...findMatchingPaths(objRecord[currentSegment], remainingSegments, [
|
|
3632
|
+
...currentPath,
|
|
3633
|
+
currentSegment,
|
|
3634
|
+
]));
|
|
3635
|
+
}
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
else if (typeof currentSegment === "number") {
|
|
3639
|
+
if (Array.isArray(obj)) {
|
|
3640
|
+
if (currentSegment >= 0 && currentSegment < obj.length) {
|
|
3641
|
+
results.push(...findMatchingPaths(obj[currentSegment], remainingSegments, [
|
|
3642
|
+
...currentPath,
|
|
3643
|
+
currentSegment,
|
|
3644
|
+
]));
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
else if (currentSegment instanceof RegExp) {
|
|
3649
|
+
if (Array.isArray(obj)) {
|
|
3650
|
+
for (let i = 0; i < obj.length; i++) {
|
|
3651
|
+
results.push(...findMatchingPaths(obj[i], remainingSegments, [...currentPath, i]));
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
else if (obj !== null && obj !== undefined && typeof obj === "object") {
|
|
3655
|
+
const objRecord = obj;
|
|
3656
|
+
for (const key of Object.keys(objRecord)) {
|
|
3657
|
+
if (currentSegment.test(key)) {
|
|
3658
|
+
results.push(...findMatchingPaths(objRecord[key], remainingSegments, [
|
|
3659
|
+
...currentPath,
|
|
3660
|
+
key,
|
|
3661
|
+
]));
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3666
|
+
return results;
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
function mergeGraphDefinitions(target, source, converter) {
|
|
3670
|
+
const existingNodeIds = new Set(target.nodes.map((n) => n.nodeId));
|
|
3671
|
+
const existingEdgeIds = new Set(target.edges.map((e) => e.id));
|
|
3672
|
+
const nodeIdMap = {};
|
|
3673
|
+
const importedNodes = source.nodes.map((n) => {
|
|
3674
|
+
let newId = n.nodeId;
|
|
3675
|
+
if (existingNodeIds.has(newId)) {
|
|
3676
|
+
newId = generateId("n", existingNodeIds);
|
|
3677
|
+
}
|
|
3678
|
+
else {
|
|
3679
|
+
existingNodeIds.add(newId);
|
|
3680
|
+
}
|
|
3681
|
+
nodeIdMap[n.nodeId] = newId;
|
|
3682
|
+
const transformedNode = {
|
|
3683
|
+
...n,
|
|
3684
|
+
nodeId: newId,
|
|
3685
|
+
};
|
|
3686
|
+
if (converter) {
|
|
3687
|
+
const nodeTypeId = transformedNode.typeId;
|
|
3688
|
+
if (transformedNode.initialInputs) {
|
|
3689
|
+
const transformedInitialInputs = {};
|
|
3690
|
+
for (const [handleId, value] of Object.entries(transformedNode.initialInputs)) {
|
|
3691
|
+
const handleDataType = transformedNode.resolvedHandles?.inputs?.[handleId]
|
|
3692
|
+
? typeof transformedNode.resolvedHandles.inputs[handleId] ===
|
|
3693
|
+
"string"
|
|
3694
|
+
? transformedNode.resolvedHandles.inputs[handleId]
|
|
3695
|
+
: transformedNode.resolvedHandles.inputs[handleId]?.typeId
|
|
3696
|
+
: undefined;
|
|
3697
|
+
transformedInitialInputs[handleId] = converter(newId, handleId, value, "initialInput", nodeTypeId, handleDataType);
|
|
3698
|
+
}
|
|
3699
|
+
transformedNode.initialInputs = transformedInitialInputs;
|
|
3700
|
+
}
|
|
3701
|
+
if (transformedNode.resolvedHandles?.inputDefaults) {
|
|
3702
|
+
const transformedInputDefaults = {};
|
|
3703
|
+
for (const [handleId, value] of Object.entries(transformedNode.resolvedHandles.inputDefaults)) {
|
|
3704
|
+
const handleDataType = transformedNode.resolvedHandles?.inputs?.[handleId]
|
|
3705
|
+
? typeof transformedNode.resolvedHandles.inputs[handleId] ===
|
|
3706
|
+
"string"
|
|
3707
|
+
? transformedNode.resolvedHandles.inputs[handleId]
|
|
3708
|
+
: transformedNode.resolvedHandles.inputs[handleId]?.typeId
|
|
3709
|
+
: undefined;
|
|
3710
|
+
transformedInputDefaults[handleId] = converter(newId, handleId, value, "inputDefault", nodeTypeId, handleDataType);
|
|
3711
|
+
}
|
|
3712
|
+
transformedNode.resolvedHandles = {
|
|
3713
|
+
...transformedNode.resolvedHandles,
|
|
3714
|
+
inputDefaults: transformedInputDefaults,
|
|
3715
|
+
};
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
return transformedNode;
|
|
3719
|
+
});
|
|
3720
|
+
const importedEdges = source.edges.map((e) => {
|
|
3721
|
+
let newEdgeId = e.id;
|
|
3722
|
+
if (existingEdgeIds.has(newEdgeId)) {
|
|
3723
|
+
newEdgeId = generateId("e", existingEdgeIds);
|
|
3724
|
+
}
|
|
3725
|
+
else {
|
|
3726
|
+
existingEdgeIds.add(newEdgeId);
|
|
3727
|
+
}
|
|
3728
|
+
const sourceNodeId = nodeIdMap[e.source.nodeId] ?? e.source.nodeId;
|
|
3729
|
+
const targetNodeId = nodeIdMap[e.target.nodeId] ?? e.target.nodeId;
|
|
3730
|
+
return {
|
|
3731
|
+
...e,
|
|
3732
|
+
id: newEdgeId,
|
|
3733
|
+
source: {
|
|
3734
|
+
...e.source,
|
|
3735
|
+
nodeId: sourceNodeId,
|
|
3736
|
+
},
|
|
3737
|
+
target: {
|
|
3738
|
+
...e.target,
|
|
3739
|
+
nodeId: targetNodeId,
|
|
3740
|
+
},
|
|
3741
|
+
};
|
|
3742
|
+
});
|
|
3743
|
+
return {
|
|
3744
|
+
merged: {
|
|
3745
|
+
nodes: [...target.nodes, ...importedNodes],
|
|
3746
|
+
edges: [...target.edges, ...importedEdges],
|
|
3747
|
+
},
|
|
3748
|
+
nodeIdMap,
|
|
3749
|
+
};
|
|
3750
|
+
}
|
|
3751
|
+
/**
|
|
3752
|
+
* Compute the center point of a graph based on node positions.
|
|
3753
|
+
*/
|
|
3754
|
+
function computeGraphCenter(positions, nodeIds) {
|
|
3755
|
+
const validPositions = nodeIds
|
|
3756
|
+
.map((id) => positions[id])
|
|
3757
|
+
.filter((pos) => pos !== undefined);
|
|
3758
|
+
if (validPositions.length === 0) {
|
|
3759
|
+
return { x: 0, y: 0 };
|
|
3760
|
+
}
|
|
3761
|
+
const minX = Math.min(...validPositions.map((p) => p.x));
|
|
3762
|
+
const maxX = Math.max(...validPositions.map((p) => p.x));
|
|
3763
|
+
const minY = Math.min(...validPositions.map((p) => p.y));
|
|
3764
|
+
const maxY = Math.max(...validPositions.map((p) => p.y));
|
|
3765
|
+
return {
|
|
3766
|
+
x: (minX + maxX) / 2,
|
|
3767
|
+
y: (minY + maxY) / 2,
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* Offset positions of imported nodes based on an anchor point.
|
|
3772
|
+
* Preserves relative layout of imported nodes while positioning them at the anchor.
|
|
3773
|
+
*/
|
|
3774
|
+
function offsetImportedPositions(targetPositions, sourcePositions, sourceDef, nodeIdMap, anchorPos) {
|
|
3775
|
+
const sourceNodeIds = sourceDef.nodes.map((n) => n.nodeId);
|
|
3776
|
+
const sourceCenter = computeGraphCenter(sourcePositions, sourceNodeIds);
|
|
3777
|
+
const dx = anchorPos.x - sourceCenter.x;
|
|
3778
|
+
const dy = anchorPos.y - sourceCenter.y;
|
|
3779
|
+
const newPositions = {
|
|
3780
|
+
...targetPositions,
|
|
3781
|
+
};
|
|
3782
|
+
for (const node of sourceDef.nodes) {
|
|
3783
|
+
const oldId = node.nodeId;
|
|
3784
|
+
const newId = nodeIdMap[oldId];
|
|
3785
|
+
const srcPos = sourcePositions[oldId] ?? { x: 0, y: 0 };
|
|
3786
|
+
newPositions[newId] = {
|
|
3787
|
+
x: srcPos.x + dx,
|
|
3788
|
+
y: srcPos.y + dy,
|
|
3789
|
+
};
|
|
3790
|
+
}
|
|
3791
|
+
return newPositions;
|
|
3792
|
+
}
|
|
3793
|
+
/**
|
|
3794
|
+
* Merge inputs and outputs from source into target, remapping node IDs.
|
|
3795
|
+
* Source values override target when merging.
|
|
3796
|
+
*/
|
|
3797
|
+
function mergeInputsOutputs(targetInputs, targetOutputs, sourceInputs, sourceOutputs, nodeIdMap, converter, nodeTypeMap, handleTypeMap) {
|
|
3798
|
+
const mergedInputs = { ...targetInputs };
|
|
3799
|
+
const mergedOutputs = { ...targetOutputs };
|
|
3800
|
+
for (const [oldId, inputs] of Object.entries(sourceInputs)) {
|
|
3801
|
+
const newId = nodeIdMap[oldId];
|
|
3802
|
+
if (newId) {
|
|
3803
|
+
const transformedInputs = {};
|
|
3804
|
+
const nodeTypeId = nodeTypeMap?.get(oldId);
|
|
3805
|
+
for (const [handleId, value] of Object.entries(inputs)) {
|
|
3806
|
+
const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
|
|
3807
|
+
transformedInputs[handleId] = converter
|
|
3808
|
+
? converter(newId, handleId, value, "input", nodeTypeId, handleDataType)
|
|
3809
|
+
: value;
|
|
3810
|
+
}
|
|
3811
|
+
mergedInputs[newId] = mergedInputs[newId]
|
|
3812
|
+
? { ...mergedInputs[newId], ...transformedInputs }
|
|
3813
|
+
: transformedInputs;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
for (const [oldId, outputs] of Object.entries(sourceOutputs)) {
|
|
3817
|
+
const newId = nodeIdMap[oldId];
|
|
3818
|
+
if (newId) {
|
|
3819
|
+
const transformedOutputs = {};
|
|
3820
|
+
const nodeTypeId = nodeTypeMap?.get(oldId);
|
|
3821
|
+
for (const [handleId, value] of Object.entries(outputs)) {
|
|
3822
|
+
const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
|
|
3823
|
+
const runtimeTypeId = isTypedOutput(value)
|
|
3824
|
+
? getTypedOutputTypeId(value)
|
|
3825
|
+
: undefined;
|
|
3826
|
+
transformedOutputs[handleId] = converter
|
|
3827
|
+
? converter(newId, handleId, value, "output", nodeTypeId, handleDataType, runtimeTypeId)
|
|
3828
|
+
: value;
|
|
3829
|
+
}
|
|
3830
|
+
mergedOutputs[newId] = mergedOutputs[newId]
|
|
3831
|
+
? { ...mergedOutputs[newId], ...transformedOutputs }
|
|
3832
|
+
: transformedOutputs;
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
return { mergedInputs, mergedOutputs };
|
|
3836
|
+
}
|
|
3837
|
+
/**
|
|
3838
|
+
* Merge snapshot data (inputs, outputs, UI positions) from source into target.
|
|
3839
|
+
* Graph definition merging should be done separately using mergeGraphDefinitions.
|
|
3840
|
+
*/
|
|
3841
|
+
function mergeSnapshotData(targetSnapshot, sourceSnapshot, sourceDef, nodeIdMap, anchorPos, converter) {
|
|
3842
|
+
const nodeTypeMap = new Map();
|
|
3843
|
+
const handleTypeMap = new Map();
|
|
3844
|
+
for (const node of sourceDef.nodes) {
|
|
3845
|
+
nodeTypeMap.set(node.nodeId, node.typeId);
|
|
3846
|
+
const nodeHandleTypes = new Map();
|
|
3847
|
+
if (node.resolvedHandles?.inputs) {
|
|
3848
|
+
for (const [handleId, handleDesc] of Object.entries(node.resolvedHandles.inputs)) {
|
|
3849
|
+
const typeId = typeof handleDesc === "string"
|
|
3850
|
+
? handleDesc
|
|
3851
|
+
: handleDesc?.typeId;
|
|
3852
|
+
if (typeId)
|
|
3853
|
+
nodeHandleTypes.set(handleId, typeId);
|
|
3854
|
+
}
|
|
3855
|
+
}
|
|
3856
|
+
if (node.resolvedHandles?.outputs) {
|
|
3857
|
+
for (const [handleId, handleDesc] of Object.entries(node.resolvedHandles.outputs)) {
|
|
3858
|
+
const typeId = typeof handleDesc === "string"
|
|
3859
|
+
? handleDesc
|
|
3860
|
+
: Array.isArray(handleDesc)
|
|
3861
|
+
? handleDesc[0]
|
|
3862
|
+
: undefined;
|
|
3863
|
+
if (typeId)
|
|
3864
|
+
nodeHandleTypes.set(handleId, typeId);
|
|
3865
|
+
}
|
|
3866
|
+
}
|
|
3867
|
+
if (nodeHandleTypes.size > 0) {
|
|
3868
|
+
handleTypeMap.set(node.nodeId, nodeHandleTypes);
|
|
3869
|
+
}
|
|
3870
|
+
}
|
|
3871
|
+
const { mergedInputs, mergedOutputs } = mergeInputsOutputs(targetSnapshot.inputs ?? {}, targetSnapshot.outputs ?? {}, sourceSnapshot.inputs ?? {}, sourceSnapshot.outputs ?? {}, nodeIdMap, converter, nodeTypeMap, handleTypeMap);
|
|
3872
|
+
const targetUI = targetSnapshot.extData?.ui || {};
|
|
3873
|
+
const sourceUI = sourceSnapshot.extData?.ui || {};
|
|
3874
|
+
const mergedPositions = offsetImportedPositions(targetUI.positions ?? {}, sourceUI.positions ?? {}, sourceDef, nodeIdMap, anchorPos);
|
|
3875
|
+
return {
|
|
3876
|
+
mergedInputs,
|
|
3877
|
+
mergedOutputs,
|
|
3878
|
+
mergedPositions,
|
|
3879
|
+
};
|
|
3880
|
+
}
|
|
3881
|
+
function matchesPattern(value, pattern) {
|
|
3882
|
+
if (!pattern)
|
|
3883
|
+
return true;
|
|
3884
|
+
if (typeof pattern === "string") {
|
|
3885
|
+
return value === pattern;
|
|
3886
|
+
}
|
|
3887
|
+
return pattern.test(value);
|
|
3888
|
+
}
|
|
3889
|
+
/**
|
|
3890
|
+
* Build a converter function from a configuration that maps values based on handle/node matching.
|
|
3891
|
+
* The converter will replace values when:
|
|
3892
|
+
* - handleId matches (if specified)
|
|
3893
|
+
* - nodeId matches (if specified)
|
|
3894
|
+
* - nodeTypeId matches (if specified)
|
|
3895
|
+
* - handleDataType matches (if specified)
|
|
3896
|
+
* - runtimeTypeId matches (if specified, for typed outputs)
|
|
3897
|
+
* - value exists in valueMap
|
|
3898
|
+
*/
|
|
3899
|
+
function buildValueConverter(config) {
|
|
3900
|
+
return (nodeId, handleId, value, type, nodeTypeId, handleDataType, runtimeTypeId) => {
|
|
3901
|
+
const isTyped = isTypedOutput(value);
|
|
3902
|
+
for (const mapping of config.mappings) {
|
|
3903
|
+
if (!matchesPattern(handleId, mapping.handleId))
|
|
3904
|
+
continue;
|
|
3905
|
+
if (!matchesPattern(nodeId, mapping.nodeId))
|
|
3906
|
+
continue;
|
|
3907
|
+
if (mapping.nodeTypeId && nodeTypeId) {
|
|
3908
|
+
if (!matchesPattern(nodeTypeId, mapping.nodeTypeId))
|
|
3909
|
+
continue;
|
|
3910
|
+
}
|
|
3911
|
+
if (mapping.handleDataType && handleDataType) {
|
|
3912
|
+
if (!matchesPattern(handleDataType, mapping.handleDataType))
|
|
3913
|
+
continue;
|
|
3914
|
+
}
|
|
3915
|
+
if (mapping.runtimeTypeId && runtimeTypeId) {
|
|
3916
|
+
if (!matchesPattern(runtimeTypeId, mapping.runtimeTypeId))
|
|
3917
|
+
continue;
|
|
3918
|
+
}
|
|
3919
|
+
if (mapping.transformTypedValue && isTyped) {
|
|
3920
|
+
const innerValue = getTypedOutputValue(value);
|
|
3921
|
+
const typedTypeId = getTypedOutputTypeId(value);
|
|
3922
|
+
if (!typedTypeId)
|
|
3923
|
+
continue;
|
|
3924
|
+
if (mapping.path !== undefined) {
|
|
3925
|
+
const pathSegments = parseJsonPath(mapping.path);
|
|
3926
|
+
const matches = findMatchingPaths(innerValue, pathSegments);
|
|
3927
|
+
if (matches.length > 0) {
|
|
3928
|
+
const transformedInner = JSON.parse(JSON.stringify(innerValue));
|
|
3929
|
+
let changed = false;
|
|
3930
|
+
for (const match of matches) {
|
|
3931
|
+
const matchValue = match.value;
|
|
3932
|
+
if (matchValue !== null && matchValue !== undefined) {
|
|
3933
|
+
let newValue = matchValue;
|
|
3934
|
+
if (mapping.valueMap instanceof Map) {
|
|
3935
|
+
if (mapping.valueMap.has(matchValue)) {
|
|
3936
|
+
newValue = mapping.valueMap.get(matchValue);
|
|
3937
|
+
changed = true;
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
else {
|
|
3941
|
+
if (typeof matchValue === "string" ||
|
|
3942
|
+
typeof matchValue === "number") {
|
|
3943
|
+
if (matchValue in mapping.valueMap) {
|
|
3944
|
+
newValue = mapping.valueMap[matchValue];
|
|
3945
|
+
changed = true;
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
if (changed && newValue !== matchValue) {
|
|
3950
|
+
setValueAtPath(transformedInner, match.path, newValue);
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
return changed ? typed(typedTypeId, transformedInner) : value;
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
else {
|
|
3958
|
+
if (innerValue !== null && innerValue !== undefined) {
|
|
3959
|
+
let newValue = innerValue;
|
|
3960
|
+
if (mapping.valueMap instanceof Map) {
|
|
3961
|
+
if (mapping.valueMap.has(innerValue)) {
|
|
3962
|
+
newValue = mapping.valueMap.get(innerValue);
|
|
3963
|
+
return typed(typedTypeId, newValue);
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
else {
|
|
3967
|
+
if (typeof innerValue === "string" ||
|
|
3968
|
+
typeof innerValue === "number") {
|
|
3969
|
+
if (innerValue in mapping.valueMap) {
|
|
3970
|
+
newValue = mapping.valueMap[innerValue];
|
|
3971
|
+
return typed(typedTypeId, newValue);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3977
|
+
continue;
|
|
3978
|
+
}
|
|
3979
|
+
if (mapping.path !== undefined) {
|
|
3980
|
+
let pathSegments = parseJsonPath(mapping.path);
|
|
3981
|
+
if (isTyped) {
|
|
3982
|
+
const typedTypeId = getTypedOutputTypeId(value);
|
|
3983
|
+
if (typedTypeId) {
|
|
3984
|
+
const firstSegment = pathSegments[0];
|
|
3985
|
+
const firstSegmentStr = typeof firstSegment === "string"
|
|
3986
|
+
? firstSegment
|
|
3987
|
+
: firstSegment instanceof RegExp
|
|
3988
|
+
? null
|
|
3989
|
+
: String(firstSegment);
|
|
3990
|
+
if (firstSegmentStr !== "__spark_value" &&
|
|
3991
|
+
firstSegmentStr !== "__spark_type") {
|
|
3992
|
+
pathSegments = ["__spark_value", ...pathSegments];
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
}
|
|
3996
|
+
const matches = findMatchingPaths(value, pathSegments);
|
|
3997
|
+
if (matches.length > 0) {
|
|
3998
|
+
const transformedValue = JSON.parse(JSON.stringify(value));
|
|
3999
|
+
let changed = false;
|
|
4000
|
+
for (const match of matches) {
|
|
4001
|
+
const matchValue = match.value;
|
|
4002
|
+
if (matchValue !== null && matchValue !== undefined) {
|
|
4003
|
+
let newValue = matchValue;
|
|
4004
|
+
if (mapping.valueMap instanceof Map) {
|
|
4005
|
+
if (mapping.valueMap.has(matchValue)) {
|
|
4006
|
+
newValue = mapping.valueMap.get(matchValue);
|
|
4007
|
+
changed = true;
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
4010
|
+
else {
|
|
4011
|
+
if (typeof matchValue === "string" ||
|
|
4012
|
+
typeof matchValue === "number") {
|
|
4013
|
+
if (matchValue in mapping.valueMap) {
|
|
4014
|
+
newValue = mapping.valueMap[matchValue];
|
|
4015
|
+
changed = true;
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
if (changed && newValue !== matchValue) {
|
|
4020
|
+
setValueAtPath(transformedValue, match.path, newValue);
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
return changed ? transformedValue : value;
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
else {
|
|
4028
|
+
if (value !== null && value !== undefined) {
|
|
4029
|
+
if (mapping.valueMap instanceof Map) {
|
|
4030
|
+
if (mapping.valueMap.has(value)) {
|
|
4031
|
+
return mapping.valueMap.get(value);
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
else {
|
|
4035
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
4036
|
+
if (value in mapping.valueMap) {
|
|
4037
|
+
return mapping.valueMap[value];
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
return value;
|
|
4045
|
+
};
|
|
4046
|
+
}
|
|
4047
|
+
|
|
3478
4048
|
exports.BatchedEngine = BatchedEngine;
|
|
3479
4049
|
exports.CompositeCategory = CompositeCategory;
|
|
3480
4050
|
exports.ComputeCategory = ComputeCategory;
|
|
@@ -3485,6 +4055,8 @@ exports.PullEngine = PullEngine;
|
|
|
3485
4055
|
exports.PushEngine = PushEngine;
|
|
3486
4056
|
exports.Registry = Registry;
|
|
3487
4057
|
exports.StepEngine = StepEngine;
|
|
4058
|
+
exports.buildValueConverter = buildValueConverter;
|
|
4059
|
+
exports.computeGraphCenter = computeGraphCenter;
|
|
3488
4060
|
exports.createAsyncGraphDef = createAsyncGraphDef;
|
|
3489
4061
|
exports.createAsyncGraphRegistry = createAsyncGraphRegistry;
|
|
3490
4062
|
exports.createEngine = createEngine;
|
|
@@ -3494,13 +4066,22 @@ exports.createSimpleGraphDef = createSimpleGraphDef;
|
|
|
3494
4066
|
exports.createSimpleGraphRegistry = createSimpleGraphRegistry;
|
|
3495
4067
|
exports.createValidationGraphDef = createValidationGraphDef;
|
|
3496
4068
|
exports.createValidationGraphRegistry = createValidationGraphRegistry;
|
|
4069
|
+
exports.findMatchingPaths = findMatchingPaths;
|
|
4070
|
+
exports.generateId = generateId;
|
|
3497
4071
|
exports.getInputTypeId = getInputTypeId;
|
|
3498
4072
|
exports.getTypedOutputTypeId = getTypedOutputTypeId;
|
|
3499
4073
|
exports.getTypedOutputValue = getTypedOutputValue;
|
|
4074
|
+
exports.getValueAtPath = getValueAtPath;
|
|
3500
4075
|
exports.installLogging = installLogging;
|
|
3501
4076
|
exports.isInputPrivate = isInputPrivate;
|
|
3502
4077
|
exports.isTypedOutput = isTypedOutput;
|
|
4078
|
+
exports.mergeGraphDefinitions = mergeGraphDefinitions;
|
|
4079
|
+
exports.mergeInputsOutputs = mergeInputsOutputs;
|
|
4080
|
+
exports.mergeSnapshotData = mergeSnapshotData;
|
|
4081
|
+
exports.offsetImportedPositions = offsetImportedPositions;
|
|
4082
|
+
exports.parseJsonPath = parseJsonPath;
|
|
3503
4083
|
exports.registerDelayNode = registerDelayNode;
|
|
3504
4084
|
exports.registerProgressNodes = registerProgressNodes;
|
|
4085
|
+
exports.setValueAtPath = setValueAtPath;
|
|
3505
4086
|
exports.typed = typed;
|
|
3506
4087
|
//# sourceMappingURL=index.cjs.map
|