@bian-womp/spark-remote 0.2.28 → 0.2.29
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 +218 -177
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/server/runtime.d.ts +11 -2
- package/lib/cjs/src/server/runtime.d.ts.map +1 -1
- package/lib/esm/index.js +218 -177
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/server/runtime.d.ts +11 -2
- package/lib/esm/src/server/runtime.d.ts.map +1 -1
- package/package.json +3 -3
package/lib/esm/index.js
CHANGED
|
@@ -508,193 +508,234 @@ async function handleCommand(label, env, runtimeApi, ack) {
|
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
-
async function createRuntimeAdapter(createRegistry, send) {
|
|
511
|
+
async function createRuntimeAdapter(createRegistry, send, extensions) {
|
|
512
512
|
const registry = await createRegistry();
|
|
513
513
|
const builder = new GraphBuilder(registry);
|
|
514
514
|
let graphRuntime;
|
|
515
515
|
let extData = {};
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
else if (d.kind === "register-node") {
|
|
553
|
-
const desc = d.desc || {};
|
|
554
|
-
registry.registerNode({
|
|
555
|
-
id: String(desc.id || ""),
|
|
556
|
-
categoryId: String(desc.categoryId || "compute"),
|
|
557
|
-
displayName: desc.displayName,
|
|
558
|
-
inputs: desc.inputs || {},
|
|
559
|
-
outputs: desc.outputs || {},
|
|
560
|
-
// impl must be empty per frontend registration contract
|
|
561
|
-
impl: () => { },
|
|
562
|
-
});
|
|
563
|
-
}
|
|
516
|
+
// Helper to get current context
|
|
517
|
+
const getContext = () => ({
|
|
518
|
+
registry,
|
|
519
|
+
builder,
|
|
520
|
+
graphRuntime,
|
|
521
|
+
extData,
|
|
522
|
+
});
|
|
523
|
+
// Original implementations - define as separate functions first to allow cross-references
|
|
524
|
+
const originals = {};
|
|
525
|
+
// Define methods that can reference each other
|
|
526
|
+
originals.coerce = async (from, to, value) => {
|
|
527
|
+
const resolved = registry.resolveCoercion(from, to);
|
|
528
|
+
if (!resolved)
|
|
529
|
+
return value;
|
|
530
|
+
if (resolved.kind === "sync")
|
|
531
|
+
return resolved.convert(value);
|
|
532
|
+
const ac = new AbortController();
|
|
533
|
+
return await resolved.convertAsync(value, ac.signal);
|
|
534
|
+
};
|
|
535
|
+
originals.getEnvironment = () => {
|
|
536
|
+
return graphRuntime?.getEnvironment?.() ?? {};
|
|
537
|
+
};
|
|
538
|
+
originals.applyRegistry = async (deltas) => {
|
|
539
|
+
// Pause runtime if exists
|
|
540
|
+
// Apply each delta to the live registry
|
|
541
|
+
for (const d of deltas || []) {
|
|
542
|
+
if (!d || typeof d !== "object")
|
|
543
|
+
continue;
|
|
544
|
+
if (d.kind === "register-enum") {
|
|
545
|
+
registry.registerEnum({
|
|
546
|
+
id: d.id,
|
|
547
|
+
displayName: d.displayName,
|
|
548
|
+
options: d.options || [],
|
|
549
|
+
bakeTarget: d.bakeTarget,
|
|
550
|
+
opts: d.opts,
|
|
551
|
+
});
|
|
564
552
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
},
|
|
573
|
-
async build(def, opts) {
|
|
574
|
-
const env = opts || {};
|
|
575
|
-
graphRuntime = builder.build(def, { environment: env });
|
|
576
|
-
graphRuntime.on("value", (p) => send({ message: { type: "value", payload: p } }));
|
|
577
|
-
graphRuntime.on("invalidate", (p) => send({ message: { type: "invalidate", payload: p } }));
|
|
578
|
-
graphRuntime.on("error", (p) => send({ message: { type: "error", payload: p } }));
|
|
579
|
-
graphRuntime.on("stats", (p) => send({ message: { type: "stats", payload: p } }));
|
|
580
|
-
},
|
|
581
|
-
setExtData(data) {
|
|
582
|
-
if (!data || typeof data !== "object") {
|
|
583
|
-
extData = {};
|
|
584
|
-
return;
|
|
553
|
+
else if (d.kind === "register-type") {
|
|
554
|
+
registry.registerType({
|
|
555
|
+
id: d.id,
|
|
556
|
+
displayName: d.displayName,
|
|
557
|
+
bakeTarget: d.bakeTarget,
|
|
558
|
+
validate: (_v) => true,
|
|
559
|
+
});
|
|
585
560
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const nodes = graphRuntime.getNodeIds();
|
|
598
|
-
for (const nodeId of nodes) {
|
|
599
|
-
const data = graphRuntime.getNodeData(nodeId);
|
|
600
|
-
if (data?.inputs && Object.keys(data.inputs).length > 0) {
|
|
601
|
-
inputs[nodeId] = { ...data.inputs };
|
|
602
|
-
}
|
|
603
|
-
if (data?.outputs && Object.keys(data.outputs).length > 0) {
|
|
604
|
-
outputs[nodeId] = { ...data.outputs };
|
|
605
|
-
}
|
|
561
|
+
else if (d.kind === "register-node") {
|
|
562
|
+
const desc = d.desc || {};
|
|
563
|
+
registry.registerNode({
|
|
564
|
+
id: String(desc.id || ""),
|
|
565
|
+
categoryId: String(desc.categoryId || "compute"),
|
|
566
|
+
displayName: desc.displayName,
|
|
567
|
+
inputs: desc.inputs || {},
|
|
568
|
+
outputs: desc.outputs || {},
|
|
569
|
+
// impl must be empty per frontend registration contract
|
|
570
|
+
impl: () => { },
|
|
571
|
+
});
|
|
606
572
|
}
|
|
573
|
+
}
|
|
574
|
+
// Notify clients (include deltas in invalidate payload)
|
|
575
|
+
send({
|
|
576
|
+
message: {
|
|
577
|
+
type: "invalidate",
|
|
578
|
+
payload: { reason: "registry-changed", deltas },
|
|
579
|
+
},
|
|
580
|
+
});
|
|
581
|
+
};
|
|
582
|
+
originals.build = async (def, opts) => {
|
|
583
|
+
const env = opts || {};
|
|
584
|
+
graphRuntime = builder.build(def, { environment: env });
|
|
585
|
+
graphRuntime.on("value", (p) => send({ message: { type: "value", payload: p } }));
|
|
586
|
+
graphRuntime.on("invalidate", (p) => send({ message: { type: "invalidate", payload: p } }));
|
|
587
|
+
graphRuntime.on("error", (p) => send({ message: { type: "error", payload: p } }));
|
|
588
|
+
graphRuntime.on("stats", (p) => send({ message: { type: "stats", payload: p } }));
|
|
589
|
+
};
|
|
590
|
+
originals.setExtData = (data) => {
|
|
591
|
+
if (!data || typeof data !== "object") {
|
|
592
|
+
extData = {};
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
// Replace to keep semantics deterministic
|
|
596
|
+
extData = { ...data };
|
|
597
|
+
};
|
|
598
|
+
originals.getExtData = () => {
|
|
599
|
+
return extData;
|
|
600
|
+
};
|
|
601
|
+
originals.snapshot = () => {
|
|
602
|
+
const inputs = {};
|
|
603
|
+
const outputs = {};
|
|
604
|
+
if (!graphRuntime)
|
|
607
605
|
return { inputs, outputs };
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
606
|
+
const nodes = graphRuntime.getNodeIds();
|
|
607
|
+
for (const nodeId of nodes) {
|
|
608
|
+
const data = graphRuntime.getNodeData(nodeId);
|
|
609
|
+
if (data?.inputs && Object.keys(data.inputs).length > 0) {
|
|
610
|
+
inputs[nodeId] = { ...data.inputs };
|
|
611
|
+
}
|
|
612
|
+
if (data?.outputs && Object.keys(data.outputs).length > 0) {
|
|
613
|
+
outputs[nodeId] = { ...data.outputs };
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return { inputs, outputs };
|
|
617
|
+
};
|
|
618
|
+
originals.snapshotFull = () => {
|
|
619
|
+
const snap = originals.snapshot();
|
|
620
|
+
const env = graphRuntime?.getEnvironment?.() ?? {};
|
|
621
|
+
const def = graphRuntime?.getGraphDef();
|
|
622
|
+
return {
|
|
623
|
+
def,
|
|
624
|
+
environment: env,
|
|
625
|
+
inputs: snap.inputs,
|
|
626
|
+
outputs: snap.outputs,
|
|
627
|
+
};
|
|
628
|
+
};
|
|
629
|
+
originals.applySnapshotFull = async (payload) => {
|
|
630
|
+
const def = payload.def;
|
|
631
|
+
if (!def)
|
|
632
|
+
return;
|
|
633
|
+
await originals.build(def, payload.environment);
|
|
634
|
+
// Hydrate inputs/outputs exactly, then re-emit outputs without scheduling runs
|
|
635
|
+
graphRuntime?.hydrate({ inputs: payload.inputs, outputs: payload.outputs }, { reemit: true });
|
|
636
|
+
};
|
|
637
|
+
originals.describeRegistry = () => {
|
|
638
|
+
// types (include enum options when available)
|
|
639
|
+
const types = Array.from(registry.types.entries()).map(([id, d]) => {
|
|
640
|
+
const en = registry.enums.get(id);
|
|
613
641
|
return {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
642
|
+
id,
|
|
643
|
+
displayName: d.displayName,
|
|
644
|
+
bakeTarget: d.bakeTarget,
|
|
645
|
+
...(en ? { options: en.options } : {}),
|
|
618
646
|
};
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
647
|
+
});
|
|
648
|
+
// categories: not directly enumerable; derive from node descriptors
|
|
649
|
+
const nodeDescs = Array.from(registry.nodes.values());
|
|
650
|
+
const catIds = new Set(nodeDescs.map((n) => n.categoryId));
|
|
651
|
+
const categories = Array.from(catIds).map((id) => {
|
|
652
|
+
const cat = registry.categories.get?.(id);
|
|
653
|
+
return { id, displayName: cat?.displayName };
|
|
654
|
+
});
|
|
655
|
+
const nodes = nodeDescs.map((n) => ({
|
|
656
|
+
id: n.id,
|
|
657
|
+
categoryId: n.categoryId,
|
|
658
|
+
displayName: n.displayName,
|
|
659
|
+
inputs: n.inputs || {},
|
|
660
|
+
outputs: n.outputs || {},
|
|
661
|
+
inputDefaults: n.inputDefaults || {},
|
|
662
|
+
}));
|
|
663
|
+
const coercions = registry.listCoercions();
|
|
664
|
+
return { types, categories, nodes, coercions, schemaVersion: 4 };
|
|
665
|
+
};
|
|
666
|
+
originals.update = async (def) => {
|
|
667
|
+
if (!graphRuntime)
|
|
668
|
+
return;
|
|
669
|
+
graphRuntime.update(def, registry);
|
|
670
|
+
send({
|
|
671
|
+
message: {
|
|
672
|
+
type: "invalidate",
|
|
673
|
+
payload: { reason: "graph-updated" },
|
|
674
|
+
},
|
|
675
|
+
});
|
|
676
|
+
};
|
|
677
|
+
originals.setEnvironment = (env, opts) => {
|
|
678
|
+
if (!graphRuntime)
|
|
679
|
+
return;
|
|
680
|
+
if (opts?.merge) {
|
|
681
|
+
const current = graphRuntime.getEnvironment();
|
|
682
|
+
const next = { ...(current || {}), ...(env || {}) };
|
|
683
|
+
graphRuntime.setEnvironment(next);
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
graphRuntime.setEnvironment(env);
|
|
687
|
+
};
|
|
688
|
+
originals.setInput = (nodeId, handle, value) => {
|
|
689
|
+
graphRuntime?.setInput(nodeId, handle, value);
|
|
690
|
+
};
|
|
691
|
+
originals.setInputs = (nodeId, inputs) => {
|
|
692
|
+
graphRuntime?.setInputs(nodeId, inputs);
|
|
693
|
+
};
|
|
694
|
+
originals.triggerExternal = (nodeId, event) => {
|
|
695
|
+
graphRuntime?.triggerExternal(nodeId, event);
|
|
696
|
+
};
|
|
697
|
+
originals.launch = () => {
|
|
698
|
+
graphRuntime?.launch();
|
|
699
|
+
};
|
|
700
|
+
originals.whenIdle = () => {
|
|
701
|
+
return graphRuntime?.whenIdle?.() ?? Promise.resolve();
|
|
702
|
+
};
|
|
703
|
+
originals.dispose = () => {
|
|
704
|
+
graphRuntime?.dispose?.();
|
|
705
|
+
graphRuntime = undefined;
|
|
706
|
+
};
|
|
707
|
+
// Cast to RuntimeApi now that all methods are defined
|
|
708
|
+
const originalsApi = originals;
|
|
709
|
+
// Helper to wrap a method with extension support
|
|
710
|
+
const wrapMethod = (key, original) => {
|
|
711
|
+
const extension = extensions?.[key];
|
|
712
|
+
if (!extension) {
|
|
713
|
+
return original;
|
|
714
|
+
}
|
|
715
|
+
return ((...args) => {
|
|
716
|
+
return extension(original, getContext(), ...args);
|
|
717
|
+
});
|
|
718
|
+
};
|
|
719
|
+
// Create API with extensions applied
|
|
720
|
+
const api = {
|
|
721
|
+
coerce: wrapMethod("coerce", originalsApi.coerce),
|
|
722
|
+
getEnvironment: wrapMethod("getEnvironment", originalsApi.getEnvironment),
|
|
723
|
+
applyRegistry: wrapMethod("applyRegistry", originalsApi.applyRegistry),
|
|
724
|
+
build: wrapMethod("build", originalsApi.build),
|
|
725
|
+
setExtData: wrapMethod("setExtData", originalsApi.setExtData),
|
|
726
|
+
getExtData: wrapMethod("getExtData", originalsApi.getExtData),
|
|
727
|
+
snapshot: wrapMethod("snapshot", originalsApi.snapshot),
|
|
728
|
+
snapshotFull: wrapMethod("snapshotFull", originalsApi.snapshotFull),
|
|
729
|
+
applySnapshotFull: wrapMethod("applySnapshotFull", originalsApi.applySnapshotFull),
|
|
730
|
+
describeRegistry: wrapMethod("describeRegistry", originalsApi.describeRegistry),
|
|
731
|
+
update: wrapMethod("update", originalsApi.update),
|
|
732
|
+
setEnvironment: wrapMethod("setEnvironment", originalsApi.setEnvironment),
|
|
733
|
+
setInput: wrapMethod("setInput", originalsApi.setInput),
|
|
734
|
+
setInputs: wrapMethod("setInputs", originalsApi.setInputs),
|
|
735
|
+
triggerExternal: wrapMethod("triggerExternal", originalsApi.triggerExternal),
|
|
736
|
+
launch: wrapMethod("launch", originalsApi.launch),
|
|
737
|
+
whenIdle: wrapMethod("whenIdle", originalsApi.whenIdle),
|
|
738
|
+
dispose: wrapMethod("dispose", originalsApi.dispose),
|
|
698
739
|
};
|
|
699
740
|
return api;
|
|
700
741
|
}
|