@bian-womp/spark-workbench 0.2.24 → 0.2.26

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.
@@ -1,8 +1,17 @@
1
1
  import type { GraphDefinition } from "@bian-womp/spark-protocol";
2
+ import { type TransportConnectOptions } from "@bian-womp/spark-remote";
2
3
  import { WorkbenchOverrides } from "./context/WorkbenchContext";
3
4
  import { InMemoryWorkbench } from "../core/InMemoryWorkbench";
4
5
  import { ExecutionBackendKind, IGraphRunner } from "../runtime/IGraphRunner";
5
- export declare function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, overrides, onInit, onChange, }: {
6
+ /**
7
+ * Optional backend configuration for remote runners.
8
+ * Allows extensions to pass connection options and custom event handlers.
9
+ */
10
+ export interface BackendOptions {
11
+ connectOptions?: TransportConnectOptions;
12
+ onCustomEvent?: (event: any) => void;
13
+ }
14
+ export declare function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, backendOptions, overrides, onInit, onChange, }: {
6
15
  engine?: string;
7
16
  onEngineChange?: (v: string | undefined) => void;
8
17
  example?: string;
@@ -21,6 +30,7 @@ export declare function WorkbenchStudio({ engine, onEngineChange, example, onExa
21
30
  onHideWorkbenchChange: (v: boolean) => void;
22
31
  autoScroll: boolean;
23
32
  onAutoScrollChange: (v: boolean) => void;
33
+ backendOptions?: BackendOptions;
24
34
  overrides?: WorkbenchOverrides;
25
35
  onInit?: (args: {
26
36
  wb: InMemoryWorkbench;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkbenchStudio.d.ts","sourceRoot":"","sources":["../../../../src/misc/WorkbenchStudio.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AA6BjE,OAAO,EAGL,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAGL,oBAAoB,EACpB,YAAY,EAEb,MAAM,yBAAyB,CAAC;AA02BjC,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,cAAc,EACd,OAAO,EACP,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,aAAa,EACb,KAAK,EACL,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,kBAAkB,EAClB,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,oBAAoB,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QACd,EAAE,EAAE,iBAAiB,CAAC;QACtB,MAAM,EAAE,YAAY,CAAC;QACrB,eAAe,EAAE,CACf,GAAG,EAAE,eAAe,EACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;KACpB,KAAK,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,GAAG,EAAE,eAAe,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KACjD,KAAK,IAAI,CAAC;CACZ,2CAiEA"}
1
+ {"version":3,"file":"WorkbenchStudio.d.ts","sourceRoot":"","sources":["../../../../src/misc/WorkbenchStudio.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAejE,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AASvE,OAAO,EAGL,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAGL,oBAAoB,EACpB,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACtC;AAizBD,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,cAAc,EACd,OAAO,EACP,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,aAAa,EACb,KAAK,EACL,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,oBAAoB,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QACd,EAAE,EAAE,iBAAiB,CAAC;QACtB,MAAM,EAAE,YAAY,CAAC;QACrB,eAAe,EAAE,CACf,GAAG,EAAE,eAAe,EACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;KACpB,KAAK,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,GAAG,EAAE,eAAe,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KACjD,KAAK,IAAI,CAAC;CACZ,2CAmFA"}
@@ -1,13 +1,17 @@
1
1
  import type { GraphDefinition, RuntimeSnapshotFull } from "@bian-womp/spark-protocol";
2
2
  import { EngineEventName, Registry, type RuntimeEventMap } from "@bian-womp/spark-graph";
3
- import { HttpPollingTransport, WebSocketTransport } from "@bian-womp/spark-remote";
3
+ import { HttpPollingTransport, WebSocketTransport, TransportConnectOptions } from "@bian-womp/spark-remote";
4
4
  export type EngineKind = "push" | "batched" | "pull" | "hybrid" | "step";
5
5
  export type RemoteExecutionBackend = {
6
6
  kind: "remote-http";
7
7
  baseUrl: string;
8
+ connectOptions?: TransportConnectOptions;
9
+ onCustomEvent?: (event: any) => void;
8
10
  } | {
9
11
  kind: "remote-ws";
10
12
  url: string;
13
+ connectOptions?: TransportConnectOptions;
14
+ onCustomEvent?: (event: any) => void;
11
15
  };
12
16
  export type ExecutionBackend = {
13
17
  kind: "local";
@@ -1 +1 @@
1
- {"version":3,"file":"IGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/IGraphRunner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/IGraphRunner.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,10 @@ export declare class RemoteGraphRunner extends AbstractGraphRunner {
13
13
  runtimeTypeId?: string;
14
14
  }>;
15
15
  listenersBound: boolean;
16
+ private registryFetched;
17
+ private registryFetching;
18
+ private readonly MAX_REGISTRY_FETCH_ATTEMPTS;
19
+ private readonly INITIAL_RETRY_DELAY_MS;
16
20
  constructor(registry: Registry, backend: RemoteExecutionBackend);
17
21
  build(def: GraphDefinition): void;
18
22
  update(def: GraphDefinition): void;
@@ -31,6 +35,11 @@ export declare class RemoteGraphRunner extends AbstractGraphRunner {
31
35
  getOutputs(def: GraphDefinition): Record<string, Record<string, unknown>>;
32
36
  getInputs(def: GraphDefinition): Record<string, Record<string, unknown>>;
33
37
  dispose(): void;
38
+ /**
39
+ * Fetch full registry description from remote and register it locally.
40
+ * Called automatically on first connection with retry mechanism.
41
+ */
42
+ private fetchRegistry;
34
43
  protected ensureRemoteRunner(): Promise<RemoteRunner>;
35
44
  }
36
45
  //# sourceMappingURL=RemoteGraphRunner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/RemoteGraphRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAU,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAEL,YAAY,EAEb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EAEtB,eAAe,EACf,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qBAAa,iBAAkB,SAAQ,mBAAmB;IACxD,SAAS,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACpC,SAAS,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAChC,SAAS,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IAEtC,UAAU;YAEF,OAAO,GAAG,QAAQ;eAAS,OAAO;wBAAkB,MAAM;OAC9D;IACJ,cAAc,UAAS;gBAEX,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB;IA8D/D,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAIjC,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAWlC,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAyDjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,KAAK,IAAI,IAAI;IAIb,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASlE,YAAY;IASZ,iBAAiB,CAAC,OAAO,EAAE,mBAAmB;IAKpD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAWvE,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAOrD,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoBzE,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAmBxE,OAAO,IAAI,IAAI;cAYC,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC;CA0B5D"}
1
+ {"version":3,"file":"RemoteGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/RemoteGraphRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAU,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAEL,YAAY,EAEb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EAEtB,eAAe,EACf,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qBAAa,iBAAkB,SAAQ,mBAAmB;IACxD,SAAS,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACpC,SAAS,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAChC,SAAS,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IAEtC,UAAU;YAEF,OAAO,GAAG,QAAQ;eAAS,OAAO;wBAAkB,MAAM;OAC9D;IACJ,cAAc,UAAS;IACvB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAK;IACjD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAQ;gBAEnC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB;IA8D/D,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAIjC,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAWlC,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAyDjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,KAAK,IAAI,IAAI;IAIb,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASlE,YAAY;IASZ,iBAAiB,CAAC,OAAO,EAAE,mBAAmB;IAKpD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAWvE,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAOrD,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoBzE,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAmBxE,OAAO,IAAI,IAAI;IAaf;;;OAGG;YACW,aAAa;cA6HX,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC;CAuD5D"}
package/lib/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { GraphBuilder, StepEngine, HybridEngine, PullEngine, BatchedEngine, PushEngine, isTypedOutput, getTypedOutputValue, getTypedOutputTypeId, isInputPrivate, getInputTypeId, createSimpleGraphRegistry, createSimpleGraphDef, createAsyncGraphDef, createAsyncGraphRegistry, createProgressGraphDef, createProgressGraphRegistry, createValidationGraphDef, createValidationGraphRegistry, Registry } from '@bian-womp/spark-graph';
1
+ import { GraphBuilder, StepEngine, HybridEngine, PullEngine, BatchedEngine, PushEngine, isTypedOutput, getTypedOutputValue, getTypedOutputTypeId, isInputPrivate, getInputTypeId, createSimpleGraphRegistry, createSimpleGraphDef, createAsyncGraphDef, createAsyncGraphRegistry, createProgressGraphDef, createProgressGraphRegistry, createValidationGraphDef, createValidationGraphRegistry } from '@bian-womp/spark-graph';
2
2
  import { HttpPollingTransport, WebSocketTransport, RemoteRunner } from '@bian-womp/spark-remote';
3
3
  import React, { useCallback, useState, useRef, useEffect, useMemo, createContext, useContext, useImperativeHandle } from 'react';
4
4
  import { Position, Handle, useUpdateNodeInternals, useReactFlow, ReactFlowProvider, ReactFlow, Background, BackgroundVariant, MiniMap, Controls } from '@xyflow/react';
@@ -570,6 +570,10 @@ class RemoteGraphRunner extends AbstractGraphRunner {
570
570
  super(registry, backend);
571
571
  this.valueCache = new Map();
572
572
  this.listenersBound = false;
573
+ this.registryFetched = false;
574
+ this.registryFetching = false;
575
+ this.MAX_REGISTRY_FETCH_ATTEMPTS = 3;
576
+ this.INITIAL_RETRY_DELAY_MS = 1000; // 1 second
573
577
  // Auto-handle registry-changed invalidations from remote
574
578
  // We listen on invalidate and if reason matches, we rehydrate registry and emit a registry event
575
579
  this.ensureRemoteRunner().then(async (runner) => {
@@ -804,39 +808,178 @@ class RemoteGraphRunner extends AbstractGraphRunner {
804
808
  super.dispose();
805
809
  this.runner = undefined;
806
810
  this.transport = undefined;
811
+ this.registryFetched = false; // Reset so registry is fetched again on reconnect
812
+ this.registryFetching = false; // Reset fetching state
807
813
  this.emit("transport", {
808
814
  state: "disconnected",
809
815
  kind: this.backend.kind,
810
816
  });
811
817
  }
818
+ /**
819
+ * Fetch full registry description from remote and register it locally.
820
+ * Called automatically on first connection with retry mechanism.
821
+ */
822
+ async fetchRegistry(runner, attempt = 1) {
823
+ if (this.registryFetching) {
824
+ // Already fetching, don't start another fetch
825
+ return;
826
+ }
827
+ this.registryFetching = true;
828
+ try {
829
+ const desc = await runner.describeRegistry();
830
+ // Register types
831
+ for (const t of desc.types) {
832
+ if (t.options) {
833
+ this.registry.registerEnum({
834
+ id: t.id,
835
+ options: t.options,
836
+ bakeTarget: t.bakeTarget,
837
+ });
838
+ }
839
+ else {
840
+ if (!this.registry.types.has(t.id)) {
841
+ this.registry.registerType({
842
+ id: t.id,
843
+ displayName: t.displayName,
844
+ validate: (_v) => true,
845
+ bakeTarget: t.bakeTarget,
846
+ });
847
+ }
848
+ }
849
+ }
850
+ // Register categories
851
+ for (const c of desc.categories || []) {
852
+ if (!this.registry.categories.has(c.id)) {
853
+ // Create placeholder category descriptor
854
+ const category = {
855
+ id: c.id,
856
+ displayName: c.displayName,
857
+ createRuntime: () => ({
858
+ async onInputsChanged() { },
859
+ }),
860
+ policy: { asyncConcurrency: "switch" },
861
+ };
862
+ this.registry.categories.register(category);
863
+ }
864
+ }
865
+ // Register coercions
866
+ for (const c of desc.coercions) {
867
+ if (c.async) {
868
+ this.registry.registerAsyncCoercion(c.from, c.to, async (v) => v, {
869
+ nonTransitive: c.nonTransitive,
870
+ });
871
+ }
872
+ else {
873
+ this.registry.registerCoercion(c.from, c.to, (v) => v, {
874
+ nonTransitive: c.nonTransitive,
875
+ });
876
+ }
877
+ }
878
+ // Register nodes
879
+ for (const n of desc.nodes) {
880
+ if (!this.registry.nodes.has(n.id)) {
881
+ this.registry.registerNode({
882
+ id: n.id,
883
+ categoryId: n.categoryId,
884
+ displayName: n.displayName,
885
+ inputs: n.inputs || {},
886
+ outputs: n.outputs || {},
887
+ impl: () => { },
888
+ });
889
+ }
890
+ }
891
+ this.registryFetched = true;
892
+ this.registryFetching = false;
893
+ this.emit("registry", this.registry);
894
+ }
895
+ catch (err) {
896
+ this.registryFetching = false;
897
+ const error = err instanceof Error ? err : new Error(String(err));
898
+ // Retry with exponential backoff if attempts remaining
899
+ if (attempt < this.MAX_REGISTRY_FETCH_ATTEMPTS) {
900
+ const delayMs = this.INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt - 1);
901
+ console.warn(`Failed to fetch registry (attempt ${attempt}/${this.MAX_REGISTRY_FETCH_ATTEMPTS}), retrying in ${delayMs}ms...`, error);
902
+ // Emit error event for UI feedback
903
+ this.emit("error", {
904
+ kind: "registry",
905
+ message: `Registry fetch failed (attempt ${attempt}/${this.MAX_REGISTRY_FETCH_ATTEMPTS}), retrying...`,
906
+ err: error,
907
+ attempt,
908
+ maxAttempts: this.MAX_REGISTRY_FETCH_ATTEMPTS,
909
+ });
910
+ // Retry after delay
911
+ setTimeout(() => {
912
+ this.fetchRegistry(runner, attempt + 1).catch(() => {
913
+ // Final failure handled below
914
+ });
915
+ }, delayMs);
916
+ }
917
+ else {
918
+ // Max attempts reached, emit final error
919
+ console.error(`Failed to fetch registry after ${this.MAX_REGISTRY_FETCH_ATTEMPTS} attempts:`, error);
920
+ this.emit("error", {
921
+ kind: "registry",
922
+ message: `Failed to fetch registry after ${this.MAX_REGISTRY_FETCH_ATTEMPTS} attempts. Please check your connection and try refreshing.`,
923
+ err: error,
924
+ attempt: this.MAX_REGISTRY_FETCH_ATTEMPTS,
925
+ maxAttempts: this.MAX_REGISTRY_FETCH_ATTEMPTS,
926
+ });
927
+ }
928
+ }
929
+ }
812
930
  // Ensure remote transport/runner
813
931
  async ensureRemoteRunner() {
814
932
  if (this.runner)
815
933
  return this.runner;
816
934
  let transport;
817
935
  const kind = this.backend.kind;
936
+ const backend = this.backend;
937
+ const connectOptions = backend.connectOptions;
818
938
  this.emit("transport", { state: "connecting", kind });
819
- if (this.backend.kind === "remote-http") {
939
+ if (backend.kind === "remote-http") {
820
940
  if (!HttpPollingTransport)
821
941
  throw new Error("HttpPollingTransport not available");
822
- transport = new HttpPollingTransport(this.backend.baseUrl);
823
- await transport.connect();
942
+ transport = new HttpPollingTransport(backend.baseUrl);
943
+ await transport.connect(connectOptions);
824
944
  }
825
- else if (this.backend.kind === "remote-ws") {
945
+ else if (backend.kind === "remote-ws") {
826
946
  if (!WebSocketTransport)
827
947
  throw new Error("WebSocketTransport not available");
828
- transport = new WebSocketTransport(this.backend.url);
829
- await transport.connect();
948
+ transport = new WebSocketTransport(backend.url);
949
+ await transport.connect(connectOptions);
830
950
  }
831
951
  else {
832
952
  throw new Error("Remote backend not configured");
833
953
  }
954
+ // Subscribe to custom events if handler provided
955
+ if (backend.onCustomEvent) {
956
+ transport.subscribe((event) => {
957
+ // Filter out standard runtime events, pass others to custom handler
958
+ const msg = event.message;
959
+ if (msg && typeof msg === "object" && "type" in msg) {
960
+ const type = msg.type;
961
+ // Standard runtime events: stats, value, error, invalidate
962
+ // Custom events are anything else (e.g., flow-opened, flow-latest)
963
+ if (!["stats", "value", "error", "invalidate"].includes(type)) {
964
+ backend.onCustomEvent?.(event);
965
+ }
966
+ }
967
+ });
968
+ }
834
969
  const runner = new RemoteRunner(transport);
835
970
  this.runner = runner;
836
971
  this.transport = transport;
837
972
  this.valueCache.clear();
838
973
  this.listenersBound = false;
839
974
  this.emit("transport", { state: "connected", kind });
975
+ // Auto-fetch registry on first connection (only once)
976
+ if (!this.registryFetched && !this.registryFetching) {
977
+ // Log loading state (UI can listen to transport status for loading indication)
978
+ console.info("Loading registry from remote...");
979
+ this.fetchRegistry(runner).catch(() => {
980
+ // Error handling is done inside fetchRegistry
981
+ });
982
+ }
840
983
  return runner;
841
984
  }
842
985
  }
@@ -2953,7 +3096,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
2953
3096
  }, onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, deleteKeyCode: ["Backspace", "Delete"], proOptions: { hideAttribution: true }, noDragClassName: "wb-nodrag", noWheelClassName: "wb-nowheel", noPanClassName: "wb-nopan", fitView: true, children: [jsx(Background, { id: "workbench-canvas-background", variant: BackgroundVariant.Dots, gap: 12, size: 1 }), jsx(MiniMap, {}), jsx(Controls, {}), jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, onAdd: addNodeAt, onClose: onCloseMenu }), !!nodeAtMenu && (jsx(NodeContextMenu, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, onClose: onCloseNodeMenu }))] }) }) }));
2954
3097
  });
2955
3098
 
2956
- function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, example, onExampleChange, engine, onEngineChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
3099
+ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, example, onExampleChange, engine, onEngineChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, backendOptions, overrides, onInit, onChange, }) {
2957
3100
  const { wb, runner, registry, def, selectedNodeId, runAutoLayout } = useWorkbenchContext();
2958
3101
  const [transportStatus, setTransportStatus] = useState({
2959
3102
  state: "local",
@@ -3002,11 +3145,14 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3002
3145
  return overrides.getExamples(defaultExamples);
3003
3146
  return defaultExamples;
3004
3147
  }, [overrides, defaultExamples]);
3005
- const [hydrated, setHydrated] = useState(false);
3006
3148
  const lastAutoLaunched = useRef(undefined);
3007
3149
  const autoLayoutRan = useRef(false);
3008
3150
  const canvasRef = useRef(null);
3009
3151
  const uploadInputRef = useRef(null);
3152
+ const [registryReady, setRegistryReady] = useState(() => {
3153
+ // For local backends, registry is always ready
3154
+ return backendKind === "local";
3155
+ });
3010
3156
  // Expose init callback with setInitialGraph helper
3011
3157
  const initCalled = useRef(false);
3012
3158
  useEffect(() => {
@@ -3065,7 +3211,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3065
3211
  const { registry: r, def } = await ex.load();
3066
3212
  // Keep registry consistent with backend:
3067
3213
  // - For local backend, allow example to provide its own registry
3068
- // - For remote backend, NEVER overwrite the hydrated remote registry
3214
+ // - For remote backend, registry is automatically managed by RemoteGraphRunner
3069
3215
  if (backendKind === "local") {
3070
3216
  if (r) {
3071
3217
  setRegistry(r);
@@ -3178,79 +3324,8 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3178
3324
  const triggerUpload = useCallback(() => {
3179
3325
  uploadInputRef.current?.click();
3180
3326
  }, []);
3181
- const hydrateFromBackend = useCallback(async (kind, base) => {
3182
- try {
3183
- const transport = kind === "remote-http"
3184
- ? new HttpPollingTransport(base)
3185
- : new WebSocketTransport(base);
3186
- await transport.connect();
3187
- const rr = new RemoteRunner(transport);
3188
- const desc = await rr.describeRegistry();
3189
- const r = new Registry();
3190
- // Types
3191
- for (const t of desc.types) {
3192
- if (t.options) {
3193
- r.registerEnum({
3194
- id: t.id,
3195
- options: t.options,
3196
- bakeTarget: t.bakeTarget,
3197
- });
3198
- }
3199
- else {
3200
- r.registerType({
3201
- id: t.id,
3202
- displayName: t.displayName,
3203
- validate: (_v) => true,
3204
- bakeTarget: t.bakeTarget,
3205
- });
3206
- }
3207
- }
3208
- // Categories: create placeholders for display name
3209
- for (const c of desc.categories || []) {
3210
- // If you later expose real category descriptors, register them here
3211
- // For now, rely on ComputeCategory for behavior
3212
- const category = {
3213
- id: c.id,
3214
- displayName: c.displayName,
3215
- createRuntime: () => ({
3216
- async onInputsChanged() { },
3217
- }),
3218
- policy: { asyncConcurrency: "switch" },
3219
- };
3220
- r.categories.register(category);
3221
- }
3222
- // Coercions (client-side no-op to satisfy validation) if provided
3223
- for (const c of desc.coercions) {
3224
- if (c.async) {
3225
- r.registerAsyncCoercion(c.from, c.to, async (v) => v, {
3226
- nonTransitive: c.nonTransitive,
3227
- });
3228
- }
3229
- else {
3230
- r.registerCoercion(c.from, c.to, (v) => v, {
3231
- nonTransitive: c.nonTransitive,
3232
- });
3233
- }
3234
- }
3235
- // Nodes (use no-op impl for compute)
3236
- for (const n of desc.nodes) {
3237
- r.registerNode({
3238
- id: n.id,
3239
- categoryId: n.categoryId,
3240
- displayName: n.displayName,
3241
- inputs: n.inputs || {},
3242
- outputs: n.outputs || {},
3243
- impl: () => { },
3244
- });
3245
- }
3246
- setRegistry(r);
3247
- wb.setRegistry(r);
3248
- await transport.close();
3249
- }
3250
- catch (err) {
3251
- console.error("Failed to hydrate registry from backend:", err);
3252
- }
3253
- }, [setRegistry, wb]);
3327
+ // Registry is now automatically fetched by RemoteGraphRunner on first connection
3328
+ // No need for manual hydration
3254
3329
  // Ensure initial example is loaded (and sync when example prop changes)
3255
3330
  useEffect(() => {
3256
3331
  if (!example)
@@ -3261,6 +3336,21 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3261
3336
  const off = runner.on("transport", (s) => setTransportStatus(s));
3262
3337
  return () => off();
3263
3338
  }, [runner]);
3339
+ // Track registry readiness for remote backends
3340
+ useEffect(() => {
3341
+ // For local backends, registry is always ready
3342
+ if (backendKind === "local") {
3343
+ setRegistryReady(true);
3344
+ return;
3345
+ }
3346
+ // Reset readiness when switching to remote backend
3347
+ setRegistryReady(false);
3348
+ // For remote backends, wait for registry event
3349
+ const off = runner.on("registry", () => {
3350
+ setRegistryReady(true);
3351
+ });
3352
+ return () => off();
3353
+ }, [runner, backendKind]);
3264
3354
  useEffect(() => {
3265
3355
  if (!engine)
3266
3356
  return;
@@ -3282,25 +3372,13 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3282
3372
  // ignore
3283
3373
  }
3284
3374
  }, [engine, runner, wb, backendKind]);
3285
- // When switching to remote backend, auto-hydrate registry from backend
3286
- useEffect(() => {
3287
- let hydrate;
3288
- if (backendKind === "remote-http" && httpBaseUrl) {
3289
- hydrate = hydrateFromBackend("remote-http", httpBaseUrl);
3290
- }
3291
- else if (backendKind === "remote-ws" && wsUrl) {
3292
- hydrate = hydrateFromBackend("remote-ws", wsUrl);
3293
- }
3294
- if (hydrate) {
3295
- hydrate.then(() => {
3296
- setHydrated(true);
3297
- });
3298
- }
3299
- }, [backendKind, httpBaseUrl, wsUrl, hydrateFromBackend, setHydrated]);
3375
+ // Registry is automatically fetched by RemoteGraphRunner when it connects
3376
+ // Run auto layout after registry is hydrated (for remote backends)
3300
3377
  useEffect(() => {
3301
3378
  if (autoLayoutRan.current)
3302
3379
  return;
3303
- if (backendKind !== "local" && !hydrated)
3380
+ // Wait for registry to be ready for remote backends
3381
+ if (backendKind !== "local" && !registryReady)
3304
3382
  return;
3305
3383
  const cur = wb.export();
3306
3384
  const positions = wb.getPositions();
@@ -3309,7 +3387,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3309
3387
  autoLayoutRan.current = true;
3310
3388
  runAutoLayout();
3311
3389
  }
3312
- }, [wb, runAutoLayout, backendKind, hydrated]);
3390
+ }, [wb, runAutoLayout, backendKind, registryReady, registry]);
3313
3391
  const baseSetInput = useCallback((handle, raw) => {
3314
3392
  if (!selectedNodeId)
3315
3393
  return;
@@ -3419,7 +3497,9 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3419
3497
  value !== null &&
3420
3498
  "url" in value &&
3421
3499
  typeof value.url === "string") {
3422
- const title = ("title" in value && typeof value.title === "string") ? value.title : "";
3500
+ const title = "title" in value && typeof value.title === "string"
3501
+ ? value.title
3502
+ : "";
3423
3503
  const url = String(value.url || "");
3424
3504
  // value.ts handles data URL formatting
3425
3505
  return title || url.slice(0, 32) + (url.length > 32 ? "…" : "");
@@ -3432,7 +3512,11 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3432
3512
  const round4 = (n) => Math.round(Number(n) * 10000) / 10000;
3433
3513
  if (typeId === "base.vec3" && Array.isArray(value)) {
3434
3514
  const a = value;
3435
- return [round4(Number(a[0] ?? 0)), round4(Number(a[1] ?? 0)), round4(Number(a[2] ?? 0))].join(",");
3515
+ return [
3516
+ round4(Number(a[0] ?? 0)),
3517
+ round4(Number(a[1] ?? 0)),
3518
+ round4(Number(a[2] ?? 0)),
3519
+ ].join(",");
3436
3520
  }
3437
3521
  const stringifyRounded = (v) => {
3438
3522
  try {
@@ -3517,21 +3601,38 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3517
3601
  }
3518
3602
  }, children: "Download Snapshot" }), jsx("input", { ref: uploadInputRef, type: "file", accept: "application/json,.json", className: "hidden", onChange: onUploadPicked }), jsx("button", { className: "ml-2 border border-gray-300 rounded px-2 py-1.5", onClick: triggerUpload, children: "Upload Graph/Snapshot" }), jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsx("span", { children: "Debug events" })] }), jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsx("span", { children: "Show values in nodes" })] })] }), jsxs("div", { className: "flex flex-1 min-h-0", children: [jsx("div", { className: "flex-1 min-w-0", children: jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement, getDefaultNodeSize: overrides?.getDefaultNodeSize }) }), jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, toElement: toElement, contextPanel: overrides?.contextPanel })] })] }));
3519
3603
  }
3520
- function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, overrides, onInit, onChange, }) {
3604
+ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, backendOptions, overrides, onInit, onChange, }) {
3521
3605
  const [registry, setRegistry] = useState(createSimpleGraphRegistry());
3522
3606
  const [wb] = useState(() => new InMemoryWorkbench({ ui: new DefaultUIExtensionRegistry() }));
3523
3607
  const runner = useMemo(() => {
3524
3608
  if (backendKind === "remote-http") {
3525
- return new RemoteGraphRunner(registry, {
3609
+ const backend = {
3526
3610
  kind: "remote-http",
3527
3611
  baseUrl: httpBaseUrl,
3528
- });
3612
+ ...(backendOptions?.connectOptions && {
3613
+ connectOptions: backendOptions.connectOptions,
3614
+ }),
3615
+ ...(backendOptions?.onCustomEvent && {
3616
+ onCustomEvent: backendOptions.onCustomEvent,
3617
+ }),
3618
+ };
3619
+ return new RemoteGraphRunner(registry, backend);
3529
3620
  }
3530
3621
  if (backendKind === "remote-ws") {
3531
- return new RemoteGraphRunner(registry, { kind: "remote-ws", url: wsUrl });
3622
+ const backend = {
3623
+ kind: "remote-ws",
3624
+ url: wsUrl,
3625
+ ...(backendOptions?.connectOptions && {
3626
+ connectOptions: backendOptions.connectOptions,
3627
+ }),
3628
+ ...(backendOptions?.onCustomEvent && {
3629
+ onCustomEvent: backendOptions.onCustomEvent,
3630
+ }),
3631
+ };
3632
+ return new RemoteGraphRunner(registry, backend);
3532
3633
  }
3533
3634
  return new LocalGraphRunner(registry);
3534
- }, [registry, backendKind, httpBaseUrl, wsUrl]);
3635
+ }, [registry, backendKind, httpBaseUrl, wsUrl, backendOptions]);
3535
3636
  // Allow external UI registration (e.g., node renderers) with access to wb
3536
3637
  useEffect(() => {
3537
3638
  const baseRegisterUI = (_wb) => { };
@@ -3542,7 +3643,7 @@ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, bac
3542
3643
  if (runner.isRunning())
3543
3644
  runner.dispose();
3544
3645
  onBackendKindChange(v);
3545
- }, httpBaseUrl: httpBaseUrl, onHttpBaseUrlChange: onHttpBaseUrlChange, wsUrl: wsUrl, onWsUrlChange: onWsUrlChange, debug: debug, onDebugChange: onDebugChange, showValues: showValues, onShowValuesChange: onShowValuesChange, hideWorkbench: hideWorkbench, onHideWorkbenchChange: onHideWorkbenchChange, overrides: overrides, onInit: onInit, onChange: onChange }) }));
3646
+ }, httpBaseUrl: httpBaseUrl, onHttpBaseUrlChange: onHttpBaseUrlChange, wsUrl: wsUrl, onWsUrlChange: onWsUrlChange, debug: debug, onDebugChange: onDebugChange, showValues: showValues, onShowValuesChange: onShowValuesChange, hideWorkbench: hideWorkbench, onHideWorkbenchChange: onHideWorkbenchChange, backendOptions: backendOptions, overrides: overrides, onInit: onInit, onChange: onChange }) }));
3546
3647
  }
3547
3648
 
3548
3649
  export { AbstractWorkbench, CLIWorkbench, DefaultNode, DefaultNodeContent, DefaultNodeHeader, DefaultUIExtensionRegistry, InMemoryWorkbench, Inspector, LocalGraphRunner, NodeHandles, RemoteGraphRunner, WorkbenchCanvas, WorkbenchContext, WorkbenchProvider, WorkbenchStudio, formatDataUrlAsLabel, formatDeclaredTypeSignature, getNodeBorderClassNames, preformatValueForDisplay, resolveOutputDisplay, summarizeDeep, toReactFlow, useQueryParamBoolean, useQueryParamString, useThrottledValue, useWorkbenchBridge, useWorkbenchContext, useWorkbenchGraphTick, useWorkbenchGraphUiTick, useWorkbenchVersionTick };