@bian-womp/spark-graph 0.3.18 → 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
@@ -2255,6 +2255,15 @@ class NodeExecutor {
2255
2255
  runId,
2256
2256
  abortSignal,
2257
2257
  reportProgress,
2258
+ setCustomData: (data) => {
2259
+ this.eventEmitter.emit("stats", {
2260
+ kind: "node-custom-data",
2261
+ nodeId,
2262
+ typeId: node.typeId,
2263
+ runId,
2264
+ data,
2265
+ });
2266
+ },
2258
2267
  log,
2259
2268
  };
2260
2269
  }
@@ -5414,62 +5423,42 @@ function findMatchingPaths(obj, pathSegments, currentPath = []) {
5414
5423
  return results;
5415
5424
  }
5416
5425
 
5417
- function mergeGraphDefinitions(target, source, converter) {
5426
+ function mergeGraphDefinitions(target, source) {
5418
5427
  const existingNodeIds = new Set(target.nodes.map((n) => n.nodeId));
5419
5428
  const existingEdgeIds = new Set(target.edges.map((e) => e.id));
5420
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
+ }
5421
5439
  const importedNodes = source.nodes.map((n) => {
5422
5440
  let newId = n.nodeId;
5423
- if (existingNodeIds.has(newId)) {
5441
+ const isExistingNode = existingNodeIds.has(newId);
5442
+ if (isExistingNode) {
5424
5443
  newId = generateId("n", existingNodeIds);
5425
5444
  }
5426
5445
  else {
5427
5446
  existingNodeIds.add(newId);
5428
5447
  }
5429
5448
  nodeIdMap[n.nodeId] = newId;
5430
- const transformedNode = {
5449
+ if (n.resolvedHandles?.inputDefaults) {
5450
+ sourceInputDefaults[n.nodeId] = { ...n.resolvedHandles.inputDefaults };
5451
+ }
5452
+ return {
5431
5453
  ...n,
5432
5454
  nodeId: newId,
5433
- };
5434
- if (converter) {
5435
- const nodeTypeId = transformedNode.typeId;
5436
- if (transformedNode.resolvedHandles?.inputDefaults) {
5437
- const transformedInputDefaults = {};
5438
- for (const [handleId, value] of Object.entries(transformedNode.resolvedHandles.inputDefaults)) {
5439
- const handleDataType = transformedNode.resolvedHandles?.inputs?.[handleId]
5440
- ? typeof transformedNode.resolvedHandles.inputs[handleId] ===
5441
- "string"
5442
- ? transformedNode.resolvedHandles.inputs[handleId]
5443
- : transformedNode.resolvedHandles.inputs[handleId]?.typeId
5444
- : undefined;
5445
- const convertedValue = converter({
5446
- nodeId: newId,
5447
- handleId,
5448
- value,
5449
- type: "inputDefault",
5450
- nodeTypeId,
5451
- handleDataType,
5452
- });
5453
- // If converter returns null, skip this input default (delete it)
5454
- if (convertedValue !== null) {
5455
- transformedInputDefaults[handleId] = convertedValue;
5456
- }
5455
+ resolvedHandles: n.resolvedHandles
5456
+ ? {
5457
+ ...n.resolvedHandles,
5458
+ inputDefaults: undefined,
5457
5459
  }
5458
- // Only set inputDefaults if there are any remaining after conversion
5459
- if (Object.keys(transformedInputDefaults).length > 0) {
5460
- transformedNode.resolvedHandles = {
5461
- ...transformedNode.resolvedHandles,
5462
- inputDefaults: transformedInputDefaults,
5463
- };
5464
- }
5465
- else if (transformedNode.resolvedHandles) {
5466
- // Remove inputDefaults if all were deleted
5467
- const { inputDefaults, ...restHandles } = transformedNode.resolvedHandles;
5468
- transformedNode.resolvedHandles = restHandles;
5469
- }
5470
- }
5471
- }
5472
- return transformedNode;
5460
+ : undefined,
5461
+ };
5473
5462
  });
5474
5463
  const importedEdges = source.edges.map((e) => {
5475
5464
  let newEdgeId = e.id;
@@ -5500,6 +5489,8 @@ function mergeGraphDefinitions(target, source, converter) {
5500
5489
  edges: [...target.edges, ...importedEdges],
5501
5490
  },
5502
5491
  nodeIdMap,
5492
+ targetInputDefaults,
5493
+ sourceInputDefaults,
5503
5494
  };
5504
5495
  }
5505
5496
  /**
@@ -5544,116 +5535,100 @@ function offsetImportedPositions(targetPositions, sourcePositions, sourceDef, no
5544
5535
  }
5545
5536
  return newPositions;
5546
5537
  }
5547
- /**
5548
- * Merge inputs and outputs from source into target, remapping node IDs.
5549
- * Source values override target when merging.
5550
- */
5551
- function mergeInputsOutputs(targetInputs, targetOutputs, sourceInputs, sourceOutputs, nodeIdMap, converter, nodeTypeMap, handleTypeMap) {
5552
- // Deep copy target inputs/outputs to avoid mutating the original
5538
+ function mergeInputsOutputs(targetInputs, targetOutputs, sourceInputs, sourceOutputs, targetInputDefaults, sourceInputDefaults, nodeIdMap, nodeTypeMap, handleTypeMap) {
5553
5539
  const mergedInputs = {};
5554
5540
  const mergedOutputs = {};
5555
- // Copy target inputs/outputs
5541
+ const mergedInputDefaults = {};
5542
+ const inputsToConvert = [];
5543
+ const outputsToConvert = [];
5544
+ const inputDefaultsToConvert = [];
5556
5545
  for (const [nodeId, inputs] of Object.entries(targetInputs)) {
5557
5546
  mergedInputs[nodeId] = { ...inputs };
5558
5547
  }
5559
5548
  for (const [nodeId, outputs] of Object.entries(targetOutputs)) {
5560
5549
  mergedOutputs[nodeId] = { ...outputs };
5561
5550
  }
5551
+ for (const [nodeId, defaults] of Object.entries(targetInputDefaults)) {
5552
+ mergedInputDefaults[nodeId] = { ...defaults };
5553
+ }
5562
5554
  for (const [oldId, inputs] of Object.entries(sourceInputs)) {
5563
5555
  const newId = nodeIdMap[oldId];
5564
5556
  if (newId) {
5565
- const transformedInputs = {};
5566
- const nodeTypeId = nodeTypeMap?.get(oldId);
5567
- // Ensure mergedInputs[newId] exists
5568
5557
  if (!mergedInputs[newId]) {
5569
5558
  mergedInputs[newId] = {};
5570
5559
  }
5560
+ const nodeTypeId = nodeTypeMap?.get(oldId);
5571
5561
  for (const [handleId, value] of Object.entries(inputs)) {
5572
5562
  const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
5573
- const convertedValue = converter
5574
- ? converter({
5575
- nodeId: newId,
5576
- handleId,
5577
- value,
5578
- type: "input",
5579
- nodeTypeId,
5580
- handleDataType,
5581
- })
5582
- : value;
5583
- // If converter returns null, delete this input
5584
- if (convertedValue === null) {
5585
- delete mergedInputs[newId][handleId];
5586
- }
5587
- else {
5588
- // Otherwise, set the converted value
5589
- transformedInputs[handleId] = convertedValue;
5590
- }
5591
- }
5592
- // Merge transformed inputs
5593
- if (Object.keys(transformedInputs).length > 0) {
5594
- mergedInputs[newId] = { ...mergedInputs[newId], ...transformedInputs };
5595
- }
5596
- // Clean up empty node input objects
5597
- if (Object.keys(mergedInputs[newId]).length === 0) {
5598
- 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;
5599
5572
  }
5600
5573
  }
5601
5574
  }
5602
5575
  for (const [oldId, outputs] of Object.entries(sourceOutputs)) {
5603
5576
  const newId = nodeIdMap[oldId];
5604
5577
  if (newId) {
5605
- const transformedOutputs = {};
5606
- const nodeTypeId = nodeTypeMap?.get(oldId);
5607
- // Ensure mergedOutputs[newId] exists
5608
5578
  if (!mergedOutputs[newId]) {
5609
5579
  mergedOutputs[newId] = {};
5610
5580
  }
5581
+ const nodeTypeId = nodeTypeMap?.get(oldId);
5611
5582
  for (const [handleId, value] of Object.entries(outputs)) {
5612
5583
  const handleDataType = handleTypeMap?.get(oldId)?.get(handleId);
5613
5584
  const runtimeTypeId = isTypedOutput(value)
5614
5585
  ? getTypedOutputTypeId(value)
5615
5586
  : undefined;
5616
- const convertedValue = converter
5617
- ? converter({
5618
- nodeId: newId,
5619
- handleId,
5620
- value,
5621
- type: "output",
5622
- nodeTypeId,
5623
- handleDataType,
5624
- runtimeTypeId,
5625
- })
5626
- : value;
5627
- // If converter returns null, delete this output
5628
- if (convertedValue === null) {
5629
- delete mergedOutputs[newId][handleId];
5630
- }
5631
- else {
5632
- // Otherwise, set the converted value
5633
- transformedOutputs[handleId] = convertedValue;
5634
- }
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;
5635
5597
  }
5636
- // Merge transformed outputs
5637
- if (Object.keys(transformedOutputs).length > 0) {
5638
- mergedOutputs[newId] = {
5639
- ...mergedOutputs[newId],
5640
- ...transformedOutputs,
5641
- };
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] = {};
5642
5605
  }
5643
- // Clean up empty node output objects
5644
- if (Object.keys(mergedOutputs[newId]).length === 0) {
5645
- 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;
5646
5618
  }
5647
5619
  }
5648
5620
  }
5649
- return { mergedInputs, mergedOutputs };
5621
+ return {
5622
+ mergedInputs,
5623
+ mergedOutputs,
5624
+ mergedInputDefaults,
5625
+ inputsToConvert,
5626
+ outputsToConvert,
5627
+ inputDefaultsToConvert,
5628
+ };
5650
5629
  }
5651
- /**
5652
- * Merge snapshot data (inputs, outputs) from source into target.
5653
- * Graph definition merging should be done separately using mergeGraphDefinitions.
5654
- * UI positions are handled separately by mergeUIState.
5655
- */
5656
- function mergeSnapshotData(targetSnapshot, sourceSnapshot, sourceDef, nodeIdMap, converter) {
5630
+ function mergeSnapshotData(targetSnapshot, sourceSnapshot, targetInputDefaults, sourceInputDefaults, nodeIdMap) {
5631
+ const sourceDef = sourceSnapshot.def ?? { nodes: []};
5657
5632
  const nodeTypeMap = new Map();
5658
5633
  const handleTypeMap = new Map();
5659
5634
  for (const node of sourceDef.nodes) {
@@ -5683,10 +5658,66 @@ function mergeSnapshotData(targetSnapshot, sourceSnapshot, sourceDef, nodeIdMap,
5683
5658
  handleTypeMap.set(node.nodeId, nodeHandleTypes);
5684
5659
  }
5685
5660
  }
5686
- 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
+ }
5687
5709
  return {
5688
- mergedInputs,
5689
- 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,
5690
5721
  };
5691
5722
  }
5692
5723
  /**
@@ -5918,11 +5949,9 @@ exports.getValueAtPath = getValueAtPath;
5918
5949
  exports.installLogging = installLogging;
5919
5950
  exports.isInputPrivate = isInputPrivate;
5920
5951
  exports.isTypedOutput = isTypedOutput;
5921
- exports.mergeGraphDefinitions = mergeGraphDefinitions;
5922
5952
  exports.mergeInputHandleDescriptors = mergeInputHandleDescriptors;
5923
- exports.mergeInputsOutputs = mergeInputsOutputs;
5924
5953
  exports.mergeRuntimeState = mergeRuntimeState;
5925
- exports.mergeSnapshotData = mergeSnapshotData;
5954
+ exports.mergeSnapshots = mergeSnapshots;
5926
5955
  exports.offsetImportedPositions = offsetImportedPositions;
5927
5956
  exports.parseJsonPath = parseJsonPath;
5928
5957
  exports.registerDelayNode = registerDelayNode;