@bian-womp/spark-graph 0.3.64 → 0.3.66

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
@@ -76,6 +76,7 @@ function mergeInputHandleDescriptors(staticDesc, dynamicDesc) {
76
76
  const merged = {
77
77
  typeId: dynamicObj.typeId ?? staticObj.typeId,
78
78
  private: dynamicObj.private ?? staticObj.private,
79
+ defaultPolicy: dynamicObj.defaultPolicy ?? staticObj.defaultPolicy,
79
80
  };
80
81
  // Merge metadata if either has it
81
82
  if (staticObj.metadata || dynamicObj.metadata) {
@@ -1111,9 +1112,11 @@ function setValueAtPathWithCreation(root, pathSegments, value) {
1111
1112
  if (value === null) {
1112
1113
  const result = getValueAtPath(root, pathSegments);
1113
1114
  if (result && result.parent !== null && !Array.isArray(result.parent)) {
1115
+ const hadValue = result.key in result.parent;
1114
1116
  delete result.parent[result.key];
1117
+ return hadValue;
1115
1118
  }
1116
- return;
1119
+ return false;
1117
1120
  }
1118
1121
  if (!root || typeof root !== "object" || Array.isArray(root)) {
1119
1122
  throw new Error("Root must be an object");
@@ -1145,7 +1148,10 @@ function setValueAtPathWithCreation(root, pathSegments, value) {
1145
1148
  if (!current || typeof current !== "object" || Array.isArray(current)) {
1146
1149
  throw new Error(`Cannot set value: parent at final segment is not an object`);
1147
1150
  }
1151
+ const hadValue = lastSegment in current;
1152
+ const oldValue = current[lastSegment];
1148
1153
  current[lastSegment] = value;
1154
+ return !hadValue || JSON.stringify(oldValue) !== JSON.stringify(value);
1149
1155
  }
1150
1156
  else {
1151
1157
  throw new Error("Array indices not supported in extData paths");
@@ -2308,18 +2314,31 @@ function getEffectiveInputs(nodeId, graph, registry) {
2308
2314
  // Build set of inbound handles (wired inputs)
2309
2315
  const inboundEdges = graph.getInboundEdges(nodeId);
2310
2316
  const inbound = new Set(inboundEdges.map((e) => e.target.handle));
2317
+ const getDefaultPolicy = (handle) => {
2318
+ const resolvedDesc = resolved?.inputs?.[handle];
2319
+ const staticDesc = desc.inputs?.[handle];
2320
+ const pick = (d) => d && typeof d === "object" && "typeId" in d ? d.defaultPolicy : undefined;
2321
+ return pick(resolvedDesc) ?? pick(staticDesc);
2322
+ };
2311
2323
  // Apply defaults only for:
2312
2324
  // 1. Unbound handles that have no explicit value
2313
2325
  // 2. Static handles (not dynamically resolved)
2314
2326
  for (const [handle, defaultValue] of Object.entries(mergedDefaults)) {
2315
2327
  if (defaultValue === undefined)
2316
2328
  continue;
2317
- if (inbound.has(handle))
2318
- continue; // Don't override wired inputs
2319
2329
  if (effective[handle] !== undefined)
2320
2330
  continue; // Already has value
2321
2331
  if (dynamicHandles.has(handle))
2322
2332
  continue; // Skip defaults for dynamic handles
2333
+ const policy = getDefaultPolicy(handle);
2334
+ if (policy === "bound") {
2335
+ if (!inbound.has(handle))
2336
+ continue;
2337
+ }
2338
+ else {
2339
+ if (inbound.has(handle))
2340
+ continue;
2341
+ }
2323
2342
  // Clone to avoid shared references
2324
2343
  effective[handle] = structuredClone(defaultValue);
2325
2344
  }