@bian-womp/spark-workbench 0.2.24 → 0.2.25

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
@@ -817,22 +817,39 @@ class RemoteGraphRunner extends AbstractGraphRunner {
817
817
  return this.runner;
818
818
  let transport;
819
819
  const kind = this.backend.kind;
820
+ const backend = this.backend;
821
+ const connectOptions = backend.connectOptions;
820
822
  this.emit("transport", { state: "connecting", kind });
821
- if (this.backend.kind === "remote-http") {
823
+ if (backend.kind === "remote-http") {
822
824
  if (!sparkRemote.HttpPollingTransport)
823
825
  throw new Error("HttpPollingTransport not available");
824
- transport = new sparkRemote.HttpPollingTransport(this.backend.baseUrl);
825
- await transport.connect();
826
+ transport = new sparkRemote.HttpPollingTransport(backend.baseUrl);
827
+ await transport.connect(connectOptions);
826
828
  }
827
- else if (this.backend.kind === "remote-ws") {
829
+ else if (backend.kind === "remote-ws") {
828
830
  if (!sparkRemote.WebSocketTransport)
829
831
  throw new Error("WebSocketTransport not available");
830
- transport = new sparkRemote.WebSocketTransport(this.backend.url);
831
- await transport.connect();
832
+ transport = new sparkRemote.WebSocketTransport(backend.url);
833
+ await transport.connect(connectOptions);
832
834
  }
833
835
  else {
834
836
  throw new Error("Remote backend not configured");
835
837
  }
838
+ // Subscribe to custom events if handler provided
839
+ if (backend.onCustomEvent) {
840
+ transport.subscribe((event) => {
841
+ // Filter out standard runtime events, pass others to custom handler
842
+ const msg = event.message;
843
+ if (msg && typeof msg === "object" && "type" in msg) {
844
+ const type = msg.type;
845
+ // Standard runtime events: stats, value, error, invalidate
846
+ // Custom events are anything else (e.g., flow-opened, flow-latest)
847
+ if (!["stats", "value", "error", "invalidate"].includes(type)) {
848
+ backend.onCustomEvent?.(event);
849
+ }
850
+ }
851
+ });
852
+ }
836
853
  const runner = new sparkRemote.RemoteRunner(transport);
837
854
  this.runner = runner;
838
855
  this.transport = transport;
@@ -3421,7 +3438,9 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3421
3438
  value !== null &&
3422
3439
  "url" in value &&
3423
3440
  typeof value.url === "string") {
3424
- const title = ("title" in value && typeof value.title === "string") ? value.title : "";
3441
+ const title = "title" in value && typeof value.title === "string"
3442
+ ? value.title
3443
+ : "";
3425
3444
  const url = String(value.url || "");
3426
3445
  // value.ts handles data URL formatting
3427
3446
  return title || url.slice(0, 32) + (url.length > 32 ? "…" : "");
@@ -3434,7 +3453,11 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3434
3453
  const round4 = (n) => Math.round(Number(n) * 10000) / 10000;
3435
3454
  if (typeId === "base.vec3" && Array.isArray(value)) {
3436
3455
  const a = value;
3437
- return [round4(Number(a[0] ?? 0)), round4(Number(a[1] ?? 0)), round4(Number(a[2] ?? 0))].join(",");
3456
+ return [
3457
+ round4(Number(a[0] ?? 0)),
3458
+ round4(Number(a[1] ?? 0)),
3459
+ round4(Number(a[2] ?? 0)),
3460
+ ].join(",");
3438
3461
  }
3439
3462
  const stringifyRounded = (v) => {
3440
3463
  try {
@@ -3519,21 +3542,38 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3519
3542
  }
3520
3543
  }, children: "Download Snapshot" }), jsxRuntime.jsx("input", { ref: uploadInputRef, type: "file", accept: "application/json,.json", className: "hidden", onChange: onUploadPicked }), jsxRuntime.jsx("button", { className: "ml-2 border border-gray-300 rounded px-2 py-1.5", onClick: triggerUpload, children: "Upload Graph/Snapshot" }), jsxRuntime.jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsxRuntime.jsx("span", { children: "Debug events" })] }), jsxRuntime.jsxs("label", { className: "ml-2 flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsxRuntime.jsx("span", { children: "Show values in nodes" })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-1 min-h-0", children: [jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntime.jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement, getDefaultNodeSize: overrides?.getDefaultNodeSize }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, toElement: toElement, contextPanel: overrides?.contextPanel })] })] }));
3521
3544
  }
3522
- function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, overrides, onInit, onChange, }) {
3545
+ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, backendOptions, overrides, onInit, onChange, }) {
3523
3546
  const [registry, setRegistry] = React.useState(sparkGraph.createSimpleGraphRegistry());
3524
3547
  const [wb] = React.useState(() => new InMemoryWorkbench({ ui: new DefaultUIExtensionRegistry() }));
3525
3548
  const runner = React.useMemo(() => {
3526
3549
  if (backendKind === "remote-http") {
3527
- return new RemoteGraphRunner(registry, {
3550
+ const backend = {
3528
3551
  kind: "remote-http",
3529
3552
  baseUrl: httpBaseUrl,
3530
- });
3553
+ ...(backendOptions?.connectOptions && {
3554
+ connectOptions: backendOptions.connectOptions,
3555
+ }),
3556
+ ...(backendOptions?.onCustomEvent && {
3557
+ onCustomEvent: backendOptions.onCustomEvent,
3558
+ }),
3559
+ };
3560
+ return new RemoteGraphRunner(registry, backend);
3531
3561
  }
3532
3562
  if (backendKind === "remote-ws") {
3533
- return new RemoteGraphRunner(registry, { kind: "remote-ws", url: wsUrl });
3563
+ const backend = {
3564
+ kind: "remote-ws",
3565
+ url: wsUrl,
3566
+ ...(backendOptions?.connectOptions && {
3567
+ connectOptions: backendOptions.connectOptions,
3568
+ }),
3569
+ ...(backendOptions?.onCustomEvent && {
3570
+ onCustomEvent: backendOptions.onCustomEvent,
3571
+ }),
3572
+ };
3573
+ return new RemoteGraphRunner(registry, backend);
3534
3574
  }
3535
3575
  return new LocalGraphRunner(registry);
3536
- }, [registry, backendKind, httpBaseUrl, wsUrl]);
3576
+ }, [registry, backendKind, httpBaseUrl, wsUrl, backendOptions]);
3537
3577
  // Allow external UI registration (e.g., node renderers) with access to wb
3538
3578
  React.useEffect(() => {
3539
3579
  const baseRegisterUI = (_wb) => { };