@evolu/common 8.0.0-next.5 → 8.0.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 (236) hide show
  1. package/dist/src/Array.d.ts +279 -173
  2. package/dist/src/Array.d.ts.map +1 -1
  3. package/dist/src/Array.js +105 -101
  4. package/dist/src/Assert.d.ts +39 -44
  5. package/dist/src/Assert.d.ts.map +1 -1
  6. package/dist/src/Assert.js +38 -31
  7. package/dist/src/BigInt.d.ts +6 -3
  8. package/dist/src/BigInt.d.ts.map +1 -1
  9. package/dist/src/BigInt.js +5 -2
  10. package/dist/src/Brand.d.ts +27 -40
  11. package/dist/src/Brand.d.ts.map +1 -1
  12. package/dist/src/Buffer.d.ts +27 -11
  13. package/dist/src/Buffer.d.ts.map +1 -1
  14. package/dist/src/Cache.d.ts +9 -4
  15. package/dist/src/Cache.d.ts.map +1 -1
  16. package/dist/src/Cache.js +8 -3
  17. package/dist/src/Callbacks.d.ts +30 -19
  18. package/dist/src/Callbacks.d.ts.map +1 -1
  19. package/dist/src/Console.d.ts +145 -66
  20. package/dist/src/Console.d.ts.map +1 -1
  21. package/dist/src/Console.js +91 -43
  22. package/dist/src/Crypto.d.ts +85 -42
  23. package/dist/src/Crypto.d.ts.map +1 -1
  24. package/dist/src/Crypto.js +44 -20
  25. package/dist/src/Eq.d.ts +87 -21
  26. package/dist/src/Eq.d.ts.map +1 -1
  27. package/dist/src/Eq.js +67 -19
  28. package/dist/src/Error.d.ts +3 -3
  29. package/dist/src/Error.d.ts.map +1 -1
  30. package/dist/src/Function.d.ts +119 -58
  31. package/dist/src/Function.d.ts.map +1 -1
  32. package/dist/src/Function.js +86 -43
  33. package/dist/src/Http.d.ts +394 -0
  34. package/dist/src/Http.d.ts.map +1 -0
  35. package/dist/src/Http.js +102 -0
  36. package/dist/src/Identicon.d.ts +16 -7
  37. package/dist/src/Identicon.d.ts.map +1 -1
  38. package/dist/src/Identicon.js +14 -5
  39. package/dist/src/LeakDetector.d.ts +88 -0
  40. package/dist/src/LeakDetector.d.ts.map +1 -0
  41. package/dist/src/LeakDetector.js +86 -0
  42. package/dist/src/LockManager.d.ts +18 -9
  43. package/dist/src/LockManager.d.ts.map +1 -1
  44. package/dist/src/LockManager.js +7 -8
  45. package/dist/src/Lookup.d.ts +43 -13
  46. package/dist/src/Lookup.d.ts.map +1 -1
  47. package/dist/src/Lookup.js +28 -8
  48. package/dist/src/Microtask.d.ts +1 -1
  49. package/dist/src/Microtask.d.ts.map +1 -1
  50. package/dist/src/Microtask.js +3 -7
  51. package/dist/src/Number.d.ts +49 -13
  52. package/dist/src/Number.d.ts.map +1 -1
  53. package/dist/src/Number.js +34 -5
  54. package/dist/src/Object.d.ts +160 -40
  55. package/dist/src/Object.d.ts.map +1 -1
  56. package/dist/src/Object.js +92 -46
  57. package/dist/src/Option.d.ts +10 -7
  58. package/dist/src/Option.d.ts.map +1 -1
  59. package/dist/src/Option.js +9 -6
  60. package/dist/src/Order.d.ts +21 -21
  61. package/dist/src/Order.d.ts.map +1 -1
  62. package/dist/src/Order.js +18 -21
  63. package/dist/src/Platform.d.ts +31 -0
  64. package/dist/src/Platform.d.ts.map +1 -1
  65. package/dist/src/Platform.js +98 -0
  66. package/dist/src/Random.d.ts +32 -17
  67. package/dist/src/Random.d.ts.map +1 -1
  68. package/dist/src/Random.js +12 -8
  69. package/dist/src/Redacted.d.ts +43 -29
  70. package/dist/src/Redacted.d.ts.map +1 -1
  71. package/dist/src/Redacted.js +14 -3
  72. package/dist/src/Ref.d.ts +11 -3
  73. package/dist/src/Ref.d.ts.map +1 -1
  74. package/dist/src/Ref.js +2 -2
  75. package/dist/src/RefCount.d.ts +2 -6
  76. package/dist/src/RefCount.d.ts.map +1 -1
  77. package/dist/src/RefCount.js +33 -90
  78. package/dist/src/Relation.d.ts +70 -5
  79. package/dist/src/Relation.d.ts.map +1 -1
  80. package/dist/src/Relation.js +77 -2
  81. package/dist/src/Resource.d.ts +590 -155
  82. package/dist/src/Resource.d.ts.map +1 -1
  83. package/dist/src/Resource.js +592 -343
  84. package/dist/src/Result.d.ts +838 -191
  85. package/dist/src/Result.d.ts.map +1 -1
  86. package/dist/src/Result.js +163 -102
  87. package/dist/src/Schedule.d.ts +684 -231
  88. package/dist/src/Schedule.d.ts.map +1 -1
  89. package/dist/src/Schedule.js +766 -295
  90. package/dist/src/Set.d.ts +89 -40
  91. package/dist/src/Set.d.ts.map +1 -1
  92. package/dist/src/Set.js +50 -29
  93. package/dist/src/Sqlite.d.ts +29 -72
  94. package/dist/src/Sqlite.d.ts.map +1 -1
  95. package/dist/src/Sqlite.js +39 -45
  96. package/dist/src/StackTrace.d.ts +40 -0
  97. package/dist/src/StackTrace.d.ts.map +1 -0
  98. package/dist/src/StackTrace.js +140 -0
  99. package/dist/src/Store.d.ts +5 -4
  100. package/dist/src/Store.d.ts.map +1 -1
  101. package/dist/src/Store.js +5 -4
  102. package/dist/src/String.d.ts +7 -1
  103. package/dist/src/String.d.ts.map +1 -1
  104. package/dist/src/String.js +20 -7
  105. package/dist/src/Task.d.ts +3428 -1629
  106. package/dist/src/Task.d.ts.map +1 -1
  107. package/dist/src/Task.js +1876 -1279
  108. package/dist/src/Test.d.ts +17 -124
  109. package/dist/src/Test.d.ts.map +1 -1
  110. package/dist/src/Test.js +17 -68
  111. package/dist/src/Time.d.ts +108 -49
  112. package/dist/src/Time.d.ts.map +1 -1
  113. package/dist/src/Time.js +172 -73
  114. package/dist/src/Type.d.ts +3542 -1926
  115. package/dist/src/Type.d.ts.map +1 -1
  116. package/dist/src/Type.js +3070 -1784
  117. package/dist/src/Types.d.ts +200 -100
  118. package/dist/src/Types.d.ts.map +1 -1
  119. package/dist/src/Types.js +39 -8
  120. package/dist/src/WebSocket.d.ts +48 -23
  121. package/dist/src/WebSocket.d.ts.map +1 -1
  122. package/dist/src/WebSocket.js +15 -6
  123. package/dist/src/Worker.d.ts +94 -36
  124. package/dist/src/Worker.d.ts.map +1 -1
  125. package/dist/src/Worker.js +58 -24
  126. package/dist/src/index.d.ts +55 -52
  127. package/dist/src/index.d.ts.map +1 -1
  128. package/dist/src/index.js +3 -1
  129. package/dist/src/intl/cs.d.ts +94 -0
  130. package/dist/src/intl/cs.d.ts.map +1 -0
  131. package/dist/src/intl/cs.js +220 -0
  132. package/dist/src/intl/index.d.ts +7 -0
  133. package/dist/src/intl/index.d.ts.map +1 -0
  134. package/dist/src/intl/index.js +6 -0
  135. package/dist/src/local-first/Db.d.ts +12 -8
  136. package/dist/src/local-first/Db.d.ts.map +1 -1
  137. package/dist/src/local-first/Db.js +107 -130
  138. package/dist/src/local-first/Error.d.ts +4 -4
  139. package/dist/src/local-first/Evolu.d.ts +338 -92
  140. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  141. package/dist/src/local-first/Evolu.js +47 -55
  142. package/dist/src/local-first/LocalAuth.d.ts +4 -4
  143. package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
  144. package/dist/src/local-first/Owner.d.ts +61 -24
  145. package/dist/src/local-first/Owner.d.ts.map +1 -1
  146. package/dist/src/local-first/Owner.js +45 -8
  147. package/dist/src/local-first/Protocol.d.ts +44 -31
  148. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  149. package/dist/src/local-first/Protocol.js +36 -13
  150. package/dist/src/local-first/Query.d.ts +147 -62
  151. package/dist/src/local-first/Query.d.ts.map +1 -1
  152. package/dist/src/local-first/Query.js +112 -58
  153. package/dist/src/local-first/Relay.d.ts +44 -14
  154. package/dist/src/local-first/Relay.d.ts.map +1 -1
  155. package/dist/src/local-first/Schema.d.ts +92 -41
  156. package/dist/src/local-first/Schema.d.ts.map +1 -1
  157. package/dist/src/local-first/Schema.js +25 -8
  158. package/dist/src/local-first/Shared.d.ts +23 -21
  159. package/dist/src/local-first/Shared.d.ts.map +1 -1
  160. package/dist/src/local-first/Shared.js +85 -42
  161. package/dist/src/local-first/Storage.d.ts +53 -32
  162. package/dist/src/local-first/Storage.d.ts.map +1 -1
  163. package/dist/src/local-first/Storage.js +194 -234
  164. package/dist/src/local-first/Timestamp.d.ts +21 -21
  165. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  166. package/dist/src/local-first/Timestamp.js +2 -2
  167. package/dist/src/local-first/index.d.ts +11 -11
  168. package/package.json +14 -13
  169. package/src/Array.ts +306 -205
  170. package/src/Assert.ts +48 -68
  171. package/src/BigInt.ts +6 -3
  172. package/src/Brand.ts +27 -40
  173. package/src/Buffer.ts +28 -12
  174. package/src/Cache.ts +9 -4
  175. package/src/Callbacks.ts +30 -19
  176. package/src/Console.ts +156 -84
  177. package/src/Crypto.ts +83 -41
  178. package/src/Eq.ts +95 -22
  179. package/src/Error.ts +5 -2
  180. package/src/Function.ts +167 -59
  181. package/src/Http.ts +549 -0
  182. package/src/Identicon.ts +16 -7
  183. package/src/LeakDetector.ts +182 -0
  184. package/src/LockManager.ts +43 -39
  185. package/src/Lookup.ts +62 -28
  186. package/src/Microtask.ts +19 -23
  187. package/src/Number.ts +64 -12
  188. package/src/Object.ts +173 -49
  189. package/src/Option.ts +10 -7
  190. package/src/Order.ts +23 -21
  191. package/src/Platform.ts +136 -0
  192. package/src/Polyfills.ts +6 -12
  193. package/src/Random.ts +32 -19
  194. package/src/Redacted.ts +44 -30
  195. package/src/Ref.ts +14 -6
  196. package/src/RefCount.ts +38 -80
  197. package/src/Relation.ts +202 -10
  198. package/src/Resource.ts +1199 -591
  199. package/src/Result.ts +930 -271
  200. package/src/Schedule.ts +859 -343
  201. package/src/Set.ts +89 -40
  202. package/src/Sqlite.ts +142 -137
  203. package/src/StackTrace.ts +230 -0
  204. package/src/Store.ts +8 -7
  205. package/src/String.ts +22 -5
  206. package/src/Task.ts +5109 -2845
  207. package/src/Test.ts +20 -167
  208. package/src/Time.ts +293 -90
  209. package/src/Type.ts +10034 -4117
  210. package/src/Types.ts +227 -101
  211. package/src/WebSocket.ts +64 -36
  212. package/src/Worker.ts +180 -72
  213. package/src/index.ts +55 -52
  214. package/src/intl/cs.ts +388 -0
  215. package/src/intl/index.ts +7 -0
  216. package/src/local-first/Db.ts +161 -190
  217. package/src/local-first/Error.ts +4 -4
  218. package/src/local-first/Evolu.ts +495 -250
  219. package/src/local-first/LocalAuth.ts +6 -12
  220. package/src/local-first/Owner.ts +58 -21
  221. package/src/local-first/Protocol.ts +49 -31
  222. package/src/local-first/Query.ts +146 -61
  223. package/src/local-first/Relay.ts +51 -21
  224. package/src/local-first/Schema.ts +109 -51
  225. package/src/local-first/Shared.ts +253 -214
  226. package/src/local-first/Storage.ts +266 -264
  227. package/src/local-first/Timestamp.ts +25 -18
  228. package/src/local-first/index.ts +11 -11
  229. package/dist/src/Skiplist.d.ts +0 -28
  230. package/dist/src/Skiplist.d.ts.map +0 -1
  231. package/dist/src/Skiplist.js +0 -64
  232. package/dist/src/Tracer.d.ts +0 -48
  233. package/dist/src/Tracer.d.ts.map +0 -1
  234. package/dist/src/Tracer.js +0 -6
  235. package/src/Skiplist.ts +0 -108
  236. package/src/Tracer.ts +0 -54
package/src/Worker.ts CHANGED
@@ -4,10 +4,10 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { assert, assertNotDisposed } from "./Assert.js";
8
- import type { Brand } from "./Brand.js";
9
- import type { ConsoleDep, ConsoleStoreOutputEntryDep } from "./Console.js";
10
- import { testWaitForMacrotask } from "./Test.js";
7
+ import { assert } from "./Assert.ts";
8
+ import type { Brand } from "./Brand.ts";
9
+ import type { ConsoleDep, ConsoleStoreOutputEntryDep } from "./Console.ts";
10
+ import { disposable } from "./Function.ts";
11
11
 
12
12
  /**
13
13
  * Typed, disposable Worker.
@@ -60,13 +60,28 @@ export interface MessagePort<Input, Output = never> extends Disposable {
60
60
  /**
61
61
  * The native underlying port for transferring via `postMessage`.
62
62
  *
63
- * ### Example
63
+ * Prepare a port for transfer:
64
64
  *
65
65
  * ```ts
66
- * sharedWorker.port.postMessage(
67
- * { type: "InitConsole", port: consoleChannel.port1.native },
68
- * [consoleChannel.port1.native],
69
- * );
66
+ * import {
67
+ * createMessageChannel,
68
+ * type NativeMessagePort,
69
+ * } from "@evolu/common";
70
+ *
71
+ * interface ConsoleMessage {
72
+ * readonly type: "ConsoleEntry";
73
+ * readonly text: string;
74
+ * }
75
+ *
76
+ * using consoleChannel = createMessageChannel<ConsoleMessage>();
77
+ * const init = {
78
+ * type: "InitConsole",
79
+ * port: consoleChannel.port1.native,
80
+ * };
81
+ *
82
+ * expectTypeOf(init.port).toEqualTypeOf<
83
+ * NativeMessagePort<ConsoleMessage>
84
+ * >();
70
85
  * ```
71
86
  */
72
87
  readonly native: NativeMessagePort<Input, Output>;
@@ -126,36 +141,80 @@ export type WorkerDeps = ConsoleDep &
126
141
  *
127
142
  * For one-way communication, omit `Output` (defaults to `never`).
128
143
  *
129
- * ### Example
130
- *
131
- * Transfer a channel port to a SharedWorker for async initialization:
144
+ * Transfer a channel port to a SharedWorker and use the retained port
145
+ * immediately:
132
146
  *
133
147
  * ```ts
134
- * // Main thread: create channel, transfer port1, use port2 immediately.
135
- * const channel = createMessageChannel<EvoluRequest, EvoluResponse>();
136
- *
137
- * sharedWorker.port.postMessage(
138
- * { type: "CreateEvolu", port: channel.port1.native },
139
- * [channel.port1.native],
140
- * );
141
- *
142
- * // Safe to send immediately — messages queue until worker is ready.
143
- * channel.port2.postMessage({ type: "Query", query });
144
- * channel.port2.onMessage = (response) => {
145
- * handleResponse(response);
146
- * };
148
+ * import {
149
+ * createMessageChannel,
150
+ * createMessagePort,
151
+ * createSharedWorker,
152
+ * type NativeMessagePort,
153
+ * } from "@evolu/common";
154
+ *
155
+ * interface Query {
156
+ * readonly text: string;
157
+ * }
158
+ * interface QueryResult {
159
+ * readonly rows: ReadonlyArray<string>;
160
+ * }
161
+ * interface ConnectToEvolu {
162
+ * readonly port: NativeMessagePort<QueryResult, Query>;
163
+ * }
164
+ *
165
+ * const response = Promise.withResolvers<QueryResult>();
166
+ * using sharedWorker = createSharedWorker<ConnectToEvolu>((self) => {
167
+ * self.onConnect = (controlPort) => {
168
+ * controlPort.onMessage = ({ port }) => {
169
+ * const workerQueries = createMessagePort<QueryResult, Query>(port);
170
+ * workerQueries.onMessage = (query) => {
171
+ * workerQueries.postMessage({ rows: [query.text] });
172
+ * workerQueries[Symbol.dispose]();
173
+ * };
174
+ * };
175
+ * };
176
+ * });
177
+ * using queryChannel = createMessageChannel<Query, QueryResult>();
178
+ * queryChannel.port1.onMessage = response.resolve;
179
+ *
180
+ * // The main thread retains port1 and transfers the worker-facing port2.
181
+ * sharedWorker.port.postMessage({ port: queryChannel.port2.native }, [
182
+ * queryChannel.port2.native,
183
+ * ]);
184
+ * queryChannel.port1.postMessage({ text: "all todos" });
185
+ *
186
+ * expect(await response.promise).toEqual({ rows: ["all todos"] });
147
187
  * ```
148
188
  *
189
+ * On the worker side, attach the handler after asynchronous initialization;
190
+ * messages sent earlier remain queued:
191
+ *
149
192
  * ```ts
150
- * // Worker: receive the port, do async init, then start listening.
151
- * const evoluPort = createMessagePort<EvoluResponse, EvoluRequest>(
152
- * message.port,
153
- * );
154
- * await openDatabase(name);
155
- * evoluPort.onMessage = (request) => {
156
- * handleRequest(request);
193
+ * import { createMessageChannel, createMessagePort } from "@evolu/common";
194
+ *
195
+ * interface Query {
196
+ * readonly text: string;
197
+ * }
198
+ *
199
+ * using channel = createMessageChannel<Query>();
200
+ * using workerPort = createMessagePort<never, Query>(channel.port2.native);
201
+ * const received: Array<Query> = [];
202
+ * const allReceived = Promise.withResolvers<void>();
203
+ * // The main thread can send several messages while the worker initializes.
204
+ * channel.port1.postMessage({ text: "all todos" });
205
+ * channel.port1.postMessage({ text: "completed todos" });
206
+ *
207
+ * await Promise.resolve();
208
+ * workerPort.onMessage = (query) => {
209
+ * received.push(query);
210
+ * if (received.length === 2) allReceived.resolve();
157
211
  * };
158
- * // Queued messages are now delivered in order.
212
+ * await allReceived.promise;
213
+ *
214
+ * expect(received).toEqual([
215
+ * { text: "all todos" },
216
+ * { text: "completed todos" },
217
+ * ]);
159
218
  * ```
160
219
  *
161
220
  * @see https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel
@@ -357,41 +416,41 @@ export const createBroadcastChannel: CreateBroadcastChannel = <
357
416
  dispatches.add(dispatch as BroadcastChannelDispatch<any>);
358
417
 
359
418
  using disposer = new DisposableStack();
419
+ let disposed = false;
360
420
 
361
421
  disposer.defer(() => {
422
+ disposed = true;
362
423
  onMessageHandler = null;
363
424
 
364
425
  dispatches.delete(dispatch as BroadcastChannelDispatch<any>);
365
426
  if (dispatches.size === 0) broadcastChannelDispatchesByName.delete(name);
366
427
  });
367
428
 
368
- const disposables = disposer.move();
369
-
370
- return {
371
- postMessage: (message) => {
372
- assertNotDisposed(disposables);
373
-
374
- const dispatches = broadcastChannelDispatchesByName.get(name);
375
- assert(dispatches, "Expected broadcast channel dispatches");
376
-
377
- for (const otherDispatch of [...dispatches]) {
378
- if (otherDispatch === dispatch) continue;
379
-
380
- globalThis.setTimeout(() => {
381
- if (!dispatches.has(otherDispatch)) return;
382
- otherDispatch(message);
383
- }, 0);
384
- }
385
- },
386
- get onMessage() {
387
- return disposables.disposed ? null : onMessageHandler;
429
+ return disposable<BroadcastChannel<Input, Output>>(
430
+ {
431
+ postMessage: (message) => {
432
+ const dispatches = broadcastChannelDispatchesByName.get(name);
433
+ assert(dispatches, "Expected broadcast channel dispatches");
434
+
435
+ for (const otherDispatch of [...dispatches]) {
436
+ if (otherDispatch === dispatch) continue;
437
+
438
+ scheduleWorkerTask(() => {
439
+ if (!dispatches.has(otherDispatch)) return;
440
+ otherDispatch(message);
441
+ });
442
+ }
443
+ },
444
+ get onMessage() {
445
+ return disposed ? null : onMessageHandler;
446
+ },
447
+ set onMessage(fn) {
448
+ if (disposed) return;
449
+ onMessageHandler = fn;
450
+ },
388
451
  },
389
- set onMessage(fn) {
390
- if (disposables.disposed) return;
391
- onMessageHandler = fn;
392
- },
393
- [Symbol.dispose]: () => disposables.dispose(),
394
- };
452
+ disposer,
453
+ );
395
454
  };
396
455
 
397
456
  type BroadcastChannelDispatch<T> = (message: T) => void;
@@ -537,17 +596,17 @@ export const testCreateBroadcastChannel = <Input, Output = Input>(
537
596
  };
538
597
 
539
598
  /**
540
- * Waits the minimal time necessary for in-memory worker message delivery in
541
- * tests.
599
+ * Waits until scheduled in-memory worker message delivery becomes idle.
542
600
  *
543
- * This is better than `vi.waitFor` when a test only needs to flush the known
544
- * in-memory worker/message-port pipeline. It encodes that transport boundary
545
- * once, avoids polling, and keeps worker-focused tests fast and explicit.
601
+ * This observes actual transport tasks instead of waiting for an arbitrary
602
+ * duration. It also waits through message handlers that schedule more worker
603
+ * tasks before the current microtask checkpoint completes.
546
604
  */
547
- export const testWaitForWorkerMessage = async (): Promise<void> => {
548
- await testWaitForMacrotask();
549
- await testWaitForMacrotask();
550
- };
605
+ export const testWaitForWorkerMessage = (): Promise<void> =>
606
+ new Promise((resolve) => {
607
+ workerTaskIdleWaiters.add(resolve);
608
+ notifyWorkerTaskIdle();
609
+ });
551
610
 
552
611
  const createMemoryWorkerPair = <Input, Output = never>(): {
553
612
  readonly worker: Worker<Input, Output>;
@@ -650,7 +709,7 @@ const createPort = <Input, Output>({
650
709
  nativePortRegistry.delete(native);
651
710
 
652
711
  if (receive.flushTimeoutId != null) {
653
- globalThis.clearTimeout(receive.flushTimeoutId);
712
+ cancelWorkerTask(receive.flushTimeoutId);
654
713
  receive.flushTimeoutId = null;
655
714
  }
656
715
 
@@ -665,8 +724,7 @@ const createPort = <Input, Output>({
665
724
  if (state.flushScheduled || state.ownerCount === 0) return;
666
725
  state.flushScheduled = true;
667
726
 
668
- // Native worker messages are task-queued; use macrotask timing.
669
- state.flushTimeoutId = globalThis.setTimeout(() => {
727
+ state.flushTimeoutId = scheduleWorkerTask(() => {
670
728
  state.flushTimeoutId = null;
671
729
  state.flushScheduled = false;
672
730
  if (state.ownerCount === 0) return;
@@ -680,7 +738,7 @@ const createPort = <Input, Output>({
680
738
 
681
739
  handler(message);
682
740
  }
683
- }, 0);
741
+ });
684
742
  };
685
743
 
686
744
  return {
@@ -718,6 +776,56 @@ const createPort = <Input, Output>({
718
776
  };
719
777
  };
720
778
 
779
+ const pendingWorkerTaskIds = new Set<
780
+ ReturnType<typeof globalThis.setTimeout>
781
+ >();
782
+ const workerTaskIdleWaiters = new Set<() => void>();
783
+ let workerTaskIdleCheckTimeoutId:
784
+ ReturnType<typeof globalThis.setTimeout> | undefined;
785
+
786
+ const scheduleWorkerTask = (
787
+ callback: () => void,
788
+ ): ReturnType<typeof globalThis.setTimeout> => {
789
+ if (workerTaskIdleCheckTimeoutId != null) {
790
+ globalThis.clearTimeout(workerTaskIdleCheckTimeoutId);
791
+ workerTaskIdleCheckTimeoutId = undefined;
792
+ }
793
+
794
+ const timeoutId = globalThis.setTimeout(() => {
795
+ pendingWorkerTaskIds.delete(timeoutId);
796
+ try {
797
+ callback();
798
+ } finally {
799
+ queueMicrotask(notifyWorkerTaskIdle);
800
+ }
801
+ }, 0);
802
+ pendingWorkerTaskIds.add(timeoutId);
803
+ return timeoutId;
804
+ };
805
+
806
+ const cancelWorkerTask = (
807
+ timeoutId: ReturnType<typeof globalThis.setTimeout>,
808
+ ): void => {
809
+ globalThis.clearTimeout(timeoutId);
810
+ pendingWorkerTaskIds.delete(timeoutId);
811
+ queueMicrotask(notifyWorkerTaskIdle);
812
+ };
813
+
814
+ const notifyWorkerTaskIdle = (): void => {
815
+ if (
816
+ pendingWorkerTaskIds.size > 0 ||
817
+ workerTaskIdleWaiters.size === 0 ||
818
+ workerTaskIdleCheckTimeoutId != null
819
+ )
820
+ return;
821
+
822
+ workerTaskIdleCheckTimeoutId = globalThis.setTimeout(() => {
823
+ workerTaskIdleCheckTimeoutId = undefined;
824
+ for (const resolve of workerTaskIdleWaiters) resolve();
825
+ workerTaskIdleWaiters.clear();
826
+ }, 0);
827
+ };
828
+
721
829
  const createTestPort = <Input, Output>(
722
830
  registration: PortRegistration<Input, Output>,
723
831
  ): MessagePort<Input, Output> => createPort(registration);
package/src/index.ts CHANGED
@@ -4,60 +4,63 @@
4
4
  * @module
5
5
  */
6
6
 
7
- export * from "./Array.js";
8
- export * from "./Assert.js";
9
- export * from "./BigInt.js";
10
- export * from "./Brand.js";
11
- export * from "./Buffer.js";
12
- export * from "./Cache.js";
13
- export * from "./Callbacks.js";
14
- export * from "./Console.js";
15
- export * from "./Crypto.js";
16
- export * from "./Eq.js";
17
- export * from "./Error.js";
18
- export * from "./Function.js";
19
- export * from "./Identicon.js";
20
- export * from "./LockManager.js";
21
- export * from "./Lookup.js";
22
- export * from "./Microtask.js";
23
- export * from "./Number.js";
24
- export * from "./Object.js";
25
- export * from "./Option.js";
26
- export * from "./Order.js";
27
- export * from "./Platform.js";
28
- export * from "./Random.js";
29
- export * from "./Redacted.js";
30
- export * from "./Ref.js";
31
- export * from "./RefCount.js";
32
- export * from "./Relation.js";
33
- export * from "./Resource.js";
34
- export * from "./Result.js";
35
- export * from "./Set.js";
36
- export * from "./Sqlite.js";
37
- export * from "./Store.js";
38
- export * from "./String.js";
39
- export * from "./Task.js";
40
- export * from "./Test.js";
41
- export * from "./Time.js";
42
- export * from "./Tracer.js";
43
- export * from "./Type.js";
44
- export * from "./Types.js";
45
- export * from "./WebSocket.js";
46
- export * from "./Worker.js";
7
+ export * from "./Array.ts";
8
+ export * from "./Assert.ts";
9
+ export * from "./BigInt.ts";
10
+ export * from "./Brand.ts";
11
+ export * from "./Buffer.ts";
12
+ export * from "./Cache.ts";
13
+ export * from "./Callbacks.ts";
14
+ export * from "./Console.ts";
15
+ export * from "./Crypto.ts";
16
+ export * from "./Eq.ts";
17
+ export * from "./Error.ts";
18
+ export * from "./Function.ts";
19
+ export * from "./Http.ts";
20
+ export * from "./Identicon.ts";
21
+ export * from "./LeakDetector.ts";
22
+ export * from "./LockManager.ts";
23
+ export * from "./Lookup.ts";
24
+ export * from "./Microtask.ts";
25
+ export * from "./Number.ts";
26
+ export * from "./Object.ts";
27
+ export * from "./Option.ts";
28
+ export * from "./Order.ts";
29
+ export * from "./Platform.ts";
30
+ export * from "./Random.ts";
31
+ export * from "./Redacted.ts";
32
+ export * from "./Ref.ts";
33
+ export * from "./RefCount.ts";
34
+ export * from "./Relation.ts";
35
+ export * from "./Resource.ts";
36
+ export * from "./Result.ts";
37
+ export * from "./Schedule.ts";
38
+ export * from "./Set.ts";
39
+ export * from "./Sqlite.ts";
40
+ export type { StandardSchemaV1 } from "@standard-schema/spec";
41
+ export * from "./Store.ts";
42
+ export * from "./String.ts";
43
+ export * from "./Task.ts";
44
+ export * from "./Test.ts";
45
+ export * from "./Time.ts";
46
+ export * from "./Type.ts";
47
+ export * from "./Types.ts";
48
+ export * from "./WebSocket.ts";
49
+ export * from "./Worker.ts";
47
50
 
48
51
  // Local-first essentials.
49
- export type { EvoluError } from "./local-first/Error.js";
50
- export { AppName, createEvolu } from "./local-first/Evolu.js";
52
+ export type { EvoluError } from "./local-first/Error.ts";
53
+ export { AppName, createEvolu } from "./local-first/Evolu.ts";
51
54
  export type {
52
55
  AppNameError,
53
56
  Evolu,
54
57
  EvoluConfig,
55
58
  EvoluDeps,
56
59
  UnuseOwner,
57
- } from "./local-first/Evolu.js";
58
- export * from "./local-first/LocalAuth.js";
59
- export * from "./local-first/Owner.js";
60
- export type { SyncOwner } from "./local-first/Owner.js";
60
+ } from "./local-first/Evolu.ts";
61
+ export * from "./local-first/LocalAuth.ts";
62
+ export * from "./local-first/Owner.ts";
63
+ export type { SyncOwner } from "./local-first/Owner.ts";
61
64
  export {
62
65
  evoluJsonArrayFrom,
63
66
  evoluJsonBuildObject,
@@ -69,8 +72,8 @@ export {
69
72
  type Query,
70
73
  type QueryRows,
71
74
  type Row,
72
- } from "./local-first/Query.js";
73
- export { createQueryBuilder } from "./local-first/Schema.js";
75
+ } from "./local-first/Query.ts";
76
+ export { createQueryBuilder } from "./local-first/Schema.ts";
74
77
  export type {
75
78
  AnyStandardSchemaV1,
76
79
  EvoluSchema,
@@ -85,22 +88,22 @@ export type {
85
88
  TableSchema,
86
89
  UpdateValues,
87
90
  UpsertValues,
88
- } from "./local-first/Schema.js";
91
+ } from "./local-first/Schema.ts";
89
92
  export type {
90
93
  // NetworkError,
91
94
  // PaymentRequiredError,
92
95
  // ServerError,
93
96
  SyncState,
94
- } from "./local-first/Shared.js";
97
+ } from "./local-first/Shared.ts";
95
98
  export {
96
99
  Timestamp,
97
100
  timestampBytesToTimestamp,
98
101
  timestampToTimestampBytes,
99
- } from "./local-first/Timestamp.js";
102
+ } from "./local-first/Timestamp.ts";
100
103
  export type {
101
104
  TimestampBytes,
102
105
  TimestampCounterOverflowError,
103
106
  TimestampDriftError,
104
107
  TimestampError,
105
108
  TimestampTimeOutOfRangeError,
106
- } from "./local-first/Timestamp.js";
109
+ } from "./local-first/Timestamp.ts";