@bian-womp/spark-remote 0.2.37 → 0.2.39

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.
Files changed (39) hide show
  1. package/lib/cjs/UnixSocketTransport-Bghy9EOO.js +103 -0
  2. package/lib/cjs/UnixSocketTransport-Bghy9EOO.js.map +1 -0
  3. package/lib/cjs/index-BKs-fgHN.js +1047 -0
  4. package/lib/cjs/index-BKs-fgHN.js.map +1 -0
  5. package/lib/cjs/index.cjs +11 -750
  6. package/lib/cjs/index.cjs.map +1 -1
  7. package/lib/cjs/src/RemoteEngine.d.ts.map +1 -1
  8. package/lib/cjs/src/RuntimeApiClient.d.ts +89 -0
  9. package/lib/cjs/src/RuntimeApiClient.d.ts.map +1 -0
  10. package/lib/cjs/src/examples/shared.d.ts +2 -2
  11. package/lib/cjs/src/examples/shared.d.ts.map +1 -1
  12. package/lib/cjs/src/index.d.ts +2 -2
  13. package/lib/cjs/src/index.d.ts.map +1 -1
  14. package/lib/cjs/src/server/RuntimeApiServer.d.ts +49 -0
  15. package/lib/cjs/src/server/RuntimeApiServer.d.ts.map +1 -0
  16. package/lib/esm/UnixSocketTransport-CVUsiFcW.js +101 -0
  17. package/lib/esm/UnixSocketTransport-CVUsiFcW.js.map +1 -0
  18. package/lib/esm/index-Dnchg7CQ.js +1037 -0
  19. package/lib/esm/index-Dnchg7CQ.js.map +1 -0
  20. package/lib/esm/index.js +3 -746
  21. package/lib/esm/index.js.map +1 -1
  22. package/lib/esm/src/RemoteEngine.d.ts.map +1 -1
  23. package/lib/esm/src/RuntimeApiClient.d.ts +89 -0
  24. package/lib/esm/src/RuntimeApiClient.d.ts.map +1 -0
  25. package/lib/esm/src/examples/shared.d.ts +2 -2
  26. package/lib/esm/src/examples/shared.d.ts.map +1 -1
  27. package/lib/esm/src/index.d.ts +2 -2
  28. package/lib/esm/src/index.d.ts.map +1 -1
  29. package/lib/esm/src/server/RuntimeApiServer.d.ts +49 -0
  30. package/lib/esm/src/server/RuntimeApiServer.d.ts.map +1 -0
  31. package/package.json +3 -3
  32. package/lib/cjs/src/RemoteRunner.d.ts +0 -24
  33. package/lib/cjs/src/RemoteRunner.d.ts.map +0 -1
  34. package/lib/cjs/src/server/command.d.ts +0 -4
  35. package/lib/cjs/src/server/command.d.ts.map +0 -1
  36. package/lib/esm/src/RemoteRunner.d.ts +0 -24
  37. package/lib/esm/src/RemoteRunner.d.ts.map +0 -1
  38. package/lib/esm/src/server/command.d.ts +0 -4
  39. package/lib/esm/src/server/command.d.ts.map +0 -1
package/lib/cjs/index.cjs CHANGED
@@ -1,756 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var ws = require('ws');
4
- var sparkGraph = require('@bian-womp/spark-graph');
3
+ var index = require('./index-BKs-fgHN.js');
4
+ require('ws');
5
+ require('@bian-womp/spark-graph');
5
6
 
6
- class SeqGenerator {
7
- constructor() {
8
- this.lastMs = 0;
9
- this.seqInMs = 0;
10
- }
11
- next() {
12
- const now = Date.now();
13
- if (now === this.lastMs) {
14
- this.seqInMs = (this.seqInMs + 1) % 1000;
15
- }
16
- else {
17
- this.lastMs = now;
18
- this.seqInMs = 0;
19
- }
20
- return now * 1000 + this.seqInMs;
21
- }
22
- }
23
7
 
24
- const OPEN = 1;
25
- class WebSocketTransport {
26
- constructor(url) {
27
- this.listeners = new Set();
28
- this.seq = new SeqGenerator();
29
- this.baseUrl = url;
30
- }
31
- async connect(options) {
32
- if (this.ws && this.ws.readyState === OPEN)
33
- return;
34
- // Build URL with connection params
35
- // Handle both ws:///wss:// URLs and http:///https:// URLs (convert to ws)
36
- let url;
37
- if (this.baseUrl.startsWith("ws://") || this.baseUrl.startsWith("wss://")) {
38
- url = new URL(this.baseUrl);
39
- }
40
- else {
41
- // Convert http/https to ws/wss
42
- const wsBaseUrl = this.baseUrl.replace(/^http/, "ws");
43
- url = new URL(wsBaseUrl);
44
- }
45
- if (options?.params) {
46
- for (const [key, value] of Object.entries(options.params)) {
47
- if (value !== undefined && value !== null) {
48
- url.searchParams.set(key, String(value));
49
- }
50
- }
51
- }
52
- const wsUrl = url.toString();
53
- this.ws = window
54
- ? new window.WebSocket(wsUrl)
55
- : new ws.WebSocket(wsUrl);
56
- await new Promise((resolve, reject) => {
57
- if (!this.ws)
58
- return reject(new Error("ws init failed"));
59
- this.ws.onopen = () => resolve();
60
- this.ws.onerror = (e) => reject(e);
61
- this.ws.onmessage = (ev) => {
62
- try {
63
- const env = JSON.parse(String(ev.data));
64
- for (const l of Array.from(this.listeners))
65
- l(env);
66
- }
67
- catch { }
68
- };
69
- });
70
- }
71
- async request(msg) {
72
- // For now, just send and wait for the next message with matching seq (simple demo)
73
- const seq = this.seq.next();
74
- const env = { ...msg, seq };
75
- const p = new Promise((resolve) => {
76
- const off = this.subscribe((incoming) => {
77
- if (incoming.seq === seq) {
78
- off();
79
- resolve(incoming);
80
- }
81
- });
82
- });
83
- this.send(env);
84
- return p;
85
- }
86
- send(msg) {
87
- if (!this.ws || this.ws.readyState !== OPEN)
88
- return;
89
- this.ws.send(JSON.stringify(msg));
90
- }
91
- subscribe(cb) {
92
- this.listeners.add(cb);
93
- return () => this.listeners.delete(cb);
94
- }
95
- async close() {
96
- if (!this.ws)
97
- return;
98
- const ws = this.ws;
99
- this.ws = undefined;
100
- await new Promise((resolve) => {
101
- ws.onclose = () => resolve();
102
- try {
103
- ws.close();
104
- }
105
- catch {
106
- resolve();
107
- }
108
- });
109
- }
110
- }
111
8
 
112
- class HttpPollingTransport {
113
- constructor(baseUrl) {
114
- this.listeners = new Set();
115
- this.baseUrl = baseUrl.replace(/\/$/, "");
116
- }
117
- async connect(options) {
118
- // Store connection params for use in requests
119
- this.connectParams = options?.params;
120
- // Start polling loop
121
- if (this.polling)
122
- return;
123
- const tick = async () => {
124
- try {
125
- const url = new URL(this.baseUrl + "/events");
126
- if (this.cursor)
127
- url.searchParams.set("cursor", this.cursor);
128
- // Add connection params to all requests
129
- if (this.connectParams) {
130
- for (const [key, value] of Object.entries(this.connectParams)) {
131
- if (value !== undefined && value !== null) {
132
- url.searchParams.set(key, String(value));
133
- }
134
- }
135
- }
136
- const res = await fetch(url.toString());
137
- if (!res.ok)
138
- return;
139
- const batch = (await res.json());
140
- for (const env of batch) {
141
- this.cursor = String(env.seq ?? Date.now());
142
- for (const l of Array.from(this.listeners))
143
- l(env);
144
- }
145
- }
146
- catch { }
147
- };
148
- this.polling = setInterval(tick, 200);
149
- }
150
- async request(msg) {
151
- const url = new URL(this.baseUrl + "/command");
152
- // Add connection params to command requests
153
- if (this.connectParams) {
154
- for (const [key, value] of Object.entries(this.connectParams)) {
155
- if (value !== undefined && value !== null) {
156
- url.searchParams.set(key, String(value));
157
- }
158
- }
159
- }
160
- const res = await fetch(url.toString(), {
161
- method: "POST",
162
- headers: { "content-type": "application/json" },
163
- body: JSON.stringify(msg),
164
- });
165
- const data = (await res.json());
166
- return data;
167
- }
168
- send(msg) {
169
- const url = new URL(this.baseUrl + "/command");
170
- // Add connection params to send requests
171
- if (this.connectParams) {
172
- for (const [key, value] of Object.entries(this.connectParams)) {
173
- if (value !== undefined && value !== null) {
174
- url.searchParams.set(key, String(value));
175
- }
176
- }
177
- }
178
- fetch(url.toString(), {
179
- method: "POST",
180
- headers: { "content-type": "application/json" },
181
- body: JSON.stringify(msg),
182
- });
183
- }
184
- subscribe(cb) {
185
- this.listeners.add(cb);
186
- return () => this.listeners.delete(cb);
187
- }
188
- async close() {
189
- if (this.polling)
190
- clearInterval(this.polling);
191
- this.polling = undefined;
192
- }
193
- }
194
-
195
- class RemoteEngine {
196
- constructor(transport) {
197
- this.transport = transport;
198
- this.listeners = new Map();
199
- this.cache = new Map();
200
- this.transport.subscribe((env) => this.onEnvelope(env));
201
- }
202
- onEnvelope(env) {
203
- const msg = env.message;
204
- if (!msg)
205
- return;
206
- if (msg.type === "value") {
207
- const key = `${msg.payload.nodeId}.${msg.payload.handle}`;
208
- this.cache.set(key, {
209
- value: msg.payload.value,
210
- runtimeTypeId: msg.payload.runtimeTypeId,
211
- });
212
- this.emit("value", msg.payload);
213
- }
214
- else if (msg.type === "error") {
215
- this.emit("error", msg.payload);
216
- }
217
- else if (msg.type === "invalidate") {
218
- this.emit("invalidate", msg.payload);
219
- }
220
- else if (msg.type === "stats") {
221
- this.emit("stats", msg.payload);
222
- }
223
- }
224
- launch(invalidate) {
225
- this.transport.send({
226
- message: { type: "Launch", payload: { invalidate } },
227
- });
228
- }
229
- setInput(nodeId, handle, value) {
230
- this.transport.send({
231
- message: { type: "SetInput", payload: { nodeId, handle, value } },
232
- });
233
- }
234
- // Batch inputs for a single network round-trip
235
- setInputs(nodeId, inputs) {
236
- this.transport.send({
237
- message: { type: "SetInputs", payload: { nodeId, inputs } },
238
- });
239
- }
240
- triggerExternal(nodeId, event) {
241
- this.transport.send({
242
- message: { type: "TriggerExternal", payload: { nodeId, event } },
243
- });
244
- }
245
- on(event, handler) {
246
- if (!this.listeners.has(event))
247
- this.listeners.set(event, new Set());
248
- const set = this.listeners.get(event);
249
- set.add(handler);
250
- return () => set.delete(handler);
251
- }
252
- emit(event, payload) {
253
- const set = this.listeners.get(event);
254
- if (set)
255
- for (const h of Array.from(set))
256
- h(payload);
257
- }
258
- getOutput(nodeId, output) {
259
- return this.cache.get(`${nodeId}.${output}`)?.value;
260
- }
261
- async whenIdle() {
262
- await this.transport.request({ message: { type: "WhenIdle" } });
263
- }
264
- dispose() {
265
- this.transport.send({ message: { type: "Dispose" } });
266
- }
267
- }
268
-
269
- class RemoteRunner {
270
- constructor(transport) {
271
- this.transport = transport;
272
- this.engine = new RemoteEngine(transport);
273
- }
274
- async build(def, opts) {
275
- await this.transport.request({
276
- message: {
277
- type: "Build",
278
- payload: { def, environment: opts?.environment },
279
- },
280
- });
281
- }
282
- async update(def) {
283
- await this.transport.request({
284
- message: { type: "Update", payload: { def } },
285
- });
286
- }
287
- async describeRegistry() {
288
- const res = await this.transport.request({
289
- message: { type: "DescribeRegistry" },
290
- });
291
- const payload = res?.message || {};
292
- return (payload.registry || {
293
- types: [],
294
- categories: [],
295
- nodes: [],
296
- coercions: [],
297
- schemaVersion: 4,
298
- });
299
- }
300
- async applyRegistry(deltas) {
301
- await this.transport.request({
302
- message: { type: "RegistryApply", payload: { deltas } },
303
- });
304
- }
305
- async snapshot() {
306
- const res = await this.transport.request({ message: { type: "Snapshot" } });
307
- const payload = res?.message || {};
308
- return payload.snapshot || { inputs: {}, outputs: {} };
309
- }
310
- async snapshotFull() {
311
- const res = await this.transport.request({
312
- message: { type: "SnapshotFull" },
313
- });
314
- const payload = res?.message || {};
315
- return (payload.snapshot || {
316
- def: undefined,
317
- environment: {},
318
- inputs: {},
319
- outputs: {},
320
- });
321
- }
322
- async applySnapshotFull(payload) {
323
- await this.transport.request({
324
- message: { type: "ApplySnapshotFull", payload },
325
- });
326
- }
327
- async setEnvironment(environment, opts) {
328
- await this.transport.request({
329
- message: {
330
- type: "SetEnvironment",
331
- payload: { environment, merge: opts?.merge },
332
- },
333
- });
334
- }
335
- async getEnvironment() {
336
- const res = await this.transport.request({
337
- message: { type: "GetEnvironment" },
338
- });
339
- const payload = res?.message || {};
340
- return payload.environment || {};
341
- }
342
- async coerce(from, to, value) {
343
- const res = await this.transport.request({
344
- message: { type: "Coerce", payload: { from, to, value } },
345
- });
346
- const payload = res?.message || {};
347
- return payload.value;
348
- }
349
- getEngine() {
350
- return this.engine;
351
- }
352
- }
353
-
354
- /* eslint-disable @typescript-eslint/no-explicit-any */
355
- function summarize(value, maxLen = 120) {
356
- try {
357
- const s = typeof value === "string" ? value : JSON.stringify(value);
358
- return s.length > maxLen ? s.slice(0, maxLen) + "…" : s;
359
- }
360
- catch {
361
- return String(value);
362
- }
363
- }
364
- function serializeError(err) {
365
- try {
366
- if (!err)
367
- return { message: String(err) };
368
- const errAny = err;
369
- if (err instanceof Error) {
370
- const base = {
371
- name: err.name,
372
- message: err.message,
373
- stack: err.stack,
374
- };
375
- for (const k of Object.keys(errAny))
376
- base[k] = errAny[k];
377
- return base;
378
- }
379
- if (typeof err === "object") {
380
- const maybeMsg = errAny?.message;
381
- const maybeName = errAny?.name;
382
- const maybeStack = errAny?.stack;
383
- const out = { ...errAny };
384
- if (maybeMsg && !out.message)
385
- out.message = String(maybeMsg);
386
- if (maybeName && !out.name)
387
- out.name = String(maybeName);
388
- if (maybeStack && !out.stack)
389
- out.stack = String(maybeStack);
390
- return out;
391
- }
392
- return { message: String(err) };
393
- }
394
- catch {
395
- return { message: String(err) };
396
- }
397
- }
398
-
399
- async function handleCommand(label, env, runtimeApi, ack) {
400
- const msg = env.message;
401
- switch (msg.type) {
402
- case "Build": {
403
- console.debug(`[${label}] rx Build seq=${env.seq} nodes=${msg.payload.def.nodes?.length ?? 0} edges=${msg.payload.def.edges?.length ?? 0} envKeys=${Object.keys(msg.payload.environment ?? {}).join(",")}`);
404
- await runtimeApi.build(msg.payload.def, msg.payload.environment);
405
- ack();
406
- break;
407
- }
408
- case "Update": {
409
- console.debug(`[${label}] rx Update seq=${env.seq} nodes=${msg.payload.def.nodes?.length ?? 0} edges=${msg.payload.def.edges?.length ?? 0}`);
410
- await runtimeApi.update(msg.payload.def);
411
- ack();
412
- break;
413
- }
414
- case "SetEnvironment": {
415
- console.debug(`[${label}] rx SetEnvironment seq=${env.seq}`);
416
- runtimeApi.setEnvironment(msg.payload.environment, {
417
- merge: Boolean(msg.payload.merge),
418
- });
419
- ack();
420
- break;
421
- }
422
- case "SetInput": {
423
- console.debug(`[${label}] rx SetInput seq=${env.seq} ${msg.payload.nodeId}.${msg.payload.handle}=${summarize(msg.payload.value)}`);
424
- runtimeApi.setInput(msg.payload.nodeId, msg.payload.handle, msg.payload.value);
425
- ack();
426
- break;
427
- }
428
- case "SetInputs": {
429
- console.debug(`[${label}] rx SetInputs seq=${env.seq} ${msg.payload.nodeId} keys=${Object.keys(msg.payload.inputs || {}).join(",")}`);
430
- const nodeId = msg.payload.nodeId;
431
- const inputs = msg.payload.inputs;
432
- runtimeApi.setInputs(nodeId, inputs);
433
- ack();
434
- break;
435
- }
436
- case "TriggerExternal": {
437
- console.debug(`[${label}] rx TriggerExternal seq=${env.seq} ${msg.payload.nodeId} event=${summarize(msg.payload.event)}`);
438
- runtimeApi.triggerExternal(msg.payload.nodeId, msg.payload.event);
439
- ack();
440
- break;
441
- }
442
- case "Launch": {
443
- console.debug(`[${label}] rx Launch seq=${env.seq}`);
444
- runtimeApi.launch(msg.payload.invalidate);
445
- ack();
446
- break;
447
- }
448
- case "WhenIdle": {
449
- console.debug(`[${label}] rx WhenIdle seq=${env.seq}`);
450
- await runtimeApi.whenIdle();
451
- ack();
452
- break;
453
- }
454
- case "Snapshot": {
455
- console.debug(`[${label}] rx Snapshot seq=${env.seq}`);
456
- const snap = runtimeApi.snapshot();
457
- ack({ snapshot: snap });
458
- break;
459
- }
460
- case "SnapshotFull": {
461
- console.debug(`[${label}] rx SnapshotFull seq=${env.seq}`);
462
- const snap = runtimeApi.snapshotFull();
463
- ack({ snapshot: snap });
464
- break;
465
- }
466
- case "GetEnvironment": {
467
- console.debug(`[${label}] rx GetEnvironment seq=${env.seq}`);
468
- const environment = runtimeApi.getEnvironment();
469
- ack({ environment });
470
- break;
471
- }
472
- case "ApplySnapshotFull": {
473
- console.debug(`[${label}] rx ApplySnapshotFull seq=${env.seq}`);
474
- await runtimeApi.applySnapshotFull(msg.payload);
475
- ack();
476
- break;
477
- }
478
- case "Coerce": {
479
- console.debug(`[${label}] rx Coerce seq=${env.seq} ${msg.payload.from} -> ${msg.payload.to}`);
480
- const value = await runtimeApi.coerce(msg.payload?.from, msg.payload?.to, msg.payload?.value);
481
- ack({ value });
482
- break;
483
- }
484
- case "DescribeRegistry": {
485
- console.debug(`[${label}] rx DescribeRegistry seq=${env.seq}`);
486
- const desc = runtimeApi.describeRegistry();
487
- ack({ registry: desc });
488
- break;
489
- }
490
- case "RegistryApply": {
491
- console.debug(`[${label}] rx RegistryApply seq=${env.seq}`);
492
- await runtimeApi.applyRegistry(msg.payload.deltas || []);
493
- ack();
494
- break;
495
- }
496
- case "Dispose": {
497
- console.debug(`[${label}] rx Dispose seq=${env.seq}`);
498
- runtimeApi.dispose();
499
- ack();
500
- break;
501
- }
502
- case "Pause":
503
- case "Resume": {
504
- console.debug(`[${label}] rx ${msg.type} seq=${env.seq} (not-impl)`);
505
- ack();
506
- break;
507
- }
508
- default: {
509
- console.debug(`[${label}] rx Unknown type seq=${env.seq}`);
510
- ack();
511
- }
512
- }
513
- }
514
-
515
- async function createRuntimeAdapter(createRegistry, send, extensions) {
516
- const registry = await createRegistry();
517
- const builder = new sparkGraph.GraphBuilder(registry);
518
- let graphRuntime;
519
- let extData = {};
520
- // Helper to get current context
521
- const getContext = () => ({
522
- registry,
523
- builder,
524
- graphRuntime,
525
- extData,
526
- });
527
- // Original implementations - define as separate functions first to allow cross-references
528
- const originalApi = {
529
- coerce: async (from, to, value) => {
530
- const resolved = registry.resolveCoercion(from, to);
531
- if (!resolved)
532
- return value;
533
- if (resolved.kind === "sync")
534
- return resolved.convert(value);
535
- const ac = new AbortController();
536
- return await resolved.convertAsync(value, ac.signal);
537
- },
538
- getEnvironment: () => {
539
- return graphRuntime?.getEnvironment?.() ?? {};
540
- },
541
- applyRegistry: async (deltas) => {
542
- // Pause runtime if exists
543
- // Apply each delta to the live registry
544
- for (const d of deltas || []) {
545
- if (!d || typeof d !== "object")
546
- continue;
547
- if (d.kind === "register-enum") {
548
- registry.registerEnum({
549
- id: d.id,
550
- displayName: d.displayName,
551
- options: d.options || [],
552
- bakeTarget: d.bakeTarget,
553
- opts: d.opts,
554
- });
555
- }
556
- else if (d.kind === "register-type") {
557
- registry.registerType({
558
- id: d.id,
559
- displayName: d.displayName,
560
- bakeTarget: d.bakeTarget,
561
- validate: (_v) => true,
562
- });
563
- }
564
- else if (d.kind === "register-node") {
565
- const desc = d.desc || {};
566
- registry.registerNode({
567
- id: String(desc.id || ""),
568
- categoryId: String(desc.categoryId || "compute"),
569
- displayName: desc.displayName,
570
- inputs: desc.inputs || {},
571
- outputs: desc.outputs || {},
572
- // impl must be empty per frontend registration contract
573
- impl: () => { },
574
- });
575
- }
576
- }
577
- // Notify clients (include deltas in invalidate payload)
578
- send({
579
- message: {
580
- type: "invalidate",
581
- payload: { reason: "registry-changed", deltas },
582
- },
583
- });
584
- },
585
- build: async (def, opts) => {
586
- const env = opts || {};
587
- graphRuntime = builder.build(def, { environment: env });
588
- graphRuntime.on("value", (p) => send({ message: { type: "value", payload: p } }));
589
- graphRuntime.on("invalidate", (p) => send({ message: { type: "invalidate", payload: p } }));
590
- graphRuntime.on("error", (p) => send({ message: { type: "error", payload: p } }));
591
- graphRuntime.on("stats", (p) => send({ message: { type: "stats", payload: p } }));
592
- },
593
- setExtData: (data) => {
594
- if (!data || typeof data !== "object") {
595
- extData = {};
596
- return;
597
- }
598
- // Replace to keep semantics deterministic
599
- extData = { ...data };
600
- },
601
- getExtData: () => {
602
- return extData;
603
- },
604
- snapshot: () => {
605
- const inputs = {};
606
- const outputs = {};
607
- if (!graphRuntime)
608
- return { inputs, outputs };
609
- const nodes = graphRuntime.getNodeIds();
610
- for (const nodeId of nodes) {
611
- const data = graphRuntime.getNodeData(nodeId);
612
- if (data?.inputs && Object.keys(data.inputs).length > 0) {
613
- inputs[nodeId] = { ...data.inputs };
614
- }
615
- if (data?.outputs && Object.keys(data.outputs).length > 0) {
616
- outputs[nodeId] = { ...data.outputs };
617
- }
618
- }
619
- return { inputs, outputs };
620
- },
621
- snapshotFull: () => {
622
- const snap = originalApi.snapshot();
623
- const env = graphRuntime?.getEnvironment?.() ?? {};
624
- const def = graphRuntime?.getGraphDef();
625
- return {
626
- def,
627
- environment: env,
628
- inputs: snap.inputs,
629
- outputs: snap.outputs,
630
- };
631
- },
632
- applySnapshotFull: async (payload) => {
633
- const def = payload.def;
634
- if (!def)
635
- return;
636
- await originalApi.build(def, payload.environment);
637
- // Hydrate inputs/outputs exactly, then re-emit outputs without scheduling runs
638
- graphRuntime?.hydrate({
639
- inputs: payload.inputs,
640
- outputs: payload.outputs,
641
- });
642
- },
643
- describeRegistry: () => {
644
- // types (include enum options when available)
645
- const types = Array.from(registry.types.entries()).map(([id, d]) => {
646
- const en = registry.enums.get(id);
647
- return {
648
- id,
649
- displayName: d.displayName,
650
- bakeTarget: d.bakeTarget,
651
- ...(en ? { options: en.options } : {}),
652
- };
653
- });
654
- // categories: not directly enumerable; derive from node descriptors
655
- const nodeDescs = Array.from(registry.nodes.values());
656
- const catIds = new Set(nodeDescs.map((n) => n.categoryId));
657
- const categories = Array.from(catIds).map((id) => {
658
- const cat = registry.categories.get?.(id);
659
- return { id, displayName: cat?.displayName };
660
- });
661
- const nodes = nodeDescs.map((n) => ({
662
- id: n.id,
663
- categoryId: n.categoryId,
664
- displayName: n.displayName,
665
- inputs: n.inputs || {},
666
- outputs: n.outputs || {},
667
- inputDefaults: n.inputDefaults || {},
668
- }));
669
- const coercions = registry.listCoercions();
670
- return { types, categories, nodes, coercions, schemaVersion: 4 };
671
- },
672
- update: async (def) => {
673
- if (!graphRuntime)
674
- return;
675
- graphRuntime.update(def, registry);
676
- send({
677
- message: {
678
- type: "invalidate",
679
- payload: { reason: "graph-updated" },
680
- },
681
- });
682
- },
683
- setEnvironment: (env, opts) => {
684
- if (!graphRuntime)
685
- return;
686
- if (opts?.merge) {
687
- const current = graphRuntime.getEnvironment();
688
- const next = { ...(current || {}), ...(env || {}) };
689
- graphRuntime.setEnvironment(next);
690
- return;
691
- }
692
- graphRuntime.setEnvironment(env);
693
- },
694
- setInput: (nodeId, handle, value) => {
695
- graphRuntime?.setInput(nodeId, handle, value);
696
- },
697
- setInputs: (nodeId, inputs) => {
698
- graphRuntime?.setInputs(nodeId, inputs);
699
- },
700
- triggerExternal: (nodeId, event) => {
701
- graphRuntime?.triggerExternal(nodeId, event);
702
- },
703
- launch: (invalidate) => {
704
- graphRuntime?.launch(invalidate);
705
- },
706
- whenIdle: () => {
707
- return graphRuntime?.whenIdle?.() ?? Promise.resolve();
708
- },
709
- dispose: () => {
710
- graphRuntime?.dispose?.();
711
- graphRuntime = undefined;
712
- },
713
- };
714
- // Helper to wrap a method with extension support
715
- const wrapMethod = (key, original) => {
716
- const extension = extensions?.[key];
717
- if (!extension) {
718
- return original;
719
- }
720
- return ((...args) => {
721
- return extension(original, getContext(), ...args);
722
- });
723
- };
724
- // Create API with extensions applied
725
- const extendedApi = {
726
- coerce: wrapMethod("coerce", originalApi.coerce),
727
- getEnvironment: wrapMethod("getEnvironment", originalApi.getEnvironment),
728
- applyRegistry: wrapMethod("applyRegistry", originalApi.applyRegistry),
729
- build: wrapMethod("build", originalApi.build),
730
- setExtData: wrapMethod("setExtData", originalApi.setExtData),
731
- getExtData: wrapMethod("getExtData", originalApi.getExtData),
732
- snapshot: wrapMethod("snapshot", originalApi.snapshot),
733
- snapshotFull: wrapMethod("snapshotFull", originalApi.snapshotFull),
734
- applySnapshotFull: wrapMethod("applySnapshotFull", originalApi.applySnapshotFull),
735
- describeRegistry: wrapMethod("describeRegistry", originalApi.describeRegistry),
736
- update: wrapMethod("update", originalApi.update),
737
- setEnvironment: wrapMethod("setEnvironment", originalApi.setEnvironment),
738
- setInput: wrapMethod("setInput", originalApi.setInput),
739
- setInputs: wrapMethod("setInputs", originalApi.setInputs),
740
- triggerExternal: wrapMethod("triggerExternal", originalApi.triggerExternal),
741
- launch: wrapMethod("launch", originalApi.launch),
742
- whenIdle: wrapMethod("whenIdle", originalApi.whenIdle),
743
- dispose: wrapMethod("dispose", originalApi.dispose),
744
- };
745
- return extendedApi;
746
- }
747
-
748
- exports.HttpPollingTransport = HttpPollingTransport;
749
- exports.RemoteEngine = RemoteEngine;
750
- exports.RemoteRunner = RemoteRunner;
751
- exports.WebSocketTransport = WebSocketTransport;
752
- exports.createRuntimeAdapter = createRuntimeAdapter;
753
- exports.handleCommand = handleCommand;
754
- exports.serializeError = serializeError;
755
- exports.summarize = summarize;
9
+ exports.HttpPollingTransport = index.HttpPollingTransport;
10
+ exports.RemoteEngine = index.RemoteEngine;
11
+ exports.RuntimeApiClient = index.RuntimeApiClient;
12
+ exports.RuntimeApiServer = index.RuntimeApiServer;
13
+ exports.WebSocketTransport = index.WebSocketTransport;
14
+ exports.createRuntimeAdapter = index.createRuntimeAdapter;
15
+ exports.serializeError = index.serializeError;
16
+ exports.summarize = index.summarize;
756
17
  //# sourceMappingURL=index.cjs.map