@bian-womp/spark-graph 0.2.36 → 0.2.38

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
@@ -521,10 +521,43 @@ class GraphRuntime {
521
521
  const hasInbound = this.edges.some((e) => e.target.nodeId === nodeId && e.target.handle === handle);
522
522
  if (hasInbound)
523
523
  continue;
524
+ // Validate input value against declared type
525
+ if (value !== undefined && this.registry) {
526
+ const desc = this.registry.nodes.get(node.typeId);
527
+ const resolved = this.resolvedByNode.get(nodeId);
528
+ // Get typeId from resolved handles first, then registry statics
529
+ const typeId = resolved
530
+ ? getInputTypeId(resolved.inputs, handle)
531
+ : desc
532
+ ? getInputTypeId(desc.inputs, handle)
533
+ : undefined;
534
+ if (typeId) {
535
+ const typeDesc = this.registry.types.get(typeId);
536
+ if (typeDesc?.validate && !typeDesc.validate(value)) {
537
+ // Emit error event for invalid input value and reject it
538
+ const errorMessage = `Invalid value for input ${nodeId}.${handle} (type ${typeId}): ${JSON.stringify(value)}`;
539
+ this.emit("error", {
540
+ kind: "input-validation",
541
+ nodeId,
542
+ handle,
543
+ typeId,
544
+ value,
545
+ message: errorMessage,
546
+ });
547
+ // Skip storing invalid value
548
+ continue;
549
+ }
550
+ }
551
+ }
524
552
  const prev = node.inputs[handle];
525
553
  const same = this.valuesEqual(prev, value);
526
554
  if (!same) {
527
- node.inputs[handle] = value;
555
+ if (value === undefined) {
556
+ delete node.inputs[handle];
557
+ }
558
+ else {
559
+ node.inputs[handle] = value;
560
+ }
528
561
  // Emit value event for input updates
529
562
  this.emit("value", { nodeId, handle, value, io: "input" });
530
563
  anyChanged = true;
@@ -1832,9 +1865,10 @@ class GraphBuilder {
1832
1865
  const innerDesc = innerNode
1833
1866
  ? this.registry.nodes.get(innerNode.typeId)
1834
1867
  : undefined;
1835
- const typeId = innerDesc ? innerDesc.inputs[map.handle] : undefined;
1836
- inputTypes[outerIn] =
1837
- typeof typeId === "string" ? typeId : typeId?.typeId ?? "untyped";
1868
+ const typeId = innerDesc
1869
+ ? getInputTypeId(innerDesc.inputs, map.handle)
1870
+ : undefined;
1871
+ inputTypes[outerIn] = typeId ?? "untyped";
1838
1872
  }
1839
1873
  for (const [outerOut, map] of Object.entries(exposure.outputs)) {
1840
1874
  const innerNode = def.nodes.find((n) => n.nodeId === map.nodeId);
@@ -1892,32 +1926,6 @@ class PushEngine extends AbstractEngine {
1892
1926
  }
1893
1927
  }
1894
1928
 
1895
- class LocalRunner {
1896
- constructor(registry) {
1897
- this.registry = registry;
1898
- this.builder = new GraphBuilder(registry);
1899
- }
1900
- async build(def, opts) {
1901
- const rt = this.builder.build(def, opts);
1902
- this.engine = new PushEngine(rt);
1903
- }
1904
- async update(def) {
1905
- // If engine exists and is a PushEngine backed by GraphRuntime, use runtime.update
1906
- // Otherwise rebuild.
1907
- const eng = this.engine;
1908
- if (eng && eng.graphRuntime) {
1909
- eng.graphRuntime.update(def, this.registry);
1910
- return;
1911
- }
1912
- await this.build(def);
1913
- }
1914
- getEngine() {
1915
- if (!this.engine)
1916
- throw new Error("Engine not built. Call build(def) first.");
1917
- return this.engine;
1918
- }
1919
- }
1920
-
1921
1929
  class BatchedEngine extends AbstractEngine {
1922
1930
  constructor(graphRuntime, opts = {}) {
1923
1931
  super(graphRuntime);
@@ -3481,7 +3489,6 @@ exports.ComputeCategory = ComputeCategory;
3481
3489
  exports.GraphBuilder = GraphBuilder;
3482
3490
  exports.GraphRuntime = GraphRuntime;
3483
3491
  exports.HybridEngine = HybridEngine;
3484
- exports.LocalRunner = LocalRunner;
3485
3492
  exports.PullEngine = PullEngine;
3486
3493
  exports.PushEngine = PushEngine;
3487
3494
  exports.Registry = Registry;