agent-comms 1.14.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +1 -1
  3. package/dist/bridges/claude-code/channel.d.ts.map +1 -1
  4. package/dist/bridges/claude-code/channel.js +6 -1
  5. package/dist/bridges/claude-code/channel.js.map +1 -1
  6. package/dist/bridges/codex/tool.d.ts.map +1 -1
  7. package/dist/bridges/codex/tool.js +6 -1
  8. package/dist/bridges/codex/tool.js.map +1 -1
  9. package/dist/bridges/mcp/index.d.ts.map +1 -1
  10. package/dist/bridges/mcp/index.js +6 -1
  11. package/dist/bridges/mcp/index.js.map +1 -1
  12. package/dist/bridges/opencode/plugin.d.ts.map +1 -1
  13. package/dist/bridges/opencode/plugin.js +5 -0
  14. package/dist/bridges/opencode/plugin.js.map +1 -1
  15. package/dist/bridges/pi/index.d.ts.map +1 -1
  16. package/dist/bridges/pi/index.js +39 -17
  17. package/dist/bridges/pi/index.js.map +1 -1
  18. package/dist/bridges/user/controller.d.ts +9 -1
  19. package/dist/bridges/user/controller.d.ts.map +1 -1
  20. package/dist/bridges/user/controller.js +25 -1
  21. package/dist/bridges/user/controller.js.map +1 -1
  22. package/dist/bridges/user/tui.js +2 -0
  23. package/dist/bridges/user/tui.js.map +1 -1
  24. package/dist/bridges/user/web/build.d.ts +2 -0
  25. package/dist/bridges/user/web/build.d.ts.map +1 -1
  26. package/dist/bridges/user/web/build.js +44 -0
  27. package/dist/bridges/user/web/build.js.map +1 -1
  28. package/dist/bridges/user/web/frontend/components/App.d.ts +5 -0
  29. package/dist/bridges/user/web/frontend/components/App.d.ts.map +1 -1
  30. package/dist/bridges/user/web/frontend/components/App.js +1 -1
  31. package/dist/bridges/user/web/frontend/components/App.js.map +1 -1
  32. package/dist/bridges/user/web/frontend/components/ProjectTree.js +6 -3
  33. package/dist/bridges/user/web/frontend/components/ProjectTree.js.map +1 -1
  34. package/dist/bridges/user/web/frontend/components/RelayPanel.d.ts +15 -0
  35. package/dist/bridges/user/web/frontend/components/RelayPanel.d.ts.map +1 -0
  36. package/dist/bridges/user/web/frontend/components/RelayPanel.js +46 -0
  37. package/dist/bridges/user/web/frontend/components/RelayPanel.js.map +1 -0
  38. package/dist/bridges/user/web/frontend/components/Sidebar.d.ts +7 -2
  39. package/dist/bridges/user/web/frontend/components/Sidebar.d.ts.map +1 -1
  40. package/dist/bridges/user/web/frontend/components/Sidebar.js +15 -9
  41. package/dist/bridges/user/web/frontend/components/Sidebar.js.map +1 -1
  42. package/dist/bridges/user/web/frontend/input.js +1 -1
  43. package/dist/bridges/user/web/frontend/input.js.map +1 -1
  44. package/dist/bridges/user/web/frontend/main.js +73 -5
  45. package/dist/bridges/user/web/frontend/main.js.map +1 -1
  46. package/dist/bridges/user/web/frontend/mesh-client.d.ts +43 -0
  47. package/dist/bridges/user/web/frontend/mesh-client.d.ts.map +1 -0
  48. package/dist/bridges/user/web/frontend/mesh-client.js +132 -0
  49. package/dist/bridges/user/web/frontend/mesh-client.js.map +1 -0
  50. package/dist/bridges/user/web/frontend/mesh-worker.d.ts +14 -0
  51. package/dist/bridges/user/web/frontend/mesh-worker.d.ts.map +1 -0
  52. package/dist/bridges/user/web/frontend/mesh-worker.js +274 -0
  53. package/dist/bridges/user/web/frontend/mesh-worker.js.map +1 -0
  54. package/dist/bridges/user/web/frontend/relay-client.d.ts +40 -0
  55. package/dist/bridges/user/web/frontend/relay-client.d.ts.map +1 -0
  56. package/dist/bridges/user/web/frontend/relay-client.js +97 -0
  57. package/dist/bridges/user/web/frontend/relay-client.js.map +1 -0
  58. package/dist/bridges/user/web/frontend/relay-worker.d.ts +15 -0
  59. package/dist/bridges/user/web/frontend/relay-worker.d.ts.map +1 -0
  60. package/dist/bridges/user/web/frontend/relay-worker.js +366 -0
  61. package/dist/bridges/user/web/frontend/relay-worker.js.map +1 -0
  62. package/dist/bridges/user/web/frontend/sw.d.ts +16 -0
  63. package/dist/bridges/user/web/frontend/sw.d.ts.map +1 -0
  64. package/dist/bridges/user/web/frontend/sw.js +145 -0
  65. package/dist/bridges/user/web/frontend/sw.js.map +1 -0
  66. package/dist/bridges/user/web/frontend/url-sync.d.ts +48 -0
  67. package/dist/bridges/user/web/frontend/url-sync.d.ts.map +1 -0
  68. package/dist/bridges/user/web/frontend/url-sync.js +74 -0
  69. package/dist/bridges/user/web/frontend/url-sync.js.map +1 -0
  70. package/dist/bridges/user/web/server.d.ts +10 -3
  71. package/dist/bridges/user/web/server.d.ts.map +1 -1
  72. package/dist/bridges/user/web/server.js +254 -12
  73. package/dist/bridges/user/web/server.js.map +1 -1
  74. package/dist/core/bridge.d.ts +28 -0
  75. package/dist/core/bridge.d.ts.map +1 -1
  76. package/dist/core/bridge.js +137 -0
  77. package/dist/core/bridge.js.map +1 -1
  78. package/dist/core/comms-store.d.ts +22 -1
  79. package/dist/core/comms-store.d.ts.map +1 -1
  80. package/dist/core/discovery-mdns.d.ts +33 -0
  81. package/dist/core/discovery-mdns.d.ts.map +1 -0
  82. package/dist/core/discovery-mdns.js +182 -0
  83. package/dist/core/discovery-mdns.js.map +1 -0
  84. package/dist/core/discovery-tailscale.d.ts +40 -0
  85. package/dist/core/discovery-tailscale.d.ts.map +1 -0
  86. package/dist/core/discovery-tailscale.js +158 -0
  87. package/dist/core/discovery-tailscale.js.map +1 -0
  88. package/dist/core/discovery.d.ts +82 -0
  89. package/dist/core/discovery.d.ts.map +1 -0
  90. package/dist/core/discovery.js +194 -0
  91. package/dist/core/discovery.js.map +1 -0
  92. package/dist/core/federation.d.ts +100 -0
  93. package/dist/core/federation.d.ts.map +1 -0
  94. package/dist/core/federation.js +411 -0
  95. package/dist/core/federation.js.map +1 -0
  96. package/dist/core/identity.d.ts +31 -0
  97. package/dist/core/identity.d.ts.map +1 -0
  98. package/dist/core/identity.js +251 -0
  99. package/dist/core/identity.js.map +1 -0
  100. package/dist/core/index.d.ts +11 -0
  101. package/dist/core/index.d.ts.map +1 -1
  102. package/dist/core/index.js +6 -0
  103. package/dist/core/index.js.map +1 -1
  104. package/dist/core/mesh-store.d.ts +72 -26
  105. package/dist/core/mesh-store.d.ts.map +1 -1
  106. package/dist/core/mesh-store.js +467 -352
  107. package/dist/core/mesh-store.js.map +1 -1
  108. package/dist/core/push-manager.d.ts +41 -0
  109. package/dist/core/push-manager.d.ts.map +1 -0
  110. package/dist/core/push-manager.js +60 -0
  111. package/dist/core/push-manager.js.map +1 -0
  112. package/dist/core/store.d.ts +21 -1
  113. package/dist/core/store.d.ts.map +1 -1
  114. package/dist/core/store.js +44 -0
  115. package/dist/core/store.js.map +1 -1
  116. package/dist/core/tcp-transport.d.ts +77 -0
  117. package/dist/core/tcp-transport.d.ts.map +1 -0
  118. package/dist/core/tcp-transport.js +596 -0
  119. package/dist/core/tcp-transport.js.map +1 -0
  120. package/dist/core/test/identity.unit.test.d.ts +5 -0
  121. package/dist/core/test/identity.unit.test.d.ts.map +1 -0
  122. package/dist/core/test/identity.unit.test.js +70 -0
  123. package/dist/core/test/identity.unit.test.js.map +1 -0
  124. package/dist/core/tls-transport.d.ts +69 -0
  125. package/dist/core/tls-transport.d.ts.map +1 -0
  126. package/dist/core/tls-transport.js +602 -0
  127. package/dist/core/tls-transport.js.map +1 -0
  128. package/dist/core/tool.d.ts +23 -2
  129. package/dist/core/tool.d.ts.map +1 -1
  130. package/dist/core/tool.js +269 -1
  131. package/dist/core/tool.js.map +1 -1
  132. package/dist/core/transport.d.ts +166 -0
  133. package/dist/core/transport.d.ts.map +1 -0
  134. package/dist/core/transport.js +20 -0
  135. package/dist/core/transport.js.map +1 -0
  136. package/dist/core/types.d.ts +136 -0
  137. package/dist/core/types.d.ts.map +1 -1
  138. package/dist/core/types.js +71 -0
  139. package/dist/core/types.js.map +1 -1
  140. package/dist/core/vapid.d.ts +22 -0
  141. package/dist/core/vapid.d.ts.map +1 -0
  142. package/dist/core/vapid.js +50 -0
  143. package/dist/core/vapid.js.map +1 -0
  144. package/dist/core/web-push.d.ts +37 -0
  145. package/dist/core/web-push.d.ts.map +1 -0
  146. package/dist/core/web-push.js +198 -0
  147. package/dist/core/web-push.js.map +1 -0
  148. package/dist/core/wire-protocol.d.ts +131 -0
  149. package/dist/core/wire-protocol.d.ts.map +1 -0
  150. package/dist/core/wire-protocol.js +54 -0
  151. package/dist/core/wire-protocol.js.map +1 -0
  152. package/dist/core/ws-transport.d.ts +71 -0
  153. package/dist/core/ws-transport.d.ts.map +1 -0
  154. package/dist/core/ws-transport.js +560 -0
  155. package/dist/core/ws-transport.js.map +1 -0
  156. package/dist/test/approval.integration.test.d.ts +9 -0
  157. package/dist/test/approval.integration.test.d.ts.map +1 -0
  158. package/dist/test/approval.integration.test.js +361 -0
  159. package/dist/test/approval.integration.test.js.map +1 -0
  160. package/dist/test/delivery-receipt.helper.d.ts +16 -0
  161. package/dist/test/delivery-receipt.helper.d.ts.map +1 -0
  162. package/dist/test/delivery-receipt.helper.js +409 -0
  163. package/dist/test/delivery-receipt.helper.js.map +1 -0
  164. package/dist/test/delivery-receipt.runner.d.ts +13 -0
  165. package/dist/test/delivery-receipt.runner.d.ts.map +1 -0
  166. package/dist/test/delivery-receipt.runner.js +51 -0
  167. package/dist/test/delivery-receipt.runner.js.map +1 -0
  168. package/dist/test/federation.integration.test.d.ts +15 -0
  169. package/dist/test/federation.integration.test.d.ts.map +1 -0
  170. package/dist/test/federation.integration.test.js +218 -0
  171. package/dist/test/federation.integration.test.js.map +1 -0
  172. package/dist/test/listener-policy.integration.test.d.ts +9 -0
  173. package/dist/test/listener-policy.integration.test.d.ts.map +1 -0
  174. package/dist/test/listener-policy.integration.test.js +239 -0
  175. package/dist/test/listener-policy.integration.test.js.map +1 -0
  176. package/dist/test/tls-transport.integration.test.d.ts +8 -0
  177. package/dist/test/tls-transport.integration.test.d.ts.map +1 -0
  178. package/dist/test/tls-transport.integration.test.js +158 -0
  179. package/dist/test/tls-transport.integration.test.js.map +1 -0
  180. package/dist/test/visibility.integration.test.d.ts +12 -0
  181. package/dist/test/visibility.integration.test.d.ts.map +1 -0
  182. package/dist/test/visibility.integration.test.js +181 -0
  183. package/dist/test/visibility.integration.test.js.map +1 -0
  184. package/package.json +4 -1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * MeshClient — main-thread API for the mesh SharedWorker.
3
+ *
4
+ * Creates a SharedWorker from the built mesh-worker.js bundle and
5
+ * provides a typed interface for the React frontend to:
6
+ *
7
+ * - Query current mesh state (agents, rooms)
8
+ * - Execute actions (send, join, create room, etc.)
9
+ * - Subscribe to real-time state changes (patches)
10
+ *
11
+ * The SharedWorker maintains a single WebSocket connection to the
12
+ * server's /ws/mesh endpoint shared across all tabs.
13
+ */
14
+ // ---------------------------------------------------------------------------
15
+ // MeshClient
16
+ // ---------------------------------------------------------------------------
17
+ export class MeshClient {
18
+ worker;
19
+ state = {
20
+ agents: [],
21
+ rooms: [],
22
+ connected: false,
23
+ };
24
+ listeners = new Set();
25
+ actionCounter = 0;
26
+ pendingActions = new Map();
27
+ /** Connect to the mesh SharedWorker. Idempotent. */
28
+ connect() {
29
+ if (this.worker)
30
+ return;
31
+ const worker = new SharedWorker("/mesh-worker.js");
32
+ this.worker = worker;
33
+ worker.port.onmessage = (event) => {
34
+ const raw = JSON.parse(typeof event.data === "string" ? event.data : String(event.data));
35
+ if (!isOutboundMessage(raw))
36
+ return;
37
+ switch (raw.type) {
38
+ case "state": {
39
+ if (!("state" in raw) ||
40
+ typeof raw.state !== "object" ||
41
+ raw.state === null)
42
+ break;
43
+ if (!("agents" in raw.state) || !("rooms" in raw.state))
44
+ break;
45
+ const state = raw.state;
46
+ // State from mesh SharedWorker is SerialisedState where agents/rooms
47
+ // are Record<string, T>. Object.values on object returns any[], which
48
+ // is the actual runtime shape.
49
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
50
+ const agents = typeof state.agents === "object" && state.agents !== null
51
+ ? Object.values(state.agents)
52
+ : [];
53
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
54
+ const rooms = typeof state.rooms === "object" && state.rooms !== null
55
+ ? Object.values(state.rooms)
56
+ : [];
57
+ this.state = {
58
+ ...this.state,
59
+ agents,
60
+ rooms,
61
+ };
62
+ this.notify();
63
+ break;
64
+ }
65
+ case "connected":
66
+ this.state = { ...this.state, connected: true };
67
+ this.notify();
68
+ break;
69
+ case "disconnected":
70
+ this.state = { ...this.state, connected: false };
71
+ this.notify();
72
+ break;
73
+ case "patch":
74
+ // After any patch, refresh from the worker's authoritative state
75
+ this.postToWorker({ type: "getState" });
76
+ break;
77
+ case "actionResult": {
78
+ // For now, action results are broadcast — we don't correlate by ID
79
+ // because the server doesn't echo back an action ID. The main.tsx
80
+ // handles action results through the existing CommsWs.
81
+ break;
82
+ }
83
+ case "actionError":
84
+ break;
85
+ }
86
+ };
87
+ worker.port.start();
88
+ // Tell the worker to connect to the mesh WS endpoint
89
+ const proto = location.protocol === "https:" ? "wss:" : "ws:";
90
+ const url = `${proto}//${location.host}/ws/mesh`;
91
+ this.postToWorker({ type: "init", url });
92
+ }
93
+ /** Get the current mesh state (snapshot). */
94
+ get() {
95
+ return this.state;
96
+ }
97
+ /** Subscribe to state changes. Returns an unsubscribe function. */
98
+ subscribe(listener) {
99
+ this.listeners.add(listener);
100
+ return () => {
101
+ this.listeners.delete(listener);
102
+ };
103
+ }
104
+ /** Send an action through the mesh worker. */
105
+ sendAction(action) {
106
+ const id = String(++this.actionCounter);
107
+ this.postToWorker({ type: "action", id, action });
108
+ }
109
+ /** Disconnect and clean up. */
110
+ disconnect() {
111
+ if (this.worker) {
112
+ this.worker.port.close();
113
+ this.worker = undefined;
114
+ }
115
+ this.pendingActions.clear();
116
+ }
117
+ postToWorker(msg) {
118
+ if (this.worker) {
119
+ this.worker.port.postMessage(JSON.stringify(msg));
120
+ }
121
+ }
122
+ notify() {
123
+ const snapshot = this.state;
124
+ for (const listener of this.listeners) {
125
+ listener(snapshot);
126
+ }
127
+ }
128
+ }
129
+ function isOutboundMessage(value) {
130
+ return typeof value === "object" && value !== null && "type" in value;
131
+ }
132
+ //# sourceMappingURL=mesh-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-client.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/mesh-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * SharedWorker — browser mesh node.
3
+ *
4
+ * Runs a lightweight mesh state store connected to the server's /ws/mesh
5
+ * endpoint. Maintains a local copy of all mesh state (agents, rooms,
6
+ * messages, DMs) by applying state_sync and state_update patches received
7
+ * over WebSocket. Exposes a postMessage API for the main thread to query
8
+ * state, execute actions, and subscribe to real-time updates.
9
+ *
10
+ * Built as a separate IIFE bundle (mesh-worker.js) so the SharedWorker
11
+ * runs in its own global scope independent of the main app bundle.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=mesh-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-worker.d.ts","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/mesh-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,274 @@
1
+ /**
2
+ * SharedWorker — browser mesh node.
3
+ *
4
+ * Runs a lightweight mesh state store connected to the server's /ws/mesh
5
+ * endpoint. Maintains a local copy of all mesh state (agents, rooms,
6
+ * messages, DMs) by applying state_sync and state_update patches received
7
+ * over WebSocket. Exposes a postMessage API for the main thread to query
8
+ * state, execute actions, and subscribe to real-time updates.
9
+ *
10
+ * Built as a separate IIFE bundle (mesh-worker.js) so the SharedWorker
11
+ * runs in its own global scope independent of the main app bundle.
12
+ */
13
+ // ---------------------------------------------------------------------------
14
+ // Lightweight mesh state
15
+ // ---------------------------------------------------------------------------
16
+ const agents = new Map();
17
+ const rooms = new Map();
18
+ const messages = new Map();
19
+ const dms = new Map();
20
+ function applyStateSync(state) {
21
+ for (const [id, agent] of Object.entries(state.agents)) {
22
+ agents.set(id, agent);
23
+ }
24
+ for (const [id, room] of Object.entries(state.rooms)) {
25
+ rooms.set(id, room);
26
+ }
27
+ for (const [id, msgs] of Object.entries(state.messages)) {
28
+ messages.set(id, msgs);
29
+ }
30
+ for (const [id, dmMsgs] of Object.entries(state.dms)) {
31
+ dms.set(id, dmMsgs);
32
+ }
33
+ }
34
+ function applyPatch(patch) {
35
+ switch (patch.type) {
36
+ case "agent_upsert": {
37
+ const existing = agents.get(patch.agent.id);
38
+ if (existing) {
39
+ const merged = patch.agent;
40
+ for (const r of existing.subscribedRooms) {
41
+ if (!merged.subscribedRooms.includes(r)) {
42
+ merged.subscribedRooms.push(r);
43
+ }
44
+ }
45
+ agents.set(merged.id, merged);
46
+ }
47
+ else {
48
+ agents.set(patch.agent.id, patch.agent);
49
+ }
50
+ break;
51
+ }
52
+ case "agent_offline": {
53
+ const agent = agents.get(patch.agentId);
54
+ if (agent) {
55
+ agent.status = "offline";
56
+ agents.set(patch.agentId, agent);
57
+ }
58
+ break;
59
+ }
60
+ case "room_upsert": {
61
+ const existing = rooms.get(patch.room.id);
62
+ if (existing) {
63
+ const merged = patch.room;
64
+ for (const m of existing.members) {
65
+ if (!merged.members.includes(m))
66
+ merged.members.push(m);
67
+ }
68
+ rooms.set(merged.id, merged);
69
+ }
70
+ else {
71
+ rooms.set(patch.room.id, patch.room);
72
+ }
73
+ break;
74
+ }
75
+ case "room_delete":
76
+ rooms.delete(patch.roomId);
77
+ break;
78
+ case "message_add": {
79
+ const arr = messages.get(patch.roomId) ?? [];
80
+ arr.push(patch.message);
81
+ messages.set(patch.roomId, arr);
82
+ break;
83
+ }
84
+ case "dm_add": {
85
+ const arr = dms.get(patch.key) ?? [];
86
+ arr.push(patch.message);
87
+ dms.set(patch.key, arr);
88
+ break;
89
+ }
90
+ case "delivery":
91
+ // Delivery events are forwarded to the main thread as patches.
92
+ break;
93
+ case "message_read": {
94
+ if (patch.room) {
95
+ const msgs = messages.get(patch.room);
96
+ if (msgs) {
97
+ const msg = msgs.find((m) => m.id === patch.messageId);
98
+ if (msg && !msg.readBy.includes(patch.readBy)) {
99
+ msg.readBy.push(patch.readBy);
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ for (const [, dmMsgs] of dms) {
105
+ const msg = dmMsgs.find((m) => m.id === patch.messageId);
106
+ if (msg && !msg.readBy.includes(patch.readBy)) {
107
+ msg.readBy.push(patch.readBy);
108
+ }
109
+ }
110
+ }
111
+ break;
112
+ }
113
+ }
114
+ }
115
+ function getStateSnapshot() {
116
+ return {
117
+ agents: [...agents.values()],
118
+ rooms: [...rooms.values()],
119
+ };
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // WebSocket connection to /ws/mesh
123
+ // ---------------------------------------------------------------------------
124
+ let ws;
125
+ let reconnectTimer;
126
+ let wsUrl;
127
+ function connect(url) {
128
+ wsUrl = url;
129
+ if (reconnectTimer !== undefined) {
130
+ clearTimeout(reconnectTimer);
131
+ reconnectTimer = undefined;
132
+ }
133
+ const socket = new WebSocket(url);
134
+ ws = socket;
135
+ socket.onopen = () => {
136
+ broadcastToPorts({ type: "connected" });
137
+ };
138
+ socket.onclose = () => {
139
+ ws = undefined;
140
+ broadcastToPorts({ type: "disconnected" });
141
+ scheduleReconnect();
142
+ };
143
+ socket.onerror = () => {
144
+ // onclose fires after this
145
+ };
146
+ socket.onmessage = (event) => {
147
+ const raw = JSON.parse(typeof event.data === "string" ? event.data : String(event.data));
148
+ handleServerMessage(raw);
149
+ };
150
+ }
151
+ function scheduleReconnect() {
152
+ if (!wsUrl)
153
+ return;
154
+ reconnectTimer = setTimeout(() => {
155
+ if (wsUrl)
156
+ connect(wsUrl);
157
+ }, 3000);
158
+ }
159
+ function handleServerMessage(raw) {
160
+ if (isMeshStateMessage(raw)) {
161
+ if (raw.method === "state_sync") {
162
+ applyStateSync(raw.state);
163
+ broadcastToPorts({ type: "state", state: getStateSnapshot() });
164
+ }
165
+ else {
166
+ applyPatch(raw.patch);
167
+ broadcastToPorts({ type: "patch", patch: raw.patch });
168
+ }
169
+ return;
170
+ }
171
+ // Action responses from the server — { type: "result" } or { type: "error" }
172
+ if (typeof raw === "object" && raw !== null && "type" in raw) {
173
+ if (raw.type === "result" &&
174
+ "result" in raw &&
175
+ typeof raw.result === "object" &&
176
+ raw.result !== null &&
177
+ "content" in raw.result &&
178
+ typeof raw.result.content === "string" &&
179
+ "isError" in raw.result &&
180
+ typeof raw.result.isError === "boolean") {
181
+ broadcastToPorts({
182
+ type: "actionResult",
183
+ id: "",
184
+ result: { content: raw.result.content, isError: raw.result.isError },
185
+ });
186
+ }
187
+ else if (raw.type === "error" &&
188
+ "message" in raw &&
189
+ typeof raw.message === "string") {
190
+ broadcastToPorts({
191
+ type: "actionError",
192
+ id: "",
193
+ message: raw.message,
194
+ });
195
+ }
196
+ }
197
+ }
198
+ function isMeshStateMessage(value) {
199
+ if (typeof value !== "object" || value === null)
200
+ return false;
201
+ if (!("method" in value))
202
+ return false;
203
+ const method = value.method;
204
+ return (typeof method === "string" &&
205
+ (method === "state_sync" || method === "state_update"));
206
+ }
207
+ // ---------------------------------------------------------------------------
208
+ // Port management — fan-out to all connected main-thread tabs
209
+ // ---------------------------------------------------------------------------
210
+ const ports = new Set();
211
+ function broadcastToPorts(msg) {
212
+ const data = JSON.stringify(msg);
213
+ for (const port of ports) {
214
+ try {
215
+ port.postMessage(data);
216
+ }
217
+ catch {
218
+ // Port closed — cleaned up via port.onmessage error
219
+ }
220
+ }
221
+ }
222
+ function handlePortMessage(msg) {
223
+ switch (msg.type) {
224
+ case "init":
225
+ connect(msg.url);
226
+ break;
227
+ case "action": {
228
+ if (ws?.readyState === WebSocket.OPEN) {
229
+ ws.send(JSON.stringify(msg.action));
230
+ }
231
+ break;
232
+ }
233
+ case "getState":
234
+ broadcastToPorts({ type: "state", state: getStateSnapshot() });
235
+ break;
236
+ }
237
+ }
238
+ function isWorkerInbound(value) {
239
+ if (typeof value !== "object" || value === null)
240
+ return false;
241
+ if (!("type" in value))
242
+ return false;
243
+ const t = value.type;
244
+ return (typeof t === "string" &&
245
+ (t === "init" || t === "action" || t === "getState"));
246
+ }
247
+ // ---------------------------------------------------------------------------
248
+ // Entry point — listen for SharedWorker connections
249
+ // ---------------------------------------------------------------------------
250
+ self.addEventListener("connect", (event) => {
251
+ const rawPort = event.ports[0];
252
+ if (rawPort === undefined)
253
+ return;
254
+ // MessagePort satisfies MessagePortLike (has postMessage, close, onmessage)
255
+ ports.add(rawPort);
256
+ // Send current state to the new port
257
+ try {
258
+ rawPort.postMessage(JSON.stringify({
259
+ type: "state",
260
+ state: getStateSnapshot(),
261
+ }));
262
+ }
263
+ catch {
264
+ // Port not ready yet — will get state on next update
265
+ }
266
+ rawPort.onmessage = (e) => {
267
+ const parsed = JSON.parse(typeof e.data === "string" ? e.data : String(e.data));
268
+ if (isWorkerInbound(parsed)) {
269
+ handlePortMessage(parsed);
270
+ }
271
+ };
272
+ });
273
+ export {};
274
+ //# sourceMappingURL=mesh-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-worker.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/mesh-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * RelayClient — main-thread API for the relay SharedWorker.
3
+ *
4
+ * Creates a SharedWorker from the built relay-worker.js bundle and
5
+ * provides a typed interface for the React frontend to:
6
+ *
7
+ * - Connect to two mesh endpoints simultaneously
8
+ * - Disconnect from both
9
+ * - Query relay status (connection state, forwarding stats)
10
+ * - Subscribe to real-time status updates
11
+ */
12
+ export interface RelayStatus {
13
+ connectedA: boolean;
14
+ connectedB: boolean;
15
+ urlA: string | undefined;
16
+ urlB: string | undefined;
17
+ forwardedCount: number;
18
+ errors: string[];
19
+ }
20
+ export type RelayStatusListener = (status: RelayStatus) => void;
21
+ export declare class RelayClient {
22
+ private worker;
23
+ private status;
24
+ private readonly listeners;
25
+ /** Connect to the relay SharedWorker. Idempotent. */
26
+ connect(): void;
27
+ /** Connect the relay to two mesh WebSocket endpoints. */
28
+ connectRelay(urlA: string, urlB: string): void;
29
+ /** Disconnect the relay from both mesh endpoints. */
30
+ disconnect(): void;
31
+ /** Get the current relay status (snapshot). */
32
+ get(): Readonly<RelayStatus>;
33
+ /** Subscribe to status changes. Returns an unsubscribe function. */
34
+ subscribe(listener: RelayStatusListener): () => void;
35
+ /** Destroy the client and release the SharedWorker port. */
36
+ destroy(): void;
37
+ private postToWorker;
38
+ private notify;
39
+ }
40
+ //# sourceMappingURL=relay-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-client.d.ts","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/relay-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;AAMhE,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAOZ;IACF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;IAE5D,qDAAqD;IACrD,OAAO,IAAI,IAAI;IAqBf,yDAAyD;IACzD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9C,qDAAqD;IACrD,UAAU,IAAI,IAAI;IAIlB,+CAA+C;IAC/C,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC;IAI5B,oEAAoE;IACpE,SAAS,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAOpD,4DAA4D;IAC5D,OAAO,IAAI,IAAI;IAOf,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,MAAM;CAMf"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * RelayClient — main-thread API for the relay SharedWorker.
3
+ *
4
+ * Creates a SharedWorker from the built relay-worker.js bundle and
5
+ * provides a typed interface for the React frontend to:
6
+ *
7
+ * - Connect to two mesh endpoints simultaneously
8
+ * - Disconnect from both
9
+ * - Query relay status (connection state, forwarding stats)
10
+ * - Subscribe to real-time status updates
11
+ */
12
+ // ---------------------------------------------------------------------------
13
+ // RelayClient
14
+ // ---------------------------------------------------------------------------
15
+ export class RelayClient {
16
+ worker;
17
+ status = {
18
+ connectedA: false,
19
+ connectedB: false,
20
+ urlA: undefined,
21
+ urlB: undefined,
22
+ forwardedCount: 0,
23
+ errors: [],
24
+ };
25
+ listeners = new Set();
26
+ /** Connect to the relay SharedWorker. Idempotent. */
27
+ connect() {
28
+ if (this.worker)
29
+ return;
30
+ const worker = new SharedWorker("/relay-worker.js");
31
+ this.worker = worker;
32
+ worker.port.onmessage = (event) => {
33
+ const raw = JSON.parse(typeof event.data === "string" ? event.data : String(event.data));
34
+ if (isStatusMessage(raw)) {
35
+ this.status = raw.status;
36
+ this.notify();
37
+ }
38
+ else if (isErrorMessage(raw)) {
39
+ console.error("[RelayClient]", raw.message);
40
+ }
41
+ };
42
+ worker.port.start();
43
+ }
44
+ /** Connect the relay to two mesh WebSocket endpoints. */
45
+ connectRelay(urlA, urlB) {
46
+ this.postToWorker({ type: "connect", urlA, urlB });
47
+ }
48
+ /** Disconnect the relay from both mesh endpoints. */
49
+ disconnect() {
50
+ this.postToWorker({ type: "disconnect" });
51
+ }
52
+ /** Get the current relay status (snapshot). */
53
+ get() {
54
+ return this.status;
55
+ }
56
+ /** Subscribe to status changes. Returns an unsubscribe function. */
57
+ subscribe(listener) {
58
+ this.listeners.add(listener);
59
+ return () => {
60
+ this.listeners.delete(listener);
61
+ };
62
+ }
63
+ /** Destroy the client and release the SharedWorker port. */
64
+ destroy() {
65
+ if (this.worker) {
66
+ this.worker.port.close();
67
+ this.worker = undefined;
68
+ }
69
+ }
70
+ postToWorker(msg) {
71
+ if (this.worker) {
72
+ this.worker.port.postMessage(JSON.stringify(msg));
73
+ }
74
+ }
75
+ notify() {
76
+ const snapshot = this.status;
77
+ for (const listener of this.listeners) {
78
+ listener(snapshot);
79
+ }
80
+ }
81
+ }
82
+ function isStatusMessage(value) {
83
+ return (typeof value === "object" &&
84
+ value !== null &&
85
+ "type" in value &&
86
+ typeof value.type === "string" &&
87
+ value.type === "status" &&
88
+ "status" in value);
89
+ }
90
+ function isErrorMessage(value) {
91
+ return (typeof value === "object" &&
92
+ value !== null &&
93
+ "type" in value &&
94
+ typeof value.type === "string" &&
95
+ value.type === "error");
96
+ }
97
+ //# sourceMappingURL=relay-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/relay-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * RelayWorker — SharedWorker that connects two mesh WebSocket endpoints
3
+ * and forwards wire messages between them with filtering and peer ID
4
+ * translation.
5
+ *
6
+ * Two isolated meshes can communicate through the browser without direct
7
+ * network connectivity between them. Peer IDs are prefixed with a mesh
8
+ * label ("a:" or "b:") to avoid collisions between the two meshes.
9
+ *
10
+ * Built as a separate IIFE bundle (relay-worker.js) so the SharedWorker
11
+ * runs in its own global scope independent of the main app and mesh-worker
12
+ * bundles.
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=relay-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-worker.d.ts","sourceRoot":"","sources":["../../../../../src/bridges/user/web/frontend/relay-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}