@bian-womp/spark-graph 0.3.19 → 0.3.20

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
@@ -5423,62 +5423,42 @@ function findMatchingPaths(obj, pathSegments, currentPath = []) {
5423
5423
  return results;
5424
5424
  }
5425
5425
 
5426
- function mergeGraphDefinitions(target, source, converter) {
5426
+ function mergeGraphDefinitions(target, source) {
5427
5427
  const existingNodeIds = new Set(target.nodes.map((n) => n.nodeId));
5428
5428
  const existingEdgeIds = new Set(target.edges.map((e) => e.id));
5429
5429
  const nodeIdMap = {};
5430
+ const targetInputDefaults = {};
5431
+ const sourceInputDefaults = {};
5432
+ for (const node of target.nodes) {
5433
+ if (node.resolvedHandles?.inputDefaults) {
5434
+ targetInputDefaults[node.nodeId] = {
5435
+ ...node.resolvedHandles.inputDefaults,
5436
+ };
5437
+ }
5438
+ }
5430
5439
  const importedNodes = source.nodes.map((n) => {
5431
5440
  let newId = n.nodeId;
5432
- if (existingNodeIds.has(newId)) {
5441
+ const isExistingNode = existingNodeIds.has(newId);
5442
+ if (isExistingNode) {
5433
5443
  newId = generateId("n", existingNodeIds);
5434
5444
  }
5435
5445
  else {
5436
5446
  existingNodeIds.add(newId);
5437
5447
  }
5438
5448
  nodeIdMap[n.nodeId] = newId;
5439
- const transformedNode = {
5449
+ if (n.resolvedHandles?.inputDefaults) {
5450
+ sourceInputDefaults[n.nodeId] = { ...n.resolvedHandles.inputDefaults };
5451
+ }
5452
+ return {
5440
5453
  ...n,
5441
5454
  nodeId: newId,
5442
- };
5443
- if (converter) {
5444
- const nodeTypeId = transformedNode.typeId;
5445
- if (transformedNode.resolvedHandles?.inputDefaults) {
5446
- const transformedInputDefaults = {};
5447
- for (const [handleId, value] of Object.entries(transformedNode.resolvedHandles.inputDefaults)) {
5448
- const handleDataType = transformedNode.resolvedHandles?.inputs?.[handleId]
5449
- ? typeof transformedNode.resolvedHandles.inputs[handleId] ===
5450
- "string"
5451
- ? transformedNode.resolvedHandles.inputs[handleId]
5452
- : transformedNode.resolvedHandles.inputs[handleId]?.typeId
5453
- : undefined;
5454
- const convertedValue = converter({
5455
- nodeId: newId,
5456
- handleId,
5457
- value,
5458
- type: "inputDefault",
5459
- nodeTypeId,
5460
- handleDataType,
5461
- });
5462
- // If converter returns null, skip this input default (delete it)
5463
- if (convertedValue !== null) {
5464
- transformedInputDefaults[handleId] = convertedValue;
5465
- }
5455
+ resolvedHandles: n.resolvedHandles
5456
+ ? {
5457
+ ...n.resolvedHandles,
5458
+ inputDefaults: undefined,
5466
5459
  }
5467
- // Only set inputDefaults if there are any remaining after conversion
5468
- if (Object.keys(transformedInputDefaults).length > 0) {
5469
- transformedNode.resolvedHandles = {
5470
- ...transformedNode.resolvedHandles,
5471
- inputDefaults: transformedInputDefaults,
5472
- };
5473
- }
5474
- else if (transformedNode.resolvedHandles) {
5475
- // Remove inputDefaults if all were deleted
5476
- const { inputDefaults, ...restHandles } = transformedNode.resolvedHandles;
5477
- transformedNode.resolvedHandles = restHandles;
5478
- }
5479
- }
5480
- }
5481
- return transformedNode;
5460
+ : undefined,
5461
+ };
5482
5462
  });
5483
5463
  const importedEdges = source.edges.map((e) => {
5484
5464
  let newEdgeId = e.id;
@@ -5509,6 +5489,8 @@ function mergeGraphDefinitions(target, source, converter) {
5509
5489
  edges: [...target.edges, ...importedEdges],
5510
5490
  },
5511
5491
  nodeIdMap,
5492
+ targetInputDefaults,
5493
+ sourceInputDefaults,
5512
5494
  };
5513
5495
  }
5514
5496
  /**
@@ -5553,116 +5535,100 @@ function offsetImportedPositions(targetPositions, sourcePositions, sourceDef, no
5553
5535
  }
5554
5536
  return newPositions;
5555
5537
  }
5556
- /**
5557
- * Merge inputs and outputs from source into target, remapping node IDs.
5558
- * Source values override target when merging.
5559
- */
5560
- function mergeInputsOutputs(targetInputs, targetOutputs, sourceInputs, sourceOutputs, nodeIdMap, converter, nodeTypeMap, handleTypeMap) {
5561
- // Deep copy target inputs/outputs to avoid mutating the original
5538
+ function mergeInputsOutputs(targetInputs, targetOutputs, sourceInputs, sourceOutputs, targetInputDefaults, sourceInputDefaults, nodeIdMap, nodeTypeMap, handleTypeMap) {
5562
5539
  const mergedInputs = {};
5563
5540
  const mergedOutputs = {};
5564
- // Copy target inputs/outputs
5541
+ const mergedInputDefaults = {};
5542
+ const inputsToConvert = [];
5543
+ const outputsToConvert = [];
5544
+ const inputDefaultsToConvert = [];
5565
5545
  for (const [nodeId, inputs] of Object.entries(targetInputs)) {
5566
5546
  mergedInputs[nodeId] = { ...inputs };
5567
5547
  }
5568
5548
  for (const [nodeId, outputs] of Object.entries(targetOutputs)) {
5569
5549
  mergedOutputs[nodeId] = { ...outputs };
5570
5550
  }
5551
+ for (const [nodeId, defaults] of Object.entries(targetInputDefaults)) {
5552
+ mergedInputDefaults[nodeId] = { ...defaults };
5553
+ }
5571
5554
  for (const [oldId, inputs] of Object.entries(sourceInputs)) {
5572
5555
  const newId = nodeIdMap[oldId];
5573
5556
  if (newId) {
5574
- const transformedInputs = {};
5575
- const nodeTypeId = nodeTypeMap?.get(oldId);
5576
- // Ensure mergedInputs[newId] exists
5577
5557
  if (!mergedInputs[newId]) {
5578
5558
  mergedInputs[newId] = {};
5579
5559
  }
5560
+ const nodeTypeId = nodeTypeMap?.get(oldId);
5580
5561
  for (const [handleId, value] of Object.entries(inputs)) {
5581
5562
  const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
5582
- const convertedValue = converter
5583
- ? converter({
5584
- nodeId: newId,
5585
- handleId,
5586
- value,
5587
- type: "input",
5588
- nodeTypeId,
5589
- handleDataType,
5590
- })
5591
- : value;
5592
- // If converter returns null, delete this input
5593
- if (convertedValue === null) {
5594
- delete mergedInputs[newId][handleId];
5595
- }
5596
- else {
5597
- // Otherwise, set the converted value
5598
- transformedInputs[handleId] = convertedValue;
5599
- }
5600
- }
5601
- // Merge transformed inputs
5602
- if (Object.keys(transformedInputs).length > 0) {
5603
- mergedInputs[newId] = { ...mergedInputs[newId], ...transformedInputs };
5604
- }
5605
- // Clean up empty node input objects
5606
- if (Object.keys(mergedInputs[newId]).length === 0) {
5607
- delete mergedInputs[newId];
5563
+ inputsToConvert.push({
5564
+ nodeId: newId,
5565
+ originalNodeId: oldId,
5566
+ handleId,
5567
+ value,
5568
+ nodeTypeId,
5569
+ handleDataType,
5570
+ });
5571
+ mergedInputs[newId][handleId] = value;
5608
5572
  }
5609
5573
  }
5610
5574
  }
5611
5575
  for (const [oldId, outputs] of Object.entries(sourceOutputs)) {
5612
5576
  const newId = nodeIdMap[oldId];
5613
5577
  if (newId) {
5614
- const transformedOutputs = {};
5615
- const nodeTypeId = nodeTypeMap?.get(oldId);
5616
- // Ensure mergedOutputs[newId] exists
5617
5578
  if (!mergedOutputs[newId]) {
5618
5579
  mergedOutputs[newId] = {};
5619
5580
  }
5581
+ const nodeTypeId = nodeTypeMap?.get(oldId);
5620
5582
  for (const [handleId, value] of Object.entries(outputs)) {
5621
5583
  const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
5622
5584
  const runtimeTypeId = isTypedOutput(value)
5623
5585
  ? getTypedOutputTypeId(value)
5624
5586
  : undefined;
5625
- const convertedValue = converter
5626
- ? converter({
5627
- nodeId: newId,
5628
- handleId,
5629
- value,
5630
- type: "output",
5631
- nodeTypeId,
5632
- handleDataType,
5633
- runtimeTypeId,
5634
- })
5635
- : value;
5636
- // If converter returns null, delete this output
5637
- if (convertedValue === null) {
5638
- delete mergedOutputs[newId][handleId];
5639
- }
5640
- else {
5641
- // Otherwise, set the converted value
5642
- transformedOutputs[handleId] = convertedValue;
5643
- }
5587
+ outputsToConvert.push({
5588
+ nodeId: newId,
5589
+ originalNodeId: oldId,
5590
+ handleId,
5591
+ value,
5592
+ nodeTypeId,
5593
+ handleDataType,
5594
+ runtimeTypeId,
5595
+ });
5596
+ mergedOutputs[newId][handleId] = value;
5644
5597
  }
5645
- // Merge transformed outputs
5646
- if (Object.keys(transformedOutputs).length > 0) {
5647
- mergedOutputs[newId] = {
5648
- ...mergedOutputs[newId],
5649
- ...transformedOutputs,
5650
- };
5598
+ }
5599
+ }
5600
+ for (const [oldId, defaults] of Object.entries(sourceInputDefaults)) {
5601
+ const newId = nodeIdMap[oldId];
5602
+ if (newId) {
5603
+ if (!mergedInputDefaults[newId]) {
5604
+ mergedInputDefaults[newId] = {};
5651
5605
  }
5652
- // Clean up empty node output objects
5653
- if (Object.keys(mergedOutputs[newId]).length === 0) {
5654
- delete mergedOutputs[newId];
5606
+ const nodeTypeId = nodeTypeMap?.get(oldId);
5607
+ for (const [handleId, value] of Object.entries(defaults)) {
5608
+ const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
5609
+ inputDefaultsToConvert.push({
5610
+ nodeId: newId,
5611
+ originalNodeId: oldId,
5612
+ handleId,
5613
+ value,
5614
+ nodeTypeId,
5615
+ handleDataType,
5616
+ });
5617
+ mergedInputDefaults[newId][handleId] = value;
5655
5618
  }
5656
5619
  }
5657
5620
  }
5658
- return { mergedInputs, mergedOutputs };
5621
+ return {
5622
+ mergedInputs,
5623
+ mergedOutputs,
5624
+ mergedInputDefaults,
5625
+ inputsToConvert,
5626
+ outputsToConvert,
5627
+ inputDefaultsToConvert,
5628
+ };
5659
5629
  }
5660
- /**
5661
- * Merge snapshot data (inputs, outputs) from source into target.
5662
- * Graph definition merging should be done separately using mergeGraphDefinitions.
5663
- * UI positions are handled separately by mergeUIState.
5664
- */
5665
- function mergeSnapshotData(targetSnapshot, sourceSnapshot, sourceDef, nodeIdMap, converter) {
5630
+ function mergeSnapshotData(targetSnapshot, sourceSnapshot, targetInputDefaults, sourceInputDefaults, nodeIdMap) {
5631
+ const sourceDef = sourceSnapshot.def ?? { nodes: []};
5666
5632
  const nodeTypeMap = new Map();
5667
5633
  const handleTypeMap = new Map();
5668
5634
  for (const node of sourceDef.nodes) {
@@ -5692,10 +5658,66 @@ function mergeSnapshotData(targetSnapshot, sourceSnapshot, sourceDef, nodeIdMap,
5692
5658
  handleTypeMap.set(node.nodeId, nodeHandleTypes);
5693
5659
  }
5694
5660
  }
5695
- const { mergedInputs, mergedOutputs } = mergeInputsOutputs(targetSnapshot.inputs ?? {}, targetSnapshot.outputs ?? {}, sourceSnapshot.inputs ?? {}, sourceSnapshot.outputs ?? {}, nodeIdMap, converter, nodeTypeMap, handleTypeMap);
5661
+ return mergeInputsOutputs(targetSnapshot.inputs ?? {}, targetSnapshot.outputs ?? {}, sourceSnapshot.inputs ?? {}, sourceSnapshot.outputs ?? {}, targetInputDefaults, sourceInputDefaults, nodeIdMap, nodeTypeMap, handleTypeMap);
5662
+ }
5663
+ function mergeSnapshots(targetSnapshot, sourceSnapshot, converter) {
5664
+ const targetDef = targetSnapshot.def ?? { nodes: [], edges: [] };
5665
+ const sourceDef = sourceSnapshot.def ?? { nodes: [], edges: [] };
5666
+ const { merged, nodeIdMap, targetInputDefaults, sourceInputDefaults } = mergeGraphDefinitions(targetDef, sourceDef);
5667
+ const { mergedInputs, mergedOutputs, mergedInputDefaults, inputsToConvert, outputsToConvert, inputDefaultsToConvert, } = mergeSnapshotData(targetSnapshot, sourceSnapshot, targetInputDefaults, sourceInputDefaults, nodeIdMap);
5668
+ if (converter) {
5669
+ const applyConversion = (items, values, type) => {
5670
+ for (const item of items) {
5671
+ const convertedValue = converter({
5672
+ nodeId: item.nodeId,
5673
+ handleId: item.handleId,
5674
+ value: item.value,
5675
+ type,
5676
+ nodeTypeId: item.nodeTypeId,
5677
+ handleDataType: item.handleDataType,
5678
+ runtimeTypeId: item.runtimeTypeId,
5679
+ });
5680
+ if (convertedValue === null) {
5681
+ delete values[item.nodeId]?.[item.handleId];
5682
+ if (values[item.nodeId] &&
5683
+ Object.keys(values[item.nodeId]).length === 0) {
5684
+ delete values[item.nodeId];
5685
+ }
5686
+ }
5687
+ else {
5688
+ if (!values[item.nodeId]) {
5689
+ values[item.nodeId] = {};
5690
+ }
5691
+ values[item.nodeId][item.handleId] = convertedValue;
5692
+ }
5693
+ }
5694
+ };
5695
+ applyConversion(inputDefaultsToConvert, mergedInputDefaults, "inputDefault");
5696
+ applyConversion(inputsToConvert, mergedInputs, "input");
5697
+ applyConversion(outputsToConvert, mergedOutputs, "output");
5698
+ }
5699
+ const nodeMap = new Map(merged.nodes.map((n) => [n.nodeId, n]));
5700
+ for (const nodeId in mergedInputDefaults) {
5701
+ const node = nodeMap.get(nodeId);
5702
+ if (node && Object.keys(mergedInputDefaults[nodeId]).length > 0) {
5703
+ if (!node.resolvedHandles) {
5704
+ node.resolvedHandles = {};
5705
+ }
5706
+ node.resolvedHandles.inputDefaults = mergedInputDefaults[nodeId];
5707
+ }
5708
+ }
5696
5709
  return {
5697
- mergedInputs,
5698
- mergedOutputs,
5710
+ merged: {
5711
+ def: merged,
5712
+ inputs: mergedInputs,
5713
+ outputs: mergedOutputs,
5714
+ environment: {
5715
+ ...targetSnapshot.environment,
5716
+ ...sourceSnapshot.environment,
5717
+ },
5718
+ extData: { ...targetSnapshot.extData, ...sourceSnapshot.extData },
5719
+ },
5720
+ nodeIdMap,
5699
5721
  };
5700
5722
  }
5701
5723
  /**
@@ -5927,11 +5949,9 @@ exports.getValueAtPath = getValueAtPath;
5927
5949
  exports.installLogging = installLogging;
5928
5950
  exports.isInputPrivate = isInputPrivate;
5929
5951
  exports.isTypedOutput = isTypedOutput;
5930
- exports.mergeGraphDefinitions = mergeGraphDefinitions;
5931
5952
  exports.mergeInputHandleDescriptors = mergeInputHandleDescriptors;
5932
- exports.mergeInputsOutputs = mergeInputsOutputs;
5933
5953
  exports.mergeRuntimeState = mergeRuntimeState;
5934
- exports.mergeSnapshotData = mergeSnapshotData;
5954
+ exports.mergeSnapshots = mergeSnapshots;
5935
5955
  exports.offsetImportedPositions = offsetImportedPositions;
5936
5956
  exports.parseJsonPath = parseJsonPath;
5937
5957
  exports.registerDelayNode = registerDelayNode;