syncorejs 0.2.0 → 0.2.2

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 (135) hide show
  1. package/README.md +2 -1
  2. package/dist/_vendor/cli/app.d.mts.map +1 -1
  3. package/dist/_vendor/cli/app.mjs +323 -42
  4. package/dist/_vendor/cli/app.mjs.map +1 -1
  5. package/dist/_vendor/cli/context.mjs +27 -9
  6. package/dist/_vendor/cli/context.mjs.map +1 -1
  7. package/dist/_vendor/cli/doctor.mjs +513 -46
  8. package/dist/_vendor/cli/doctor.mjs.map +1 -1
  9. package/dist/_vendor/cli/messages.mjs +5 -4
  10. package/dist/_vendor/cli/messages.mjs.map +1 -1
  11. package/dist/_vendor/cli/project.mjs +110 -12
  12. package/dist/_vendor/cli/project.mjs.map +1 -1
  13. package/dist/_vendor/cli/render.mjs +57 -9
  14. package/dist/_vendor/cli/render.mjs.map +1 -1
  15. package/dist/_vendor/cli/targets.mjs +4 -3
  16. package/dist/_vendor/cli/targets.mjs.map +1 -1
  17. package/dist/_vendor/core/cli.d.mts +13 -3
  18. package/dist/_vendor/core/cli.d.mts.map +1 -1
  19. package/dist/_vendor/core/cli.mjs +242 -91
  20. package/dist/_vendor/core/cli.mjs.map +1 -1
  21. package/dist/_vendor/core/devtools-auth.mjs +60 -0
  22. package/dist/_vendor/core/devtools-auth.mjs.map +1 -0
  23. package/dist/_vendor/core/index.d.mts +5 -3
  24. package/dist/_vendor/core/index.mjs +22 -2
  25. package/dist/_vendor/core/index.mjs.map +1 -1
  26. package/dist/_vendor/core/runtime/components.d.mts +111 -0
  27. package/dist/_vendor/core/runtime/components.d.mts.map +1 -0
  28. package/dist/_vendor/core/runtime/components.mjs +186 -0
  29. package/dist/_vendor/core/runtime/components.mjs.map +1 -0
  30. package/dist/_vendor/core/runtime/devtools.d.mts +4 -4
  31. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
  32. package/dist/_vendor/core/runtime/devtools.mjs +52 -41
  33. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
  34. package/dist/_vendor/core/runtime/functions.d.mts +10 -10
  35. package/dist/_vendor/core/runtime/functions.d.mts.map +1 -1
  36. package/dist/_vendor/core/runtime/functions.mjs +2 -2
  37. package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
  38. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +77 -0
  39. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -0
  40. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +617 -0
  41. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -0
  42. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +186 -0
  43. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -0
  44. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs +220 -0
  45. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs.map +1 -0
  46. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs +203 -0
  47. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs.map +1 -0
  48. package/dist/_vendor/core/runtime/internal/engines/shared.mjs +177 -0
  49. package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -0
  50. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +144 -0
  51. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -0
  52. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +220 -0
  53. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -0
  54. package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs +32 -0
  55. package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs.map +1 -0
  56. package/dist/_vendor/core/runtime/internal/systemMeta.mjs +61 -0
  57. package/dist/_vendor/core/runtime/internal/systemMeta.mjs.map +1 -0
  58. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs +37 -0
  59. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs.map +1 -0
  60. package/dist/_vendor/core/runtime/runtime.d.mts +159 -205
  61. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
  62. package/dist/_vendor/core/runtime/runtime.mjs +16 -1371
  63. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
  64. package/dist/_vendor/core/transport.d.mts +111 -0
  65. package/dist/_vendor/core/transport.d.mts.map +1 -0
  66. package/dist/_vendor/core/transport.mjs +419 -0
  67. package/dist/_vendor/core/transport.mjs.map +1 -0
  68. package/dist/_vendor/devtools-protocol/index.d.ts +39 -1
  69. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
  70. package/dist/_vendor/devtools-protocol/index.js +25 -9
  71. package/dist/_vendor/devtools-protocol/index.js.map +1 -1
  72. package/dist/_vendor/next/index.d.ts +1 -1
  73. package/dist/_vendor/next/index.d.ts.map +1 -1
  74. package/dist/_vendor/next/index.js +31 -13
  75. package/dist/_vendor/next/index.js.map +1 -1
  76. package/dist/_vendor/platform-expo/index.d.ts +12 -12
  77. package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
  78. package/dist/_vendor/platform-expo/index.js +4 -2
  79. package/dist/_vendor/platform-expo/index.js.map +1 -1
  80. package/dist/_vendor/platform-expo/react.d.ts.map +1 -1
  81. package/dist/_vendor/platform-expo/react.js +11 -10
  82. package/dist/_vendor/platform-expo/react.js.map +1 -1
  83. package/dist/_vendor/platform-node/index.d.mts +23 -19
  84. package/dist/_vendor/platform-node/index.d.mts.map +1 -1
  85. package/dist/_vendor/platform-node/index.mjs +13 -5
  86. package/dist/_vendor/platform-node/index.mjs.map +1 -1
  87. package/dist/_vendor/platform-node/ipc-react.d.mts.map +1 -1
  88. package/dist/_vendor/platform-node/ipc-react.mjs +15 -2
  89. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
  90. package/dist/_vendor/platform-node/ipc.d.mts +11 -35
  91. package/dist/_vendor/platform-node/ipc.d.mts.map +1 -1
  92. package/dist/_vendor/platform-node/ipc.mjs +3 -273
  93. package/dist/_vendor/platform-node/ipc.mjs.map +1 -1
  94. package/dist/_vendor/platform-web/external-change.d.ts +2 -1
  95. package/dist/_vendor/platform-web/external-change.d.ts.map +1 -1
  96. package/dist/_vendor/platform-web/external-change.js +2 -1
  97. package/dist/_vendor/platform-web/external-change.js.map +1 -1
  98. package/dist/_vendor/platform-web/index.d.ts +21 -21
  99. package/dist/_vendor/platform-web/index.d.ts.map +1 -1
  100. package/dist/_vendor/platform-web/index.js +44 -7
  101. package/dist/_vendor/platform-web/index.js.map +1 -1
  102. package/dist/_vendor/platform-web/react.d.ts.map +1 -1
  103. package/dist/_vendor/platform-web/react.js +29 -13
  104. package/dist/_vendor/platform-web/react.js.map +1 -1
  105. package/dist/_vendor/platform-web/worker.d.ts +11 -35
  106. package/dist/_vendor/platform-web/worker.d.ts.map +1 -1
  107. package/dist/_vendor/platform-web/worker.js +3 -267
  108. package/dist/_vendor/platform-web/worker.js.map +1 -1
  109. package/dist/_vendor/react/index.d.ts +36 -20
  110. package/dist/_vendor/react/index.d.ts.map +1 -1
  111. package/dist/_vendor/react/index.js +279 -57
  112. package/dist/_vendor/react/index.js.map +1 -1
  113. package/dist/_vendor/schema/definition.d.ts +48 -63
  114. package/dist/_vendor/schema/definition.d.ts.map +1 -1
  115. package/dist/_vendor/schema/definition.js +22 -39
  116. package/dist/_vendor/schema/definition.js.map +1 -1
  117. package/dist/_vendor/schema/index.d.ts +4 -4
  118. package/dist/_vendor/schema/index.js +2 -2
  119. package/dist/_vendor/schema/planner.d.ts +19 -2
  120. package/dist/_vendor/schema/planner.d.ts.map +1 -1
  121. package/dist/_vendor/schema/planner.js +79 -3
  122. package/dist/_vendor/schema/planner.js.map +1 -1
  123. package/dist/_vendor/schema/validators.d.ts +141 -121
  124. package/dist/_vendor/schema/validators.d.ts.map +1 -1
  125. package/dist/_vendor/schema/validators.js +300 -42
  126. package/dist/_vendor/schema/validators.js.map +1 -1
  127. package/dist/_vendor/svelte/index.d.ts +47 -19
  128. package/dist/_vendor/svelte/index.d.ts.map +1 -1
  129. package/dist/_vendor/svelte/index.js +250 -20
  130. package/dist/_vendor/svelte/index.js.map +1 -1
  131. package/dist/components.d.ts +2 -0
  132. package/dist/components.js +2 -0
  133. package/dist/index.d.ts +3 -2
  134. package/dist/index.js +2 -1
  135. package/package.json +8 -3
@@ -1,143 +1,6 @@
1
- import { generateId } from "../core/index.mjs";
1
+ import { SyncoreBridgeClient, attachRuntimeBridge } from "../core/index.mjs";
2
2
  //#region src/ipc.ts
3
- var SyncoreRendererClient = class {
4
- pendingRequests = /* @__PURE__ */ new Map();
5
- watchRecordsByKey = /* @__PURE__ */ new Map();
6
- watchKeyBySubscriptionId = /* @__PURE__ */ new Map();
7
- disposed = false;
8
- handleMessage = (event) => {
9
- const message = event.data;
10
- if (!message || typeof message !== "object" || !("type" in message)) return;
11
- switch (message.type) {
12
- case "runtime.ready": return;
13
- case "runtime.error":
14
- this.rejectAllPending(new Error(message.error));
15
- return;
16
- case "invoke.result": {
17
- const pending = this.pendingRequests.get(message.requestId);
18
- if (!pending) return;
19
- this.pendingRequests.delete(message.requestId);
20
- if (message.success) pending.resolve(message.value);
21
- else pending.reject(new Error(message.error));
22
- return;
23
- }
24
- case "watch.update": {
25
- const watchKey = this.watchKeyBySubscriptionId.get(message.subscriptionId);
26
- if (!watchKey) return;
27
- const watchRecord = this.watchRecordsByKey.get(watchKey);
28
- if (!watchRecord) return;
29
- if (message.success) {
30
- watchRecord.result = message.value;
31
- watchRecord.error = void 0;
32
- } else watchRecord.error = new Error(message.error);
33
- for (const listener of watchRecord.listeners) listener();
34
- }
35
- }
36
- };
37
- constructor(endpoint) {
38
- this.endpoint = endpoint;
39
- this.endpoint.addEventListener("message", this.handleMessage);
40
- }
41
- query(reference, ...args) {
42
- return this.invoke("query", reference, normalizeOptionalArgs(args));
43
- }
44
- mutation(reference, ...args) {
45
- return this.invoke("mutation", reference, normalizeOptionalArgs(args));
46
- }
47
- action(reference, ...args) {
48
- return this.invoke("action", reference, normalizeOptionalArgs(args));
49
- }
50
- watchQuery(reference, ...args) {
51
- this.ensureNotDisposed();
52
- const normalizedArgs = normalizeOptionalArgs(args);
53
- const watchKey = createWatchKey(reference, normalizedArgs);
54
- let watchRecord = this.watchRecordsByKey.get(watchKey);
55
- if (!watchRecord) {
56
- watchRecord = {
57
- subscriptionId: generateId(),
58
- listeners: /* @__PURE__ */ new Set(),
59
- consumers: 0,
60
- result: void 0,
61
- error: void 0
62
- };
63
- this.watchRecordsByKey.set(watchKey, watchRecord);
64
- this.watchKeyBySubscriptionId.set(watchRecord.subscriptionId, watchKey);
65
- this.endpoint.postMessage({
66
- type: "watch.subscribe",
67
- subscriptionId: watchRecord.subscriptionId,
68
- reference,
69
- args: normalizedArgs
70
- });
71
- }
72
- watchRecord.consumers += 1;
73
- let disposed = false;
74
- const ownedListeners = /* @__PURE__ */ new Set();
75
- return {
76
- onUpdate: (callback) => {
77
- watchRecord.listeners.add(callback);
78
- ownedListeners.add(callback);
79
- queueMicrotask(callback);
80
- return () => {
81
- watchRecord.listeners.delete(callback);
82
- ownedListeners.delete(callback);
83
- };
84
- },
85
- localQueryResult: () => watchRecord.result,
86
- localQueryError: () => watchRecord.error,
87
- dispose: () => {
88
- if (disposed) return;
89
- disposed = true;
90
- for (const callback of ownedListeners) watchRecord.listeners.delete(callback);
91
- ownedListeners.clear();
92
- watchRecord.consumers = Math.max(0, watchRecord.consumers - 1);
93
- if (watchRecord.consumers > 0) return;
94
- this.endpoint.postMessage({
95
- type: "watch.unsubscribe",
96
- subscriptionId: watchRecord.subscriptionId
97
- });
98
- this.watchKeyBySubscriptionId.delete(watchRecord.subscriptionId);
99
- this.watchRecordsByKey.delete(watchKey);
100
- }
101
- };
102
- }
103
- dispose() {
104
- if (this.disposed) return;
105
- this.disposed = true;
106
- this.endpoint.removeEventListener("message", this.handleMessage);
107
- for (const watchRecord of this.watchRecordsByKey.values()) this.endpoint.postMessage({
108
- type: "watch.unsubscribe",
109
- subscriptionId: watchRecord.subscriptionId
110
- });
111
- this.watchKeyBySubscriptionId.clear();
112
- this.watchRecordsByKey.clear();
113
- this.rejectAllPending(/* @__PURE__ */ new Error("Syncore renderer client was disposed."));
114
- }
115
- invoke(kind, reference, args) {
116
- this.ensureNotDisposed();
117
- const requestId = generateId();
118
- const promise = new Promise((resolve, reject) => {
119
- this.pendingRequests.set(requestId, {
120
- resolve,
121
- reject
122
- });
123
- });
124
- switch (kind) {
125
- case "query":
126
- case "mutation":
127
- case "action":
128
- this.endpoint.postMessage(createInvokeRequest(requestId, kind, reference, args));
129
- break;
130
- }
131
- return promise;
132
- }
133
- rejectAllPending(error) {
134
- for (const pending of this.pendingRequests.values()) pending.reject(error);
135
- this.pendingRequests.clear();
136
- }
137
- ensureNotDisposed() {
138
- if (this.disposed) throw new Error("Syncore renderer client was disposed.");
139
- }
140
- };
3
+ var SyncoreRendererClient = class extends SyncoreBridgeClient {};
141
4
  /**
142
5
  * Install the default Electron preload bridge used by Syncore renderer helpers.
143
6
  */
@@ -202,140 +65,7 @@ function createNodeIpcMessageEndpoint(bridge) {
202
65
  };
203
66
  }
204
67
  function attachNodeIpcRuntime(options) {
205
- const subscriptions = /* @__PURE__ */ new Map();
206
- const runtimePromise = Promise.resolve(options.createRuntime()).then(async (runtime) => {
207
- await runtime.start();
208
- return runtime;
209
- });
210
- const clientPromise = runtimePromise.then((runtime) => runtime.createClient());
211
- const ready = clientPromise.then(() => {
212
- options.endpoint.postMessage({ type: "runtime.ready" });
213
- }).catch((error) => {
214
- options.endpoint.postMessage({
215
- type: "runtime.error",
216
- error: error instanceof Error ? error.message : String(error)
217
- });
218
- throw error;
219
- });
220
- const handleMessage = (event) => {
221
- (async () => {
222
- const message = event.data;
223
- if (!message || typeof message !== "object" || !("type" in message)) return;
224
- try {
225
- const client = await clientPromise;
226
- switch (message.type) {
227
- case "invoke": {
228
- const value = message.kind === "query" ? await client.query(message.reference, message.args) : message.kind === "mutation" ? await client.mutation(message.reference, message.args) : await client.action(message.reference, message.args);
229
- options.endpoint.postMessage({
230
- type: "invoke.result",
231
- requestId: message.requestId,
232
- success: true,
233
- value
234
- });
235
- return;
236
- }
237
- case "watch.subscribe": {
238
- if (subscriptions.has(message.subscriptionId)) return;
239
- const watch = client.watchQuery(message.reference, message.args);
240
- const sendCurrentState = () => {
241
- const error = watch.localQueryError();
242
- if (error) {
243
- options.endpoint.postMessage({
244
- type: "watch.update",
245
- subscriptionId: message.subscriptionId,
246
- success: false,
247
- error: error.message
248
- });
249
- return;
250
- }
251
- options.endpoint.postMessage({
252
- type: "watch.update",
253
- subscriptionId: message.subscriptionId,
254
- success: true,
255
- value: watch.localQueryResult()
256
- });
257
- };
258
- const unsubscribe = watch.onUpdate(sendCurrentState);
259
- subscriptions.set(message.subscriptionId, {
260
- watch,
261
- unsubscribe
262
- });
263
- sendCurrentState();
264
- return;
265
- }
266
- case "watch.unsubscribe": {
267
- const subscription = subscriptions.get(message.subscriptionId);
268
- if (!subscription) return;
269
- subscription.unsubscribe();
270
- subscriptions.delete(message.subscriptionId);
271
- }
272
- }
273
- } catch (error) {
274
- const errorMessage = error instanceof Error ? error.message : String(error);
275
- if (message.type === "invoke") options.endpoint.postMessage({
276
- type: "invoke.result",
277
- requestId: message.requestId,
278
- success: false,
279
- error: errorMessage
280
- });
281
- if (message.type === "watch.subscribe") options.endpoint.postMessage({
282
- type: "watch.update",
283
- subscriptionId: message.subscriptionId,
284
- success: false,
285
- error: errorMessage
286
- });
287
- }
288
- })();
289
- };
290
- options.endpoint.addEventListener("message", handleMessage);
291
- return {
292
- ready,
293
- async dispose() {
294
- options.endpoint.removeEventListener("message", handleMessage);
295
- for (const subscription of subscriptions.values()) subscription.unsubscribe();
296
- subscriptions.clear();
297
- await (await runtimePromise).stop();
298
- }
299
- };
300
- }
301
- function createInvokeRequest(requestId, kind, reference, args) {
302
- switch (kind) {
303
- case "query": return {
304
- type: "invoke",
305
- requestId,
306
- kind,
307
- reference,
308
- args
309
- };
310
- case "mutation": return {
311
- type: "invoke",
312
- requestId,
313
- kind,
314
- reference,
315
- args
316
- };
317
- case "action": return {
318
- type: "invoke",
319
- requestId,
320
- kind,
321
- reference,
322
- args
323
- };
324
- }
325
- }
326
- function createWatchKey(reference, args) {
327
- return `${reference.name}:${stableStringify(args)}`;
328
- }
329
- function normalizeOptionalArgs(args) {
330
- return args[0] ?? {};
331
- }
332
- function stableStringify(value) {
333
- return JSON.stringify(sortValue(value));
334
- }
335
- function sortValue(value) {
336
- if (Array.isArray(value)) return value.map(sortValue);
337
- if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, nested]) => [key, sortValue(nested)]));
338
- return value;
68
+ return attachRuntimeBridge(options);
339
69
  }
340
70
  //#endregion
341
71
  export { SyncoreRendererClient, attachNodeIpcRuntime, createNodeIpcMessageEndpoint, createRendererSyncoreBridgeClient, createRendererSyncoreClient, createRendererSyncoreWindowClient, installSyncoreWindowBridge };
@@ -1 +1 @@
1
- {"version":3,"file":"ipc.mjs","names":[],"sources":["../src/ipc.ts"],"sourcesContent":["import {\n generateId,\n type AnySyncoreSchema,\n type FunctionReference,\n type JsonObject,\n type SyncoreClient,\n type SyncoreRuntime,\n type SyncoreWatch\n} from \"@syncore/core\";\n\nexport type NodeIpcSyncoreSchema = AnySyncoreSchema;\n\nexport interface SyncoreIpcMessageEndpoint {\n postMessage(message: unknown): void;\n addEventListener(\n type: \"message\",\n listener: (event: MessageEvent<unknown>) => void\n ): void;\n removeEventListener(\n type: \"message\",\n listener: (event: MessageEvent<unknown>) => void\n ): void;\n}\n\ntype SyncoreIpcRequest =\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"query\";\n reference: FunctionReference<\"query\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"mutation\";\n reference: FunctionReference<\"mutation\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"invoke\";\n requestId: string;\n kind: \"action\";\n reference: FunctionReference<\"action\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"watch.subscribe\";\n subscriptionId: string;\n reference: FunctionReference<\"query\", unknown, unknown>;\n args: JsonObject;\n }\n | {\n type: \"watch.unsubscribe\";\n subscriptionId: string;\n };\n\ntype SyncoreIpcResponse =\n | {\n type: \"runtime.ready\";\n }\n | {\n type: \"runtime.error\";\n error: string;\n }\n | {\n type: \"invoke.result\";\n requestId: string;\n success: true;\n value: unknown;\n }\n | {\n type: \"invoke.result\";\n requestId: string;\n success: false;\n error: string;\n }\n | {\n type: \"watch.update\";\n subscriptionId: string;\n success: true;\n value: unknown;\n }\n | {\n type: \"watch.update\";\n subscriptionId: string;\n success: false;\n error: string;\n };\n\ninterface PendingRequest {\n resolve(value: unknown): void;\n reject(error: Error): void;\n}\n\ninterface WatchRecord {\n subscriptionId: string;\n listeners: Set<() => void>;\n consumers: number;\n result: unknown;\n error: Error | undefined;\n}\n\nexport type RendererQueryWatch<TValue> = SyncoreWatch<TValue> & {\n dispose(): void;\n};\n\ntype OptionalArgsTuple<TArgs> =\n Record<never, never> extends TArgs ? [args?: TArgs] : [args: TArgs];\n\nexport class SyncoreRendererClient implements SyncoreClient {\n private readonly pendingRequests = new Map<string, PendingRequest>();\n private readonly watchRecordsByKey = new Map<string, WatchRecord>();\n private readonly watchKeyBySubscriptionId = new Map<string, string>();\n private disposed = false;\n\n private readonly handleMessage = (event: MessageEvent<unknown>) => {\n const message = event.data as SyncoreIpcResponse;\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n return;\n }\n\n switch (message.type) {\n case \"runtime.ready\":\n return;\n case \"runtime.error\":\n this.rejectAllPending(new Error(message.error));\n return;\n case \"invoke.result\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (!pending) {\n return;\n }\n this.pendingRequests.delete(message.requestId);\n if (message.success) {\n pending.resolve(message.value);\n } else {\n pending.reject(new Error(message.error));\n }\n return;\n }\n case \"watch.update\": {\n const watchKey = this.watchKeyBySubscriptionId.get(\n message.subscriptionId\n );\n if (!watchKey) {\n return;\n }\n const watchRecord = this.watchRecordsByKey.get(watchKey);\n if (!watchRecord) {\n return;\n }\n if (message.success) {\n watchRecord.result = message.value;\n watchRecord.error = undefined;\n } else {\n watchRecord.error = new Error(message.error);\n }\n for (const listener of watchRecord.listeners) {\n listener();\n }\n }\n }\n };\n\n constructor(private readonly endpoint: SyncoreIpcMessageEndpoint) {\n this.endpoint.addEventListener(\"message\", this.handleMessage);\n }\n\n query<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"query\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n mutation<TArgs, TResult>(\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"mutation\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n action<TArgs, TResult>(\n reference: FunctionReference<\"action\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): Promise<TResult> {\n return this.invoke(\n \"action\",\n reference,\n normalizeOptionalArgs(args) as JsonObject\n );\n }\n\n watchQuery<TArgs, TResult>(\n reference: FunctionReference<\"query\", TArgs, TResult>,\n ...args: OptionalArgsTuple<TArgs>\n ): RendererQueryWatch<TResult> {\n this.ensureNotDisposed();\n const normalizedArgs = normalizeOptionalArgs(args) as JsonObject;\n const watchKey = createWatchKey(reference, normalizedArgs);\n let watchRecord = this.watchRecordsByKey.get(watchKey);\n if (!watchRecord) {\n watchRecord = {\n subscriptionId: generateId(),\n listeners: new Set<() => void>(),\n consumers: 0,\n result: undefined,\n error: undefined\n };\n this.watchRecordsByKey.set(watchKey, watchRecord);\n this.watchKeyBySubscriptionId.set(watchRecord.subscriptionId, watchKey);\n this.endpoint.postMessage({\n type: \"watch.subscribe\",\n subscriptionId: watchRecord.subscriptionId,\n reference,\n args: normalizedArgs\n } satisfies SyncoreIpcRequest);\n }\n\n watchRecord.consumers += 1;\n let disposed = false;\n const ownedListeners = new Set<() => void>();\n\n return {\n onUpdate: (callback) => {\n watchRecord.listeners.add(callback);\n ownedListeners.add(callback);\n queueMicrotask(callback);\n return () => {\n watchRecord.listeners.delete(callback);\n ownedListeners.delete(callback);\n };\n },\n localQueryResult: () => watchRecord.result as TResult | undefined,\n localQueryError: () => watchRecord.error,\n dispose: () => {\n if (disposed) {\n return;\n }\n disposed = true;\n for (const callback of ownedListeners) {\n watchRecord.listeners.delete(callback);\n }\n ownedListeners.clear();\n watchRecord.consumers = Math.max(0, watchRecord.consumers - 1);\n if (watchRecord.consumers > 0) {\n return;\n }\n this.endpoint.postMessage({\n type: \"watch.unsubscribe\",\n subscriptionId: watchRecord.subscriptionId\n } satisfies SyncoreIpcRequest);\n this.watchKeyBySubscriptionId.delete(watchRecord.subscriptionId);\n this.watchRecordsByKey.delete(watchKey);\n }\n };\n }\n\n dispose(): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.endpoint.removeEventListener(\"message\", this.handleMessage);\n for (const watchRecord of this.watchRecordsByKey.values()) {\n this.endpoint.postMessage({\n type: \"watch.unsubscribe\",\n subscriptionId: watchRecord.subscriptionId\n } satisfies SyncoreIpcRequest);\n }\n this.watchKeyBySubscriptionId.clear();\n this.watchRecordsByKey.clear();\n this.rejectAllPending(new Error(\"Syncore renderer client was disposed.\"));\n }\n\n private invoke<TArgs, TResult>(\n kind: \"query\",\n reference: FunctionReference<\"query\", TArgs, TResult>,\n args: JsonObject\n ): Promise<TResult>;\n private invoke<TArgs, TResult>(\n kind: \"mutation\",\n reference: FunctionReference<\"mutation\", TArgs, TResult>,\n args: JsonObject\n ): Promise<TResult>;\n private invoke<TArgs, TResult>(\n kind: \"action\",\n reference: FunctionReference<\"action\", TArgs, TResult>,\n args: JsonObject\n ): Promise<TResult>;\n private invoke<TArgs, TResult>(\n kind: \"query\" | \"mutation\" | \"action\",\n reference: FunctionReference<\n \"query\" | \"mutation\" | \"action\",\n TArgs,\n TResult\n >,\n args: JsonObject\n ): Promise<TResult> {\n this.ensureNotDisposed();\n const requestId = generateId();\n const promise = new Promise<TResult>((resolve, reject) => {\n this.pendingRequests.set(requestId, { resolve, reject });\n });\n\n switch (kind) {\n case \"query\":\n case \"mutation\":\n case \"action\":\n this.endpoint.postMessage(\n createInvokeRequest(requestId, kind, reference, args)\n );\n break;\n }\n\n return promise;\n }\n\n private rejectAllPending(error: Error): void {\n for (const pending of this.pendingRequests.values()) {\n pending.reject(error);\n }\n this.pendingRequests.clear();\n }\n\n private ensureNotDisposed(): void {\n if (this.disposed) {\n throw new Error(\"Syncore renderer client was disposed.\");\n }\n }\n}\n\nexport interface AttachNodeIpcRuntimeOptions {\n endpoint: SyncoreIpcMessageEndpoint;\n createRuntime:\n | (() => Promise<SyncoreRuntime<NodeIpcSyncoreSchema>>)\n | (() => SyncoreRuntime<NodeIpcSyncoreSchema>);\n}\n\nexport interface SyncoreRendererBridge {\n postMessage(message: unknown): void;\n onMessage(listener: (message: unknown) => void): () => void;\n}\n\nexport interface SyncoreWindowBridge {\n postMessage(message: unknown): void;\n onMessage(listener: (message: unknown) => void): () => void;\n}\n\nexport interface SyncoreMainProcessBridge {\n postMessage(message: unknown): void;\n onMessage(listener: (message: unknown) => void): () => void;\n}\n\n/**\n * Install the default Electron preload bridge used by Syncore renderer helpers.\n */\nexport function installSyncoreWindowBridge(options?: {\n bridgeName?: string;\n}): string {\n return `(function(){const bridgeName=${JSON.stringify(options?.bridgeName ?? \"syncoreBridge\")};const {contextBridge,ipcRenderer}=require(\"electron\");const channel=\"syncore:message\";const listeners=new Map();contextBridge.exposeInMainWorld(bridgeName,{postMessage(message){ipcRenderer.send(channel,message);},onMessage(listener){const wrapped=(_event,payload)=>{listener(payload);};listeners.set(listener,wrapped);ipcRenderer.on(channel,wrapped);return()=>{ipcRenderer.off(channel,wrapped);listeners.delete(listener);};}});})();`;\n}\n\nexport interface AttachedNodeIpcRuntime {\n ready: Promise<void>;\n dispose(): Promise<void>;\n}\n\n/**\n * Create a renderer client from a low-level IPC message endpoint.\n */\nexport function createRendererSyncoreClient(\n endpoint: SyncoreIpcMessageEndpoint\n): SyncoreRendererClient {\n return new SyncoreRendererClient(endpoint);\n}\n\n/**\n * Create a renderer client from a bridge object exposed by preload code.\n */\nexport function createRendererSyncoreBridgeClient(\n bridge: SyncoreRendererBridge\n): SyncoreRendererClient {\n const listeners = new Map<\n (event: MessageEvent<unknown>) => void,\n () => void\n >();\n\n return createRendererSyncoreClient({\n postMessage(message) {\n bridge.postMessage(message);\n },\n addEventListener(_type, listener) {\n listeners.set(\n listener,\n bridge.onMessage((message) => {\n listener({ data: message } as MessageEvent<unknown>);\n })\n );\n },\n removeEventListener(_type, listener) {\n listeners.get(listener)?.();\n listeners.delete(listener);\n }\n });\n}\n\n/**\n * Create a renderer client from `window.syncoreBridge` or another named bridge.\n */\nexport function createRendererSyncoreWindowClient(\n windowObject: Window & typeof globalThis,\n bridgeName = \"syncoreBridge\"\n): SyncoreRendererClient {\n const bridge = (\n windowObject as typeof windowObject & Record<string, unknown>\n )[bridgeName];\n if (!bridge || typeof bridge !== \"object\") {\n throw new Error(`Missing window.${bridgeName} bridge.`);\n }\n\n const candidate = bridge as SyncoreWindowBridge;\n if (\n typeof candidate.postMessage !== \"function\" ||\n typeof candidate.onMessage !== \"function\"\n ) {\n throw new Error(\n `window.${bridgeName} must expose postMessage() and onMessage().`\n );\n }\n\n return createRendererSyncoreBridgeClient(candidate);\n}\n\nexport function createNodeIpcMessageEndpoint(\n bridge: SyncoreMainProcessBridge\n): SyncoreIpcMessageEndpoint & { dispose(): void } {\n const listeners = new Map<\n (event: MessageEvent<unknown>) => void,\n () => void\n >();\n\n return {\n postMessage(message) {\n bridge.postMessage(message);\n },\n addEventListener(_type, listener) {\n listeners.set(\n listener,\n bridge.onMessage((message) => {\n listener({ data: message } as MessageEvent<unknown>);\n })\n );\n },\n removeEventListener(_type, listener) {\n listeners.get(listener)?.();\n listeners.delete(listener);\n },\n dispose() {\n for (const dispose of listeners.values()) {\n dispose();\n }\n listeners.clear();\n }\n };\n}\n\nexport function attachNodeIpcRuntime(\n options: AttachNodeIpcRuntimeOptions\n): AttachedNodeIpcRuntime {\n const subscriptions = new Map<\n string,\n {\n watch: SyncoreWatch<unknown>;\n unsubscribe: () => void;\n }\n >();\n\n const runtimePromise = Promise.resolve(options.createRuntime()).then(\n async (runtime) => {\n await runtime.start();\n return runtime;\n }\n );\n\n const clientPromise = runtimePromise.then((runtime) =>\n runtime.createClient()\n );\n\n const ready = clientPromise\n .then(() => {\n options.endpoint.postMessage({\n type: \"runtime.ready\"\n } satisfies SyncoreIpcResponse);\n })\n .catch((error) => {\n options.endpoint.postMessage({\n type: \"runtime.error\",\n error: error instanceof Error ? error.message : String(error)\n } satisfies SyncoreIpcResponse);\n throw error;\n });\n\n const handleMessage = (event: MessageEvent<unknown>) => {\n void (async () => {\n const message = event.data as SyncoreIpcRequest;\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n return;\n }\n\n try {\n const client = await clientPromise;\n switch (message.type) {\n case \"invoke\": {\n const value =\n message.kind === \"query\"\n ? await client.query(message.reference, message.args)\n : message.kind === \"mutation\"\n ? await client.mutation(message.reference, message.args)\n : await client.action(message.reference, message.args);\n options.endpoint.postMessage({\n type: \"invoke.result\",\n requestId: message.requestId,\n success: true,\n value\n } satisfies SyncoreIpcResponse);\n return;\n }\n case \"watch.subscribe\": {\n if (subscriptions.has(message.subscriptionId)) {\n return;\n }\n const watch = client.watchQuery(message.reference, message.args);\n const sendCurrentState = () => {\n const error = watch.localQueryError();\n if (error) {\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: false,\n error: error.message\n } satisfies SyncoreIpcResponse);\n return;\n }\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: true,\n value: watch.localQueryResult()\n } satisfies SyncoreIpcResponse);\n };\n const unsubscribe = watch.onUpdate(sendCurrentState);\n subscriptions.set(message.subscriptionId, { watch, unsubscribe });\n sendCurrentState();\n return;\n }\n case \"watch.unsubscribe\": {\n const subscription = subscriptions.get(message.subscriptionId);\n if (!subscription) {\n return;\n }\n subscription.unsubscribe();\n subscriptions.delete(message.subscriptionId);\n }\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n if (message.type === \"invoke\") {\n options.endpoint.postMessage({\n type: \"invoke.result\",\n requestId: message.requestId,\n success: false,\n error: errorMessage\n } satisfies SyncoreIpcResponse);\n }\n if (message.type === \"watch.subscribe\") {\n options.endpoint.postMessage({\n type: \"watch.update\",\n subscriptionId: message.subscriptionId,\n success: false,\n error: errorMessage\n } satisfies SyncoreIpcResponse);\n }\n }\n })();\n };\n\n options.endpoint.addEventListener(\"message\", handleMessage);\n\n return {\n ready,\n async dispose() {\n options.endpoint.removeEventListener(\"message\", handleMessage);\n for (const subscription of subscriptions.values()) {\n subscription.unsubscribe();\n }\n subscriptions.clear();\n const runtime = await runtimePromise;\n await runtime.stop();\n }\n };\n}\n\nfunction createInvokeRequest(\n requestId: string,\n kind: \"query\" | \"mutation\" | \"action\",\n reference:\n | FunctionReference<\"query\", unknown, unknown>\n | FunctionReference<\"mutation\", unknown, unknown>\n | FunctionReference<\"action\", unknown, unknown>,\n args: JsonObject\n): SyncoreIpcRequest {\n switch (kind) {\n case \"query\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"query\">,\n args\n };\n case \"mutation\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"mutation\">,\n args\n };\n case \"action\":\n return {\n type: \"invoke\",\n requestId,\n kind,\n reference: reference as FunctionReference<\"action\">,\n args\n };\n }\n}\n\nfunction createWatchKey(\n reference: FunctionReference<\"query\", unknown, unknown>,\n args: JsonObject\n): string {\n return `${reference.name}:${stableStringify(args)}`;\n}\n\nfunction normalizeOptionalArgs<TArgs>(\n args: [] | [TArgs] | readonly unknown[]\n): TArgs {\n return (args[0] ?? {}) as TArgs;\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortValue(value));\n}\n\nfunction sortValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(sortValue);\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, nested]) => [key, sortValue(nested)])\n );\n }\n return value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ipc.mjs","names":[],"sources":["../src/ipc.ts"],"sourcesContent":["import {\n attachRuntimeBridge,\n type AttachRuntimeBridgeOptions,\n type AttachedRuntimeBridge,\n type BridgeQueryWatch,\n SyncoreBridgeClient,\n type SyncoreBridgeMessageEndpoint,\n type SyncoreDataModel\n} from \"@syncore/core\";\n\nexport type NodeIpcSyncoreSchema<\n TSchema extends SyncoreDataModel = SyncoreDataModel\n> = TSchema;\nexport type SyncoreIpcMessageEndpoint = SyncoreBridgeMessageEndpoint;\nexport type RendererQueryWatch<TValue> = BridgeQueryWatch<TValue>;\n\nexport class SyncoreRendererClient extends SyncoreBridgeClient {\n declare query: SyncoreBridgeClient[\"query\"];\n declare mutation: SyncoreBridgeClient[\"mutation\"];\n declare action: SyncoreBridgeClient[\"action\"];\n declare watchQuery: SyncoreBridgeClient[\"watchQuery\"];\n}\n\nexport type AttachNodeIpcRuntimeOptions<\n TSchema extends NodeIpcSyncoreSchema = NodeIpcSyncoreSchema\n> = AttachRuntimeBridgeOptions<TSchema>;\nexport type AttachedNodeIpcRuntime = AttachedRuntimeBridge;\n\nexport interface SyncoreRendererBridge {\n postMessage(message: unknown): void;\n onMessage(listener: (message: unknown) => void): () => void;\n}\n\nexport interface SyncoreWindowBridge {\n postMessage(message: unknown): void;\n onMessage(listener: (message: unknown) => void): () => void;\n}\n\nexport interface SyncoreMainProcessBridge {\n postMessage(message: unknown): void;\n onMessage(listener: (message: unknown) => void): () => void;\n}\n\n/**\n * Install the default Electron preload bridge used by Syncore renderer helpers.\n */\nexport function installSyncoreWindowBridge(options?: {\n bridgeName?: string;\n}): string {\n return `(function(){const bridgeName=${JSON.stringify(options?.bridgeName ?? \"syncoreBridge\")};const {contextBridge,ipcRenderer}=require(\"electron\");const channel=\"syncore:message\";const listeners=new Map();contextBridge.exposeInMainWorld(bridgeName,{postMessage(message){ipcRenderer.send(channel,message);},onMessage(listener){const wrapped=(_event,payload)=>{listener(payload);};listeners.set(listener,wrapped);ipcRenderer.on(channel,wrapped);return()=>{ipcRenderer.off(channel,wrapped);listeners.delete(listener);};}});})();`;\n}\n\n/**\n * Create a renderer client from a low-level IPC message endpoint.\n */\nexport function createRendererSyncoreClient(\n endpoint: SyncoreIpcMessageEndpoint\n): SyncoreRendererClient {\n return new SyncoreRendererClient(endpoint);\n}\n\n/**\n * Create a renderer client from a bridge object exposed by preload code.\n */\nexport function createRendererSyncoreBridgeClient(\n bridge: SyncoreRendererBridge\n): SyncoreRendererClient {\n const listeners = new Map<\n (event: MessageEvent<unknown>) => void,\n () => void\n >();\n\n return createRendererSyncoreClient({\n postMessage(message) {\n bridge.postMessage(message);\n },\n addEventListener(_type, listener) {\n listeners.set(\n listener,\n bridge.onMessage((message) => {\n listener({ data: message } as MessageEvent<unknown>);\n })\n );\n },\n removeEventListener(_type, listener) {\n listeners.get(listener)?.();\n listeners.delete(listener);\n }\n });\n}\n\n/**\n * Create a renderer client from `window.syncoreBridge` or another named bridge.\n */\nexport function createRendererSyncoreWindowClient(\n windowObject: Window & typeof globalThis,\n bridgeName = \"syncoreBridge\"\n): SyncoreRendererClient {\n const bridge = (\n windowObject as typeof windowObject & Record<string, unknown>\n )[bridgeName];\n if (!bridge || typeof bridge !== \"object\") {\n throw new Error(`Missing window.${bridgeName} bridge.`);\n }\n\n const candidate = bridge as SyncoreWindowBridge;\n if (\n typeof candidate.postMessage !== \"function\" ||\n typeof candidate.onMessage !== \"function\"\n ) {\n throw new Error(\n `window.${bridgeName} must expose postMessage() and onMessage().`\n );\n }\n\n return createRendererSyncoreBridgeClient(candidate);\n}\n\nexport function createNodeIpcMessageEndpoint(\n bridge: SyncoreMainProcessBridge\n): SyncoreIpcMessageEndpoint & { dispose(): void } {\n const listeners = new Map<\n (event: MessageEvent<unknown>) => void,\n () => void\n >();\n\n return {\n postMessage(message) {\n bridge.postMessage(message);\n },\n addEventListener(_type, listener) {\n listeners.set(\n listener,\n bridge.onMessage((message) => {\n listener({ data: message } as MessageEvent<unknown>);\n })\n );\n },\n removeEventListener(_type, listener) {\n listeners.get(listener)?.();\n listeners.delete(listener);\n },\n dispose() {\n for (const dispose of listeners.values()) {\n dispose();\n }\n listeners.clear();\n }\n };\n}\n\nexport function attachNodeIpcRuntime(\n options: AttachNodeIpcRuntimeOptions\n): AttachedNodeIpcRuntime {\n return attachRuntimeBridge(options);\n}\n"],"mappings":";;AAgBA,IAAa,wBAAb,cAA2C,oBAAoB;;;;AA8B/D,SAAgB,2BAA2B,SAEhC;AACT,QAAO,gCAAgC,KAAK,UAAU,SAAS,cAAc,gBAAgB,CAAC;;;;;AAMhG,SAAgB,4BACd,UACuB;AACvB,QAAO,IAAI,sBAAsB,SAAS;;;;;AAM5C,SAAgB,kCACd,QACuB;CACvB,MAAM,4BAAY,IAAI,KAGnB;AAEH,QAAO,4BAA4B;EACjC,YAAY,SAAS;AACnB,UAAO,YAAY,QAAQ;;EAE7B,iBAAiB,OAAO,UAAU;AAChC,aAAU,IACR,UACA,OAAO,WAAW,YAAY;AAC5B,aAAS,EAAE,MAAM,SAAS,CAA0B;KACpD,CACH;;EAEH,oBAAoB,OAAO,UAAU;AACnC,aAAU,IAAI,SAAS,IAAI;AAC3B,aAAU,OAAO,SAAS;;EAE7B,CAAC;;;;;AAMJ,SAAgB,kCACd,cACA,aAAa,iBACU;CACvB,MAAM,SACJ,aACA;AACF,KAAI,CAAC,UAAU,OAAO,WAAW,SAC/B,OAAM,IAAI,MAAM,kBAAkB,WAAW,UAAU;CAGzD,MAAM,YAAY;AAClB,KACE,OAAO,UAAU,gBAAgB,cACjC,OAAO,UAAU,cAAc,WAE/B,OAAM,IAAI,MACR,UAAU,WAAW,6CACtB;AAGH,QAAO,kCAAkC,UAAU;;AAGrD,SAAgB,6BACd,QACiD;CACjD,MAAM,4BAAY,IAAI,KAGnB;AAEH,QAAO;EACL,YAAY,SAAS;AACnB,UAAO,YAAY,QAAQ;;EAE7B,iBAAiB,OAAO,UAAU;AAChC,aAAU,IACR,UACA,OAAO,WAAW,YAAY;AAC5B,aAAS,EAAE,MAAM,SAAS,CAA0B;KACpD,CACH;;EAEH,oBAAoB,OAAO,UAAU;AACnC,aAAU,IAAI,SAAS,IAAI;AAC3B,aAAU,OAAO,SAAS;;EAE5B,UAAU;AACR,QAAK,MAAM,WAAW,UAAU,QAAQ,CACtC,UAAS;AAEX,aAAU,OAAO;;EAEpB;;AAGH,SAAgB,qBACd,SACwB;AACxB,QAAO,oBAAoB,QAAQ"}
@@ -1,5 +1,5 @@
1
1
  import { SyncoreWebPersistence } from "./persistence.js";
2
- import { SyncoreExternalChangeApplier, SyncoreExternalChangeEvent, SyncoreExternalChangeSignal } from "../core/index.d.mts";
2
+ import { ImpactScope, SyncoreExternalChangeApplier, SyncoreExternalChangeEvent, SyncoreExternalChangeSignal } from "../core/index.d.mts";
3
3
  import initSqlJs from "sql.js";
4
4
 
5
5
  //#region src/external-change.d.ts
@@ -31,6 +31,7 @@ declare class SqlJsExternalChangeApplier implements SyncoreExternalChangeApplier
31
31
  applyExternalChange(event: SyncoreExternalChangeEvent): Promise<{
32
32
  databaseChanged: boolean;
33
33
  storageChanged: boolean;
34
+ changedScopes: ImpactScope[];
34
35
  }>;
35
36
  }
36
37
  declare function createDefaultSyncChannelName(databaseName: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"external-change.d.ts","names":[],"sources":["../src/external-change.ts"],"mappings":";;;;;KAQK,aAAA,GAAgB,SAAA,CAAU,QAAA;AAAA,UAEd,2CAAA;EACf,WAAA;AAAA;AAAA,cAGW,oCAAA,YAAgD,2BAAA;EAAA,iBAC1C,OAAA;EAAA,iBACA,SAAA;cAIL,OAAA,EAAS,2CAAA;EAOrB,SAAA,CAAU,QAAA,GAAW,KAAA,EAAO,0BAAA;EAO5B,OAAA,CAAQ,KAAA,EAAO,0BAAA;EAIf,KAAA,CAAA;EAAA,iBAKiB,eAAA;AAAA;AAAA,UAUF,iCAAA;EACf,YAAA;EACA,WAAA,EAAa,qBAAA;EACb,cAAA,GAAiB,KAAA,GAAQ,UAAA,KAAe,aAAA;EACxC,eAAA,CAAgB,QAAA,EAAU,aAAA;AAAA;AAAA,cAGf,0BAAA,YAAsC,4BAAA;EAAA,iBAChC,YAAA;EAAA,iBACA,WAAA;EAAA,iBACA,cAAA;EAAA,iBACA,eAAA;cAEL,OAAA,EAAS,iCAAA;EAOf,mBAAA,CAAoB,KAAA,EAAO,0BAAA,GAA0B,OAAA;;;;;iBAe7C,4BAAA,CAA6B,YAAA"}
1
+ {"version":3,"file":"external-change.d.ts","names":[],"sources":["../src/external-change.ts"],"mappings":";;;;;KASK,aAAA,GAAgB,SAAA,CAAU,QAAA;AAAA,UAEd,2CAAA;EACf,WAAA;AAAA;AAAA,cAGW,oCAAA,YAAgD,2BAAA;EAAA,iBAC1C,OAAA;EAAA,iBACA,SAAA;cAIL,OAAA,EAAS,2CAAA;EAOrB,SAAA,CAAU,QAAA,GAAW,KAAA,EAAO,0BAAA;EAO5B,OAAA,CAAQ,KAAA,EAAO,0BAAA;EAIf,KAAA,CAAA;EAAA,iBAKiB,eAAA;AAAA;AAAA,UAUF,iCAAA;EACf,YAAA;EACA,WAAA,EAAa,qBAAA;EACb,cAAA,GAAiB,KAAA,GAAQ,UAAA,KAAe,aAAA;EACxC,eAAA,CAAgB,QAAA,EAAU,aAAA;AAAA;AAAA,cAGf,0BAAA,YAAsC,4BAAA;EAAA,iBAChC,YAAA;EAAA,iBACA,WAAA;EAAA,iBACA,cAAA;EAAA,iBACA,eAAA;cAEL,OAAA,EAAS,iCAAA;EAOf,mBAAA,CAAoB,KAAA,EAAO,0BAAA,GAA0B,OAAA;;;;;;iBAqB7C,4BAAA,CAA6B,YAAA"}
@@ -45,7 +45,8 @@ var SqlJsExternalChangeApplier = class {
45
45
  }
46
46
  return {
47
47
  databaseChanged,
48
- storageChanged: event.scope === "storage" || event.scope === "all"
48
+ storageChanged: event.scope === "storage" || event.scope === "all",
49
+ changedScopes: event.changedScopes ?? [...(event.changedTables ?? []).map((tableName) => `table:${tableName}`), ...(event.storageIds ?? []).map((storageId) => `storage:${storageId}`)]
49
50
  };
50
51
  }
51
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"external-change.js","names":[],"sources":["../src/external-change.ts"],"sourcesContent":["import type {\n SyncoreExternalChangeApplier,\n SyncoreExternalChangeEvent,\n SyncoreExternalChangeSignal\n} from \"@syncore/core\";\nimport type initSqlJs from \"sql.js\";\nimport type { SyncoreWebPersistence } from \"./persistence.js\";\n\ntype SqlJsDatabase = initSqlJs.Database;\n\nexport interface BroadcastChannelExternalChangeSignalOptions {\n channelName: string;\n}\n\nexport class BroadcastChannelExternalChangeSignal implements SyncoreExternalChangeSignal {\n private readonly channel: BroadcastChannel | undefined;\n private readonly listeners = new Set<\n (event: SyncoreExternalChangeEvent) => void\n >();\n\n constructor(options: BroadcastChannelExternalChangeSignalOptions) {\n if (typeof BroadcastChannel !== \"undefined\") {\n this.channel = new BroadcastChannel(options.channelName);\n this.channel.addEventListener(\"message\", this.messageListener);\n }\n }\n\n subscribe(listener: (event: SyncoreExternalChangeEvent) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n publish(event: SyncoreExternalChangeEvent): void {\n this.channel?.postMessage(event);\n }\n\n close(): void {\n this.channel?.removeEventListener(\"message\", this.messageListener);\n this.channel?.close();\n }\n\n private readonly messageListener = (event: MessageEvent<unknown>) => {\n if (!isExternalChangeEvent(event.data)) {\n return;\n }\n for (const listener of this.listeners) {\n listener(event.data);\n }\n };\n}\n\nexport interface SqlJsExternalChangeApplierOptions {\n databaseName: string;\n persistence: SyncoreWebPersistence;\n createDatabase: (bytes?: Uint8Array) => SqlJsDatabase;\n replaceDatabase(database: SqlJsDatabase): void;\n}\n\nexport class SqlJsExternalChangeApplier implements SyncoreExternalChangeApplier {\n private readonly databaseName: string;\n private readonly persistence: SyncoreWebPersistence;\n private readonly createDatabase: (bytes?: Uint8Array) => SqlJsDatabase;\n private readonly replaceDatabase: (database: SqlJsDatabase) => void;\n\n constructor(options: SqlJsExternalChangeApplierOptions) {\n this.databaseName = options.databaseName;\n this.persistence = options.persistence;\n this.createDatabase = (bytes) => options.createDatabase(bytes);\n this.replaceDatabase = (database) => options.replaceDatabase(database);\n }\n\n async applyExternalChange(event: SyncoreExternalChangeEvent) {\n const databaseChanged = event.scope === \"database\" || event.scope === \"all\";\n if (databaseChanged) {\n const bytes = await this.persistence.loadDatabase(this.databaseName);\n if (bytes) {\n this.replaceDatabase(this.createDatabase(bytes));\n }\n }\n return {\n databaseChanged,\n storageChanged: event.scope === \"storage\" || event.scope === \"all\"\n };\n }\n}\n\nexport function createDefaultSyncChannelName(databaseName: string): string {\n return `syncore:external:${databaseName}`;\n}\n\nfunction isExternalChangeEvent(\n value: unknown\n): value is SyncoreExternalChangeEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"sourceId\" in value &&\n \"scope\" in value &&\n \"reason\" in value &&\n \"timestamp\" in value\n );\n}\n"],"mappings":";AAcA,IAAa,uCAAb,MAAyF;CACvF;CACA,4BAA6B,IAAI,KAE9B;CAEH,YAAY,SAAsD;AAChE,MAAI,OAAO,qBAAqB,aAAa;AAC3C,QAAK,UAAU,IAAI,iBAAiB,QAAQ,YAAY;AACxD,QAAK,QAAQ,iBAAiB,WAAW,KAAK,gBAAgB;;;CAIlE,UAAU,UAAmE;AAC3E,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,QAAQ,OAAyC;AAC/C,OAAK,SAAS,YAAY,MAAM;;CAGlC,QAAc;AACZ,OAAK,SAAS,oBAAoB,WAAW,KAAK,gBAAgB;AAClE,OAAK,SAAS,OAAO;;CAGvB,mBAAoC,UAAiC;AACnE,MAAI,CAAC,sBAAsB,MAAM,KAAK,CACpC;AAEF,OAAK,MAAM,YAAY,KAAK,UAC1B,UAAS,MAAM,KAAK;;;AAY1B,IAAa,6BAAb,MAAgF;CAC9E;CACA;CACA;CACA;CAEA,YAAY,SAA4C;AACtD,OAAK,eAAe,QAAQ;AAC5B,OAAK,cAAc,QAAQ;AAC3B,OAAK,kBAAkB,UAAU,QAAQ,eAAe,MAAM;AAC9D,OAAK,mBAAmB,aAAa,QAAQ,gBAAgB,SAAS;;CAGxE,MAAM,oBAAoB,OAAmC;EAC3D,MAAM,kBAAkB,MAAM,UAAU,cAAc,MAAM,UAAU;AACtE,MAAI,iBAAiB;GACnB,MAAM,QAAQ,MAAM,KAAK,YAAY,aAAa,KAAK,aAAa;AACpE,OAAI,MACF,MAAK,gBAAgB,KAAK,eAAe,MAAM,CAAC;;AAGpD,SAAO;GACL;GACA,gBAAgB,MAAM,UAAU,aAAa,MAAM,UAAU;GAC9D;;;AAIL,SAAgB,6BAA6B,cAA8B;AACzE,QAAO,oBAAoB;;AAG7B,SAAS,sBACP,OACqC;AACrC,QACE,OAAO,UAAU,YACjB,UAAU,QACV,cAAc,SACd,WAAW,SACX,YAAY,SACZ,eAAe"}
1
+ {"version":3,"file":"external-change.js","names":[],"sources":["../src/external-change.ts"],"sourcesContent":["import type {\n ImpactScope,\n SyncoreExternalChangeApplier,\n SyncoreExternalChangeEvent,\n SyncoreExternalChangeSignal\n} from \"@syncore/core\";\nimport type initSqlJs from \"sql.js\";\nimport type { SyncoreWebPersistence } from \"./persistence.js\";\n\ntype SqlJsDatabase = initSqlJs.Database;\n\nexport interface BroadcastChannelExternalChangeSignalOptions {\n channelName: string;\n}\n\nexport class BroadcastChannelExternalChangeSignal implements SyncoreExternalChangeSignal {\n private readonly channel: BroadcastChannel | undefined;\n private readonly listeners = new Set<\n (event: SyncoreExternalChangeEvent) => void\n >();\n\n constructor(options: BroadcastChannelExternalChangeSignalOptions) {\n if (typeof BroadcastChannel !== \"undefined\") {\n this.channel = new BroadcastChannel(options.channelName);\n this.channel.addEventListener(\"message\", this.messageListener);\n }\n }\n\n subscribe(listener: (event: SyncoreExternalChangeEvent) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n publish(event: SyncoreExternalChangeEvent): void {\n this.channel?.postMessage(event);\n }\n\n close(): void {\n this.channel?.removeEventListener(\"message\", this.messageListener);\n this.channel?.close();\n }\n\n private readonly messageListener = (event: MessageEvent<unknown>) => {\n if (!isExternalChangeEvent(event.data)) {\n return;\n }\n for (const listener of this.listeners) {\n listener(event.data);\n }\n };\n}\n\nexport interface SqlJsExternalChangeApplierOptions {\n databaseName: string;\n persistence: SyncoreWebPersistence;\n createDatabase: (bytes?: Uint8Array) => SqlJsDatabase;\n replaceDatabase(database: SqlJsDatabase): void;\n}\n\nexport class SqlJsExternalChangeApplier implements SyncoreExternalChangeApplier {\n private readonly databaseName: string;\n private readonly persistence: SyncoreWebPersistence;\n private readonly createDatabase: (bytes?: Uint8Array) => SqlJsDatabase;\n private readonly replaceDatabase: (database: SqlJsDatabase) => void;\n\n constructor(options: SqlJsExternalChangeApplierOptions) {\n this.databaseName = options.databaseName;\n this.persistence = options.persistence;\n this.createDatabase = (bytes) => options.createDatabase(bytes);\n this.replaceDatabase = (database) => options.replaceDatabase(database);\n }\n\n async applyExternalChange(event: SyncoreExternalChangeEvent) {\n const databaseChanged = event.scope === \"database\" || event.scope === \"all\";\n if (databaseChanged) {\n const bytes = await this.persistence.loadDatabase(this.databaseName);\n if (bytes) {\n this.replaceDatabase(this.createDatabase(bytes));\n }\n }\n return {\n databaseChanged,\n storageChanged: event.scope === \"storage\" || event.scope === \"all\",\n changedScopes:\n event.changedScopes ??\n ([\n ...(event.changedTables ?? []).map((tableName) => `table:${tableName}`),\n ...(event.storageIds ?? []).map((storageId) => `storage:${storageId}`)\n ] as ImpactScope[])\n };\n }\n}\n\nexport function createDefaultSyncChannelName(databaseName: string): string {\n return `syncore:external:${databaseName}`;\n}\n\nfunction isExternalChangeEvent(\n value: unknown\n): value is SyncoreExternalChangeEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"sourceId\" in value &&\n \"scope\" in value &&\n \"reason\" in value &&\n \"timestamp\" in value\n );\n}\n"],"mappings":";AAeA,IAAa,uCAAb,MAAyF;CACvF;CACA,4BAA6B,IAAI,KAE9B;CAEH,YAAY,SAAsD;AAChE,MAAI,OAAO,qBAAqB,aAAa;AAC3C,QAAK,UAAU,IAAI,iBAAiB,QAAQ,YAAY;AACxD,QAAK,QAAQ,iBAAiB,WAAW,KAAK,gBAAgB;;;CAIlE,UAAU,UAAmE;AAC3E,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,QAAQ,OAAyC;AAC/C,OAAK,SAAS,YAAY,MAAM;;CAGlC,QAAc;AACZ,OAAK,SAAS,oBAAoB,WAAW,KAAK,gBAAgB;AAClE,OAAK,SAAS,OAAO;;CAGvB,mBAAoC,UAAiC;AACnE,MAAI,CAAC,sBAAsB,MAAM,KAAK,CACpC;AAEF,OAAK,MAAM,YAAY,KAAK,UAC1B,UAAS,MAAM,KAAK;;;AAY1B,IAAa,6BAAb,MAAgF;CAC9E;CACA;CACA;CACA;CAEA,YAAY,SAA4C;AACtD,OAAK,eAAe,QAAQ;AAC5B,OAAK,cAAc,QAAQ;AAC3B,OAAK,kBAAkB,UAAU,QAAQ,eAAe,MAAM;AAC9D,OAAK,mBAAmB,aAAa,QAAQ,gBAAgB,SAAS;;CAGxE,MAAM,oBAAoB,OAAmC;EAC3D,MAAM,kBAAkB,MAAM,UAAU,cAAc,MAAM,UAAU;AACtE,MAAI,iBAAiB;GACnB,MAAM,QAAQ,MAAM,KAAK,YAAY,aAAa,KAAK,aAAa;AACpE,OAAI,MACF,MAAK,gBAAgB,KAAK,eAAe,MAAM,CAAC;;AAGpD,SAAO;GACL;GACA,gBAAgB,MAAM,UAAU,aAAa,MAAM,UAAU;GAC7D,eACE,MAAM,iBACL,CACC,IAAI,MAAM,iBAAiB,EAAE,EAAE,KAAK,cAAc,SAAS,YAAY,EACvE,IAAI,MAAM,cAAc,EAAE,EAAE,KAAK,cAAc,WAAW,YAAY,CACvE;GACJ;;;AAIL,SAAgB,6BAA6B,cAA8B;AACzE,QAAO,oBAAoB;;AAG7B,SAAS,sBACP,OACqC;AACrC,QACE,OAAO,UAAU,YACjB,UAAU,QACV,cAAc,SACd,WAAW,SACX,YAAY,SACZ,eAAe"}
@@ -1,32 +1,32 @@
1
- import { AttachWebWorkerRuntimeOptions, AttachedWebWorkerRuntime, CreateWebWorkerClientProviderOptions, ManagedWebWorkerClient, SyncoreWebWorkerClient, SyncoreWorkerMessageEndpoint, WebWorkerSyncoreSchema, WorkerQueryWatch, attachWebWorkerRuntime, createManagedWebWorkerClient, createSyncoreWebWorkerClient, createWebWorkerClient } from "./worker.js";
2
1
  import { CreateWebPersistenceOptions, StoredWebFile, SyncoreWebPersistence, WebPersistenceMode, createWebPersistence, isOpfsAvailable } from "./persistence.js";
3
2
  import { BroadcastChannelExternalChangeSignal, BroadcastChannelExternalChangeSignalOptions, SqlJsExternalChangeApplier, SqlJsExternalChangeApplierOptions, createDefaultSyncChannelName } from "./external-change.js";
3
+ import { AttachWebWorkerRuntimeOptions, AttachedWebWorkerRuntime, CreateWebWorkerClientProviderOptions, ManagedWebWorkerClient, SyncoreWebWorkerClient, SyncoreWorkerMessageEndpoint, WebWorkerSyncoreSchema, WorkerQueryWatch, attachWebWorkerRuntime, createManagedWebWorkerClient, createSyncoreWebWorkerClient, createWebWorkerClient } from "./worker.js";
4
4
  import { IndexedDbPersistenceOptions, SyncoreIndexedDbPersistence } from "./indexeddb.js";
5
5
  import { OpfsPersistenceOptions, SyncoreOpfsPersistence } from "./opfs.js";
6
6
  import * as _syncore_core0 from "../core/index.d.mts";
7
- import { AnySyncoreSchema, DevtoolsCommandHandler, DevtoolsSink, DevtoolsSubscriptionHost, SchedulerOptions, StorageObject, StorageWriteInput, SyncoreCapabilities, SyncoreExperimentalPlugin, SyncoreRuntime, SyncoreRuntimeOptions, SyncoreStorageAdapter } from "../core/index.d.mts";
7
+ import { DevtoolsCommandHandler, DevtoolsSink, DevtoolsSubscriptionHost, SchedulerOptions, StorageObject, StorageWriteInput, SyncoreCapabilities, SyncoreDataModel, SyncoreRuntime, SyncoreRuntimeOptions, SyncoreStorageAdapter } from "../core/index.d.mts";
8
8
 
9
9
  //#region src/index.d.ts
10
- type WebSyncoreSchema = AnySyncoreSchema;
11
- type BrowserSyncoreSchema = WebSyncoreSchema;
10
+ type WebSyncoreSchema<TSchema extends SyncoreDataModel = SyncoreDataModel> = TSchema;
11
+ type BrowserSyncoreSchema<TSchema extends SyncoreDataModel = SyncoreDataModel> = WebSyncoreSchema<TSchema>;
12
12
  /**
13
13
  * Options for constructing a browser Syncore runtime.
14
14
  *
15
15
  * Use this when you want to host the full runtime in a browser tab or worker.
16
16
  */
17
- interface CreateWebRuntimeOptions {
17
+ interface CreateWebRuntimeOptions<TSchema extends WebSyncoreSchema = WebSyncoreSchema> {
18
18
  /** The schema for the local Syncore app. */
19
- schema: WebSyncoreSchema;
19
+ schema: TSchema;
20
20
  /** The generated function registry for the local Syncore app. */
21
- functions: SyncoreRuntimeOptions<WebSyncoreSchema>["functions"];
21
+ functions: SyncoreRuntimeOptions<TSchema>["functions"];
22
+ /** Optional resolved installed components for the local Syncore app. */
23
+ components?: SyncoreRuntimeOptions<TSchema>["components"];
22
24
  /** Optional platform capabilities exposed to function handlers. */
23
25
  capabilities?: SyncoreCapabilities;
24
26
  /** Optional custom SQL driver. Defaults to SQL.js with local persistence. */
25
- driver?: SyncoreRuntimeOptions<WebSyncoreSchema>["driver"];
27
+ driver?: SyncoreRuntimeOptions<TSchema>["driver"];
26
28
  /** Optional custom file/blob storage adapter. */
27
29
  storage?: SyncoreStorageAdapter;
28
- /** Optional experimental plugins for runtime hooks. */
29
- experimentalPlugins?: Array<SyncoreExperimentalPlugin<WebSyncoreSchema>>;
30
30
  /** Optional explicit persistence implementation. */
31
31
  persistence?: SyncoreWebPersistence;
32
32
  /** Which browser persistence mode to use when Syncore creates one for you. */
@@ -53,18 +53,18 @@ interface CreateWebRuntimeOptions {
53
53
  /**
54
54
  * Options for hosting a Syncore runtime inside a browser Worker.
55
55
  */
56
- interface CreateWebWorkerRuntimeOptions extends CreateWebRuntimeOptions {
56
+ interface CreateWebWorkerRuntimeOptions<TSchema extends WebSyncoreSchema = WebSyncoreSchema> extends CreateWebRuntimeOptions<TSchema> {
57
57
  /** The message endpoint exposed by the current worker global. */
58
58
  endpoint: SyncoreWorkerMessageEndpoint;
59
59
  }
60
60
  /**
61
61
  * Options for constructing a browser Syncore runtime.
62
62
  */
63
- type CreateBrowserRuntimeOptions = CreateWebRuntimeOptions;
63
+ type CreateBrowserRuntimeOptions<TSchema extends BrowserSyncoreSchema = BrowserSyncoreSchema> = CreateWebRuntimeOptions<TSchema>;
64
64
  /**
65
65
  * Options for hosting a Syncore runtime inside a browser Worker.
66
66
  */
67
- type CreateBrowserWorkerRuntimeOptions = CreateWebWorkerRuntimeOptions;
67
+ type CreateBrowserWorkerRuntimeOptions<TSchema extends BrowserSyncoreSchema = BrowserSyncoreSchema> = CreateWebWorkerRuntimeOptions<TSchema>;
68
68
  interface WebExternalChangeSupport {
69
69
  signal: BroadcastChannelExternalChangeSignal;
70
70
  applier?: SqlJsExternalChangeApplier;
@@ -75,11 +75,11 @@ interface WebExternalChangeSupport {
75
75
  * Most React apps should use a worker runtime instead so queries and SQLite work
76
76
  * stay off the main thread.
77
77
  */
78
- declare function createWebSyncoreRuntime(options: CreateWebRuntimeOptions): Promise<SyncoreRuntime<WebSyncoreSchema>>;
78
+ declare function createWebSyncoreRuntime<TSchema extends WebSyncoreSchema>(options: CreateWebRuntimeOptions<TSchema>): Promise<SyncoreRuntime<TSchema>>;
79
79
  declare function createWebExternalChangeSupport(options: {
80
80
  databaseName: string;
81
81
  persistence: SyncoreWebPersistence;
82
- driver: CreateWebRuntimeOptions["driver"] | undefined;
82
+ driver: CreateWebRuntimeOptions<SyncoreDataModel>["driver"] | undefined;
83
83
  }): WebExternalChangeSupport;
84
84
  declare function createExpoWebExternalChangeSupport(options: {
85
85
  databaseName: string;
@@ -92,23 +92,23 @@ declare function createExpoWebExternalChangeSupport(options: {
92
92
  /**
93
93
  * Attach a Syncore runtime to a browser Worker endpoint.
94
94
  */
95
- declare function createWebWorkerRuntime(options: CreateWebWorkerRuntimeOptions): AttachedWebWorkerRuntime;
95
+ declare function createWebWorkerRuntime<TSchema extends WebSyncoreSchema>(options: CreateWebWorkerRuntimeOptions<TSchema>): _syncore_core0.AttachedRuntimeBridge;
96
96
  /**
97
97
  * Attach a Syncore runtime to a browser Worker endpoint.
98
98
  */
99
- declare function createBrowserWorkerRuntime(options: CreateBrowserWorkerRuntimeOptions): AttachedWebWorkerRuntime;
99
+ declare function createBrowserWorkerRuntime(options: CreateBrowserWorkerRuntimeOptions): _syncore_core0.AttachedRuntimeBridge;
100
100
  /**
101
101
  * Create a client directly from a browser Syncore runtime.
102
102
  */
103
- declare function createWebSyncoreClient(runtime: SyncoreRuntime<WebSyncoreSchema>): _syncore_core0.SyncoreClient;
103
+ declare function createWebSyncoreClient<TSchema extends WebSyncoreSchema>(runtime: SyncoreRuntime<TSchema>): _syncore_core0.SyncoreClient;
104
104
  /**
105
105
  * Create a full Syncore runtime directly in the browser.
106
106
  */
107
- declare function createBrowserSyncoreRuntime(options: CreateBrowserRuntimeOptions): Promise<SyncoreRuntime<AnySyncoreSchema>>;
107
+ declare function createBrowserSyncoreRuntime<TSchema extends BrowserSyncoreSchema>(options: CreateBrowserRuntimeOptions<TSchema>): Promise<SyncoreRuntime<TSchema>>;
108
108
  /**
109
109
  * Create a client directly from a browser Syncore runtime.
110
110
  */
111
- declare function createBrowserSyncoreClient(runtime: SyncoreRuntime<BrowserSyncoreSchema>): _syncore_core0.SyncoreClient;
111
+ declare function createBrowserSyncoreClient<TSchema extends BrowserSyncoreSchema>(runtime: SyncoreRuntime<TSchema>): _syncore_core0.SyncoreClient;
112
112
  interface BrowserWebSocketDevtoolsSinkOptions {
113
113
  url: string;
114
114
  reconnectDelayMs?: number;
@@ -121,7 +121,7 @@ interface BrowserWebSocketDevtoolsSinkOptions {
121
121
  storageIdentity?: string;
122
122
  }
123
123
  interface BrowserWebSocketDevtoolsSink extends DevtoolsSink {
124
- attachRuntime(runtime: SyncoreRuntime<AnySyncoreSchema>): void;
124
+ attachRuntime(runtime: SyncoreRuntime<WebSyncoreSchema>): void;
125
125
  attachCommandHandler(handler: DevtoolsCommandHandler): void;
126
126
  attachSubscriptionHost(host: DevtoolsSubscriptionHost): void;
127
127
  dispose(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;KA0CY,gBAAA,GAAmB,gBAAA;AAAA,KACnB,oBAAA,GAAuB,gBAAA;;;;AAAnC;;UAOiB,uBAAA;EAPkB;EASjC,MAAA,EAAQ,gBAAA;EAFO;EAKf,SAAA,EAAW,qBAAA,CAAsB,gBAAA;;EAGjC,YAAA,GAAe,mBAAA;EAHkB;EAMjC,MAAA,GAAS,qBAAA,CAAsB,gBAAA;EAHhB;EAMf,OAAA,GAAU,qBAAA;EAHD;EAMT,mBAAA,GAAsB,KAAA,CAAM,yBAAA,CAA0B,gBAAA;EAAA;EAGtD,WAAA,GAAc,qBAAA;EAHQ;EAMtB,eAAA,GAAkB,kBAAA;EAAA;EAGlB,YAAA;EAwBY;EArBZ,uBAAA;EAqB4B;EAlB5B,qBAAA;EA9BQ;EAiCR,gBAAA;EA9BW;EAiCX,OAAA;EA9BA;EAiCA,UAAA,IAAc,QAAA;EA9Bd;EAiCA,QAAA;EAjC+B;EAoC/B,QAAA,GAAW,YAAA;EAjCD;EAoCV,SAAA,GAAY,gBAAA;AAAA;;;;UAMG,6BAAA,SAAsC,uBAAA;EAjCrD;EAmCA,QAAA,EAAU,4BAAA;AAAA;;;;KAMA,2BAAA,GAA8B,uBAAA;;;;KAK9B,iCAAA,GAAoC,6BAAA;AAAA,UAE/B,wBAAA;EACf,MAAA,EAAQ,oCAAA;EACR,OAAA,GAAU,0BAAA;AAAA;;AAjBZ;;;;;iBA0BsB,uBAAA,CACpB,OAAA,EAAS,uBAAA,GACR,OAAA,CAAQ,cAAA,CAAe,gBAAA;AAAA,iBAoHV,8BAAA,CAA+B,OAAA;EAC7C,YAAA;EACA,WAAA,EAAa,qBAAA;EACb,MAAA,EAAQ,uBAAA;AAAA,IACN,wBAAA;AAAA,iBAwBkB,kCAAA,CAAmC,OAAA;EACvD,YAAA;EACA,UAAA,IAAc,QAAA;EACd,OAAA;EACA,uBAAA;EACA,qBAAA;EACA,eAAA,GAAkB,kBAAA;AAAA,IAChB,OAAA,CAAQ,wBAAA;AApKZ;;;AAAA,iBA6LgB,sBAAA,CAAuB,OAAA,EAAS,6BAAA,GAA6B,wBAAA;;;;iBAU7D,0BAAA,CACd,OAAA,EAAS,iCAAA,GAAiC,wBAAA;;;AA7L5C;iBAqMgB,sBAAA,CACd,OAAA,EAAS,cAAA,CAAe,gBAAA,IAAD,cAAA,CAAkB,aAAA;;;;iBAQ3B,2BAAA,CACd,OAAA,EAAS,2BAAA,GAA2B,OAAA,CAAA,cAAA,CAAA,gBAAA;;;;iBAQtB,0BAAA,CACd,OAAA,EAAS,cAAA,CAAe,oBAAA,IAAD,cAAA,CAAsB,aAAA;AAAA,UAK9B,mCAAA;EACf,GAAA;EACA,gBAAA;EACA,OAAA;EACA,MAAA;EACA,YAAA;EACA,UAAA;EACA,eAAA;EACA,aAAA;EACA,eAAA;AAAA;AAAA,UAGe,4BAAA,SAAqC,YAAA;EACpD,aAAA,CAAc,OAAA,EAAS,cAAA,CAAe,gBAAA;EACtC,oBAAA,CAAqB,OAAA,EAAS,sBAAA;EAC9B,sBAAA,CAAuB,IAAA,EAAM,wBAAA;EAC7B,OAAA;AAAA;AAAA,iBAGc,kCAAA,CACd,OAAA,EAAS,mCAAA,GACR,4BAAA;;;;cA0hBU,yBAAA,YAAqC,qBAAA;EAAA,iBAE7B,WAAA;EAAA,iBACA,SAAA;cADA,WAAA,EAAa,qBAAA,EACb,SAAA;EAGb,GAAA,CAAI,EAAA,UAAY,KAAA,EAAO,iBAAA,GAAoB,OAAA,CAAQ,aAAA;EAgBnD,GAAA,CAAI,EAAA,WAAa,OAAA,CAAQ,aAAA;EAazB,IAAA,CAAK,EAAA,WAAa,OAAA,CAAQ,UAAA;EAK1B,MAAA,CAAO,EAAA,WAAa,OAAA;EAIpB,IAAA,CAAA,GAAQ,OAAA,CAAQ,aAAA;AAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":"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"}