@derivation/rpc 0.3.5 → 0.5.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 (96) hide show
  1. package/dist/client-DJZfuakf.d.cts +27 -0
  2. package/dist/{client.d.ts → client-TPsVZH_B.d.ts} +7 -4
  3. package/dist/index.cjs +335 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +55 -0
  6. package/dist/index.d.ts +55 -7
  7. package/dist/index.js +305 -6
  8. package/dist/index.js.map +1 -0
  9. package/dist/iso.cjs +151 -0
  10. package/dist/iso.cjs.map +1 -0
  11. package/dist/iso.d.cts +52 -0
  12. package/dist/iso.d.ts +35 -19
  13. package/dist/iso.js +99 -101
  14. package/dist/iso.js.map +1 -0
  15. package/dist/{presence-manager.d.ts → presence-manager-4LlEyuGp.d.cts} +3 -1
  16. package/dist/presence-manager-4LlEyuGp.d.ts +7 -0
  17. package/dist/shared-worker-client.cjs +271 -0
  18. package/dist/shared-worker-client.cjs.map +1 -0
  19. package/dist/shared-worker-client.d.cts +26 -0
  20. package/dist/shared-worker-client.d.ts +8 -4
  21. package/dist/shared-worker-client.js +243 -24
  22. package/dist/shared-worker-client.js.map +1 -0
  23. package/dist/shared-worker-server.cjs +363 -0
  24. package/dist/shared-worker-server.cjs.map +1 -0
  25. package/dist/shared-worker-server.d.cts +31 -0
  26. package/dist/shared-worker-server.d.ts +9 -6
  27. package/dist/shared-worker-server.js +332 -58
  28. package/dist/shared-worker-server.js.map +1 -0
  29. package/dist/stream-types-Q_EqNLtO.d.cts +46 -0
  30. package/dist/stream-types-Q_EqNLtO.d.ts +46 -0
  31. package/dist/transport.cjs +19 -0
  32. package/dist/transport.cjs.map +1 -0
  33. package/dist/transport.d.cts +29 -0
  34. package/dist/transport.d.ts +3 -1
  35. package/dist/transport.js +1 -1
  36. package/dist/transport.js.map +1 -0
  37. package/dist/web-socket-server.cjs +469 -0
  38. package/dist/web-socket-server.cjs.map +1 -0
  39. package/dist/web-socket-server.d.cts +14 -0
  40. package/dist/web-socket-server.d.ts +10 -7
  41. package/dist/web-socket-server.js +437 -52
  42. package/dist/web-socket-server.js.map +1 -0
  43. package/dist/web-socket-transport.cjs +52 -0
  44. package/dist/web-socket-transport.cjs.map +1 -0
  45. package/dist/web-socket-transport.d.cts +16 -0
  46. package/dist/web-socket-transport.d.ts +5 -2
  47. package/dist/web-socket-transport.js +27 -25
  48. package/dist/web-socket-transport.js.map +1 -0
  49. package/package.json +26 -17
  50. package/dist/client-handler.d.ts +0 -27
  51. package/dist/client-handler.js +0 -187
  52. package/dist/client-message.d.ts +0 -57
  53. package/dist/client-message.js +0 -59
  54. package/dist/client.js +0 -133
  55. package/dist/messageport-transport.d.ts +0 -13
  56. package/dist/messageport-transport.js +0 -28
  57. package/dist/node-web-socket-transport.d.ts +0 -16
  58. package/dist/node-web-socket-transport.js +0 -33
  59. package/dist/presence-manager.js +0 -1
  60. package/dist/queue.d.ts +0 -9
  61. package/dist/queue.js +0 -32
  62. package/dist/rate-limiter.d.ts +0 -7
  63. package/dist/rate-limiter.js +0 -24
  64. package/dist/reactive-map-adapter.d.ts +0 -24
  65. package/dist/reactive-map-adapter.js +0 -43
  66. package/dist/reactive-set-adapter.d.ts +0 -24
  67. package/dist/reactive-set-adapter.js +0 -41
  68. package/dist/server-message.d.ts +0 -48
  69. package/dist/server-message.js +0 -52
  70. package/dist/shared-worker-client-handler.d.ts +0 -27
  71. package/dist/shared-worker-client-handler.js +0 -149
  72. package/dist/stream-adapter.d.ts +0 -23
  73. package/dist/stream-adapter.js +0 -35
  74. package/dist/stream-types.d.ts +0 -44
  75. package/dist/stream-types.js +0 -1
  76. package/dist/tests/context.test.d.ts +0 -1
  77. package/dist/tests/context.test.js +0 -252
  78. package/dist/tests/iso.test.d.ts +0 -1
  79. package/dist/tests/iso.test.js +0 -186
  80. package/dist/tests/messages.test.d.ts +0 -1
  81. package/dist/tests/messages.test.js +0 -152
  82. package/dist/tests/mutations.test.d.ts +0 -1
  83. package/dist/tests/mutations.test.js +0 -122
  84. package/dist/tests/queue.test.d.ts +0 -1
  85. package/dist/tests/queue.test.js +0 -84
  86. package/dist/tests/reactive-map-adapter.test.d.ts +0 -1
  87. package/dist/tests/reactive-map-adapter.test.js +0 -190
  88. package/dist/tests/reactive-set-adapter.test.d.ts +0 -1
  89. package/dist/tests/reactive-set-adapter.test.js +0 -157
  90. package/dist/tests/stream-adapter.test.d.ts +0 -1
  91. package/dist/tests/stream-adapter.test.js +0 -119
  92. package/dist/tests/weak-list.test.d.ts +0 -1
  93. package/dist/tests/weak-list.test.js +0 -100
  94. package/dist/tsconfig.tsbuildinfo +0 -1
  95. package/dist/weak-list.d.ts +0 -5
  96. package/dist/weak-list.js +0 -19
@@ -1,25 +1,244 @@
1
- import { Client } from "./client.js";
2
- import { MessagePortTransport } from "./messageport-transport.js";
3
- /**
4
- * Create a client connected to a SharedWorker.
5
- *
6
- * @example
7
- * ```typescript
8
- * // main.ts
9
- * const graph = new Graph();
10
- * const worker = new SharedWorker('/worker.js');
11
- *
12
- * const client = createSharedWorkerClient(worker.port, {
13
- * streams: {
14
- * todos: setSink(graph, todoIso),
15
- * },
16
- * }, graph);
17
- *
18
- * const todos = await client.run('todos', { filter: 'active' });
19
- * ```
20
- */
21
- export function createSharedWorkerClient(port, sinks, graph) {
22
- const transport = new MessagePortTransport(port);
23
- port.start();
24
- return new Client(transport, sinks, graph);
1
+ // src/client-message.ts
2
+ import { z } from "zod";
3
+ var SubscribeMessageSchema = z.object({
4
+ type: z.literal("subscribe"),
5
+ id: z.number(),
6
+ name: z.string(),
7
+ args: z.looseObject({})
8
+ });
9
+ var UnsubscribeMessageSchema = z.object({
10
+ type: z.literal("unsubscribe"),
11
+ id: z.number()
12
+ });
13
+ var HeartbeatMessageSchema = z.object({
14
+ type: z.literal("heartbeat")
15
+ });
16
+ var CallMessageSchema = z.object({
17
+ type: z.literal("call"),
18
+ id: z.number(),
19
+ name: z.string(),
20
+ args: z.looseObject({})
21
+ });
22
+ var PresenceMessageSchema = z.object({
23
+ type: z.literal("presence"),
24
+ data: z.looseObject({})
25
+ });
26
+ var ClientMessageSchema = z.discriminatedUnion("type", [
27
+ SubscribeMessageSchema,
28
+ UnsubscribeMessageSchema,
29
+ HeartbeatMessageSchema,
30
+ CallMessageSchema,
31
+ PresenceMessageSchema
32
+ ]);
33
+ var ClientMessage = {
34
+ subscribe: (id, name, args) => ({
35
+ type: "subscribe",
36
+ id,
37
+ name,
38
+ args
39
+ }),
40
+ unsubscribe: (id) => ({
41
+ type: "unsubscribe",
42
+ id
43
+ }),
44
+ call: (id, name, args) => ({
45
+ type: "call",
46
+ id,
47
+ name,
48
+ args
49
+ }),
50
+ heartbeat: () => ({
51
+ type: "heartbeat"
52
+ }),
53
+ presence: (data) => ({
54
+ type: "presence",
55
+ data
56
+ })
57
+ };
58
+
59
+ // src/client.ts
60
+ function changer(sink, input) {
61
+ return (change) => {
62
+ const i = input.deref();
63
+ if (i) {
64
+ sink.apply(change, i);
65
+ }
66
+ };
25
67
  }
68
+ var Client = class {
69
+ constructor(transport, sinks, graph) {
70
+ this.transport = transport;
71
+ this.sinks = sinks;
72
+ this.graph = graph;
73
+ this.nextId = 1;
74
+ this.pendingStreams = /* @__PURE__ */ new Map();
75
+ this.pendingMutations = /* @__PURE__ */ new Map();
76
+ this.activeStreams = /* @__PURE__ */ new Map();
77
+ this.registry = new FinalizationRegistry(
78
+ ([id, name]) => {
79
+ console.log(`\u{1F9F9} Stream ${id} (${name}) collected \u2014 unsubscribing`);
80
+ this.sendMessage(ClientMessage.unsubscribe(id));
81
+ this.activeStreams.delete(id);
82
+ }
83
+ );
84
+ this.transport.onMessage((data) => {
85
+ const message = JSON.parse(data);
86
+ this.handleMessage(message);
87
+ });
88
+ this.resetHeartbeat();
89
+ this.resetInactivity();
90
+ }
91
+ resetHeartbeat() {
92
+ if (this.heartbeatTimeout) {
93
+ clearTimeout(this.heartbeatTimeout);
94
+ }
95
+ this.heartbeatTimeout = setTimeout(() => {
96
+ this.sendMessage(ClientMessage.heartbeat());
97
+ }, 1e4);
98
+ }
99
+ resetInactivity() {
100
+ if (this.inactivityTimeout) {
101
+ clearTimeout(this.inactivityTimeout);
102
+ }
103
+ this.inactivityTimeout = setTimeout(() => {
104
+ this.close();
105
+ }, 3e4);
106
+ }
107
+ handleMessage(message) {
108
+ this.resetInactivity();
109
+ switch (message.type) {
110
+ case "snapshot": {
111
+ console.log(`[Client] Received snapshot for stream ${message.id}`);
112
+ const resolve = this.pendingStreams.get(message.id);
113
+ if (resolve) {
114
+ resolve(message.snapshot);
115
+ this.pendingStreams.delete(message.id);
116
+ }
117
+ break;
118
+ }
119
+ case "delta": {
120
+ const changeCount = Object.keys(message.changes).length;
121
+ console.log(`[Client] Received delta with ${changeCount} changes for streams: ${Object.keys(message.changes).join(", ")}`);
122
+ for (const [idStr, change] of Object.entries(message.changes)) {
123
+ const id = Number(idStr);
124
+ const sink = this.activeStreams.get(id);
125
+ if (sink && change && typeof change === "object") {
126
+ sink(change);
127
+ } else if (!sink) {
128
+ console.log(`\u{1F9F9} Sink ${id} GC'd \u2014 auto-unsubscribing`);
129
+ this.sendMessage(ClientMessage.unsubscribe(id));
130
+ this.activeStreams.delete(id);
131
+ }
132
+ }
133
+ console.log("[Client] Stepping graph");
134
+ this.graph.step();
135
+ break;
136
+ }
137
+ case "result": {
138
+ console.log(`[Client] Received mutation result for call ${message.id}:`, message.success ? "success" : "error");
139
+ const resolve = this.pendingMutations.get(message.id);
140
+ if (resolve) {
141
+ if (message.success) {
142
+ resolve({ success: true, value: message.value });
143
+ } else {
144
+ resolve({
145
+ success: false,
146
+ error: message.error || "Unknown error"
147
+ });
148
+ }
149
+ this.pendingMutations.delete(message.id);
150
+ }
151
+ break;
152
+ }
153
+ case "heartbeat":
154
+ console.log("[Client] Received heartbeat");
155
+ break;
156
+ }
157
+ }
158
+ sendMessage(message) {
159
+ this.resetHeartbeat();
160
+ this.transport.send(JSON.stringify(message));
161
+ }
162
+ async run(key, args) {
163
+ console.log(
164
+ `Running stream ${String(key)} with args ${JSON.stringify(args)}`
165
+ );
166
+ const id = this.nextId++;
167
+ this.sendMessage(ClientMessage.subscribe(id, String(key), args));
168
+ const snapshot = await new Promise((resolve) => {
169
+ this.pendingStreams.set(id, resolve);
170
+ });
171
+ const endpoint = this.sinks[key];
172
+ const sinkAdapter = endpoint(snapshot);
173
+ const { stream, input } = sinkAdapter.build();
174
+ const inputRef = new WeakRef(input);
175
+ this.activeStreams.set(id, changer(sinkAdapter, inputRef));
176
+ this.registry.register(input, [id, String(key)]);
177
+ return stream;
178
+ }
179
+ async call(key, args) {
180
+ console.log(
181
+ `Calling mutation ${String(key)} with args ${JSON.stringify(args)}`
182
+ );
183
+ const id = this.nextId++;
184
+ this.sendMessage(
185
+ ClientMessage.call(id, String(key), args)
186
+ );
187
+ const result = await new Promise((resolve) => {
188
+ this.pendingMutations.set(
189
+ id,
190
+ resolve
191
+ );
192
+ });
193
+ return result;
194
+ }
195
+ close() {
196
+ clearTimeout(this.heartbeatTimeout);
197
+ clearTimeout(this.inactivityTimeout);
198
+ try {
199
+ this.transport.close();
200
+ } catch (e) {
201
+ }
202
+ }
203
+ setPresence(value) {
204
+ this.sendMessage(ClientMessage.presence(value));
205
+ }
206
+ };
207
+
208
+ // src/messageport-transport.ts
209
+ var MessagePortTransport = class {
210
+ constructor(port) {
211
+ this.port = port;
212
+ }
213
+ send(data) {
214
+ console.log("[MessagePortTransport] Sending:", data.substring(0, 100) + (data.length > 100 ? "..." : ""));
215
+ this.port.postMessage(data);
216
+ }
217
+ onMessage(handler) {
218
+ this.port.onmessage = (event) => {
219
+ console.log("[MessagePortTransport] Received:", event.data.substring(0, 100) + (event.data.length > 100 ? "..." : ""));
220
+ handler(event.data);
221
+ };
222
+ }
223
+ onClose(handler) {
224
+ this.port.onmessageerror = handler;
225
+ }
226
+ close() {
227
+ this.port.close();
228
+ }
229
+ // MessagePort doesn't provide bufferedAmount
230
+ get bufferedAmount() {
231
+ return void 0;
232
+ }
233
+ };
234
+
235
+ // src/shared-worker-client.ts
236
+ function createSharedWorkerClient(port, sinks, graph) {
237
+ const transport = new MessagePortTransport(port);
238
+ port.start();
239
+ return new Client(transport, sinks, graph);
240
+ }
241
+ export {
242
+ createSharedWorkerClient
243
+ };
244
+ //# sourceMappingURL=shared-worker-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client-message.ts","../src/client.ts","../src/messageport-transport.ts","../src/shared-worker-client.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const SubscribeMessageSchema = z.object({\n type: z.literal(\"subscribe\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type SubscribeMessage = z.infer<typeof SubscribeMessageSchema>;\n\nexport const UnsubscribeMessageSchema = z.object({\n type: z.literal(\"unsubscribe\"),\n id: z.number(),\n});\nexport type UnsubscribeMessage = z.infer<typeof UnsubscribeMessageSchema>;\n\nexport const HeartbeatMessageSchema = z.object({\n type: z.literal(\"heartbeat\"),\n});\nexport type HeartbeatMessage = z.infer<typeof HeartbeatMessageSchema>;\n\nexport const CallMessageSchema = z.object({\n type: z.literal(\"call\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type CallMessage = z.infer<typeof CallMessageSchema>;\n\nexport const PresenceMessageSchema = z.object({\n type: z.literal(\"presence\"),\n data: z.looseObject({}),\n});\nexport type PresenceMessage = z.infer<typeof PresenceMessageSchema>;\n\nexport const ClientMessageSchema = z.discriminatedUnion(\"type\", [\n SubscribeMessageSchema,\n UnsubscribeMessageSchema,\n HeartbeatMessageSchema,\n CallMessageSchema,\n PresenceMessageSchema,\n]);\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\nexport function parseClientMessage(data: unknown): ClientMessage {\n return ClientMessageSchema.parse(data);\n}\n\nexport const ClientMessage = {\n subscribe: (\n id: number,\n name: string,\n args: object,\n ): SubscribeMessage => ({\n type: \"subscribe\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n unsubscribe: (id: number): UnsubscribeMessage => ({\n type: \"unsubscribe\",\n id,\n }),\n call: (\n id: number,\n name: string,\n args: object,\n ): CallMessage => ({\n type: \"call\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n heartbeat: (): HeartbeatMessage => ({\n type: \"heartbeat\",\n }),\n presence: (data: object): PresenceMessage => ({\n type: \"presence\",\n data: data as Record<string, unknown>,\n }),\n};\n","import { ClientMessage } from \"./client-message.js\";\nimport { ServerMessage } from \"./server-message.js\";\nimport type { Graph } from \"derivation\";\nimport type {\n Sink,\n StreamSinks,\n RPCDefinition,\n MutationResult,\n} from \"./stream-types.js\";\nimport { Transport } from \"./transport.js\";\n\nfunction changer<T extends object, I extends object>(\n sink: Sink<T, I>,\n input: WeakRef<I>,\n): (change: object) => void {\n return (change) => {\n const i = input.deref();\n if (i) {\n sink.apply(change, i);\n }\n };\n}\n\nexport class Client<Defs extends RPCDefinition> {\n private nextId = 1;\n private pendingStreams = new Map<number, (snapshot: object) => void>();\n private pendingMutations = new Map<\n number,\n (result: MutationResult<unknown>) => void\n >();\n private activeStreams = new Map<number, (change: object) => void>();\n private heartbeatTimeout: NodeJS.Timeout | undefined;\n private inactivityTimeout: NodeJS.Timeout | undefined;\n\n private registry = new FinalizationRegistry<[number, string]>(\n ([id, name]) => {\n console.log(`🧹 Stream ${id} (${name}) collected — unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n },\n );\n\n private resetHeartbeat() {\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n }\n\n this.heartbeatTimeout = setTimeout(() => {\n this.sendMessage(ClientMessage.heartbeat());\n }, 10_000);\n }\n\n private resetInactivity() {\n if (this.inactivityTimeout) {\n clearTimeout(this.inactivityTimeout);\n }\n\n this.inactivityTimeout = setTimeout(() => {\n this.close();\n }, 30_000);\n }\n\n constructor(\n private transport: Transport,\n private sinks: StreamSinks<Defs[\"streams\"]>,\n private graph: Graph,\n ) {\n this.transport.onMessage((data: string) => {\n const message = JSON.parse(data) as ServerMessage;\n this.handleMessage(message);\n });\n this.resetHeartbeat();\n this.resetInactivity();\n }\n\n private handleMessage(message: ServerMessage) {\n this.resetInactivity();\n\n switch (message.type) {\n case \"snapshot\": {\n console.log(`[Client] Received snapshot for stream ${message.id}`);\n const resolve = this.pendingStreams.get(message.id);\n if (resolve) {\n resolve(message.snapshot as object);\n this.pendingStreams.delete(message.id);\n }\n break;\n }\n case \"delta\": {\n const changeCount = Object.keys(message.changes).length;\n console.log(`[Client] Received delta with ${changeCount} changes for streams: ${Object.keys(message.changes).join(\", \")}`);\n for (const [idStr, change] of Object.entries(message.changes)) {\n const id = Number(idStr);\n const sink = this.activeStreams.get(id);\n\n if (sink && change && typeof change === \"object\") {\n sink(change);\n } else if (!sink) {\n console.log(`🧹 Sink ${id} GC'd — auto-unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n }\n }\n console.log(\"[Client] Stepping graph\");\n this.graph.step();\n break;\n }\n case \"result\": {\n console.log(`[Client] Received mutation result for call ${message.id}:`, message.success ? \"success\" : \"error\");\n const resolve = this.pendingMutations.get(message.id);\n if (resolve) {\n if (message.success) {\n resolve({ success: true, value: message.value });\n } else {\n resolve({\n success: false,\n error: message.error || \"Unknown error\",\n });\n }\n this.pendingMutations.delete(message.id);\n }\n break;\n }\n case \"heartbeat\":\n console.log(\"[Client] Received heartbeat\");\n break;\n }\n }\n\n private sendMessage(message: ClientMessage) {\n this.resetHeartbeat();\n this.transport.send(JSON.stringify(message));\n }\n\n async run<Key extends keyof Defs[\"streams\"]>(\n key: Key,\n args: Defs[\"streams\"][Key][\"args\"],\n ): Promise<Defs[\"streams\"][Key][\"returnType\"]> {\n console.log(\n `Running stream ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(ClientMessage.subscribe(id, String(key), args));\n\n const snapshot = await new Promise<object>((resolve) => {\n this.pendingStreams.set(id, resolve);\n });\n\n const endpoint = this.sinks[key];\n const sinkAdapter = endpoint(snapshot);\n const { stream, input } = sinkAdapter.build();\n const inputRef = new WeakRef(input);\n this.activeStreams.set(id, changer(sinkAdapter, inputRef));\n this.registry.register(input, [id, String(key)]);\n\n return stream;\n }\n\n async call<Key extends keyof Defs[\"mutations\"]>(\n key: Key,\n args: Defs[\"mutations\"][Key][\"args\"],\n ): Promise<MutationResult<Defs[\"mutations\"][Key][\"result\"]>> {\n console.log(\n `Calling mutation ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(\n ClientMessage.call(id, String(key), args as Record<string, unknown>),\n );\n\n const result = await new Promise<\n MutationResult<Defs[\"mutations\"][Key][\"result\"]>\n >((resolve) => {\n this.pendingMutations.set(\n id,\n resolve as (result: MutationResult<unknown>) => void,\n );\n });\n\n return result;\n }\n\n close() {\n clearTimeout(this.heartbeatTimeout);\n clearTimeout(this.inactivityTimeout);\n try {\n this.transport.close();\n } catch {}\n }\n\n setPresence(value: Record<string, unknown>): void {\n this.sendMessage(ClientMessage.presence(value));\n }\n}\n","import { Transport } from \"./transport.js\";\n\n/**\n * Transport implementation for MessagePort (SharedWorker communication).\n */\nexport class MessagePortTransport implements Transport {\n constructor(private port: MessagePort) {}\n\n send(data: string): void {\n console.log(\"[MessagePortTransport] Sending:\", data.substring(0, 100) + (data.length > 100 ? \"...\" : \"\"));\n this.port.postMessage(data);\n }\n\n onMessage(handler: (data: string) => void): void {\n this.port.onmessage = (event: MessageEvent) => {\n console.log(\"[MessagePortTransport] Received:\", event.data.substring(0, 100) + (event.data.length > 100 ? \"...\" : \"\"));\n handler(event.data);\n };\n }\n\n onClose(handler: () => void): void {\n // MessagePort doesn't have a reliable close event\n // We'll use messageerror as a signal, though it's not perfect\n this.port.onmessageerror = handler;\n }\n\n close(): void {\n this.port.close();\n }\n\n // MessagePort doesn't provide bufferedAmount\n get bufferedAmount(): undefined {\n return undefined;\n }\n}\n","import { Graph } from \"derivation\";\nimport { Client } from \"./client.js\";\nimport { MessagePortTransport } from \"./messageport-transport.js\";\nimport { StreamSinks, RPCDefinition } from \"./stream-types.js\";\n\n/**\n * Create a client connected to a SharedWorker.\n *\n * @example\n * ```typescript\n * // main.ts\n * const graph = new Graph();\n * const worker = new SharedWorker('/worker.js');\n *\n * const client = createSharedWorkerClient(worker.port, {\n * streams: {\n * todos: setSink(graph, todoIso),\n * },\n * }, graph);\n *\n * const todos = await client.run('todos', { filter: 'active' });\n * ```\n */\nexport function createSharedWorkerClient<Defs extends RPCDefinition>(\n port: MessagePort,\n sinks: StreamSinks<Defs[\"streams\"]>,\n graph: Graph,\n): Client<Defs> {\n const transport = new MessagePortTransport(port);\n port.start();\n return new Client<Defs>(transport, sinks, graph);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,363 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/shared-worker-server.ts
21
+ var shared_worker_server_exports = {};
22
+ __export(shared_worker_server_exports, {
23
+ setupSharedWorker: () => setupSharedWorker
24
+ });
25
+ module.exports = __toCommonJS(shared_worker_server_exports);
26
+
27
+ // src/client-message.ts
28
+ var import_zod = require("zod");
29
+ var SubscribeMessageSchema = import_zod.z.object({
30
+ type: import_zod.z.literal("subscribe"),
31
+ id: import_zod.z.number(),
32
+ name: import_zod.z.string(),
33
+ args: import_zod.z.looseObject({})
34
+ });
35
+ var UnsubscribeMessageSchema = import_zod.z.object({
36
+ type: import_zod.z.literal("unsubscribe"),
37
+ id: import_zod.z.number()
38
+ });
39
+ var HeartbeatMessageSchema = import_zod.z.object({
40
+ type: import_zod.z.literal("heartbeat")
41
+ });
42
+ var CallMessageSchema = import_zod.z.object({
43
+ type: import_zod.z.literal("call"),
44
+ id: import_zod.z.number(),
45
+ name: import_zod.z.string(),
46
+ args: import_zod.z.looseObject({})
47
+ });
48
+ var PresenceMessageSchema = import_zod.z.object({
49
+ type: import_zod.z.literal("presence"),
50
+ data: import_zod.z.looseObject({})
51
+ });
52
+ var ClientMessageSchema = import_zod.z.discriminatedUnion("type", [
53
+ SubscribeMessageSchema,
54
+ UnsubscribeMessageSchema,
55
+ HeartbeatMessageSchema,
56
+ CallMessageSchema,
57
+ PresenceMessageSchema
58
+ ]);
59
+ function parseClientMessage(data) {
60
+ return ClientMessageSchema.parse(data);
61
+ }
62
+
63
+ // src/server-message.ts
64
+ var import_zod2 = require("zod");
65
+ var HeartbeatMessageSchema2 = import_zod2.z.object({
66
+ type: import_zod2.z.literal("heartbeat")
67
+ });
68
+ var SubscribedSchema = import_zod2.z.object({
69
+ type: import_zod2.z.literal("snapshot"),
70
+ id: import_zod2.z.number(),
71
+ snapshot: import_zod2.z.unknown()
72
+ });
73
+ var DeltaMessageSchema = import_zod2.z.object({
74
+ type: import_zod2.z.literal("delta"),
75
+ changes: import_zod2.z.record(import_zod2.z.number(), import_zod2.z.unknown())
76
+ });
77
+ var ResultMessageSchema = import_zod2.z.object({
78
+ type: import_zod2.z.literal("result"),
79
+ id: import_zod2.z.number(),
80
+ success: import_zod2.z.boolean(),
81
+ value: import_zod2.z.unknown().optional(),
82
+ error: import_zod2.z.string().optional()
83
+ });
84
+ var ServerMessageSchema = import_zod2.z.discriminatedUnion("type", [
85
+ HeartbeatMessageSchema2,
86
+ SubscribedSchema,
87
+ DeltaMessageSchema,
88
+ ResultMessageSchema
89
+ ]);
90
+ var ServerMessage = {
91
+ heartbeat: () => ({
92
+ type: "heartbeat"
93
+ }),
94
+ subscribed: (id, snapshot) => ({
95
+ type: "snapshot",
96
+ id,
97
+ snapshot
98
+ }),
99
+ delta: (changes) => ({
100
+ type: "delta",
101
+ changes
102
+ }),
103
+ resultSuccess: (id, value) => ({
104
+ type: "result",
105
+ id,
106
+ success: true,
107
+ value
108
+ }),
109
+ resultError: (id, error) => ({
110
+ type: "result",
111
+ id,
112
+ success: false,
113
+ error
114
+ })
115
+ };
116
+
117
+ // src/shared-worker-client-handler.ts
118
+ var SharedWorkerClientHandler = class {
119
+ constructor(transport, context, streamEndpoints, mutationEndpoints, presenceHandler) {
120
+ this.closed = false;
121
+ this.streams = /* @__PURE__ */ new Map();
122
+ this.transport = transport;
123
+ this.context = context;
124
+ this.streamEndpoints = streamEndpoints;
125
+ this.mutationEndpoints = mutationEndpoints;
126
+ this.presenceHandler = presenceHandler;
127
+ console.log("new client connected");
128
+ this.transport.onMessage((data) => this.handleMessage(data));
129
+ this.transport.onClose(() => this.handleDisconnect());
130
+ }
131
+ handleMessage(message) {
132
+ let data;
133
+ try {
134
+ data = JSON.parse(message);
135
+ } catch (e) {
136
+ console.error("Invalid JSON received:", message);
137
+ return this.close();
138
+ }
139
+ let parsed;
140
+ try {
141
+ parsed = parseClientMessage(data);
142
+ } catch (error) {
143
+ console.error("Invalid client message:", error);
144
+ return this.close();
145
+ }
146
+ this.handleClientMessage(parsed);
147
+ }
148
+ async handleClientMessage(message) {
149
+ switch (message.type) {
150
+ case "subscribe": {
151
+ const { id, name, args } = message;
152
+ if (!(name in this.streamEndpoints)) {
153
+ console.error(`Unknown stream: ${name}`);
154
+ this.close();
155
+ return;
156
+ }
157
+ const endpoint = this.streamEndpoints[name];
158
+ try {
159
+ const source = await endpoint(
160
+ args,
161
+ this.context
162
+ );
163
+ this.streams.set(id, source);
164
+ this.sendMessage(ServerMessage.subscribed(id, source.Snapshot));
165
+ console.log(`Client subscribed to "${name}" (${id})`);
166
+ } catch (err) {
167
+ console.error(`Error building stream ${name}:`, err);
168
+ this.close();
169
+ }
170
+ break;
171
+ }
172
+ case "unsubscribe": {
173
+ const { id } = message;
174
+ this.streams.delete(id);
175
+ console.log(`Client unsubscribed from ${id}`);
176
+ break;
177
+ }
178
+ case "call": {
179
+ const { id, name, args } = message;
180
+ if (!(name in this.mutationEndpoints)) {
181
+ console.error(`Unknown mutation: ${name}`);
182
+ this.close();
183
+ return;
184
+ }
185
+ const endpoint = this.mutationEndpoints[name];
186
+ endpoint(
187
+ args,
188
+ this.context
189
+ ).then((result) => {
190
+ if (result.success) {
191
+ this.sendMessage(ServerMessage.resultSuccess(id, result.value));
192
+ console.log(
193
+ `Mutation "${name}" (${id}) completed successfully`
194
+ );
195
+ } else {
196
+ this.sendMessage(ServerMessage.resultError(id, result.error));
197
+ console.log(
198
+ `Mutation "${name}" (${id}) returned error: ${result.error}`
199
+ );
200
+ }
201
+ }).catch((err) => {
202
+ console.error(
203
+ `Unhandled exception in mutation "${name}" (${id}):`,
204
+ err
205
+ );
206
+ this.close();
207
+ });
208
+ break;
209
+ }
210
+ case "heartbeat":
211
+ break;
212
+ case "presence": {
213
+ if (!this.presenceHandler) {
214
+ console.error("Presence not configured");
215
+ this.close();
216
+ return;
217
+ }
218
+ const { data } = message;
219
+ if (this.currentPresence !== void 0) {
220
+ this.presenceHandler.update(this.currentPresence, data);
221
+ } else {
222
+ this.presenceHandler.add(data);
223
+ }
224
+ this.currentPresence = data;
225
+ break;
226
+ }
227
+ }
228
+ }
229
+ handleStep() {
230
+ if (this.closed) return;
231
+ const changes = {};
232
+ for (const [id, source] of this.streams) {
233
+ const change = source.LastChange;
234
+ if (change === null) continue;
235
+ changes[id] = change;
236
+ }
237
+ if (Object.keys(changes).length > 0) {
238
+ console.log(`[ClientHandler] Sending delta with ${Object.keys(changes).length} changes for streams: ${Object.keys(changes).join(", ")}`);
239
+ this.sendMessage(ServerMessage.delta(changes));
240
+ }
241
+ }
242
+ sendMessage(message) {
243
+ if (this.closed) return;
244
+ this.transport.send(JSON.stringify(message));
245
+ }
246
+ handleDisconnect() {
247
+ this.close();
248
+ }
249
+ close() {
250
+ if (this.closed) return;
251
+ console.log("[ClientHandler] Closing client connection");
252
+ this.closed = true;
253
+ if (this.presenceHandler && this.currentPresence) {
254
+ this.presenceHandler.remove(this.currentPresence);
255
+ }
256
+ console.log(`[ClientHandler] Cleaning up ${this.streams.size} active streams`);
257
+ this.streams.clear();
258
+ try {
259
+ this.transport.close();
260
+ } catch (e) {
261
+ }
262
+ }
263
+ };
264
+
265
+ // src/weak-list.ts
266
+ var WeakList = class {
267
+ constructor() {
268
+ this.items = [];
269
+ }
270
+ add(value) {
271
+ this.items.push(new WeakRef(value));
272
+ }
273
+ *[Symbol.iterator]() {
274
+ const newItems = [];
275
+ for (const ref of this.items) {
276
+ const value = ref.deref();
277
+ if (value !== void 0) {
278
+ yield value;
279
+ newItems.push(ref);
280
+ }
281
+ }
282
+ this.items = newItems;
283
+ }
284
+ };
285
+
286
+ // src/messageport-transport.ts
287
+ var MessagePortTransport = class {
288
+ constructor(port) {
289
+ this.port = port;
290
+ }
291
+ send(data) {
292
+ console.log("[MessagePortTransport] Sending:", data.substring(0, 100) + (data.length > 100 ? "..." : ""));
293
+ this.port.postMessage(data);
294
+ }
295
+ onMessage(handler) {
296
+ this.port.onmessage = (event) => {
297
+ console.log("[MessagePortTransport] Received:", event.data.substring(0, 100) + (event.data.length > 100 ? "..." : ""));
298
+ handler(event.data);
299
+ };
300
+ }
301
+ onClose(handler) {
302
+ this.port.onmessageerror = handler;
303
+ }
304
+ close() {
305
+ this.port.close();
306
+ }
307
+ // MessagePort doesn't provide bufferedAmount
308
+ get bufferedAmount() {
309
+ return void 0;
310
+ }
311
+ };
312
+
313
+ // src/shared-worker-server.ts
314
+ function setupSharedWorker(options, graph) {
315
+ const { streams, mutations, createContext, presenceHandler } = options;
316
+ const clients = new WeakList();
317
+ graph.afterStep(() => {
318
+ console.log("[SharedWorker] Broadcasting deltas to clients");
319
+ for (const client of clients) {
320
+ client.handleStep();
321
+ }
322
+ });
323
+ const globalScope = self;
324
+ globalScope.onconnect = (event) => {
325
+ console.log("[SharedWorker] New client connecting...");
326
+ const port = event.ports[0];
327
+ const messageBuffer = [];
328
+ let client = null;
329
+ const tempMessageHandler = (e) => {
330
+ console.log("[SharedWorker] Buffering message during setup:", e.data);
331
+ messageBuffer.push(e.data);
332
+ };
333
+ port.onmessage = tempMessageHandler;
334
+ Promise.resolve(createContext(port)).then((context) => {
335
+ console.log("[SharedWorker] Context created, setting up client handler");
336
+ const transport = new MessagePortTransport(port);
337
+ client = new SharedWorkerClientHandler(
338
+ transport,
339
+ context,
340
+ streams,
341
+ mutations,
342
+ presenceHandler
343
+ );
344
+ clients.add(client);
345
+ console.log("[SharedWorker] Client handler registered");
346
+ console.log(`[SharedWorker] Processing ${messageBuffer.length} buffered messages`);
347
+ for (const msg of messageBuffer) {
348
+ client.handleMessage(msg);
349
+ }
350
+ messageBuffer.length = 0;
351
+ port.start();
352
+ console.log("[SharedWorker] Client connection ready");
353
+ }).catch((err) => {
354
+ console.error("[SharedWorker] Error creating context:", err);
355
+ port.close();
356
+ });
357
+ };
358
+ }
359
+ // Annotate the CommonJS export names for ESM import in node:
360
+ 0 && (module.exports = {
361
+ setupSharedWorker
362
+ });
363
+ //# sourceMappingURL=shared-worker-server.cjs.map