@rainbow-robotics/plugin-ui 0.1.2-dev.5 → 0.1.2-dev.7

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/dist/connect.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import { type ComponentType } from "react";
2
2
  /**
3
- * Mount a plugin. Call this once from the sandbox entry (sandbox.html), passing
4
- * the plugin's root component.
3
+ * Mount a plugin. Call this once from the sandbox entry (content.tsx).
5
4
  *
6
5
  * @example
7
6
  * import { connect } from "@rainbow-robotics/plugin-ui/connect";
8
- * import App from "./content";
7
+ * import App from "./App";
9
8
  * connect(App);
10
9
  */
11
10
  export declare function connect(App: ComponentType): void;
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAc1D;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAwBhD"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAUA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAe1D;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA4BhD"}
package/dist/connect.js CHANGED
@@ -4,15 +4,20 @@ import { createElement } from "react";
4
4
  import { createRoot } from "react-dom/client";
5
5
  import { defineElements } from "./elements";
6
6
  import { RbContext } from "./sdk";
7
+ import { RbWs } from "./ws";
7
8
  function connect(App) {
8
9
  defineElements();
9
10
  const host = ThreadWindow.parent.import({
10
11
  targetOrigin: "*"
11
12
  });
12
- void host.connect().then(({ connection, action, notify }) => {
13
+ void host.connect().then(async ({ connection, toast, socketUrl, pluginId }) => {
14
+ const ws = await RbWs.connect(socketUrl, pluginId);
13
15
  const rb = {
14
- action: (id, payload) => Promise.resolve(action(id, payload)),
15
- notify: (message, type) => notify(message, type)
16
+ pub: (topic, payload) => ws.pub(topic, payload),
17
+ sub: (topic, handler) => ws.sub(topic, handler),
18
+ action: (topic, payload) => ws.action(topic, payload),
19
+ serve: (topic, handler) => ws.serve(topic, handler),
20
+ toast: (message, type) => toast(message, type)
16
21
  };
17
22
  const root = document.createElement("remote-root");
18
23
  document.body.append(root);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/connect.ts"],
4
- "sourcesContent": ["/**\n * Sandbox bootstrap \u2014 runs *inside* the plugin iframe.\n *\n * The sandbox initiates the handshake (the iframe is the side that knows when it\n * is ready): it imports the host's `connect()` and calls it. The host responds\n * with a `RemoteConnection` (its `receiver.connection`, ferried by\n * @quilted/threads) plus the host SDK. We then render the plugin's React tree\n * into a detached root and let `RemoteMutationObserver` stream every DOM\n * mutation to the host, where the real rb-components live.\n *\n * The child-initiates-handshake pattern is required because @quilted/threads\n * does not buffer a call made before the other side is listening; the host has\n * been listening since it mounted the iframe, so a call *from* the sandbox is\n * always delivered.\n *\n * Verified against @remote-dom/core@1.11.x + @quilted/threads@4.x.\n */\nimport { RemoteMutationObserver } from \"@remote-dom/core/elements\";\nimport type { RemoteConnection } from \"@remote-dom/core\";\nimport { ThreadWindow } from \"@quilted/threads\";\nimport { createElement, type ComponentType } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { defineElements } from \"./elements\";\nimport { RbContext, type RbSdk } from \"./sdk\";\n\n/** What the host exposes to the sandbox. */\ninterface HostExports {\n connect: () => Promise<{\n connection: RemoteConnection;\n action: (id: string, payload?: unknown) => Promise<unknown> | unknown;\n notify: (message: string, type?: string) => void;\n }>;\n}\n\n/**\n * Mount a plugin. Call this once from the sandbox entry (sandbox.html), passing\n * the plugin's root component.\n *\n * @example\n * import { connect } from \"@rainbow-robotics/plugin-ui/connect\";\n * import App from \"./content\";\n * connect(App);\n */\nexport function connect(App: ComponentType): void {\n defineElements();\n\n const host = ThreadWindow.parent.import<HostExports>({\n targetOrigin: \"*\",\n });\n\n void host.connect().then(({ connection, action, notify }) => {\n const rb: RbSdk = {\n action: (id, payload) => Promise.resolve(action(id, payload)),\n notify: (message, type) => notify(message, type as string | undefined),\n };\n\n const root = document.createElement(\"remote-root\");\n\n document.body.append(root);\n\n const observer = new RemoteMutationObserver(connection);\n observer.observe(root);\n\n createRoot(root).render(\n createElement(RbContext.Provider, { value: rb }, createElement(App)),\n );\n });\n}\n"],
5
- "mappings": "AAiBA,SAAS,8BAA8B;AAEvC,SAAS,oBAAoB;AAC7B,SAAS,qBAAyC;AAClD,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,iBAA6B;AAoB/B,SAAS,QAAQ,KAA0B;AAChD,iBAAe;AAEf,QAAM,OAAO,aAAa,OAAO,OAAoB;AAAA,IACnD,cAAc;AAAA,EAChB,CAAC;AAED,OAAK,KAAK,QAAQ,EAAE,KAAK,CAAC,EAAE,YAAY,QAAQ,OAAO,MAAM;AAC3D,UAAM,KAAY;AAAA,MAChB,QAAQ,CAAC,IAAI,YAAY,QAAQ,QAAQ,OAAO,IAAI,OAAO,CAAC;AAAA,MAC5D,QAAQ,CAAC,SAAS,SAAS,OAAO,SAAS,IAA0B;AAAA,IACvE;AAEA,UAAM,OAAO,SAAS,cAAc,aAAa;AAEjD,aAAS,KAAK,OAAO,IAAI;AAEzB,UAAM,WAAW,IAAI,uBAAuB,UAAU;AACtD,aAAS,QAAQ,IAAI;AAErB,eAAW,IAAI,EAAE;AAAA,MACf,cAAc,UAAU,UAAU,EAAE,OAAO,GAAG,GAAG,cAAc,GAAG,CAAC;AAAA,IACrE;AAAA,EACF,CAAC;AACH;",
4
+ "sourcesContent": ["/**\n * Sandbox bootstrap \u2014 runs *inside* the plugin iframe.\n *\n * The sandbox initiates the handshake: imports the host's `connect()` and calls\n * it. The host responds with the RemoteConnection, toast(), and Socket.IO config\n * (socketUrl + pluginId). We open a Socket.IO connection and wire up the rb object.\n */\nimport { RemoteMutationObserver } from \"@remote-dom/core/elements\";\nimport type { RemoteConnection } from \"@remote-dom/core\";\nimport { ThreadWindow } from \"@quilted/threads\";\nimport { createElement, type ComponentType } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { defineElements } from \"./elements\";\nimport { RbContext, type RbSdk } from \"./sdk\";\nimport { RbWs } from \"./ws\";\n\ninterface HostExports {\n connect: () => Promise<{\n connection: RemoteConnection;\n toast: (message: string, type?: string) => void;\n socketUrl: string;\n pluginId: string;\n }>;\n}\n\n/**\n * Mount a plugin. Call this once from the sandbox entry (content.tsx).\n *\n * @example\n * import { connect } from \"@rainbow-robotics/plugin-ui/connect\";\n * import App from \"./App\";\n * connect(App);\n */\nexport function connect(App: ComponentType): void {\n defineElements();\n\n const host = ThreadWindow.parent.import<HostExports>({\n targetOrigin: \"*\",\n });\n\n void host.connect().then(async ({ connection, toast, socketUrl, pluginId }) => {\n const ws = await RbWs.connect(socketUrl, pluginId);\n\n const rb: RbSdk = {\n pub: (topic, payload) => ws.pub(topic, payload),\n sub: (topic, handler) => ws.sub(topic, handler),\n action: (topic, payload) => ws.action(topic, payload),\n serve: (topic, handler) => ws.serve(topic, handler),\n toast: (message, type) => toast(message, type),\n };\n\n const root = document.createElement(\"remote-root\");\n document.body.append(root);\n\n const observer = new RemoteMutationObserver(connection);\n observer.observe(root);\n\n createRoot(root).render(\n createElement(RbContext.Provider, { value: rb }, createElement(App)),\n );\n });\n}\n"],
5
+ "mappings": "AAOA,SAAS,8BAA8B;AAEvC,SAAS,oBAAoB;AAC7B,SAAS,qBAAyC;AAClD,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,iBAA6B;AACtC,SAAS,YAAY;AAmBd,SAAS,QAAQ,KAA0B;AAChD,iBAAe;AAEf,QAAM,OAAO,aAAa,OAAO,OAAoB;AAAA,IACnD,cAAc;AAAA,EAChB,CAAC;AAED,OAAK,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,YAAY,OAAO,WAAW,SAAS,MAAM;AAC7E,UAAM,KAAK,MAAM,KAAK,QAAQ,WAAW,QAAQ;AAEjD,UAAM,KAAY;AAAA,MAChB,KAAQ,CAAC,OAAO,YAAY,GAAG,IAAI,OAAO,OAAO;AAAA,MACjD,KAAQ,CAAC,OAAO,YAAY,GAAG,IAAI,OAAO,OAAO;AAAA,MACjD,QAAQ,CAAC,OAAO,YAAY,GAAG,OAAO,OAAO,OAAO;AAAA,MACpD,OAAQ,CAAC,OAAO,YAAY,GAAG,MAAM,OAAO,OAAO;AAAA,MACnD,OAAQ,CAAC,SAAS,SAAU,MAAM,SAAS,IAAI;AAAA,IACjD;AAEA,UAAM,OAAO,SAAS,cAAc,aAAa;AACjD,aAAS,KAAK,OAAO,IAAI;AAEzB,UAAM,WAAW,IAAI,uBAAuB,UAAU;AACtD,aAAS,QAAQ,IAAI;AAErB,eAAW,IAAI,EAAE;AAAA,MACf,cAAc,UAAU,UAAU,EAAE,OAAO,GAAG,GAAG,cAAc,GAAG,CAAC;AAAA,IACrE;AAAA,EACF,CAAC;AACH;",
6
6
  "names": []
7
7
  }
package/dist/sdk.d.ts CHANGED
@@ -1,12 +1,26 @@
1
+ import type { WsSubscriber as Subscriber, WsQueryable as Queryable } from "./ws";
1
2
  export type RbNotifyType = "info" | "success" | "warning" | "error";
2
3
  export interface RbSdk {
3
4
  /**
4
- * Invoke a host-side action (declared in manifest.actions). Resolves with
5
- * whatever the host/back end returns.
5
+ * Publish JSON payload to a topic.
6
+ * "sensor/data" → plugin/{pluginId}/sensor/data
7
+ * "/broadcast/x" → broadcast/x (absolute)
6
8
  */
7
- action: (id: string, payload?: unknown) => Promise<unknown>;
9
+ pub: <P = any>(topic: string, payload: P) => Promise<void>;
10
+ /** Subscribe to a topic. Returns a handle with undeclare(). */
11
+ sub: <P = any>(topic: string, handler: (payload: P) => void) => Promise<Subscriber>;
12
+ /**
13
+ * Send a request and await the first reply (Zenoh query).
14
+ * Use this to call a backend handler registered with rb.serve() / ZenohRouter.
15
+ */
16
+ action: <R = any, P = any>(topic: string, payload?: P) => Promise<R>;
17
+ /**
18
+ * Register a queryable — the frontend responds to backend queries.
19
+ * Mirror of rb.action() on the other side.
20
+ */
21
+ serve: <P = any, R = any>(topic: string, handler: (payload?: P) => R | Promise<R>) => Promise<Queryable>;
8
22
  /** Show a transient notification through the host's toast system. */
9
- notify: (message: string, type?: RbNotifyType) => void;
23
+ toast: (message: string, type?: RbNotifyType) => void;
10
24
  }
11
25
  export declare const RbContext: import("react").Context<RbSdk>;
12
26
  /** Access the host SDK from within a plugin component. */
package/dist/sdk.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpE,MAAM,WAAW,KAAK;IACpB;;;OAGG;IACH,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,qEAAqE;IACrE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CACxD;AAgBD,eAAO,MAAM,SAAS,gCAAgC,CAAC;AAEvD,0DAA0D;AAC1D,wBAAgB,KAAK,IAAI,KAAK,CAE7B"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,IAAI,UAAU,EAAE,WAAW,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpE,MAAM,WAAW,KAAK;IACpB;;;;OAIG;IACH,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D,+DAA+D;IAC/D,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,KAC1B,OAAO,CAAC,UAAU,CAAC,CAAC;IAEzB;;;OAGG;IACH,MAAM,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAErE;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EACtB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KACrC,OAAO,CAAC,SAAS,CAAC,CAAC;IAExB,qEAAqE;IACrE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CACvD;AAuBD,eAAO,MAAM,SAAS,gCAAgC,CAAC;AAEvD,0DAA0D;AAC1D,wBAAgB,KAAK,IAAI,KAAK,CAE7B"}
package/dist/sdk.js CHANGED
@@ -1,15 +1,24 @@
1
1
  import { createContext, useContext } from "react";
2
2
  const noopSdk = {
3
- action: async () => {
4
- if (typeof console !== "undefined") {
5
- console.warn("[plugin-ui] rb.action called outside of a host context");
6
- }
3
+ pub: async (_topic, _payload) => {
4
+ console.warn("[plugin-ui] rb.pub called outside of a host context");
5
+ },
6
+ sub: async (_topic, _handler) => {
7
+ console.warn("[plugin-ui] rb.sub called outside of a host context");
8
+ return { undeclare: async () => {
9
+ } };
10
+ },
11
+ action: async (_topic, _payload) => {
12
+ console.warn("[plugin-ui] rb.action called outside of a host context");
7
13
  return void 0;
8
14
  },
9
- notify: (message) => {
10
- if (typeof console !== "undefined") {
11
- console.warn("[plugin-ui] rb.notify (no host):", message);
12
- }
15
+ serve: async (_topic, _handler) => {
16
+ console.warn("[plugin-ui] rb.serve called outside of a host context");
17
+ return { undeclare: async () => {
18
+ } };
19
+ },
20
+ toast: (message) => {
21
+ console.warn("[plugin-ui] rb.toast (no host):", message);
13
22
  }
14
23
  };
15
24
  const RbContext = createContext(noopSdk);
package/dist/sdk.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sdk.ts"],
4
- "sourcesContent": ["/**\n * Plugin runtime SDK \u2014 the small, stable surface a plugin author calls from\n * inside the sandbox to talk to the host (Muscat / nexus).\n *\n * The concrete implementation is injected by the host across the iframe thread\n * (see ./connect for the sandbox side, ./host for the host side).\n */\nimport { createContext, useContext } from \"react\";\n\nexport type RbNotifyType = \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport interface RbSdk {\n /**\n * Invoke a host-side action (declared in manifest.actions). Resolves with\n * whatever the host/back end returns.\n */\n action: (id: string, payload?: unknown) => Promise<unknown>;\n /** Show a transient notification through the host's toast system. */\n notify: (message: string, type?: RbNotifyType) => void;\n}\n\nconst noopSdk: RbSdk = {\n action: async () => {\n if (typeof console !== \"undefined\") {\n console.warn(\"[plugin-ui] rb.action called outside of a host context\");\n }\n return undefined;\n },\n notify: (message) => {\n if (typeof console !== \"undefined\") {\n console.warn(\"[plugin-ui] rb.notify (no host):\", message);\n }\n },\n};\n\nexport const RbContext = createContext<RbSdk>(noopSdk);\n\n/** Access the host SDK from within a plugin component. */\nexport function useRb(): RbSdk {\n return useContext(RbContext);\n}\n"],
5
- "mappings": "AAOA,SAAS,eAAe,kBAAkB;AAc1C,MAAM,UAAiB;AAAA,EACrB,QAAQ,YAAY;AAClB,QAAI,OAAO,YAAY,aAAa;AAClC,cAAQ,KAAK,wDAAwD;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AAAA,EACA,QAAQ,CAAC,YAAY;AACnB,QAAI,OAAO,YAAY,aAAa;AAClC,cAAQ,KAAK,oCAAoC,OAAO;AAAA,IAC1D;AAAA,EACF;AACF;AAEO,MAAM,YAAY,cAAqB,OAAO;AAG9C,SAAS,QAAe;AAC7B,SAAO,WAAW,SAAS;AAC7B;",
4
+ "sourcesContent": ["/**\n * Plugin runtime SDK \u2014 the surface a plugin author calls from inside the sandbox.\n *\n * Zenoh methods (pub/sub/action/serve) talk directly to the Zenoh router via\n * WebSocket. Topics are auto-namespaced to plugin/{pluginId}/... to prevent\n * cross-plugin collisions. A leading \"/\" bypasses namespacing (absolute path).\n *\n * notify() is still host-mediated (goes through the Muscat shell).\n */\nimport { createContext, useContext } from \"react\";\nimport type { WsSubscriber as Subscriber, WsQueryable as Queryable } from \"./ws\";\n\nexport type RbNotifyType = \"info\" | \"success\" | \"warning\" | \"error\";\n\nexport interface RbSdk {\n /**\n * Publish JSON payload to a topic.\n * \"sensor/data\" \u2192 plugin/{pluginId}/sensor/data\n * \"/broadcast/x\" \u2192 broadcast/x (absolute)\n */\n pub: <P = any>(topic: string, payload: P) => Promise<void>;\n\n /** Subscribe to a topic. Returns a handle with undeclare(). */\n sub: <P = any>(\n topic: string,\n handler: (payload: P) => void,\n ) => Promise<Subscriber>;\n\n /**\n * Send a request and await the first reply (Zenoh query).\n * Use this to call a backend handler registered with rb.serve() / ZenohRouter.\n */\n action: <R = any, P = any>(topic: string, payload?: P) => Promise<R>;\n\n /**\n * Register a queryable \u2014 the frontend responds to backend queries.\n * Mirror of rb.action() on the other side.\n */\n serve: <P = any, R = any>(\n topic: string,\n handler: (payload?: P) => R | Promise<R>,\n ) => Promise<Queryable>;\n\n /** Show a transient notification through the host's toast system. */\n toast: (message: string, type?: RbNotifyType) => void;\n}\n\nconst noopSdk: RbSdk = {\n pub: async <P = any>(_topic?: string, _payload?: P) => {\n console.warn(\"[plugin-ui] rb.pub called outside of a host context\");\n },\n sub: async <P = any>(_topic?: string, _handler?: (payload: P) => void) => {\n console.warn(\"[plugin-ui] rb.sub called outside of a host context\");\n return { undeclare: async () => {} } as unknown as Subscriber;\n },\n action: async <R = any, P = any>(_topic?: string, _payload?: P) => {\n console.warn(\"[plugin-ui] rb.action called outside of a host context\");\n return undefined as R;\n },\n serve: async <P = any, R = any>(_topic?: string, _handler?: (payload?: P) => R) => {\n console.warn(\"[plugin-ui] rb.serve called outside of a host context\");\n return { undeclare: async () => {} } as unknown as Queryable;\n },\n toast: (message) => {\n console.warn(\"[plugin-ui] rb.toast (no host):\", message);\n },\n};\n\nexport const RbContext = createContext<RbSdk>(noopSdk);\n\n/** Access the host SDK from within a plugin component. */\nexport function useRb(): RbSdk {\n return useContext(RbContext);\n}\n"],
5
+ "mappings": "AASA,SAAS,eAAe,kBAAkB;AAsC1C,MAAM,UAAiB;AAAA,EACrB,KAAK,OAAgB,QAAiB,aAAiB;AACrD,YAAQ,KAAK,qDAAqD;AAAA,EACpE;AAAA,EACA,KAAK,OAAgB,QAAiB,aAAoC;AACxE,YAAQ,KAAK,qDAAqD;AAClE,WAAO,EAAE,WAAW,YAAY;AAAA,IAAC,EAAE;AAAA,EACrC;AAAA,EACA,QAAQ,OAAyB,QAAiB,aAAiB;AACjE,YAAQ,KAAK,wDAAwD;AACrE,WAAO;AAAA,EACT;AAAA,EACA,OAAO,OAAyB,QAAiB,aAAkC;AACjF,YAAQ,KAAK,uDAAuD;AACpE,WAAO,EAAE,WAAW,YAAY;AAAA,IAAC,EAAE;AAAA,EACrC;AAAA,EACA,OAAO,CAAC,YAAY;AAClB,YAAQ,KAAK,mCAAmC,OAAO;AAAA,EACzD;AACF;AAEO,MAAM,YAAY,cAAqB,OAAO;AAG9C,SAAS,QAAe;AAC7B,SAAO,WAAW,SAAS;AAC7B;",
6
6
  "names": []
7
7
  }
package/dist/ws.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export interface WsHandle {
2
+ undeclare(): void;
3
+ }
4
+ export type WsSubscriber = WsHandle;
5
+ export type WsQueryable = WsHandle;
6
+ export declare class RbWs {
7
+ private readonly _socket;
8
+ private readonly _pluginId;
9
+ private readonly _subHandlers;
10
+ private readonly _serveHandlers;
11
+ private constructor();
12
+ static connect(url: string, pluginId: string): Promise<RbWs>;
13
+ private _key;
14
+ pub<P = any>(topic: string, payload: P): Promise<void>;
15
+ sub<P = any>(topic: string, handler: (payload: P) => void): Promise<WsSubscriber>;
16
+ action<R = any, P = any>(topic: string, payload?: P): Promise<R>;
17
+ serve<P = any, R = any>(topic: string, handler: (payload?: P) => R | Promise<R>): Promise<WsQueryable>;
18
+ close(): void;
19
+ }
20
+ //# sourceMappingURL=ws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,QAAQ;IACvB,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;AACpC,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;AAMnC,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsD;IACnF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwE;IAEvG,OAAO;IAiBP,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5D,OAAO,CAAC,IAAI;IAKN,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtD,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;IAsBjF,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAWhE,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvC,OAAO,CAAC,WAAW,CAAC;IAYvB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1 @@
1
+ var f=Object.defineProperty;var g=a=>{throw TypeError(a)};var h=(a,b,c)=>b in a?f(a,b,{enumerable:!0,configurable:!0,writable:!0,value:c}):a[b]=c;var i=(a,b)=>{for(var c in b)f(a,c,{get:b[c],enumerable:!0})};var j=(a,b,c)=>h(a,typeof b!="symbol"?b+"":b,c),d=(a,b,c)=>b.has(a)||g("Cannot "+c);var k=(a,b,c)=>(d(a,b,"read from private field"),c?c.call(a):b.get(a)),l=(a,b,c)=>b.has(a)?g("Cannot add the same private member more than once"):b instanceof WeakSet?b.add(a):b.set(a,c),m=(a,b,c,e)=>(d(a,b,"write to private field"),e?e.call(a,c):b.set(a,c),c),n=(a,b,c)=>(d(a,b,"access private method"),c);export{i as a,j as b,k as c,l as d,m as e,n as f};
@@ -1 +1 @@
1
- import{a as v,b as P,c as Q,d as ee}from"./chunk-AMCIKVG7.js";var M=class extends CustomEvent{respondWith(t){this.response=t}};var g=new WeakMap;var B=new WeakMap,ce=0;function y(e){let t=B.get(e);return t==null&&(t=String(ce++),k(e,t)),t}function k(e,t){B.set(e,t)}var L=new WeakMap;function S(e){return L.get(e)}var I=new WeakMap;function ae(e){let t=I.get(e);if(t!=null)return t;if(!(!(e instanceof Element)||e.tagName.includes("-"))){t={};for(let{name:r,value:n}of e.attributes)t[r]=n;return t}}var z=new WeakMap;function Y(e){return z.get(e)}function _(e,t,r){let n=L.get(e);if(n==null&&(n={},L.set(e,n)),n[t]===r)return;n[t]=r;let o=g.get(e);o?.mutate([[3,y(e),t,r,1]])}function A(e,t,r){let n=I.get(e);if(n==null&&(n={},I.set(e,n)),n[t]===r)return;r==null?delete n[t]:n[t]=String(r);let o=g.get(e);o?.mutate([[3,y(e),t,r,2]])}function j(e,t,r){let n=z.get(e);if(n==null&&(n={},z.set(e,n)),n[t]===r)return;r==null?delete n[t]:n[t]=r;let o=g.get(e);o?.mutate([[3,y(e),t,r,3]])}function D(e,t){if(g.get(e)!==t&&(g.set(e,t),e.childNodes))for(let n=0;n<e.childNodes.length;n++)D(e.childNodes[n],t)}function O(e){if(g.get(e)!=null&&(g.delete(e),e.childNodes))for(let r=0;r<e.childNodes.length;r++)O(e.childNodes[r])}function T(e){let{nodeType:t}=e;switch(t){case 1:return{id:y(e),type:t,element:e.localName,properties:w(S(e)),attributes:w(ae(e)),eventListeners:w(Y(e)),children:Array.from(e.childNodes).map(T)};case 3:case 8:return{id:y(e),type:t,data:e.data};default:throw new Error(`Cannot serialize node of type ${e.nodeType} (${typeof e.nodeType})`)}}function w(e){return e?{...e}:void 0}function te(e,t,...r){let n=B.get(e),o=g.get(e);if(n==null||o==null)throw new Error(`Cannot call method ${t} on an unconnected node`);return o.call(n,t,...r)}var U=Object.freeze({});var p=class extends HTMLElement{static get observedAttributes(){return this.finalize().__observedAttributes}static get remotePropertyDefinitions(){return this.finalize().__remotePropertyDefinitions}static get remoteAttributeDefinitions(){return this.finalize().__remoteAttributeDefinitions}static get remoteEventDefinitions(){return this.finalize().__remoteEventDefinitions}static get remoteSlotDefinitions(){return this.finalize().__remoteSlotDefinitions}static createProperty(t,r){F(t,r,this.observedAttributes,this.remotePropertyDefinitions,this.__attributeToPropertyMap,this.__eventToPropertyMap)}static finalize(){if(this.hasOwnProperty("__finalized"))return this;this.__finalized=!0;let{slottable:t,remoteSlots:r,remoteProperties:n,remoteAttributes:o,remoteEvents:i,remoteMethods:s}=this,c=Object.getPrototypeOf(this),a=new Set;t&&a.add("slot");let u=new Map,d=new Map,f=new Map,h=new Map,b=new Map,E=new Map;if(typeof c.finalize=="function"&&(c.finalize(),c.observedAttributes.forEach(l=>{a.add(l)}),c.remotePropertyDefinitions.forEach((l,m)=>{h.set(m,l)}),c.remoteAttributeDefinitions.forEach((l,m)=>{b.set(m,l)}),c.remoteEventDefinitions.forEach((l,m)=>{E.set(m,l)}),c.remoteSlotDefinitions.forEach((l,m)=>{f.set(m,l)})),r!=null&&(Array.isArray(r)?r:Object.keys(r)).forEach(m=>{f.set(m,U)}),n!=null&&(Array.isArray(n)?n.forEach(l=>{F(l,void 0,a,h,u,d)}):Object.keys(n).forEach(l=>{F(l,n[l],a,h,u,d)})),o?.forEach(l=>{b.set(l,U),a.add(l)}),i!=null&&(Array.isArray(i)?i.forEach(l=>{E.set(l,U)}):Object.keys(i).forEach(l=>{E.set(l,i[l])})),s!=null)if(Array.isArray(s))for(let l of s)this.prototype[l]=function(...m){return this.callRemoteMethod(l,...m)};else Object.assign(this,s);return Object.defineProperties(this,{__observedAttributes:{value:[...a],enumerable:!1},__remoteSlotDefinitions:{value:f,enumerable:!1},__remotePropertyDefinitions:{value:h,enumerable:!1},__remoteAttributeDefinitions:{value:b,enumerable:!1},__remoteEventDefinitions:{value:E,enumerable:!1},__attributeToPropertyMap:{value:u,enumerable:!1},__eventToPropertyMap:{value:d,enumerable:!1}}),this}constructor(){super(),this.constructor.finalize();let t={},r={},n=Object.getPrototypeOf(this),o=this.constructor;for(let[i,s]of o.remotePropertyDefinitions.entries()){let c=s.name;if(n.hasOwnProperty(i))continue;i===c&&(r[i]=s.default);let a={configurable:!0,enumerable:i===c,get:()=>S(this)?.[c],set:u=>{_(this,c,u)}};t[i]=a}for(let[i,s]of o.remoteEventDefinitions.entries()){let c=s.property??!0;if(!c)continue;let a=c===!0?`on${i}`:c;t[a]={configurable:!0,enumerable:!0,get:()=>N(this).properties.get(a)??null,set:u=>{let d=N(this),f=d.properties.get(a);if(typeof u=="function"){let h=function(...b){return u.call(this,...b)};d.properties.set(a,h),this.addEventListener(i,h)}else d.properties.delete(a);f&&this.removeEventListener(i,f)}}}Object.defineProperties(this,t),Object.assign(this,r)}attributeChangedCallback(t,r,n){if(t==="slot"&&this.constructor.slottable){A(this,t,n?String(n):void 0);return}let{remotePropertyDefinitions:o,remoteAttributeDefinitions:i,__attributeToPropertyMap:s}=this.constructor;if(i.has(t)){A(this,t,n);return}let c=s.get(t),a=c==null?c:o.get(c);a!=null&&(this[c]=ue(n,a.type))}connectedCallback(){for(let[t,r]of this.constructor.remoteEventDefinitions.entries())r.bubbles&&this.addEventListener(t,ne)}disconnectedCallback(){for(let[t,r]of this.constructor.remoteEventDefinitions.entries())r.bubbles&&this.removeEventListener(t,ne)}addEventListener(t,r,n){let{remoteEventDefinitions:o,__eventToPropertyMap:i}=this.constructor,s=o.get(t),c=i.get(t);if(s==null&&c==null)return super.addEventListener(t,r,n);let a=N(this),u=le.call(this,t,{property:c,definition:s}),d=typeof n=="object"&&n?.once?(...h)=>{let b=typeof r=="object"?r.handleEvent(...h):r.call(this,...h);return W.call(this,t,r,f),b}:r,f=[d,u];u.listeners.add(r),a.listeners.set(r,f),super.addEventListener(t,d,n),typeof n=="object"&&n.signal&&n.signal.addEventListener("abort",()=>{W.call(this,t,r,f)},{once:!0}),s?j(this,t,u.dispatch):_(this,c,u.dispatch)}removeEventListener(t,r,n){let o=$.get(this)?.listeners.get(r),i=o?o[0]:r;super.removeEventListener(t,i,n),o!=null&&W.call(this,t,r,o)}updateRemoteProperty(t,r){_(this,t,r)}updateRemoteAttribute(t,r){A(this,t,r)}callRemoteMethod(t,...r){return te(this,t,...r)}};v(p,"slottable",!0),v(p,"__finalized",!0),v(p,"__observedAttributes",[]),v(p,"__attributeToPropertyMap",new Map),v(p,"__eventToPropertyMap",new Map),v(p,"__remotePropertyDefinitions",new Map),v(p,"__remoteAttributeDefinitions",new Map),v(p,"__remoteEventDefinitions",new Map),v(p,"__remoteSlotDefinitions",new Map);var $=new WeakMap;function N(e){let t=$.get(e);return t||(t={events:new Map,properties:new Map,listeners:new WeakMap},$.set(e,t),t)}function le(e,{property:t,definition:r}){let n=N(this),o=n.events.get(e);return o==null&&(o={name:e,property:t,definition:r,listeners:new Set,dispatch:(...i)=>{let s=r?.dispatchEvent?.apply(this,i)??new M(e,{detail:i[0],bubbles:r?.bubbles});return this.dispatchEvent(s),s.response}},n.events.set(e,o)),o}function W(e,t,r){let n=N(this),o=r[1];o.listeners.delete(t),n.listeners.delete(t),!(o.listeners.size>0)&&(n.events.delete(e),o.property?S(this)?.[o.property]===o.dispatch&&_(this,o.property,void 0):Y(this)?.[e]===o.dispatch&&j(this,e,void 0))}function F(e,t,r,n,o,i){if(n.has(e))return n.get(e);let s=e[0]==="o"&&e[1]==="n",c=t??{},{alias:a}=c,{type:u=s?Function:String,attribute:d=u!==Function,event:f=s,default:h=u===Boolean?!1:void 0}=c;if(a==null){let m=e.toLowerCase();m!==e&&(a=[m]),s&&(a??(a=[]),a.unshift(`_${e}`))}let b;d===!0?b=re(e):typeof d=="string"&&(b=d),b&&(Array.isArray(r)?r.push(b):r.add(b),o.set(b,e));let E;f===!0?E=re(s?e.slice(2):e):typeof f=="string"&&(E=f),E&&i.set(E,e);let l={name:e,type:u,alias:a,event:E,attribute:b,default:h};if(n.set(e,l),a)for(let m of a)n.set(m,l);return l}function ue(e,t){if(e!=null)switch(t){case Boolean:return e!=null&&e!=="false";case Object:case Array:try{return JSON.parse(e)}catch{return}case String:return String(e);case Number:return Number.parseFloat(e);case Function:return;default:return t.parse?.(e)}}function re(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function ne(){}var R,H=class extends MutationObserver{constructor(r){super(n=>{let o=[],i=[];for(let s of n){let c=y(s.target);if(s.type==="childList"){let a=s.previousSibling?pe(s.previousSibling,s.target.childNodes)+1:0;s.removedNodes.forEach(u=>{O(u),i.push([1,c,a])}),s.addedNodes.forEach((u,d)=>{o.some(f=>f===u||f.contains(u))||(o.push(u),D(u,r),i.push([0,c,T(u),a+d]))})}else s.type==="characterData"?i.push([2,c,s.target.textContent??""]):s.type==="attributes"&&s.attributeName!=null&&s.target instanceof Element&&!s.target.tagName.includes("-")&&i.push([3,c,s.attributeName,s.target.getAttribute(s.attributeName)])}r.mutate(i)});Q(this,R);this.connection=r,ee(this,R,new Set)}observe(r,n){let o=n?.id??"~";if(k(r,o),P(this,R).add(r),n?.initial!==!1&&r.childNodes.length>0){if(o!=="~")this.connection.mutate([[0,"~",T(r),P(this,R).size-1]]);else if(r.childNodes.length>0){let i=[];for(let s=0;s<r.childNodes.length;s++){let c=r.childNodes[s];D(c,this.connection),i.push([0,"~",T(c),s])}this.connection.mutate(i)}}super.observe(r,{subtree:!0,childList:!0,attributes:!0,characterData:!0,...n})}disconnect({empty:r=!1}={}){if(r&&P(this,R).size>0){let n=[];for(let o of P(this,R)){O(o);let i=y(o);if(i==="~")for(let s=0;s<o.childNodes.length;s++)n.push([1,i,0]);else n.push([1,"~",0])}this.connection.mutate(n)}P(this,R).clear(),super.disconnect()}};R=new WeakMap;function pe(e,t){for(let r=0;r<t.length;r++)if(t[r]===e)return r;return-1}var V=class extends p{static get remoteProperties(){return{value:{type:Number},min:{type:Number},max:{type:Number},step:{type:Number},disabled:{type:Boolean}}}static get remoteEvents(){return["change"]}},J=class extends p{static get remoteProperties(){return{label:{type:String},variant:{type:String},size:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["press"]}},K=class extends p{static get remoteProperties(){return{icon:{type:String},variant:{type:String},size:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["press"]}},X=class extends p{static get remoteProperties(){return{}}},Z=class extends p{static get remoteProperties(){return{value:{type:String},placeholder:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["input"]}},q=class extends p{static get remoteProperties(){return{checked:{type:Boolean},disabled:{type:Boolean}}}static get remoteEvents(){return["change"]}},G=class extends p{static get remoteProperties(){return{value:{type:String},options:{type:Array},placeholder:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["change"]}},De=["rb-slider","rb-button","rb-icon-button","rb-text","rb-text-input","rb-switch","rb-select"],ie=!1;function Oe(){ie||typeof customElements>"u"||(ie=!0,customElements.define("rb-slider",V),customElements.define("rb-button",J),customElements.define("rb-icon-button",K),customElements.define("rb-text",X),customElements.define("rb-text-input",Z),customElements.define("rb-switch",q),customElements.define("rb-select",G))}export{H as a,V as b,J as c,K as d,X as e,Z as f,q as g,G as h,De as i,Oe as j};
1
+ import{b as v,c as P,d as Q,e as ee}from"./chunk-37HVFFJB.js";var M=class extends CustomEvent{respondWith(t){this.response=t}};var g=new WeakMap;var B=new WeakMap,ce=0;function y(e){let t=B.get(e);return t==null&&(t=String(ce++),k(e,t)),t}function k(e,t){B.set(e,t)}var L=new WeakMap;function S(e){return L.get(e)}var I=new WeakMap;function ae(e){let t=I.get(e);if(t!=null)return t;if(!(!(e instanceof Element)||e.tagName.includes("-"))){t={};for(let{name:r,value:n}of e.attributes)t[r]=n;return t}}var z=new WeakMap;function Y(e){return z.get(e)}function _(e,t,r){let n=L.get(e);if(n==null&&(n={},L.set(e,n)),n[t]===r)return;n[t]=r;let o=g.get(e);o?.mutate([[3,y(e),t,r,1]])}function A(e,t,r){let n=I.get(e);if(n==null&&(n={},I.set(e,n)),n[t]===r)return;r==null?delete n[t]:n[t]=String(r);let o=g.get(e);o?.mutate([[3,y(e),t,r,2]])}function j(e,t,r){let n=z.get(e);if(n==null&&(n={},z.set(e,n)),n[t]===r)return;r==null?delete n[t]:n[t]=r;let o=g.get(e);o?.mutate([[3,y(e),t,r,3]])}function D(e,t){if(g.get(e)!==t&&(g.set(e,t),e.childNodes))for(let n=0;n<e.childNodes.length;n++)D(e.childNodes[n],t)}function O(e){if(g.get(e)!=null&&(g.delete(e),e.childNodes))for(let r=0;r<e.childNodes.length;r++)O(e.childNodes[r])}function T(e){let{nodeType:t}=e;switch(t){case 1:return{id:y(e),type:t,element:e.localName,properties:w(S(e)),attributes:w(ae(e)),eventListeners:w(Y(e)),children:Array.from(e.childNodes).map(T)};case 3:case 8:return{id:y(e),type:t,data:e.data};default:throw new Error(`Cannot serialize node of type ${e.nodeType} (${typeof e.nodeType})`)}}function w(e){return e?{...e}:void 0}function te(e,t,...r){let n=B.get(e),o=g.get(e);if(n==null||o==null)throw new Error(`Cannot call method ${t} on an unconnected node`);return o.call(n,t,...r)}var U=Object.freeze({});var p=class extends HTMLElement{static get observedAttributes(){return this.finalize().__observedAttributes}static get remotePropertyDefinitions(){return this.finalize().__remotePropertyDefinitions}static get remoteAttributeDefinitions(){return this.finalize().__remoteAttributeDefinitions}static get remoteEventDefinitions(){return this.finalize().__remoteEventDefinitions}static get remoteSlotDefinitions(){return this.finalize().__remoteSlotDefinitions}static createProperty(t,r){F(t,r,this.observedAttributes,this.remotePropertyDefinitions,this.__attributeToPropertyMap,this.__eventToPropertyMap)}static finalize(){if(this.hasOwnProperty("__finalized"))return this;this.__finalized=!0;let{slottable:t,remoteSlots:r,remoteProperties:n,remoteAttributes:o,remoteEvents:i,remoteMethods:s}=this,c=Object.getPrototypeOf(this),a=new Set;t&&a.add("slot");let u=new Map,d=new Map,f=new Map,h=new Map,b=new Map,E=new Map;if(typeof c.finalize=="function"&&(c.finalize(),c.observedAttributes.forEach(l=>{a.add(l)}),c.remotePropertyDefinitions.forEach((l,m)=>{h.set(m,l)}),c.remoteAttributeDefinitions.forEach((l,m)=>{b.set(m,l)}),c.remoteEventDefinitions.forEach((l,m)=>{E.set(m,l)}),c.remoteSlotDefinitions.forEach((l,m)=>{f.set(m,l)})),r!=null&&(Array.isArray(r)?r:Object.keys(r)).forEach(m=>{f.set(m,U)}),n!=null&&(Array.isArray(n)?n.forEach(l=>{F(l,void 0,a,h,u,d)}):Object.keys(n).forEach(l=>{F(l,n[l],a,h,u,d)})),o?.forEach(l=>{b.set(l,U),a.add(l)}),i!=null&&(Array.isArray(i)?i.forEach(l=>{E.set(l,U)}):Object.keys(i).forEach(l=>{E.set(l,i[l])})),s!=null)if(Array.isArray(s))for(let l of s)this.prototype[l]=function(...m){return this.callRemoteMethod(l,...m)};else Object.assign(this,s);return Object.defineProperties(this,{__observedAttributes:{value:[...a],enumerable:!1},__remoteSlotDefinitions:{value:f,enumerable:!1},__remotePropertyDefinitions:{value:h,enumerable:!1},__remoteAttributeDefinitions:{value:b,enumerable:!1},__remoteEventDefinitions:{value:E,enumerable:!1},__attributeToPropertyMap:{value:u,enumerable:!1},__eventToPropertyMap:{value:d,enumerable:!1}}),this}constructor(){super(),this.constructor.finalize();let t={},r={},n=Object.getPrototypeOf(this),o=this.constructor;for(let[i,s]of o.remotePropertyDefinitions.entries()){let c=s.name;if(n.hasOwnProperty(i))continue;i===c&&(r[i]=s.default);let a={configurable:!0,enumerable:i===c,get:()=>S(this)?.[c],set:u=>{_(this,c,u)}};t[i]=a}for(let[i,s]of o.remoteEventDefinitions.entries()){let c=s.property??!0;if(!c)continue;let a=c===!0?`on${i}`:c;t[a]={configurable:!0,enumerable:!0,get:()=>N(this).properties.get(a)??null,set:u=>{let d=N(this),f=d.properties.get(a);if(typeof u=="function"){let h=function(...b){return u.call(this,...b)};d.properties.set(a,h),this.addEventListener(i,h)}else d.properties.delete(a);f&&this.removeEventListener(i,f)}}}Object.defineProperties(this,t),Object.assign(this,r)}attributeChangedCallback(t,r,n){if(t==="slot"&&this.constructor.slottable){A(this,t,n?String(n):void 0);return}let{remotePropertyDefinitions:o,remoteAttributeDefinitions:i,__attributeToPropertyMap:s}=this.constructor;if(i.has(t)){A(this,t,n);return}let c=s.get(t),a=c==null?c:o.get(c);a!=null&&(this[c]=ue(n,a.type))}connectedCallback(){for(let[t,r]of this.constructor.remoteEventDefinitions.entries())r.bubbles&&this.addEventListener(t,ne)}disconnectedCallback(){for(let[t,r]of this.constructor.remoteEventDefinitions.entries())r.bubbles&&this.removeEventListener(t,ne)}addEventListener(t,r,n){let{remoteEventDefinitions:o,__eventToPropertyMap:i}=this.constructor,s=o.get(t),c=i.get(t);if(s==null&&c==null)return super.addEventListener(t,r,n);let a=N(this),u=le.call(this,t,{property:c,definition:s}),d=typeof n=="object"&&n?.once?(...h)=>{let b=typeof r=="object"?r.handleEvent(...h):r.call(this,...h);return W.call(this,t,r,f),b}:r,f=[d,u];u.listeners.add(r),a.listeners.set(r,f),super.addEventListener(t,d,n),typeof n=="object"&&n.signal&&n.signal.addEventListener("abort",()=>{W.call(this,t,r,f)},{once:!0}),s?j(this,t,u.dispatch):_(this,c,u.dispatch)}removeEventListener(t,r,n){let o=$.get(this)?.listeners.get(r),i=o?o[0]:r;super.removeEventListener(t,i,n),o!=null&&W.call(this,t,r,o)}updateRemoteProperty(t,r){_(this,t,r)}updateRemoteAttribute(t,r){A(this,t,r)}callRemoteMethod(t,...r){return te(this,t,...r)}};v(p,"slottable",!0),v(p,"__finalized",!0),v(p,"__observedAttributes",[]),v(p,"__attributeToPropertyMap",new Map),v(p,"__eventToPropertyMap",new Map),v(p,"__remotePropertyDefinitions",new Map),v(p,"__remoteAttributeDefinitions",new Map),v(p,"__remoteEventDefinitions",new Map),v(p,"__remoteSlotDefinitions",new Map);var $=new WeakMap;function N(e){let t=$.get(e);return t||(t={events:new Map,properties:new Map,listeners:new WeakMap},$.set(e,t),t)}function le(e,{property:t,definition:r}){let n=N(this),o=n.events.get(e);return o==null&&(o={name:e,property:t,definition:r,listeners:new Set,dispatch:(...i)=>{let s=r?.dispatchEvent?.apply(this,i)??new M(e,{detail:i[0],bubbles:r?.bubbles});return this.dispatchEvent(s),s.response}},n.events.set(e,o)),o}function W(e,t,r){let n=N(this),o=r[1];o.listeners.delete(t),n.listeners.delete(t),!(o.listeners.size>0)&&(n.events.delete(e),o.property?S(this)?.[o.property]===o.dispatch&&_(this,o.property,void 0):Y(this)?.[e]===o.dispatch&&j(this,e,void 0))}function F(e,t,r,n,o,i){if(n.has(e))return n.get(e);let s=e[0]==="o"&&e[1]==="n",c=t??{},{alias:a}=c,{type:u=s?Function:String,attribute:d=u!==Function,event:f=s,default:h=u===Boolean?!1:void 0}=c;if(a==null){let m=e.toLowerCase();m!==e&&(a=[m]),s&&(a??(a=[]),a.unshift(`_${e}`))}let b;d===!0?b=re(e):typeof d=="string"&&(b=d),b&&(Array.isArray(r)?r.push(b):r.add(b),o.set(b,e));let E;f===!0?E=re(s?e.slice(2):e):typeof f=="string"&&(E=f),E&&i.set(E,e);let l={name:e,type:u,alias:a,event:E,attribute:b,default:h};if(n.set(e,l),a)for(let m of a)n.set(m,l);return l}function ue(e,t){if(e!=null)switch(t){case Boolean:return e!=null&&e!=="false";case Object:case Array:try{return JSON.parse(e)}catch{return}case String:return String(e);case Number:return Number.parseFloat(e);case Function:return;default:return t.parse?.(e)}}function re(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function ne(){}var R,H=class extends MutationObserver{constructor(r){super(n=>{let o=[],i=[];for(let s of n){let c=y(s.target);if(s.type==="childList"){let a=s.previousSibling?pe(s.previousSibling,s.target.childNodes)+1:0;s.removedNodes.forEach(u=>{O(u),i.push([1,c,a])}),s.addedNodes.forEach((u,d)=>{o.some(f=>f===u||f.contains(u))||(o.push(u),D(u,r),i.push([0,c,T(u),a+d]))})}else s.type==="characterData"?i.push([2,c,s.target.textContent??""]):s.type==="attributes"&&s.attributeName!=null&&s.target instanceof Element&&!s.target.tagName.includes("-")&&i.push([3,c,s.attributeName,s.target.getAttribute(s.attributeName)])}r.mutate(i)});Q(this,R);this.connection=r,ee(this,R,new Set)}observe(r,n){let o=n?.id??"~";if(k(r,o),P(this,R).add(r),n?.initial!==!1&&r.childNodes.length>0){if(o!=="~")this.connection.mutate([[0,"~",T(r),P(this,R).size-1]]);else if(r.childNodes.length>0){let i=[];for(let s=0;s<r.childNodes.length;s++){let c=r.childNodes[s];D(c,this.connection),i.push([0,"~",T(c),s])}this.connection.mutate(i)}}super.observe(r,{subtree:!0,childList:!0,attributes:!0,characterData:!0,...n})}disconnect({empty:r=!1}={}){if(r&&P(this,R).size>0){let n=[];for(let o of P(this,R)){O(o);let i=y(o);if(i==="~")for(let s=0;s<o.childNodes.length;s++)n.push([1,i,0]);else n.push([1,"~",0])}this.connection.mutate(n)}P(this,R).clear(),super.disconnect()}};R=new WeakMap;function pe(e,t){for(let r=0;r<t.length;r++)if(t[r]===e)return r;return-1}var V=class extends p{static get remoteProperties(){return{value:{type:Number},min:{type:Number},max:{type:Number},step:{type:Number},disabled:{type:Boolean}}}static get remoteEvents(){return["change"]}},J=class extends p{static get remoteProperties(){return{label:{type:String},variant:{type:String},size:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["press"]}},K=class extends p{static get remoteProperties(){return{icon:{type:String},variant:{type:String},size:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["press"]}},X=class extends p{static get remoteProperties(){return{}}},Z=class extends p{static get remoteProperties(){return{value:{type:String},placeholder:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["input"]}},q=class extends p{static get remoteProperties(){return{checked:{type:Boolean},disabled:{type:Boolean}}}static get remoteEvents(){return["change"]}},G=class extends p{static get remoteProperties(){return{value:{type:String},options:{type:Array},placeholder:{type:String},disabled:{type:Boolean}}}static get remoteEvents(){return["change"]}},De=["rb-slider","rb-button","rb-icon-button","rb-text","rb-text-input","rb-switch","rb-select"],ie=!1;function Oe(){ie||typeof customElements>"u"||(ie=!0,customElements.define("rb-slider",V),customElements.define("rb-button",J),customElements.define("rb-icon-button",K),customElements.define("rb-text",X),customElements.define("rb-text-input",Z),customElements.define("rb-switch",q),customElements.define("rb-select",G))}export{H as a,V as b,J as c,K as d,X as e,Z as f,q as g,G as h,De as i,Oe as j};
@@ -0,0 +1 @@
1
+ import{createContext as e,useContext as a}from"react";var t={pub:async(o,n)=>{console.warn("[plugin-ui] rb.pub called outside of a host context")},sub:async(o,n)=>(console.warn("[plugin-ui] rb.sub called outside of a host context"),{undeclare:async()=>{}}),action:async(o,n)=>{console.warn("[plugin-ui] rb.action called outside of a host context")},serve:async(o,n)=>(console.warn("[plugin-ui] rb.serve called outside of a host context"),{undeclare:async()=>{}}),toast:o=>{console.warn("[plugin-ui] rb.toast (no host):",o)}},r=e(t);function i(){return a(r)}export{r as a,i as b};
@@ -1 +1 @@
1
- import{a as v}from"./chunks/chunk-GJWPOWHG.js";import{a as Q,j as X}from"./chunks/chunk-JRCDA3EG.js";import{a as I,b as c,c as p,d as L,e as m}from"./chunks/chunk-AMCIKVG7.js";var W=Symbol.for("quilt.threads.serialize"),tt=Symbol.for("quilt.threads.transferable");var z=class extends AbortController{constructor(...t){super();let e=t.find(r=>r.aborted);if(e)this.abort(e.reason);else{let r=n=>this.abort(n.target.reason),o={signal:this.signal};for(let n of t)n.addEventListener("abort",r,o)}}};var C=class extends Error{constructor(){super("You attempted to call a function on a closed thread.")}};var at="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";function N(a=21){let t="",e=crypto.getRandomValues(new Uint8Array(a));for(let r=0;r<a;r++)t+=at[63&e[r]];return t}var A,y,x,O,_,et,F=class{constructor(){p(this,_);p(this,A,new Map);p(this,y,new Map);p(this,x,new Map);p(this,O,new WeakMap)}get(t){return c(this,y).get(t)}release(t){let e=c(this,y).get(t);return e&&(c(this,y).delete(t),c(this,A).delete(e)),!!e}serialize(t){let e=c(this,A).get(t);return e==null&&(e=N(),c(this,A).set(t,e),c(this,y).set(e,t)),e}deserialize(t,e){let r=c(this,x).get(t)?.deref();return r||(r=(...o)=>{if(!c(this,x).has(t))throw new Error("You attempted to call a function that was already revoked.");return e.call((n,s,l)=>{e.messages.send([3,n,t,s],l)},o)},m(this,_,et).call(this,e)?.register(r,t),c(this,x).set(t,new WeakRef(r)),r)}};A=new WeakMap,y=new WeakMap,x=new WeakMap,O=new WeakMap,_=new WeakSet,et=function(t){let e=c(this,O).get(t);if(!(typeof FinalizationRegistry>"u"))return e||(e=new FinalizationRegistry(r=>{t.messages.send([5,r])}),c(this,O).set(t,e)),e};function rt(a){return a!=null&&(Symbol.asyncIterator in a||Symbol.iterator in a)&&typeof a.next=="function"}function Y(a){if(a==null||typeof a!="object")return!1;let t=Object.getPrototypeOf(a);return t==null||t===Object.prototype}var V="_@f",ot="_@i",T,M,h,k,w,U=class{constructor(t){p(this,h);p(this,T);p(this,M);L(this,T,t?.serialize),L(this,M,t?.deserialize)}serialize(t,e,r){return m(this,h,k).call(this,t,e,r)}deserialize(t,e){return m(this,h,w).call(this,t,e)}};T=new WeakMap,M=new WeakMap,h=new WeakSet,k=function(t,e,r,o=new Map,n=!1){if(t==null)return t;if(o.has(t))return o.get(t);if(o.set(t,void 0),typeof t=="object"){if(c(this,T)&&!n){let i=c(this,T).call(this,t,f=>m(this,h,k).call(this,f,e,r,o,!0),e,r);if(i!==void 0)return o.set(t,i),i}if(t[tt])return r?.push(t),o.set(t,t),t;let s=i=>m(this,h,k).call(this,i,e,r,o);if(typeof t[W]=="function"){let i=t[W]({serialize:s});return o.set(t,i),i}if(Array.isArray(t)){let i=t.map(f=>s(f));return o.set(t,i),i}if(t instanceof Map){let i=[...t.entries()].map(([E,g])=>[s(E),s(g)]),f=new Map(i);return o.set(t,f),f}if(t instanceof Set){let i=[...t].map(E=>s(E)),f=new Set(i);return o.set(t,f),f}let l=rt(t);if(Y(t)||l){let i={};for(let f of Object.keys(t))i[f]=s(t[f]);return l&&(i.next??(i.next=s(t.next.bind(t))),i.return??(i.return=s(t.return.bind(t))),i.throw??(i.throw=s(t.throw.bind(t))),i[ot]=!0),o.set(t,i),i}}if(typeof t=="function"){let s=e.functions.serialize(t,e,r),l={[V]:s};return o.set(t,l),l}return o.set(t,t),t},w=function(t,e,r=!1){if(t==null)return t;if(typeof t=="object"){if(c(this,M)&&!r){let n=c(this,M).call(this,t,s=>m(this,h,w).call(this,s,e,!0),e);if(n!==void 0)return n}if(t==null)return t;if(Array.isArray(t))return t.map(n=>m(this,h,w).call(this,n,e));if(t instanceof Map)return new Map([...t].map(([n,s])=>[m(this,h,w).call(this,n,e),m(this,h,w).call(this,s,e)]));if(t instanceof Set)return new Set([...t].map(n=>m(this,h,w).call(this,n,e)));if(V in t)return e.functions.deserialize(t[V],e);if(!Y(t))return t;let o={};for(let n of Object.keys(t))n===ot?o[Symbol.asyncIterator]=()=>o:o[n]=m(this,h,w).call(this,t[n],e);return o}return t};var b,S,u,Z,nt,q,it,j=class{constructor(t,{imports:e,exports:r,functions:o=new F,serialization:n=new U,signal:s}={}){p(this,u);p(this,b);p(this,S,new Map);this.messages=t,L(this,b,s?new z(s):new AbortController),this.exports=r??{},this.imports=pt(m(this,u,nt).bind(this),e),this.functions=o,this.serialization=n,this.functions.start?.(this),this.serialization.start?.(this),this.signal.addEventListener("abort",()=>{for(let l of c(this,S).keys())m(this,u,q).call(this,l,void 0,new C);c(this,S).clear()},{once:!0}),t.listen(async l=>{if(!(Array.isArray(l)&&typeof l[0]=="number"))return;let f=l;switch(f[0]){case 1:{let[,E,g,P]=f,G=this.exports[g]??(()=>{throw new Error(`No '${g}' method is exported from this thread`)});await m(this,u,Z).call(this,G,P,(D,B,H)=>{this.messages.send([2,E,D,B],H)});break}case 3:{let[,E,g,P]=f,G=this.functions.get(g,this)??ht;await m(this,u,Z).call(this,G,P,(D,B,H)=>{this.messages.send([4,E,D,B],H)});break}case 2:case 4:{m(this,u,q).call(this,...f.slice(1));break}case 5:{let E=f[1];this.functions.release(E,this);break}}},{signal:this.signal})}get signal(){return c(this,b).signal}get closed(){return c(this,b).signal.aborted}close(){c(this,b).abort()}call(t,e){if(this.closed)return Promise.reject(new C);let r=[],o=this.serialization.serialize(e,this,r),n=N(),s=m(this,u,it).call(this,n);return t(n,o,r),s}};b=new WeakMap,S=new WeakMap,u=new WeakSet,Z=async function(t,e,r){try{let o=this.functions.call?await this.functions.call(t,e,this):await t(...this.serialization.deserialize(e,this)),n=[],s=this.serialization.serialize(o,this,n);r(s,void 0,n)}catch(o){r(void 0,this.serialization.serialize(o,this))}},nt=function(t){return(...e)=>{try{if(typeof t!="string"&&typeof t!="number")throw new Error(`Can\u2019t call a symbol method on a thread: ${t.toString()}`);return this.call((r,o,n)=>{this.messages.send([1,r,t,o],n)},e)}catch(r){return Promise.reject(r)}}},q=function(...t){let e=t[0],r=c(this,S).get(e);r&&(r(...t),c(this,S).delete(e))},it=function(t){let e=new Promise((r,o)=>{c(this,S).set(t,(n,s,l)=>{l==null?r(this.serialization.deserialize(s,this)):o(this.serialization.deserialize(l,this))})});return Object.defineProperty(e,Symbol.asyncIterator,{async*value(){let r=await e;Object.defineProperty(r,Symbol.asyncIterator,{value:()=>r}),yield*r}}),e};function pt(a,t){let e;if(t==null){if(typeof Proxy!="function")throw new Error("You must pass an array of callable methods in environments without Proxies.");let r=new Map;e=new Proxy({},{get(o,n){if(r.has(n))return r.get(n);let s=a(n);return r.set(n,s),s}})}else{e={};for(let r of t)Object.defineProperty(e,r,{value:a(r),writable:!1,configurable:!0,enumerable:!0})}return e}function ht(){throw new Error("You attempted to call a function that is not stored. It may have already been released.")}var d=class d extends j{static from(t,e){return new d(t,e)}static import(t,e){return new d(t,e).imports}static export(t,e,r){new d(t,{...r,exports:e})}constructor(t,{targetOrigin:e="*",...r}={}){super(ut(t,{targetOrigin:e}),r),this.window=t}};I(d,"iframe",Object.assign((t,e)=>d.from(K(t),e),{import:(t,e)=>d.import(K(t),e),export:(t,e,r)=>d.export(K(t),e,r)})),I(d,"parent",Object.assign(t=>d.from($(),t),{import:t=>d.import($(),t),export:(t,e)=>d.export($(),t,e)})),I(d,"opener",Object.assign(t=>d.from(J(),t),{import:t=>d.import(J(),t),export:(t,e)=>d.export(J(),t,e)}));var R=d;function J(){if(typeof window>"u"||window.opener==null)throw new Error("No opener window found");return window.opener}function $(){if(typeof window>"u"||window.parent==null||window.parent===window)throw new Error("No parent window found");return window.parent}function K(a){if(a.contentWindow==null)throw new Error("No content window found");return a.contentWindow}function ut(a,{targetOrigin:t="*"}={}){let e=function(o,n){a.postMessage(o,t,n)};return{send(r,o){return e(r,o)},listen(r,{signal:o}){self.addEventListener("message",n=>{n.source===a&&r(n.data)},{signal:o})}}}import{createElement as st}from"react";import{createRoot as Et}from"react-dom/client";function $t(a){X(),R.parent.import({targetOrigin:"*"}).connect().then(({connection:e,action:r,notify:o})=>{let n={action:(i,f)=>Promise.resolve(r(i,f)),notify:(i,f)=>o(i,f)},s=document.createElement("remote-root");document.body.append(s),new Q(e).observe(s),Et(s).render(st(v.Provider,{value:n},st(a)))})}export{$t as connect};
1
+ import{a as Xt}from"./chunks/chunk-Q6XGCIPE.js";import{a as jt,j as Jt}from"./chunks/chunk-4MGSRUAS.js";import{a as Pe,b as T,c as l,d as _,e as Y,f as m}from"./chunks/chunk-37HVFFJB.js";var At=Symbol.for("quilt.threads.serialize"),$t=Symbol.for("quilt.threads.transferable");var G=class extends AbortController{constructor(...t){super();let e=t.find(r=>r.aborted);if(e)this.abort(e.reason);else{let r=i=>this.abort(i.target.reason),n={signal:this.signal};for(let i of t)i.addEventListener("abort",r,n)}}};var j=class extends Error{constructor(){super("You attempted to call a function on a closed thread.")}};var Ie="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";function at(s=21){let t="",e=crypto.getRandomValues(new Uint8Array(s));for(let r=0;r<s;r++)t+=Ie[63&e[r]];return t}var F,B,q,J,ht,Qt,ct=class{constructor(){_(this,ht);_(this,F,new Map);_(this,B,new Map);_(this,q,new Map);_(this,J,new WeakMap)}get(t){return l(this,B).get(t)}release(t){let e=l(this,B).get(t);return e&&(l(this,B).delete(t),l(this,F).delete(e)),!!e}serialize(t){let e=l(this,F).get(t);return e==null&&(e=at(),l(this,F).set(t,e),l(this,B).set(e,t)),e}deserialize(t,e){let r=l(this,q).get(t)?.deref();return r||(r=(...n)=>{if(!l(this,q).has(t))throw new Error("You attempted to call a function that was already revoked.");return e.call((i,o,c)=>{e.messages.send([3,i,t,o],c)},n)},m(this,ht,Qt).call(this,e)?.register(r,t),l(this,q).set(t,new WeakRef(r)),r)}};F=new WeakMap,B=new WeakMap,q=new WeakMap,J=new WeakMap,ht=new WeakSet,Qt=function(t){let e=l(this,J).get(t);if(!(typeof FinalizationRegistry>"u"))return e||(e=new FinalizationRegistry(r=>{t.messages.send([5,r])}),l(this,J).set(t,e)),e};function Zt(s){return s!=null&&(Symbol.asyncIterator in s||Symbol.iterator in s)&&typeof s.next=="function"}function Rt(s){if(s==null||typeof s!="object")return!1;let t=Object.getPrototypeOf(s);return t==null||t===Object.prototype}var vt="_@f",te="_@i",U,D,b,ft,v,ut=class{constructor(t){_(this,b);_(this,U);_(this,D);Y(this,U,t?.serialize),Y(this,D,t?.deserialize)}serialize(t,e,r){return m(this,b,ft).call(this,t,e,r)}deserialize(t,e){return m(this,b,v).call(this,t,e)}};U=new WeakMap,D=new WeakMap,b=new WeakSet,ft=function(t,e,r,n=new Map,i=!1){if(t==null)return t;if(n.has(t))return n.get(t);if(n.set(t,void 0),typeof t=="object"){if(l(this,U)&&!i){let a=l(this,U).call(this,t,u=>m(this,b,ft).call(this,u,e,r,n,!0),e,r);if(a!==void 0)return n.set(t,a),a}if(t[$t])return r?.push(t),n.set(t,t),t;let o=a=>m(this,b,ft).call(this,a,e,r,n);if(typeof t[At]=="function"){let a=t[At]({serialize:o});return n.set(t,a),a}if(Array.isArray(t)){let a=t.map(u=>o(u));return n.set(t,a),a}if(t instanceof Map){let a=[...t.entries()].map(([f,d])=>[o(f),o(d)]),u=new Map(a);return n.set(t,u),u}if(t instanceof Set){let a=[...t].map(f=>o(f)),u=new Set(a);return n.set(t,u),u}let c=Zt(t);if(Rt(t)||c){let a={};for(let u of Object.keys(t))a[u]=o(t[u]);return c&&(a.next??(a.next=o(t.next.bind(t))),a.return??(a.return=o(t.return.bind(t))),a.throw??(a.throw=o(t.throw.bind(t))),a[te]=!0),n.set(t,a),a}}if(typeof t=="function"){let o=e.functions.serialize(t,e,r),c={[vt]:o};return n.set(t,c),c}return n.set(t,t),t},v=function(t,e,r=!1){if(t==null)return t;if(typeof t=="object"){if(l(this,D)&&!r){let i=l(this,D).call(this,t,o=>m(this,b,v).call(this,o,e,!0),e);if(i!==void 0)return i}if(t==null)return t;if(Array.isArray(t))return t.map(i=>m(this,b,v).call(this,i,e));if(t instanceof Map)return new Map([...t].map(([i,o])=>[m(this,b,v).call(this,i,e),m(this,b,v).call(this,o,e)]));if(t instanceof Set)return new Set([...t].map(i=>m(this,b,v).call(this,i,e)));if(vt in t)return e.functions.deserialize(t[vt],e);if(!Rt(t))return t;let n={};for(let i of Object.keys(t))i===te?n[Symbol.asyncIterator]=()=>n:n[i]=m(this,b,v).call(this,t[i],e);return n}return t};var P,C,E,Ct,ee,Ot,re,lt=class{constructor(t,{imports:e,exports:r,functions:n=new ct,serialization:i=new ut,signal:o}={}){_(this,E);_(this,P);_(this,C,new Map);this.messages=t,Y(this,P,o?new G(o):new AbortController),this.exports=r??{},this.imports=ze(m(this,E,ee).bind(this),e),this.functions=n,this.serialization=i,this.functions.start?.(this),this.serialization.start?.(this),this.signal.addEventListener("abort",()=>{for(let c of l(this,C).keys())m(this,E,Ot).call(this,c,void 0,new j);l(this,C).clear()},{once:!0}),t.listen(async c=>{if(!(Array.isArray(c)&&typeof c[0]=="number"))return;let u=c;switch(u[0]){case 1:{let[,f,d,k]=u,xt=this.exports[d]??(()=>{throw new Error(`No '${d}' method is exported from this thread`)});await m(this,E,Ct).call(this,xt,k,(kt,Tt,St)=>{this.messages.send([2,f,kt,Tt],St)});break}case 3:{let[,f,d,k]=u,xt=this.functions.get(d,this)??He;await m(this,E,Ct).call(this,xt,k,(kt,Tt,St)=>{this.messages.send([4,f,kt,Tt],St)});break}case 2:case 4:{m(this,E,Ot).call(this,...u.slice(1));break}case 5:{let f=u[1];this.functions.release(f,this);break}}},{signal:this.signal})}get signal(){return l(this,P).signal}get closed(){return l(this,P).signal.aborted}close(){l(this,P).abort()}call(t,e){if(this.closed)return Promise.reject(new j);let r=[],n=this.serialization.serialize(e,this,r),i=at(),o=m(this,E,re).call(this,i);return t(i,n,r),o}};P=new WeakMap,C=new WeakMap,E=new WeakSet,Ct=async function(t,e,r){try{let n=this.functions.call?await this.functions.call(t,e,this):await t(...this.serialization.deserialize(e,this)),i=[],o=this.serialization.serialize(n,this,i);r(o,void 0,i)}catch(n){r(void 0,this.serialization.serialize(n,this))}},ee=function(t){return(...e)=>{try{if(typeof t!="string"&&typeof t!="number")throw new Error(`Can\u2019t call a symbol method on a thread: ${t.toString()}`);return this.call((r,n,i)=>{this.messages.send([1,r,t,n],i)},e)}catch(r){return Promise.reject(r)}}},Ot=function(...t){let e=t[0],r=l(this,C).get(e);r&&(r(...t),l(this,C).delete(e))},re=function(t){let e=new Promise((r,n)=>{l(this,C).set(t,(i,o,c)=>{c==null?r(this.serialization.deserialize(o,this)):n(this.serialization.deserialize(c,this))})});return Object.defineProperty(e,Symbol.asyncIterator,{async*value(){let r=await e;Object.defineProperty(r,Symbol.asyncIterator,{value:()=>r}),yield*r}}),e};function ze(s,t){let e;if(t==null){if(typeof Proxy!="function")throw new Error("You must pass an array of callable methods in environments without Proxies.");let r=new Map;e=new Proxy({},{get(n,i){if(r.has(i))return r.get(i);let o=s(i);return r.set(i,o),o}})}else{e={};for(let r of t)Object.defineProperty(e,r,{value:s(r),writable:!1,configurable:!0,enumerable:!0})}return e}function He(){throw new Error("You attempted to call a function that is not stored. It may have already been released.")}var y=class y extends lt{static from(t,e){return new y(t,e)}static import(t,e){return new y(t,e).imports}static export(t,e,r){new y(t,{...r,exports:e})}constructor(t,{targetOrigin:e="*",...r}={}){super(Ve(t,{targetOrigin:e}),r),this.window=t}};T(y,"iframe",Object.assign((t,e)=>y.from(Bt(t),e),{import:(t,e)=>y.import(Bt(t),e),export:(t,e,r)=>y.export(Bt(t),e,r)})),T(y,"parent",Object.assign(t=>y.from(Lt(),t),{import:t=>y.import(Lt(),t),export:(t,e)=>y.export(Lt(),t,e)})),T(y,"opener",Object.assign(t=>y.from(Nt(),t),{import:t=>y.import(Nt(),t),export:(t,e)=>y.export(Nt(),t,e)}));var X=y;function Nt(){if(typeof window>"u"||window.opener==null)throw new Error("No opener window found");return window.opener}function Lt(){if(typeof window>"u"||window.parent==null||window.parent===window)throw new Error("No parent window found");return window.parent}function Bt(s){if(s.contentWindow==null)throw new Error("No content window found");return s.contentWindow}function Ve(s,{targetOrigin:t="*"}={}){let e=function(n,i){s.postMessage(n,t,i)};return{send(r,n){return e(r,n)},listen(r,{signal:n}){self.addEventListener("message",i=>{i.source===s&&r(i.data)},{signal:n})}}}import{createElement as Be}from"react";import{createRoot as dr}from"react-dom/client";var x=Object.create(null);x.open="0";x.close="1";x.ping="2";x.pong="3";x.message="4";x.upgrade="5";x.noop="6";var $=Object.create(null);Object.keys(x).forEach(s=>{$[x[s]]=s});var Q={type:"error",data:"parser error"};var ie=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",oe=typeof ArrayBuffer=="function",ae=s=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(s):s&&s.buffer instanceof ArrayBuffer,Z=({type:s,data:t},e,r)=>ie&&t instanceof Blob?e?r(t):se(t,r):oe&&(t instanceof ArrayBuffer||ae(t))?e?r(t):se(new Blob([t]),r):r(x[s]+(t||"")),se=(s,t)=>{let e=new FileReader;return e.onload=function(){let r=e.result.split(",")[1];t("b"+(r||""))},e.readAsDataURL(s)};function ne(s){return s instanceof Uint8Array?s:s instanceof ArrayBuffer?new Uint8Array(s):new Uint8Array(s.buffer,s.byteOffset,s.byteLength)}var Pt;function ce(s,t){if(ie&&s.data instanceof Blob)return s.data.arrayBuffer().then(ne).then(t);if(oe&&(s.data instanceof ArrayBuffer||ae(s.data)))return t(ne(s.data));Z(s,!1,e=>{Pt||(Pt=new TextEncoder),t(Pt.encode(e))})}var he="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",tt=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let s=0;s<he.length;s++)tt[he.charCodeAt(s)]=s;var fe=s=>{let t=s.length*.75,e=s.length,r,n=0,i,o,c,a;s[s.length-1]==="="&&(t--,s[s.length-2]==="="&&t--);let u=new ArrayBuffer(t),f=new Uint8Array(u);for(r=0;r<e;r+=4)i=tt[s.charCodeAt(r)],o=tt[s.charCodeAt(r+1)],c=tt[s.charCodeAt(r+2)],a=tt[s.charCodeAt(r+3)],f[n++]=i<<2|o>>4,f[n++]=(o&15)<<4|c>>2,f[n++]=(c&3)<<6|a&63;return u};var We=typeof ArrayBuffer=="function",et=(s,t)=>{if(typeof s!="string")return{type:"message",data:ue(s,t)};let e=s.charAt(0);return e==="b"?{type:"message",data:Ke(s.substring(1),t)}:$[e]?s.length>1?{type:$[e],data:s.substring(1)}:{type:$[e]}:Q},Ke=(s,t)=>{if(We){let e=fe(s);return ue(e,t)}else return{base64:!0,data:s}},ue=(s,t)=>{switch(t){case"blob":return s instanceof Blob?s:new Blob([s]);case"arraybuffer":default:return s instanceof ArrayBuffer?s:s.buffer}};var le="",pe=(s,t)=>{let e=s.length,r=new Array(e),n=0;s.forEach((i,o)=>{Z(i,!1,c=>{r[o]=c,++n===e&&t(r.join(le))})})},de=(s,t)=>{let e=s.split(le),r=[];for(let n=0;n<e.length;n++){let i=et(e[n],t);if(r.push(i),i.type==="error")break}return r};function me(){return new TransformStream({transform(s,t){ce(s,e=>{let r=e.length,n;if(r<126)n=new Uint8Array(1),new DataView(n.buffer).setUint8(0,r);else if(r<65536){n=new Uint8Array(3);let i=new DataView(n.buffer);i.setUint8(0,126),i.setUint16(1,r)}else{n=new Uint8Array(9);let i=new DataView(n.buffer);i.setUint8(0,127),i.setBigUint64(1,BigInt(r))}s.data&&typeof s.data!="string"&&(n[0]|=128),t.enqueue(n),t.enqueue(e)})}})}var It;function pt(s){return s.reduce((t,e)=>t+e.length,0)}function dt(s,t){if(s[0].length===t)return s.shift();let e=new Uint8Array(t),r=0;for(let n=0;n<t;n++)e[n]=s[0][r++],r===s[0].length&&(s.shift(),r=0);return s.length&&r<s[0].length&&(s[0]=s[0].slice(r)),e}function ye(s,t){It||(It=new TextDecoder);let e=[],r=0,n=-1,i=!1;return new TransformStream({transform(o,c){for(e.push(o);;){if(r===0){if(pt(e)<1)break;let a=dt(e,1);i=(a[0]&128)===128,n=a[0]&127,n<126?r=3:n===126?r=1:r=2}else if(r===1){if(pt(e)<2)break;let a=dt(e,2);n=new DataView(a.buffer,a.byteOffset,a.length).getUint16(0),r=3}else if(r===2){if(pt(e)<8)break;let a=dt(e,8),u=new DataView(a.buffer,a.byteOffset,a.length),f=u.getUint32(0);if(f>Math.pow(2,21)-1){c.enqueue(Q);break}n=f*Math.pow(2,32)+u.getUint32(4),r=3}else{if(pt(e)<n)break;let a=dt(e,n);c.enqueue(et(i?a:It.decode(a),t)),r=0}if(n===0||n>s){c.enqueue(Q);break}}}})}var Mt=4;function p(s){if(s)return Ye(s)}function Ye(s){for(var t in p.prototype)s[t]=p.prototype[t];return s}p.prototype.on=p.prototype.addEventListener=function(s,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+s]=this._callbacks["$"+s]||[]).push(t),this};p.prototype.once=function(s,t){function e(){this.off(s,e),t.apply(this,arguments)}return e.fn=t,this.on(s,e),this};p.prototype.off=p.prototype.removeListener=p.prototype.removeAllListeners=p.prototype.removeEventListener=function(s,t){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var e=this._callbacks["$"+s];if(!e)return this;if(arguments.length==1)return delete this._callbacks["$"+s],this;for(var r,n=0;n<e.length;n++)if(r=e[n],r===t||r.fn===t){e.splice(n,1);break}return e.length===0&&delete this._callbacks["$"+s],this};p.prototype.emit=function(s){this._callbacks=this._callbacks||{};for(var t=new Array(arguments.length-1),e=this._callbacks["$"+s],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(e){e=e.slice(0);for(var r=0,n=e.length;r<n;++r)e[r].apply(this,t)}return this};p.prototype.emitReserved=p.prototype.emit;p.prototype.listeners=function(s){return this._callbacks=this._callbacks||{},this._callbacks["$"+s]||[]};p.prototype.hasListeners=function(s){return!!this.listeners(s).length};var S=typeof Promise=="function"&&typeof Promise.resolve=="function"?t=>Promise.resolve().then(t):(t,e)=>e(t,0),g=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),ge="arraybuffer";function mt(s,...t){return t.reduce((e,r)=>(s.hasOwnProperty(r)&&(e[r]=s[r]),e),{})}var Ge=g.setTimeout,je=g.clearTimeout;function A(s,t){t.useNativeTimers?(s.setTimeoutFn=Ge.bind(g),s.clearTimeoutFn=je.bind(g)):(s.setTimeoutFn=g.setTimeout.bind(g),s.clearTimeoutFn=g.clearTimeout.bind(g))}var Je=1.33;function _e(s){return typeof s=="string"?Xe(s):Math.ceil((s.byteLength||s.size)*Je)}function Xe(s){let t=0,e=0;for(let r=0,n=s.length;r<n;r++)t=s.charCodeAt(r),t<128?e+=1:t<2048?e+=2:t<55296||t>=57344?e+=3:(r++,e+=4);return e}function yt(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function be(s){let t="";for(let e in s)s.hasOwnProperty(e)&&(t.length&&(t+="&"),t+=encodeURIComponent(e)+"="+encodeURIComponent(s[e]));return t}function we(s){let t={},e=s.split("&");for(let r=0,n=e.length;r<n;r++){let i=e[r].split("=");t[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return t}var gt=class extends Error{constructor(t,e,r){super(t),this.description=e,this.context=r,this.type="TransportError"}},R=class extends p{constructor(t){super(),this.writable=!1,A(this,t),this.opts=t,this.query=t.query,this.socket=t.socket,this.supportsBinary=!t.forceBase64}onError(t,e,r){return super.emitReserved("error",new gt(t,e,r)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(t){this.readyState==="open"&&this.write(t)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(t){let e=et(t,this.socket.binaryType);this.onPacket(e)}onPacket(t){super.emitReserved("packet",t)}onClose(t){this.readyState="closed",super.emitReserved("close",t)}pause(t){}createUri(t,e={}){return t+"://"+this._hostname()+this._port()+this.opts.path+this._query(e)}_hostname(){let t=this.opts.hostname;return t.indexOf(":")===-1?t:"["+t+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(t){let e=be(t);return e.length?"?"+e:""}};var rt=class extends R{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(t){this.readyState="pausing";let e=()=>{this.readyState="paused",t()};if(this._polling||!this.writable){let r=0;this._polling&&(r++,this.once("pollComplete",function(){--r||e()})),this.writable||(r++,this.once("drain",function(){--r||e()}))}else e()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(t){let e=r=>{if(this.readyState==="opening"&&r.type==="open"&&this.onOpen(),r.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(r)};de(t,this.socket.binaryType).forEach(e),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){let t=()=>{this.write([{type:"close"}])};this.readyState==="open"?t():this.once("open",t)}write(t){this.writable=!1,pe(t,e=>{this.doWrite(e,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){let t=this.opts.secure?"https":"http",e=this.query||{};return this.opts.timestampRequests!==!1&&(e[this.opts.timestampParam]=yt()),!this.supportsBinary&&!e.sid&&(e.b64=1),this.createUri(t,e)}};var Ee=!1;try{Ee=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}var xe=Ee;function $e(){}var Ft=class extends rt{constructor(t){if(super(t),typeof location<"u"){let e=location.protocol==="https:",r=location.port;r||(r=e?"443":"80"),this.xd=typeof location<"u"&&t.hostname!==location.hostname||r!==t.port}}doWrite(t,e){let r=this.request({method:"POST",data:t});r.on("success",e),r.on("error",(n,i)=>{this.onError("xhr post error",n,i)})}doPoll(){let t=this.request();t.on("data",this.onData.bind(this)),t.on("error",(e,r)=>{this.onError("xhr poll error",e,r)}),this.pollXhr=t}},O=class s extends p{constructor(t,e,r){super(),this.createRequest=t,A(this,r),this._opts=r,this._method=r.method||"GET",this._uri=e,this._data=r.data!==void 0?r.data:null,this._create()}_create(){var t;let e=mt(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this._opts.xd;let r=this._xhr=this.createRequest(e);try{r.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){r.setDisableHeaderCheck&&r.setDisableHeaderCheck(!0);for(let n in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(n)&&r.setRequestHeader(n,this._opts.extraHeaders[n])}}catch{}if(this._method==="POST")try{r.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{r.setRequestHeader("Accept","*/*")}catch{}(t=this._opts.cookieJar)===null||t===void 0||t.addCookies(r),"withCredentials"in r&&(r.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(r.timeout=this._opts.requestTimeout),r.onreadystatechange=()=>{var n;r.readyState===3&&((n=this._opts.cookieJar)===null||n===void 0||n.parseCookies(r.getResponseHeader("set-cookie"))),r.readyState===4&&(r.status===200||r.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof r.status=="number"?r.status:0)},0))},r.send(this._data)}catch(n){this.setTimeoutFn(()=>{this._onError(n)},0);return}typeof document<"u"&&(this._index=s.requestsCount++,s.requests[this._index]=this)}_onError(t){this.emitReserved("error",t,this._xhr),this._cleanup(!0)}_cleanup(t){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=$e,t)try{this._xhr.abort()}catch{}typeof document<"u"&&delete s.requests[this._index],this._xhr=null}}_onLoad(){let t=this._xhr.responseText;t!==null&&(this.emitReserved("data",t),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}};O.requestsCount=0;O.requests={};if(typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",ke);else if(typeof addEventListener=="function"){let s="onpagehide"in g?"pagehide":"unload";addEventListener(s,ke,!1)}}function ke(){for(let s in O.requests)O.requests.hasOwnProperty(s)&&O.requests[s].abort()}var Qe=(function(){let s=Te({xdomain:!1});return s&&s.responseType!==null})(),N=class extends Ft{constructor(t){super(t);let e=t&&t.forceBase64;this.supportsBinary=Qe&&!e}request(t={}){return Object.assign(t,{xd:this.xd},this.opts),new O(Te,this.uri(),t)}};function Te(s){let t=s.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!t||xe))return new XMLHttpRequest}catch{}if(!t)try{return new g[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}var Se=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative",Ut=class extends R{get name(){return"websocket"}doOpen(){let t=this.uri(),e=this.opts.protocols,r=Se?{}:mt(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(r.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,e,r)}catch(n){return this.emitReserved("error",n)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:"websocket connection closed",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError("websocket error",t)}write(t){this.writable=!1;for(let e=0;e<t.length;e++){let r=t[e],n=e===t.length-1;Z(r,this.supportsBinary,i=>{try{this.doWrite(r,i)}catch{}n&&S(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){let t=this.opts.secure?"wss":"ws",e=this.query||{};return this.opts.timestampRequests&&(e[this.opts.timestampParam]=yt()),this.supportsBinary||(e.b64=1),this.createUri(t,e)}},qt=g.WebSocket||g.MozWebSocket,L=class extends Ut{createSocket(t,e,r){return Se?new qt(t,e,r):e?new qt(t,e):new qt(t)}doWrite(t,e){this.ws.send(e)}};var z=class extends R{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(t){return this.emitReserved("error",t)}this._transport.closed.then(()=>{this.onClose()}).catch(t=>{this.onError("webtransport error",t)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(t=>{let e=ye(Number.MAX_SAFE_INTEGER,this.socket.binaryType),r=t.readable.pipeThrough(e).getReader(),n=me();n.readable.pipeTo(t.writable),this._writer=n.writable.getWriter();let i=()=>{r.read().then(({done:c,value:a})=>{c||(this.onPacket(a),i())}).catch(c=>{})};i();let o={type:"open"};this.query.sid&&(o.data=`{"sid":"${this.query.sid}"}`),this._writer.write(o).then(()=>this.onOpen())})})}write(t){this.writable=!1;for(let e=0;e<t.length;e++){let r=t[e],n=e===t.length-1;this._writer.write(r).then(()=>{n&&S(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var t;(t=this._transport)===null||t===void 0||t.close()}};var Dt={websocket:L,webtransport:z,polling:N};var Ze=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,tr=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function H(s){if(s.length>8e3)throw"URI too long";let t=s,e=s.indexOf("["),r=s.indexOf("]");e!=-1&&r!=-1&&(s=s.substring(0,e)+s.substring(e,r).replace(/:/g,";")+s.substring(r,s.length));let n=Ze.exec(s||""),i={},o=14;for(;o--;)i[tr[o]]=n[o]||"";return e!=-1&&r!=-1&&(i.source=t,i.host=i.host.substring(1,i.host.length-1).replace(/;/g,":"),i.authority=i.authority.replace("[","").replace("]","").replace(/;/g,":"),i.ipv6uri=!0),i.pathNames=er(i,i.path),i.queryKey=rr(i,i.query),i}function er(s,t){let e=/\/{2,9}/g,r=t.replace(e,"/").split("/");return(t.slice(0,1)=="/"||t.length===0)&&r.splice(0,1),t.slice(-1)=="/"&&r.splice(r.length-1,1),r}function rr(s,t){let e={};return t.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(r,n,i){n&&(e[n]=i)}),e}var zt=typeof addEventListener=="function"&&typeof removeEventListener=="function",_t=[];zt&&addEventListener("offline",()=>{_t.forEach(s=>s())},!1);var I=class s extends p{constructor(t,e){if(super(),this.binaryType=ge,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,t&&typeof t=="object"&&(e=t,t=null),t){let r=H(t);e.hostname=r.host,e.secure=r.protocol==="https"||r.protocol==="wss",e.port=r.port,r.query&&(e.query=r.query)}else e.host&&(e.hostname=H(e.host).host);A(this,e),this.secure=e.secure!=null?e.secure:typeof location<"u"&&location.protocol==="https:",e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.hostname=e.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=e.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},e.transports.forEach(r=>{let n=r.prototype.name;this.transports.push(n),this._transportsByName[n]=r}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},e),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=we(this.opts.query)),zt&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},_t.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(t){let e=Object.assign({},this.opts.query);e.EIO=Mt,e.transport=t,this.id&&(e.sid=this.id);let r=Object.assign({},this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[t]);return new this._transportsByName[t](r)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}let t=this.opts.rememberUpgrade&&s.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";let e=this.createTransport(t);e.open(),this.setTransport(e)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",e=>this._onClose("transport close",e))}onOpen(){this.readyState="open",s.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(t){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",t),this.emitReserved("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":let e=new Error("server error");e.code=t.data,this._onError(e);break;case"message":this.emitReserved("data",t.data),this.emitReserved("message",t.data);break}}onHandshake(t){this.emitReserved("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this._pingInterval=t.pingInterval,this._pingTimeout=t.pingTimeout,this._maxPayload=t.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);let t=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+t,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},t),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){let t=this._getWritablePackets();this.transport.send(t),this._prevBufferLen=t.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let e=1;for(let r=0;r<this.writeBuffer.length;r++){let n=this.writeBuffer[r].data;if(n&&(e+=_e(n)),r>0&&e>this._maxPayload)return this.writeBuffer.slice(0,r);e+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;let t=Date.now()>this._pingTimeoutTime;return t&&(this._pingTimeoutTime=0,S(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),t}write(t,e,r){return this._sendPacket("message",t,e,r),this}send(t,e,r){return this._sendPacket("message",t,e,r),this}_sendPacket(t,e,r,n){if(typeof e=="function"&&(n=e,e=void 0),typeof r=="function"&&(n=r,r=null),this.readyState==="closing"||this.readyState==="closed")return;r=r||{},r.compress=r.compress!==!1;let i={type:t,data:e,options:r};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),n&&this.once("flush",n),this.flush()}close(){let t=()=>{this._onClose("forced close"),this.transport.close()},e=()=>{this.off("upgrade",e),this.off("upgradeError",e),t()},r=()=>{this.once("upgrade",e),this.once("upgradeError",e)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?r():t()}):this.upgrading?r():t()),this}_onError(t){if(s.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",t),this._onClose("transport error",t)}_onClose(t,e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),zt&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){let r=_t.indexOf(this._offlineEventListener);r!==-1&&_t.splice(r,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this._prevBufferLen=0}}};I.protocol=Mt;var bt=class extends I{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let t=0;t<this._upgrades.length;t++)this._probe(this._upgrades[t])}_probe(t){let e=this.createTransport(t),r=!1;I.priorWebsocketSuccess=!1;let n=()=>{r||(e.send([{type:"ping",data:"probe"}]),e.once("packet",d=>{if(!r)if(d.type==="pong"&&d.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",e),!e)return;I.priorWebsocketSuccess=e.name==="websocket",this.transport.pause(()=>{r||this.readyState!=="closed"&&(f(),this.setTransport(e),e.send([{type:"upgrade"}]),this.emitReserved("upgrade",e),e=null,this.upgrading=!1,this.flush())})}else{let k=new Error("probe error");k.transport=e.name,this.emitReserved("upgradeError",k)}}))};function i(){r||(r=!0,f(),e.close(),e=null)}let o=d=>{let k=new Error("probe error: "+d);k.transport=e.name,i(),this.emitReserved("upgradeError",k)};function c(){o("transport closed")}function a(){o("socket closed")}function u(d){e&&d.name!==e.name&&i()}let f=()=>{e.removeListener("open",n),e.removeListener("error",o),e.removeListener("close",c),this.off("close",a),this.off("upgrading",u)};e.once("open",n),e.once("error",o),e.once("close",c),this.once("close",a),this.once("upgrading",u),this._upgrades.indexOf("webtransport")!==-1&&t!=="webtransport"?this.setTimeoutFn(()=>{r||e.open()},200):e.open()}onHandshake(t){this._upgrades=this._filterUpgrades(t.upgrades),super.onHandshake(t)}_filterUpgrades(t){let e=[];for(let r=0;r<t.length;r++)~this.transports.indexOf(t[r])&&e.push(t[r]);return e}},V=class extends bt{constructor(t,e={}){let r=typeof t=="object"?t:e;(!r.transports||r.transports&&typeof r.transports[0]=="string")&&(r.transports=(r.transports||["polling","websocket","webtransport"]).map(n=>Dt[n]).filter(n=>!!n)),super(t,r)}};var Ks=V.protocol;function Ae(s,t="",e){let r=s;e=e||typeof location<"u"&&location,s==null&&(s=e.protocol+"//"+e.host),typeof s=="string"&&(s.charAt(0)==="/"&&(s.charAt(1)==="/"?s=e.protocol+s:s=e.host+s),/^(https?|wss?):\/\//.test(s)||(typeof e<"u"?s=e.protocol+"//"+s:s="https://"+s),r=H(s)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";let i=r.host.indexOf(":")!==-1?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+i+":"+r.port+t,r.href=r.protocol+"://"+i+(e&&e.port===r.port?"":":"+r.port),r}var Gt={};Pe(Gt,{Decoder:()=>Kt,Encoder:()=>Wt,PacketType:()=>h,isPacketValid:()=>ur,protocol:()=>Ne});var nr=typeof ArrayBuffer=="function",ir=s=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(s):s.buffer instanceof ArrayBuffer,Re=Object.prototype.toString,or=typeof Blob=="function"||typeof Blob<"u"&&Re.call(Blob)==="[object BlobConstructor]",ar=typeof File=="function"||typeof File<"u"&&Re.call(File)==="[object FileConstructor]";function nt(s){return nr&&(s instanceof ArrayBuffer||ir(s))||or&&s instanceof Blob||ar&&s instanceof File}function st(s,t){if(!s||typeof s!="object")return!1;if(Array.isArray(s)){for(let e=0,r=s.length;e<r;e++)if(st(s[e]))return!0;return!1}if(nt(s))return!0;if(s.toJSON&&typeof s.toJSON=="function"&&arguments.length===1)return st(s.toJSON(),!0);for(let e in s)if(Object.prototype.hasOwnProperty.call(s,e)&&st(s[e]))return!0;return!1}function ve(s){let t=[],e=s.data,r=s;return r.data=Ht(e,t),r.attachments=t.length,{packet:r,buffers:t}}function Ht(s,t){if(!s)return s;if(nt(s)){let e={_placeholder:!0,num:t.length};return t.push(s),e}else if(Array.isArray(s)){let e=new Array(s.length);for(let r=0;r<s.length;r++)e[r]=Ht(s[r],t);return e}else if(typeof s=="object"&&!(s instanceof Date)){let e={};for(let r in s)Object.prototype.hasOwnProperty.call(s,r)&&(e[r]=Ht(s[r],t));return e}return s}function Ce(s,t){return s.data=Vt(s.data,t),delete s.attachments,s}function Vt(s,t){if(!s)return s;if(s&&s._placeholder===!0){if(typeof s.num=="number"&&s.num>=0&&s.num<t.length)return t[s.num];throw new Error("illegal attachments")}else if(Array.isArray(s))for(let e=0;e<s.length;e++)s[e]=Vt(s[e],t);else if(typeof s=="object")for(let e in s)Object.prototype.hasOwnProperty.call(s,e)&&(s[e]=Vt(s[e],t));return s}var Oe=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"],Ne=5,h;(function(s){s[s.CONNECT=0]="CONNECT",s[s.DISCONNECT=1]="DISCONNECT",s[s.EVENT=2]="EVENT",s[s.ACK=3]="ACK",s[s.CONNECT_ERROR=4]="CONNECT_ERROR",s[s.BINARY_EVENT=5]="BINARY_EVENT",s[s.BINARY_ACK=6]="BINARY_ACK"})(h||(h={}));var Wt=class{constructor(t){this.replacer=t}encode(t){return(t.type===h.EVENT||t.type===h.ACK)&&st(t)?this.encodeAsBinary({type:t.type===h.EVENT?h.BINARY_EVENT:h.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id}):[this.encodeAsString(t)]}encodeAsString(t){let e=""+t.type;return(t.type===h.BINARY_EVENT||t.type===h.BINARY_ACK)&&(e+=t.attachments+"-"),t.nsp&&t.nsp!=="/"&&(e+=t.nsp+","),t.id!=null&&(e+=t.id),t.data!=null&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){let e=ve(t),r=this.encodeAsString(e.packet),n=e.buffers;return n.unshift(r),n}},Kt=class s extends p{constructor(t){super(),this.opts=Object.assign({reviver:void 0,maxAttachments:10},typeof t=="function"?{reviver:t}:t)}add(t){let e;if(typeof t=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);let r=e.type===h.BINARY_EVENT;r||e.type===h.BINARY_ACK?(e.type=r?h.EVENT:h.ACK,this.reconstructor=new Yt(e),e.attachments===0&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else if(nt(t)||t.base64)if(this.reconstructor)e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+t)}decodeString(t){let e=0,r={type:Number(t.charAt(0))};if(h[r.type]===void 0)throw new Error("unknown packet type "+r.type);if(r.type===h.BINARY_EVENT||r.type===h.BINARY_ACK){let i=e+1;for(;t.charAt(++e)!=="-"&&e!=t.length;);let o=t.substring(i,e);if(o!=Number(o)||t.charAt(e)!=="-")throw new Error("Illegal attachments");let c=Number(o);if(!Le(c)||c<0)throw new Error("Illegal attachments");if(c>this.opts.maxAttachments)throw new Error("too many attachments");r.attachments=c}if(t.charAt(e+1)==="/"){let i=e+1;for(;++e&&!(t.charAt(e)===","||e===t.length););r.nsp=t.substring(i,e)}else r.nsp="/";let n=t.charAt(e+1);if(n!==""&&Number(n)==n){let i=e+1;for(;++e;){let o=t.charAt(e);if(o==null||Number(o)!=o){--e;break}if(e===t.length)break}r.id=Number(t.substring(i,e+1))}if(t.charAt(++e)){let i=this.tryParse(t.substr(e));if(s.isPayloadValid(r.type,i))r.data=i;else throw new Error("invalid payload")}return r}tryParse(t){try{return JSON.parse(t,this.opts.reviver)}catch{return!1}}static isPayloadValid(t,e){switch(t){case h.CONNECT:return wt(e);case h.DISCONNECT:return e===void 0;case h.CONNECT_ERROR:return typeof e=="string"||wt(e);case h.EVENT:case h.BINARY_EVENT:return Array.isArray(e)&&(typeof e[0]=="number"||typeof e[0]=="string"&&Oe.indexOf(e[0])===-1);case h.ACK:case h.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}},Yt=class{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){let e=Ce(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}};function cr(s){return typeof s=="string"}var Le=Number.isInteger||function(s){return typeof s=="number"&&isFinite(s)&&Math.floor(s)===s};function hr(s){return s===void 0||Le(s)}function wt(s){return Object.prototype.toString.call(s)==="[object Object]"}function fr(s,t){switch(s){case h.CONNECT:return t===void 0||wt(t);case h.DISCONNECT:return t===void 0;case h.EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&Oe.indexOf(t[0])===-1);case h.ACK:return Array.isArray(t);case h.CONNECT_ERROR:return typeof t=="string"||wt(t);default:return!1}}function ur(s){return cr(s.nsp)&&hr(s.id)&&fr(s.type,s.data)}function w(s,t,e){return s.on(t,e),function(){s.off(t,e)}}var lr=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1}),W=class extends p{constructor(t,e,r){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=e,r&&r.auth&&(this.auth=r.auth),this._opts=Object.assign({},r),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;let t=this.io;this.subs=[w(t,"open",this.onopen.bind(this)),w(t,"packet",this.onpacket.bind(this)),w(t,"error",this.onerror.bind(this)),w(t,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...t){return t.unshift("message"),this.emit.apply(this,t),this}emit(t,...e){var r,n,i;if(lr.hasOwnProperty(t))throw new Error('"'+t.toString()+'" is a reserved event name');if(e.unshift(t),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(e),this;let o={type:h.EVENT,data:e};if(o.options={},o.options.compress=this.flags.compress!==!1,typeof e[e.length-1]=="function"){let f=this.ids++,d=e.pop();this._registerAckCallback(f,d),o.id=f}let c=(n=(r=this.io.engine)===null||r===void 0?void 0:r.transport)===null||n===void 0?void 0:n.writable,a=this.connected&&!(!((i=this.io.engine)===null||i===void 0)&&i._hasPingExpired());return this.flags.volatile&&!c||(a?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(t,e){var r;let n=(r=this.flags.timeout)!==null&&r!==void 0?r:this._opts.ackTimeout;if(n===void 0){this.acks[t]=e;return}let i=this.io.setTimeoutFn(()=>{delete this.acks[t];for(let c=0;c<this.sendBuffer.length;c++)this.sendBuffer[c].id===t&&this.sendBuffer.splice(c,1);e.call(this,new Error("operation has timed out"))},n),o=(...c)=>{this.io.clearTimeoutFn(i),e.apply(this,c)};o.withError=!0,this.acks[t]=o}emitWithAck(t,...e){return new Promise((r,n)=>{let i=(o,c)=>o?n(o):r(c);i.withError=!0,e.push(i),this.emit(t,...e)})}_addToQueue(t){let e;typeof t[t.length-1]=="function"&&(e=t.pop());let r={id:this._queueSeq++,tryCount:0,pending:!1,args:t,flags:Object.assign({fromQueue:!0},this.flags)};t.push((n,...i)=>(this._queue[0],n!==null?r.tryCount>this._opts.retries&&(this._queue.shift(),e&&e(n)):(this._queue.shift(),e&&e(null,...i)),r.pending=!1,this._drainQueue())),this._queue.push(r),this._drainQueue()}_drainQueue(t=!1){if(!this.connected||this._queue.length===0)return;let e=this._queue[0];e.pending&&!t||(e.pending=!0,e.tryCount++,this.flags=e.flags,this.emit.apply(this,e.args))}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){typeof this.auth=="function"?this.auth(t=>{this._sendConnectPacket(t)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(t){this.packet({type:h.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},t):t})}onerror(t){this.connected||this.emitReserved("connect_error",t)}onclose(t,e){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,e),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(t=>{if(!this.sendBuffer.some(r=>String(r.id)===t)){let r=this.acks[t];delete this.acks[t],r.withError&&r.call(this,new Error("socket has been disconnected"))}})}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case h.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case h.EVENT:case h.BINARY_EVENT:this.onevent(t);break;case h.ACK:case h.BINARY_ACK:this.onack(t);break;case h.DISCONNECT:this.ondisconnect();break;case h.CONNECT_ERROR:this.destroy();let r=new Error(t.data.message);r.data=t.data.data,this.emitReserved("connect_error",r);break}}onevent(t){let e=t.data||[];t.id!=null&&e.push(this.ack(t.id)),this.connected?this.emitEvent(e):this.receiveBuffer.push(Object.freeze(e))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){let e=this._anyListeners.slice();for(let r of e)r.apply(this,t)}super.emit.apply(this,t),this._pid&&t.length&&typeof t[t.length-1]=="string"&&(this._lastOffset=t[t.length-1])}ack(t){let e=this,r=!1;return function(...n){r||(r=!0,e.packet({type:h.ACK,id:t,data:n}))}}onack(t){let e=this.acks[t.id];typeof e=="function"&&(delete this.acks[t.id],e.withError&&t.data.unshift(null),e.apply(this,t.data))}onconnect(t,e){this.id=t,this.recovered=e&&this._pid===e,this._pid=e,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(t=>this.emitEvent(t)),this.receiveBuffer=[],this.sendBuffer.forEach(t=>{this.notifyOutgoingListeners(t),this.packet(t)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(t=>t()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:h.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){let e=this._anyListeners;for(let r=0;r<e.length;r++)if(t===e[r])return e.splice(r,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){let e=this._anyOutgoingListeners;for(let r=0;r<e.length;r++)if(t===e[r])return e.splice(r,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){let e=this._anyOutgoingListeners.slice();for(let r of e)r.apply(this,t.data)}}};function M(s){s=s||{},this.ms=s.min||100,this.max=s.max||1e4,this.factor=s.factor||2,this.jitter=s.jitter>0&&s.jitter<=1?s.jitter:0,this.attempts=0}M.prototype.duration=function(){var s=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var t=Math.random(),e=Math.floor(t*this.jitter*s);s=(Math.floor(t*10)&1)==0?s-e:s+e}return Math.min(s,this.max)|0};M.prototype.reset=function(){this.attempts=0};M.prototype.setMin=function(s){this.ms=s};M.prototype.setMax=function(s){this.max=s};M.prototype.setJitter=function(s){this.jitter=s};var K=class extends p{constructor(t,e){var r;super(),this.nsps={},this.subs=[],t&&typeof t=="object"&&(e=t,t=void 0),e=e||{},e.path=e.path||"/socket.io",this.opts=e,A(this,e),this.reconnection(e.reconnection!==!1),this.reconnectionAttempts(e.reconnectionAttempts||1/0),this.reconnectionDelay(e.reconnectionDelay||1e3),this.reconnectionDelayMax(e.reconnectionDelayMax||5e3),this.randomizationFactor((r=e.randomizationFactor)!==null&&r!==void 0?r:.5),this.backoff=new M({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(e.timeout==null?2e4:e.timeout),this._readyState="closed",this.uri=t;let n=e.parser||Gt;this.encoder=new n.Encoder,this.decoder=new n.Decoder,this._autoConnect=e.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,t||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(t){return t===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var e;return t===void 0?this._reconnectionDelay:(this._reconnectionDelay=t,(e=this.backoff)===null||e===void 0||e.setMin(t),this)}randomizationFactor(t){var e;return t===void 0?this._randomizationFactor:(this._randomizationFactor=t,(e=this.backoff)===null||e===void 0||e.setJitter(t),this)}reconnectionDelayMax(t){var e;return t===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,(e=this.backoff)===null||e===void 0||e.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(t){if(~this._readyState.indexOf("open"))return this;this.engine=new V(this.uri,this.opts);let e=this.engine,r=this;this._readyState="opening",this.skipReconnect=!1;let n=w(e,"open",function(){r.onopen(),t&&t()}),i=c=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",c),t?t(c):this.maybeReconnectOnOpen()},o=w(e,"error",i);if(this._timeout!==!1){let c=this._timeout,a=this.setTimeoutFn(()=>{n(),i(new Error("timeout")),e.close()},c);this.opts.autoUnref&&a.unref(),this.subs.push(()=>{this.clearTimeoutFn(a)})}return this.subs.push(n),this.subs.push(o),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");let t=this.engine;this.subs.push(w(t,"ping",this.onping.bind(this)),w(t,"data",this.ondata.bind(this)),w(t,"error",this.onerror.bind(this)),w(t,"close",this.onclose.bind(this)),w(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(t){try{this.decoder.add(t)}catch(e){this.onclose("parse error",e)}}ondecoded(t){S(()=>{this.emitReserved("packet",t)},this.setTimeoutFn)}onerror(t){this.emitReserved("error",t)}socket(t,e){let r=this.nsps[t];return r?this._autoConnect&&!r.active&&r.connect():(r=new W(this,t,e),this.nsps[t]=r),r}_destroy(t){let e=Object.keys(this.nsps);for(let r of e)if(this.nsps[r].active)return;this._close()}_packet(t){let e=this.encoder.encode(t);for(let r=0;r<e.length;r++)this.engine.write(e[r],t.options)}cleanup(){this.subs.forEach(t=>t()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(t,e){var r;this.cleanup(),(r=this.engine)===null||r===void 0||r.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",t,e),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;let t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{let e=this.backoff.duration();this._reconnecting=!0;let r=this.setTimeoutFn(()=>{t.skipReconnect||(this.emitReserved("reconnect_attempt",t.backoff.attempts),!t.skipReconnect&&t.open(n=>{n?(t._reconnecting=!1,t.reconnect(),this.emitReserved("reconnect_error",n)):t.onreconnect()}))},e);this.opts.autoUnref&&r.unref(),this.subs.push(()=>{this.clearTimeoutFn(r)})}}onreconnect(){let t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}};var it={};function ot(s,t){typeof s=="object"&&(t=s,s=void 0),t=t||{};let e=Ae(s,t.path||"/socket.io"),r=e.source,n=e.id,i=e.path,o=it[n]&&i in it[n].nsps,c=t.forceNew||t["force new connection"]||t.multiplex===!1||o,a;return c?a=new K(r,t):(it[n]||(it[n]=new K(r,t)),a=it[n]),e.query&&!t.query&&(t.query=e.queryKey),a.socket(e.path,t)}Object.assign(ot,{Manager:K,Socket:W,io:ot,connect:ot});function pr(s,t){return t.startsWith("/")?t.slice(1):`plugin/${s}/${t}`}var Et=class s{constructor(t,e){T(this,"_socket");T(this,"_pluginId");T(this,"_subHandlers",new Map);T(this,"_serveHandlers",new Map);this._socket=t,this._pluginId=e,t.on("msg",({topic:r,payload:n})=>{this._subHandlers.get(r)?.forEach(i=>i(n))}),t.on("serve_call",async({id:r,topic:n,payload:i})=>{let o=this._serveHandlers.get(n),c=o?await o(i):void 0;t.emit("serve_reply",{id:r,payload:c})})}static connect(t,e){return new Promise((r,n)=>{let i=ot(t,{transports:["websocket"]}),o=()=>{a(),r(new s(i,e))},c=u=>{a(),n(u)},a=()=>{i.off("connect",o),i.off("connect_error",c)};i.once("connect",o),i.once("connect_error",c)})}_key(t){return pr(this._pluginId,t)}async pub(t,e){this._socket.emit("pub",{topic:this._key(t),payload:e})}async sub(t,e){let r=this._key(t);this._subHandlers.has(r)||(this._subHandlers.set(r,new Set),this._socket.emit("sub",{topic:r}));let n=e;return this._subHandlers.get(r).add(n),{undeclare:()=>{let i=this._subHandlers.get(r);i&&(i.delete(n),i.size===0&&(this._subHandlers.delete(r),this._socket.emit("unsub",{topic:r})))}}}async action(t,e){return new Promise(r=>{this._socket.timeout(1e4).emit("action",{topic:this._key(t),payload:e},(n,i)=>{r(n?void 0:i)})})}async serve(t,e){let r=this._key(t);return this._serveHandlers.set(r,e),this._socket.emit("serve_register",{topic:r}),{undeclare:()=>{this._serveHandlers.delete(r),this._socket.emit("serve_unregister",{topic:r})}}}close(){this._socket.disconnect()}};function Hn(s){Jt(),X.parent.import({targetOrigin:"*"}).connect().then(async({connection:e,toast:r,socketUrl:n,pluginId:i})=>{let o=await Et.connect(n,i),c={pub:(f,d)=>o.pub(f,d),sub:(f,d)=>o.sub(f,d),action:(f,d)=>o.action(f,d),serve:(f,d)=>o.serve(f,d),toast:(f,d)=>r(f,d)},a=document.createElement("remote-root");document.body.append(a),new jt(e).observe(a),dr(a).render(Be(Xt.Provider,{value:c},Be(s)))})}export{Hn as connect};
@@ -1 +1 @@
1
- import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i}from"./chunks/chunk-JRCDA3EG.js";import"./chunks/chunk-AMCIKVG7.js";export{h as RB_ELEMENT_NAMES,b as RbButtonElement,c as RbIconButtonElement,g as RbSelectElement,a as RbSliderElement,f as RbSwitchElement,d as RbTextElement,e as RbTextInputElement,i as defineElements};
1
+ import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i}from"./chunks/chunk-4MGSRUAS.js";import"./chunks/chunk-37HVFFJB.js";export{h as RB_ELEMENT_NAMES,b as RbButtonElement,c as RbIconButtonElement,g as RbSelectElement,a as RbSliderElement,f as RbSwitchElement,d as RbTextElement,e as RbTextInputElement,i as defineElements};
@@ -1 +1 @@
1
- import{b as A}from"./chunks/chunk-GJWPOWHG.js";import{b as d,c as x,d as h,e as S,f as C,g as y,h as g}from"./chunks/chunk-JRCDA3EG.js";import"./chunks/chunk-AMCIKVG7.js";import{forwardRef as L,useRef as T,isValidElement as k,cloneElement as M,createElement as I,useLayoutEffect as O}from"react";function o(n,w=customElements.get(n),{slotProps:m=!0,eventProps:B={}}={}){let N=!!m,c=(typeof m=="object"?m.wrapper:void 0)??!0,E=typeof c=="string"?c:c?"remote-fragment":!1,u=L(function(l,i){let a=T(),v=T(),r={},R=V(l.children);for(let e in l){let t=l[e];if(e==="slot"){r.slot=t;continue}if(N&&w.remoteSlotDefinitions.has(e)&&k(t)){E?R.push(I(E,{slot:e},t)):R.push(M(t,{slot:e}));continue}r[e]=t}return O(()=>{let e=a.current;if(e!=null){for(let t in r){if(t==="children")continue;let b=v.current?.[t],s=r[t];if(b===s)continue;let P=B[t];if(P){let f=P.event;b&&e.removeEventListener(f,b),s&&e.addEventListener(f,s);continue}if(t in e){e[t]=r[t];continue}s==null?e.removeAttribute(t):e.setAttribute(t,String(s))}v.current=r}}),I(n,{ref:e=>{a.current=e,typeof i=="function"?i(e):i!=null&&(i.current=e)}},...R)});return u.displayName=`RemoteComponent(${n})`,u}function V(n){return n==null?[]:Array.isArray(n)?[...n]:[n]}var p=n=>({eventProps:n}),G=o("rb-slider",d,p({onChange:{event:"change"}})),H=o("rb-button",x,p({onPress:{event:"press"}})),J=o("rb-icon-button",h,p({onPress:{event:"press"}})),K=o("rb-text",S),Q=o("rb-text-input",C,p({onInput:{event:"input"}})),U=o("rb-switch",y,p({onChange:{event:"change"}})),X=o("rb-select",g,p({onChange:{event:"change"}}));export{H as Button,J as IconButton,X as Select,G as Slider,U as Switch,K as Text,Q as TextInput,A as useRb};
1
+ import{b as A}from"./chunks/chunk-Q6XGCIPE.js";import{b as d,c as x,d as h,e as S,f as C,g as y,h as g}from"./chunks/chunk-4MGSRUAS.js";import"./chunks/chunk-37HVFFJB.js";import{forwardRef as L,useRef as T,isValidElement as k,cloneElement as M,createElement as I,useLayoutEffect as O}from"react";function o(n,w=customElements.get(n),{slotProps:m=!0,eventProps:B={}}={}){let N=!!m,c=(typeof m=="object"?m.wrapper:void 0)??!0,E=typeof c=="string"?c:c?"remote-fragment":!1,u=L(function(l,i){let a=T(),v=T(),r={},R=V(l.children);for(let e in l){let t=l[e];if(e==="slot"){r.slot=t;continue}if(N&&w.remoteSlotDefinitions.has(e)&&k(t)){E?R.push(I(E,{slot:e},t)):R.push(M(t,{slot:e}));continue}r[e]=t}return O(()=>{let e=a.current;if(e!=null){for(let t in r){if(t==="children")continue;let b=v.current?.[t],s=r[t];if(b===s)continue;let P=B[t];if(P){let f=P.event;b&&e.removeEventListener(f,b),s&&e.addEventListener(f,s);continue}if(t in e){e[t]=r[t];continue}s==null?e.removeAttribute(t):e.setAttribute(t,String(s))}v.current=r}}),I(n,{ref:e=>{a.current=e,typeof i=="function"?i(e):i!=null&&(i.current=e)}},...R)});return u.displayName=`RemoteComponent(${n})`,u}function V(n){return n==null?[]:Array.isArray(n)?[...n]:[n]}var p=n=>({eventProps:n}),G=o("rb-slider",d,p({onChange:{event:"change"}})),H=o("rb-button",x,p({onPress:{event:"press"}})),J=o("rb-icon-button",h,p({onPress:{event:"press"}})),K=o("rb-text",S),Q=o("rb-text-input",C,p({onInput:{event:"input"}})),U=o("rb-switch",y,p({onChange:{event:"change"}})),X=o("rb-select",g,p({onChange:{event:"change"}}));export{H as Button,J as IconButton,X as Select,G as Slider,U as Switch,K as Text,Q as TextInput,A as useRb};
@@ -1 +1 @@
1
- import{a,b}from"./chunks/chunk-GJWPOWHG.js";import"./chunks/chunk-AMCIKVG7.js";export{a as RbContext,b as useRb};
1
+ import{a,b}from"./chunks/chunk-Q6XGCIPE.js";import"./chunks/chunk-37HVFFJB.js";export{a as RbContext,b as useRb};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainbow-robotics/plugin-ui",
3
- "version": "0.1.2-dev.5",
3
+ "version": "0.1.2-dev.7",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -48,6 +48,7 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@repo/eslint-config": "*",
51
+ "@repo/rb-components": "*",
51
52
  "@repo/typescript-config": "*",
52
53
  "@types/node": "^22.13.9",
53
54
  "@types/react": "^19.0.10",
@@ -58,16 +59,11 @@
58
59
  "dependencies": {
59
60
  "@quilted/threads": "^4.0.3",
60
61
  "@remote-dom/core": "^1.11.1",
61
- "@remote-dom/react": "^1.2.2"
62
+ "@remote-dom/react": "^1.2.2",
63
+ "socket.io-client": "^4.8.0"
62
64
  },
63
65
  "peerDependencies": {
64
- "@repo/rb-components": "*",
65
66
  "react": ">=18",
66
67
  "react-dom": ">=18"
67
- },
68
- "peerDependenciesMeta": {
69
- "@repo/rb-components": {
70
- "optional": true
71
- }
72
68
  }
73
69
  }
package/src/connect.ts CHANGED
@@ -1,19 +1,9 @@
1
1
  /**
2
2
  * Sandbox bootstrap — runs *inside* the plugin iframe.
3
3
  *
4
- * The sandbox initiates the handshake (the iframe is the side that knows when it
5
- * is ready): it imports the host's `connect()` and calls it. The host responds
6
- * with a `RemoteConnection` (its `receiver.connection`, ferried by
7
- * @quilted/threads) plus the host SDK. We then render the plugin's React tree
8
- * into a detached root and let `RemoteMutationObserver` stream every DOM
9
- * mutation to the host, where the real rb-components live.
10
- *
11
- * The child-initiates-handshake pattern is required because @quilted/threads
12
- * does not buffer a call made before the other side is listening; the host has
13
- * been listening since it mounted the iframe, so a call *from* the sandbox is
14
- * always delivered.
15
- *
16
- * Verified against @remote-dom/core@1.11.x + @quilted/threads@4.x.
4
+ * The sandbox initiates the handshake: imports the host's `connect()` and calls
5
+ * it. The host responds with the RemoteConnection, toast(), and Socket.IO config
6
+ * (socketUrl + pluginId). We open a Socket.IO connection and wire up the rb object.
17
7
  */
18
8
  import { RemoteMutationObserver } from "@remote-dom/core/elements";
19
9
  import type { RemoteConnection } from "@remote-dom/core";
@@ -22,23 +12,23 @@ import { createElement, type ComponentType } from "react";
22
12
  import { createRoot } from "react-dom/client";
23
13
  import { defineElements } from "./elements";
24
14
  import { RbContext, type RbSdk } from "./sdk";
15
+ import { RbWs } from "./ws";
25
16
 
26
- /** What the host exposes to the sandbox. */
27
17
  interface HostExports {
28
18
  connect: () => Promise<{
29
19
  connection: RemoteConnection;
30
- action: (id: string, payload?: unknown) => Promise<unknown> | unknown;
31
- notify: (message: string, type?: string) => void;
20
+ toast: (message: string, type?: string) => void;
21
+ socketUrl: string;
22
+ pluginId: string;
32
23
  }>;
33
24
  }
34
25
 
35
26
  /**
36
- * Mount a plugin. Call this once from the sandbox entry (sandbox.html), passing
37
- * the plugin's root component.
27
+ * Mount a plugin. Call this once from the sandbox entry (content.tsx).
38
28
  *
39
29
  * @example
40
30
  * import { connect } from "@rainbow-robotics/plugin-ui/connect";
41
- * import App from "./content";
31
+ * import App from "./App";
42
32
  * connect(App);
43
33
  */
44
34
  export function connect(App: ComponentType): void {
@@ -48,14 +38,18 @@ export function connect(App: ComponentType): void {
48
38
  targetOrigin: "*",
49
39
  });
50
40
 
51
- void host.connect().then(({ connection, action, notify }) => {
41
+ void host.connect().then(async ({ connection, toast, socketUrl, pluginId }) => {
42
+ const ws = await RbWs.connect(socketUrl, pluginId);
43
+
52
44
  const rb: RbSdk = {
53
- action: (id, payload) => Promise.resolve(action(id, payload)),
54
- notify: (message, type) => notify(message, type as string | undefined),
45
+ pub: (topic, payload) => ws.pub(topic, payload),
46
+ sub: (topic, handler) => ws.sub(topic, handler),
47
+ action: (topic, payload) => ws.action(topic, payload),
48
+ serve: (topic, handler) => ws.serve(topic, handler),
49
+ toast: (message, type) => toast(message, type),
55
50
  };
56
51
 
57
52
  const root = document.createElement("remote-root");
58
-
59
53
  document.body.append(root);
60
54
 
61
55
  const observer = new RemoteMutationObserver(connection);
package/src/host.tsx CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  RBIcons,
40
40
  } from "@repo/rb-components/new_components";
41
41
  import type { RbSelectOption } from "./elements";
42
- import type { RbSdk } from "./sdk";
42
+ import type { RbNotifyType } from "./sdk";
43
43
 
44
44
  type IconComponent = ComponentType<{ title?: string }>;
45
45
 
@@ -266,36 +266,49 @@ export const RB_COMPONENT_MAP: RemoteComponentRendererMap = new Map([
266
266
  /* Host SDK contract + mount component */
267
267
  /* -------------------------------------------------------------------------- */
268
268
 
269
- export type RbSdkImpl = RbSdk;
270
-
271
- /** Shape the host exposes to the sandbox over the thread (see ./connect). */
269
+ /**
270
+ * Shape the host exposes to the sandbox over the thread (see ./connect).
271
+ * The sandbox opens its own Socket.IO connection from `socketUrl` + `pluginId`
272
+ * and implements pub/sub/action/serve directly; the host only forwards the
273
+ * remote-dom connection, the Socket.IO config, and toast().
274
+ */
272
275
  interface HostThreadExports {
273
276
  connect: () => {
274
277
  connection: {
275
278
  mutate: (records: unknown) => void;
276
279
  call: (id: string, method: string, ...args: unknown[]) => unknown;
277
280
  };
278
- action: (id: string, payload?: unknown) => Promise<unknown>;
279
- notify: (message: string, type?: string) => void;
281
+ toast: (message: string, type?: RbNotifyType) => void;
282
+ socketUrl: string;
283
+ pluginId: string;
280
284
  };
281
285
  }
282
286
 
283
287
  export interface PluginContentProps {
284
288
  /** URL of the plugin sandbox document (e.g. /plugin/:id/sandbox.html). */
285
289
  sandboxUrl: string;
286
- /** Host SDK implementation handed to the plugin. */
287
- rb: RbSdkImpl;
290
+ /** Zenoh router URL the sandbox connects to. */
291
+ socketUrl: string;
292
+ /** Plugin id — used for Zenoh topic namespacing inside the sandbox. */
293
+ pluginId: string;
294
+ /** Host toast notification handed to the plugin. */
295
+ toast: (message: string, type?: RbNotifyType) => void;
288
296
  }
289
297
 
290
298
  /**
291
299
  * Renders a sandboxed plugin: spins up a hidden iframe running the plugin's
292
300
  * remote tree, and mirrors that tree with real rb-components in the host.
293
301
  */
294
- export function PluginContent({ sandboxUrl, rb }: PluginContentProps) {
302
+ export function PluginContent({
303
+ sandboxUrl,
304
+ socketUrl,
305
+ pluginId,
306
+ toast,
307
+ }: PluginContentProps) {
295
308
  const receiver = useMemo(() => new RemoteReceiver(), []);
296
309
  const iframeRef = useRef<HTMLIFrameElement>(null);
297
- const rbRef = useRef(rb);
298
- rbRef.current = rb;
310
+ const toastRef = useRef(toast);
311
+ toastRef.current = toast;
299
312
 
300
313
  useEffect(() => {
301
314
  const iframe = iframeRef.current;
@@ -316,17 +329,17 @@ export function PluginContent({ sandboxUrl, rb }: PluginContentProps) {
316
329
  call: (id: string, method: string, ...args: unknown[]) =>
317
330
  receiver.connection.call(id, method, ...args),
318
331
  },
319
- action: (id: string, payload?: unknown) =>
320
- rbRef.current.action(id, payload),
321
- notify: (message: string, type?: string) =>
322
- rbRef.current.notify(message, type as never),
332
+ toast: (message: string, type?: RbNotifyType) =>
333
+ toastRef.current(message, type),
334
+ socketUrl,
335
+ pluginId,
323
336
  };
324
337
  },
325
338
  },
326
339
  });
327
340
 
328
341
  return () => controller.abort();
329
- }, [receiver]);
342
+ }, [receiver, socketUrl, pluginId]);
330
343
 
331
344
  return (
332
345
  <>
package/src/sdk.ts CHANGED
@@ -1,35 +1,68 @@
1
1
  /**
2
- * Plugin runtime SDK — the small, stable surface a plugin author calls from
3
- * inside the sandbox to talk to the host (Muscat / nexus).
2
+ * Plugin runtime SDK — the surface a plugin author calls from inside the sandbox.
4
3
  *
5
- * The concrete implementation is injected by the host across the iframe thread
6
- * (see ./connect for the sandbox side, ./host for the host side).
4
+ * Zenoh methods (pub/sub/action/serve) talk directly to the Zenoh router via
5
+ * WebSocket. Topics are auto-namespaced to plugin/{pluginId}/... to prevent
6
+ * cross-plugin collisions. A leading "/" bypasses namespacing (absolute path).
7
+ *
8
+ * notify() is still host-mediated (goes through the Muscat shell).
7
9
  */
8
10
  import { createContext, useContext } from "react";
11
+ import type { WsSubscriber as Subscriber, WsQueryable as Queryable } from "./ws";
9
12
 
10
13
  export type RbNotifyType = "info" | "success" | "warning" | "error";
11
14
 
12
15
  export interface RbSdk {
13
16
  /**
14
- * Invoke a host-side action (declared in manifest.actions). Resolves with
15
- * whatever the host/back end returns.
17
+ * Publish JSON payload to a topic.
18
+ * "sensor/data" → plugin/{pluginId}/sensor/data
19
+ * "/broadcast/x" → broadcast/x (absolute)
20
+ */
21
+ pub: <P = any>(topic: string, payload: P) => Promise<void>;
22
+
23
+ /** Subscribe to a topic. Returns a handle with undeclare(). */
24
+ sub: <P = any>(
25
+ topic: string,
26
+ handler: (payload: P) => void,
27
+ ) => Promise<Subscriber>;
28
+
29
+ /**
30
+ * Send a request and await the first reply (Zenoh query).
31
+ * Use this to call a backend handler registered with rb.serve() / ZenohRouter.
32
+ */
33
+ action: <R = any, P = any>(topic: string, payload?: P) => Promise<R>;
34
+
35
+ /**
36
+ * Register a queryable — the frontend responds to backend queries.
37
+ * Mirror of rb.action() on the other side.
16
38
  */
17
- action: (id: string, payload?: unknown) => Promise<unknown>;
39
+ serve: <P = any, R = any>(
40
+ topic: string,
41
+ handler: (payload?: P) => R | Promise<R>,
42
+ ) => Promise<Queryable>;
43
+
18
44
  /** Show a transient notification through the host's toast system. */
19
- notify: (message: string, type?: RbNotifyType) => void;
45
+ toast: (message: string, type?: RbNotifyType) => void;
20
46
  }
21
47
 
22
48
  const noopSdk: RbSdk = {
23
- action: async () => {
24
- if (typeof console !== "undefined") {
25
- console.warn("[plugin-ui] rb.action called outside of a host context");
26
- }
27
- return undefined;
49
+ pub: async <P = any>(_topic?: string, _payload?: P) => {
50
+ console.warn("[plugin-ui] rb.pub called outside of a host context");
51
+ },
52
+ sub: async <P = any>(_topic?: string, _handler?: (payload: P) => void) => {
53
+ console.warn("[plugin-ui] rb.sub called outside of a host context");
54
+ return { undeclare: async () => {} } as unknown as Subscriber;
55
+ },
56
+ action: async <R = any, P = any>(_topic?: string, _payload?: P) => {
57
+ console.warn("[plugin-ui] rb.action called outside of a host context");
58
+ return undefined as R;
59
+ },
60
+ serve: async <P = any, R = any>(_topic?: string, _handler?: (payload?: P) => R) => {
61
+ console.warn("[plugin-ui] rb.serve called outside of a host context");
62
+ return { undeclare: async () => {} } as unknown as Queryable;
28
63
  },
29
- notify: (message) => {
30
- if (typeof console !== "undefined") {
31
- console.warn("[plugin-ui] rb.notify (no host):", message);
32
- }
64
+ toast: (message) => {
65
+ console.warn("[plugin-ui] rb.toast (no host):", message);
33
66
  },
34
67
  };
35
68
 
package/src/ws.ts ADDED
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Socket.IO communication client for plugin frontends.
3
+ *
4
+ * Topics are automatically namespaced to prevent cross-plugin collisions:
5
+ * "sensor/data" → "plugin/{pluginId}/sensor/data"
6
+ * "/broadcast/x" → "broadcast/x" (leading slash = absolute)
7
+ *
8
+ * Browser ←→ Python backend protocol:
9
+ * browser emits : sub, unsub, pub, action (with ack), serve_reply
10
+ * server emits : msg, serve_call
11
+ */
12
+ import { io, type Socket } from "socket.io-client";
13
+
14
+ export interface WsHandle {
15
+ undeclare(): void;
16
+ }
17
+
18
+ export type WsSubscriber = WsHandle;
19
+ export type WsQueryable = WsHandle;
20
+
21
+ function resolveTopic(pluginId: string, topic: string): string {
22
+ return topic.startsWith("/") ? topic.slice(1) : `plugin/${pluginId}/${topic}`;
23
+ }
24
+
25
+ export class RbWs {
26
+ private readonly _socket: Socket;
27
+ private readonly _pluginId: string;
28
+ private readonly _subHandlers = new Map<string, Set<(payload: unknown) => void>>();
29
+ private readonly _serveHandlers = new Map<string, (payload?: unknown) => unknown | Promise<unknown>>();
30
+
31
+ private constructor(socket: Socket, pluginId: string) {
32
+ this._socket = socket;
33
+ this._pluginId = pluginId;
34
+
35
+ // Deliver incoming pub/sub messages to registered handlers
36
+ socket.on("msg", ({ topic, payload }: { topic: string; payload: unknown }) => {
37
+ this._subHandlers.get(topic)?.forEach((h) => h(payload));
38
+ });
39
+
40
+ // Python calls a browser-side serve handler
41
+ socket.on("serve_call", async ({ id, topic, payload }: { id: string; topic: string; payload: unknown }) => {
42
+ const handler = this._serveHandlers.get(topic);
43
+ const result = handler ? await handler(payload) : undefined;
44
+ socket.emit("serve_reply", { id, payload: result });
45
+ });
46
+ }
47
+
48
+ static connect(url: string, pluginId: string): Promise<RbWs> {
49
+ return new Promise((resolve, reject) => {
50
+ const socket = io(url, { transports: ["websocket"] });
51
+ const onConnect = () => { cleanup(); resolve(new RbWs(socket, pluginId)); };
52
+ const onError = (err: Error) => { cleanup(); reject(err); };
53
+ const cleanup = () => { socket.off("connect", onConnect); socket.off("connect_error", onError); };
54
+ socket.once("connect", onConnect);
55
+ socket.once("connect_error", onError);
56
+ });
57
+ }
58
+
59
+ private _key(topic: string): string {
60
+ return resolveTopic(this._pluginId, topic);
61
+ }
62
+
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ async pub<P = any>(topic: string, payload: P): Promise<void> {
65
+ this._socket.emit("pub", { topic: this._key(topic), payload });
66
+ }
67
+
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ async sub<P = any>(topic: string, handler: (payload: P) => void): Promise<WsSubscriber> {
70
+ const key = this._key(topic);
71
+ if (!this._subHandlers.has(key)) {
72
+ this._subHandlers.set(key, new Set());
73
+ this._socket.emit("sub", { topic: key });
74
+ }
75
+ const h = handler as (payload: unknown) => void;
76
+ this._subHandlers.get(key)!.add(h);
77
+ return {
78
+ undeclare: () => {
79
+ const set = this._subHandlers.get(key);
80
+ if (!set) return;
81
+ set.delete(h);
82
+ if (set.size === 0) {
83
+ this._subHandlers.delete(key);
84
+ this._socket.emit("unsub", { topic: key });
85
+ }
86
+ },
87
+ };
88
+ }
89
+
90
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
+ async action<R = any, P = any>(topic: string, payload?: P): Promise<R> {
92
+ return new Promise((resolve) => {
93
+ this._socket
94
+ .timeout(10_000)
95
+ .emit("action", { topic: this._key(topic), payload }, (_err: Error | null, result: R) => {
96
+ resolve(_err ? (undefined as R) : result);
97
+ });
98
+ });
99
+ }
100
+
101
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
+ async serve<P = any, R = any>(
103
+ topic: string,
104
+ handler: (payload?: P) => R | Promise<R>,
105
+ ): Promise<WsQueryable> {
106
+ const key = this._key(topic);
107
+ this._serveHandlers.set(key, handler as (payload?: unknown) => unknown);
108
+ this._socket.emit("serve_register", { topic: key });
109
+ return {
110
+ undeclare: () => {
111
+ this._serveHandlers.delete(key);
112
+ this._socket.emit("serve_unregister", { topic: key });
113
+ },
114
+ };
115
+ }
116
+
117
+ close(): void {
118
+ this._socket.disconnect();
119
+ }
120
+ }
@@ -1 +0,0 @@
1
- var g=Object.defineProperty;var f=a=>{throw TypeError(a)};var h=(a,b,c)=>b in a?g(a,b,{enumerable:!0,configurable:!0,writable:!0,value:c}):a[b]=c;var i=(a,b,c)=>h(a,typeof b!="symbol"?b+"":b,c),d=(a,b,c)=>b.has(a)||f("Cannot "+c);var j=(a,b,c)=>(d(a,b,"read from private field"),c?c.call(a):b.get(a)),k=(a,b,c)=>b.has(a)?f("Cannot add the same private member more than once"):b instanceof WeakSet?b.add(a):b.set(a,c),l=(a,b,c,e)=>(d(a,b,"write to private field"),e?e.call(a,c):b.set(a,c),c),m=(a,b,c)=>(d(a,b,"access private method"),c);export{i as a,j as b,k as c,l as d,m as e};
@@ -1 +0,0 @@
1
- import{createContext as o,useContext as e}from"react";var t={action:async()=>{typeof console<"u"&&console.warn("[plugin-ui] rb.action called outside of a host context")},notify:n=>{typeof console<"u"&&console.warn("[plugin-ui] rb.notify (no host):",n)}},i=o(t);function s(){return e(i)}export{i as a,s as b};