@evolu/common 7.4.1 → 8.0.0-next.1

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 (250) hide show
  1. package/README.md +4 -61
  2. package/dist/src/Array.d.ts +343 -102
  3. package/dist/src/Array.d.ts.map +1 -1
  4. package/dist/src/Array.js +181 -85
  5. package/dist/src/Assert.d.ts +57 -11
  6. package/dist/src/Assert.d.ts.map +1 -1
  7. package/dist/src/Assert.js +47 -11
  8. package/dist/src/BigInt.d.ts +6 -1
  9. package/dist/src/BigInt.d.ts.map +1 -1
  10. package/dist/src/BigInt.js +5 -0
  11. package/dist/src/Brand.d.ts +40 -12
  12. package/dist/src/Brand.d.ts.map +1 -1
  13. package/dist/src/Brand.js +5 -0
  14. package/dist/src/Buffer.d.ts +6 -1
  15. package/dist/src/Buffer.d.ts.map +1 -1
  16. package/dist/src/Buffer.js +7 -2
  17. package/dist/src/Cache.d.ts +10 -2
  18. package/dist/src/Cache.d.ts.map +1 -1
  19. package/dist/src/Cache.js +6 -0
  20. package/dist/src/Callbacks.d.ts +10 -7
  21. package/dist/src/Callbacks.d.ts.map +1 -1
  22. package/dist/src/Callbacks.js +23 -13
  23. package/dist/src/Console.d.ts +361 -69
  24. package/dist/src/Console.d.ts.map +1 -1
  25. package/dist/src/Console.js +217 -117
  26. package/dist/src/Crypto.d.ts +70 -21
  27. package/dist/src/Crypto.d.ts.map +1 -1
  28. package/dist/src/Crypto.js +72 -27
  29. package/dist/src/Eq.d.ts +22 -2
  30. package/dist/src/Eq.d.ts.map +1 -1
  31. package/dist/src/Eq.js +21 -1
  32. package/dist/src/Error.d.ts +23 -12
  33. package/dist/src/Error.d.ts.map +1 -1
  34. package/dist/src/Error.js +27 -11
  35. package/dist/src/Function.d.ts +128 -56
  36. package/dist/src/Function.d.ts.map +1 -1
  37. package/dist/src/Function.js +118 -14
  38. package/dist/src/Identicon.d.ts +5 -0
  39. package/dist/src/Identicon.d.ts.map +1 -1
  40. package/dist/src/Identicon.js +6 -1
  41. package/dist/src/Lookup.d.ts +162 -0
  42. package/dist/src/Lookup.d.ts.map +1 -0
  43. package/dist/src/Lookup.js +200 -0
  44. package/dist/src/Microtask.d.ts +21 -0
  45. package/dist/src/Microtask.d.ts.map +1 -0
  46. package/dist/src/Microtask.js +37 -0
  47. package/dist/src/Number.d.ts +18 -4
  48. package/dist/src/Number.d.ts.map +1 -1
  49. package/dist/src/Number.js +23 -1
  50. package/dist/src/Object.d.ts +110 -5
  51. package/dist/src/Object.d.ts.map +1 -1
  52. package/dist/src/Object.js +108 -5
  53. package/dist/src/Option.d.ts +58 -0
  54. package/dist/src/Option.d.ts.map +1 -0
  55. package/dist/src/Option.js +43 -0
  56. package/dist/src/Order.d.ts +5 -0
  57. package/dist/src/Order.d.ts.map +1 -1
  58. package/dist/src/Order.js +8 -3
  59. package/dist/src/Platform.d.ts +36 -2
  60. package/dist/src/Platform.d.ts.map +1 -1
  61. package/dist/src/Platform.js +10 -6
  62. package/dist/src/Polyfills.d.ts +29 -0
  63. package/dist/src/Polyfills.d.ts.map +1 -0
  64. package/dist/src/Polyfills.js +329 -0
  65. package/dist/src/Random.d.ts +18 -7
  66. package/dist/src/Random.d.ts.map +1 -1
  67. package/dist/src/Random.js +9 -7
  68. package/dist/src/Redacted.d.ts +7 -4
  69. package/dist/src/Redacted.d.ts.map +1 -1
  70. package/dist/src/Redacted.js +5 -0
  71. package/dist/src/Ref.d.ts +31 -16
  72. package/dist/src/Ref.d.ts.map +1 -1
  73. package/dist/src/Ref.js +35 -7
  74. package/dist/src/RefCount.d.ts +62 -0
  75. package/dist/src/RefCount.d.ts.map +1 -0
  76. package/dist/src/RefCount.js +83 -0
  77. package/dist/src/Relation.d.ts +84 -29
  78. package/dist/src/Relation.d.ts.map +1 -1
  79. package/dist/src/Relation.js +83 -105
  80. package/dist/src/Resource.d.ts +263 -0
  81. package/dist/src/Resource.d.ts.map +1 -0
  82. package/dist/src/Resource.js +389 -0
  83. package/dist/src/Result.d.ts +390 -374
  84. package/dist/src/Result.d.ts.map +1 -1
  85. package/dist/src/Result.js +142 -70
  86. package/dist/src/Schedule.d.ts +953 -0
  87. package/dist/src/Schedule.d.ts.map +1 -0
  88. package/dist/src/Schedule.js +1199 -0
  89. package/dist/src/Set.d.ts +181 -0
  90. package/dist/src/Set.d.ts.map +1 -0
  91. package/dist/src/Set.js +137 -0
  92. package/dist/src/Skiplist.d.ts +6 -1
  93. package/dist/src/Skiplist.d.ts.map +1 -1
  94. package/dist/src/Skiplist.js +5 -0
  95. package/dist/src/Sqlite.d.ts +160 -60
  96. package/dist/src/Sqlite.d.ts.map +1 -1
  97. package/dist/src/Sqlite.js +290 -190
  98. package/dist/src/Store.d.ts +36 -28
  99. package/dist/src/Store.d.ts.map +1 -1
  100. package/dist/src/Store.js +55 -15
  101. package/dist/src/String.d.ts +5 -0
  102. package/dist/src/String.d.ts.map +1 -1
  103. package/dist/src/String.js +5 -0
  104. package/dist/src/Task.d.ts +2274 -423
  105. package/dist/src/Task.d.ts.map +1 -1
  106. package/dist/src/Task.js +1499 -348
  107. package/dist/src/Test.d.ts +150 -0
  108. package/dist/src/Test.d.ts.map +1 -0
  109. package/dist/src/Test.js +97 -0
  110. package/dist/src/Time.d.ts +202 -48
  111. package/dist/src/Time.d.ts.map +1 -1
  112. package/dist/src/Time.js +199 -88
  113. package/dist/src/Tracer.d.ts +48 -0
  114. package/dist/src/Tracer.d.ts.map +1 -0
  115. package/dist/src/Tracer.js +6 -0
  116. package/dist/src/Type.d.ts +587 -209
  117. package/dist/src/Type.d.ts.map +1 -1
  118. package/dist/src/Type.js +370 -240
  119. package/dist/src/Types.d.ts +160 -6
  120. package/dist/src/Types.d.ts.map +1 -1
  121. package/dist/src/Types.js +22 -2
  122. package/dist/src/WebSocket.d.ts +130 -58
  123. package/dist/src/WebSocket.d.ts.map +1 -1
  124. package/dist/src/WebSocket.js +274 -113
  125. package/dist/src/Worker.d.ts +245 -60
  126. package/dist/src/Worker.d.ts.map +1 -1
  127. package/dist/src/Worker.js +220 -64
  128. package/dist/src/index.d.ts +25 -3
  129. package/dist/src/index.d.ts.map +1 -1
  130. package/dist/src/index.js +19 -3
  131. package/dist/src/local-first/Db.d.ts +24 -213
  132. package/dist/src/local-first/Db.d.ts.map +1 -1
  133. package/dist/src/local-first/Db.js +621 -293
  134. package/dist/src/local-first/Error.d.ts +12 -0
  135. package/dist/src/local-first/Error.d.ts.map +1 -0
  136. package/dist/src/local-first/Error.js +6 -0
  137. package/dist/src/local-first/Evolu.d.ts +330 -285
  138. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  139. package/dist/src/local-first/Evolu.js +472 -402
  140. package/dist/src/local-first/LocalAuth.d.ts +10 -10
  141. package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
  142. package/dist/src/local-first/LocalAuth.js +6 -1
  143. package/dist/src/local-first/Owner.d.ts +70 -27
  144. package/dist/src/local-first/Owner.d.ts.map +1 -1
  145. package/dist/src/local-first/Owner.js +27 -14
  146. package/dist/src/local-first/Protocol.d.ts +58 -50
  147. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  148. package/dist/src/local-first/Protocol.js +253 -155
  149. package/dist/src/local-first/Query.d.ts +133 -43
  150. package/dist/src/local-first/Query.d.ts.map +1 -1
  151. package/dist/src/local-first/Query.js +139 -90
  152. package/dist/src/local-first/Relay.d.ts +34 -49
  153. package/dist/src/local-first/Relay.d.ts.map +1 -1
  154. package/dist/src/local-first/Relay.js +59 -177
  155. package/dist/src/local-first/Schema.d.ts +139 -144
  156. package/dist/src/local-first/Schema.d.ts.map +1 -1
  157. package/dist/src/local-first/Schema.js +78 -163
  158. package/dist/src/local-first/Shared.d.ts +125 -0
  159. package/dist/src/local-first/Shared.d.ts.map +1 -0
  160. package/dist/src/local-first/Shared.js +569 -0
  161. package/dist/src/local-first/Storage.d.ts +54 -58
  162. package/dist/src/local-first/Storage.d.ts.map +1 -1
  163. package/dist/src/local-first/Storage.js +127 -179
  164. package/dist/src/local-first/Timestamp.d.ts +28 -35
  165. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  166. package/dist/src/local-first/Timestamp.js +24 -25
  167. package/dist/src/local-first/index.d.ts +2 -15
  168. package/dist/src/local-first/index.d.ts.map +1 -1
  169. package/dist/src/local-first/index.js +2 -15
  170. package/package.json +37 -24
  171. package/src/Array.ts +467 -106
  172. package/src/Assert.ts +87 -12
  173. package/src/BigInt.ts +7 -1
  174. package/src/Brand.ts +41 -12
  175. package/src/Buffer.ts +10 -4
  176. package/src/Cache.ts +11 -2
  177. package/src/Callbacks.ts +33 -23
  178. package/src/Console.ts +567 -178
  179. package/src/Crypto.ts +111 -62
  180. package/src/Eq.ts +30 -3
  181. package/src/Error.ts +50 -34
  182. package/src/Function.ts +140 -68
  183. package/src/Identicon.ts +7 -1
  184. package/src/Lookup.ts +429 -0
  185. package/src/Microtask.ts +58 -0
  186. package/src/Number.ts +40 -7
  187. package/src/Object.ts +155 -16
  188. package/src/Option.ts +74 -0
  189. package/src/Order.ts +11 -3
  190. package/src/Platform.ts +43 -7
  191. package/src/Polyfills.ts +520 -0
  192. package/src/Random.ts +25 -11
  193. package/src/Redacted.ts +8 -4
  194. package/src/Ref.ts +72 -21
  195. package/src/RefCount.ts +170 -0
  196. package/src/Relation.ts +188 -136
  197. package/src/Resource.ts +864 -0
  198. package/src/Result.ts +548 -381
  199. package/src/Schedule.ts +1471 -0
  200. package/src/Set.ts +247 -0
  201. package/src/Skiplist.ts +7 -1
  202. package/src/Sqlite.ts +409 -304
  203. package/src/Store.ts +94 -48
  204. package/src/String.ts +6 -0
  205. package/src/Task.ts +3696 -740
  206. package/src/Test.ts +202 -0
  207. package/src/Time.ts +357 -147
  208. package/src/Tracer.ts +54 -0
  209. package/src/Type.ts +866 -430
  210. package/src/Types.ts +202 -7
  211. package/src/WebSocket.ts +404 -167
  212. package/src/Worker.ts +527 -147
  213. package/src/index.ts +74 -3
  214. package/src/local-first/Db.ts +867 -597
  215. package/src/local-first/Error.ts +17 -0
  216. package/src/local-first/Evolu.ts +884 -824
  217. package/src/local-first/LocalAuth.ts +10 -10
  218. package/src/local-first/Owner.ts +94 -42
  219. package/src/local-first/Protocol.ts +441 -307
  220. package/src/local-first/Query.ts +243 -194
  221. package/src/local-first/Relay.ts +119 -273
  222. package/src/local-first/Schema.ts +284 -394
  223. package/src/local-first/Shared.ts +932 -0
  224. package/src/local-first/Storage.ts +211 -283
  225. package/src/local-first/Timestamp.ts +38 -45
  226. package/src/local-first/index.ts +2 -16
  227. package/dist/src/Instances.d.ts +0 -34
  228. package/dist/src/Instances.d.ts.map +0 -1
  229. package/dist/src/Instances.js +0 -44
  230. package/dist/src/Resources.d.ts +0 -118
  231. package/dist/src/Resources.d.ts.map +0 -1
  232. package/dist/src/Resources.js +0 -197
  233. package/dist/src/local-first/Platform.d.ts +0 -25
  234. package/dist/src/local-first/Platform.d.ts.map +0 -1
  235. package/dist/src/local-first/Platform.js +0 -1
  236. package/dist/src/local-first/Public.d.ts +0 -22
  237. package/dist/src/local-first/Public.d.ts.map +0 -1
  238. package/dist/src/local-first/Public.js +0 -15
  239. package/dist/src/local-first/PublicKysely.d.ts +0 -148
  240. package/dist/src/local-first/PublicKysely.d.ts.map +0 -1
  241. package/dist/src/local-first/PublicKysely.js +0 -184
  242. package/dist/src/local-first/Sync.d.ts +0 -112
  243. package/dist/src/local-first/Sync.d.ts.map +0 -1
  244. package/dist/src/local-first/Sync.js +0 -526
  245. package/src/Instances.ts +0 -92
  246. package/src/Resources.ts +0 -367
  247. package/src/local-first/Platform.ts +0 -27
  248. package/src/local-first/Public.ts +0 -42
  249. package/src/local-first/PublicKysely.ts +0 -239
  250. package/src/local-first/Sync.ts +0 -949
@@ -1,67 +1,252 @@
1
- import { TransferableError } from "./Error.js";
2
- /** Cross-platform worker abstraction. */
3
- export interface Worker<Input, Output> {
4
- /** Sends a message to the worker. */
5
- readonly postMessage: (message: Input) => void;
6
- /** Sets a callback for messages from the worker. */
7
- readonly onMessage: (callback: (message: Output) => void) => void;
1
+ /**
2
+ * Platform-agnostic Worker abstractions.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Brand } from "./Brand.js";
7
+ import type { ConsoleDep, ConsoleStoreOutputEntryDep } from "./Console.js";
8
+ /**
9
+ * Platform-agnostic Worker.
10
+ *
11
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Worker
12
+ */
13
+ export interface Worker<Input, Output = never> extends MessagePort<Input, Output> {
14
+ }
15
+ /**
16
+ * Platform-agnostic SharedWorker.
17
+ *
18
+ * A shared worker is shared across multiple clients (tabs, windows, iframes)
19
+ * and provides a port for bidirectional communication with each client.
20
+ *
21
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker
22
+ */
23
+ export interface SharedWorker<Input, Output = never> extends Disposable {
24
+ /** Port for communicating with the shared worker. */
25
+ readonly port: MessagePort<Input, Output>;
8
26
  }
9
- export interface WorkerPostMessageDep<Output> {
10
- readonly postMessage: (message: Output) => void;
27
+ /**
28
+ * Platform-agnostic MessagePort.
29
+ *
30
+ * Note: There is no reliable way to detect when a port is closed or
31
+ * disconnected. Calling `postMessage` on a disposed port does not throw — it
32
+ * silently fails. To detect dead ports, use a heartbeat pattern where the other
33
+ * end periodically sends "alive" messages and stale ports are pruned after a
34
+ * timeout.
35
+ *
36
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
37
+ */
38
+ export interface MessagePort<Input, Output = never> extends Disposable {
39
+ readonly postMessage: (message: Input, transfer?: ReadonlyArray<Transferable>) => void;
40
+ /**
41
+ * Handler for incoming messages. Messages are queued until this is assigned,
42
+ * matching native `MessagePort` behavior where setting `onmessage` implicitly
43
+ * calls `start()`. This enables safe async initialization — the sender can
44
+ * post messages immediately while the receiver sets up.
45
+ */
46
+ onMessage: ((message: Output) => void) | null;
47
+ /**
48
+ * The native underlying port for transferring via `postMessage`.
49
+ *
50
+ * ### Example
51
+ *
52
+ * ```ts
53
+ * sharedWorker.port.postMessage(
54
+ * { type: "InitConsole", port: consoleChannel.port1.native },
55
+ * [consoleChannel.port1.native],
56
+ * );
57
+ * ```
58
+ */
59
+ readonly native: NativeMessagePort<Input, Output>;
11
60
  }
12
61
  /**
13
- * Error reporting wrapper that catches synchronous errors in handlers and
14
- * converts them to transferable error messages sent to the main thread.
15
- */
16
- export type WithErrorReporting = <A extends Array<any>>(handler: (...args: A) => void) => (...args: A) => void;
17
- type HasInit<Input> = Extract<Input, {
18
- type: "init";
19
- }> extends never ? ["Input must contain a variant with { type: 'init' }"] : unknown;
20
- type HasWorkerErrorOutput<T> = Extract<T, {
21
- type: "onError";
22
- }> extends infer E ? [E] extends [never] ? [
23
- "Output must contain { type: 'onError'; error: TransferableError | ... }"
24
- ] : E extends {
25
- error: infer Err;
26
- } ? TransferableError extends Err ? unknown : ["Output.onError.error must include TransferableError"] : ["Output.onError must have an error property"] : never;
27
- /**
28
- * Creates a {@link Worker} that supports initialization with dependencies and
29
- * safe error handling.
30
- */
31
- export declare const createInitializedWorker: <Input extends {
32
- readonly type: string;
33
- } & HasInit<Input>, Output extends {
34
- readonly type: string;
35
- } & HasWorkerErrorOutput<Output>, Deps>({ init, onMessage, }: {
36
- readonly init: (initMessage: Extract<Input, {
37
- type: "init";
38
- }>, postMessage: (msg: Output) => void, withErrorReporting: WithErrorReporting) => Promise<Deps | null>;
39
- readonly onMessage: (deps: Deps) => (message: Exclude<Input, {
40
- type: "init";
41
- }>) => void;
42
- }) => Worker<Input, Output>;
43
- /** Type helper to extract message types from a union type */
44
- export type MessageHandlers<Input extends {
45
- readonly type: string;
46
- }, Deps> = {
47
- readonly [K in Input["type"]]: (deps: Deps) => (message: Extract<Input, {
48
- type: K;
49
- }>) => void;
62
+ * Objects whose ownership can be transferred between threads via `postMessage`.
63
+ *
64
+ * Intentionally scoped to types Evolu uses. The web platform defines additional
65
+ * transferable types (`ImageBitmap`, `OffscreenCanvas`, `ReadableStream`, etc.)
66
+ * that can be added here if needed.
67
+ */
68
+ export type Transferable = NativeMessagePort<any, any> | ArrayBuffer;
69
+ /**
70
+ * Opaque type for platform-specific native MessagePort.
71
+ *
72
+ * Exists because `postMessage` transfer requires the native object itself, not
73
+ * a wrapper. Ensures type-safe wiring between {@link MessagePort.native} and
74
+ * {@link CreateMessagePort} without exposing platform details.
75
+ */
76
+ export type NativeMessagePort<Input = unknown, Output = never> = Brand<"NativeMessagePort"> & {
77
+ readonly [nativeMessagePortInput]?: Input;
78
+ readonly [nativeMessagePortOutput]?: Output;
50
79
  };
80
+ declare const nativeMessagePortInput: unique symbol;
81
+ declare const nativeMessagePortOutput: unique symbol;
82
+ /** Factory function to create a {@link MessagePort} from a native port. */
83
+ export type CreateMessagePort = <Input, Output = never>(nativePort: NativeMessagePort<Input, Output>) => MessagePort<Input, Output>;
84
+ export interface CreateMessagePortDep {
85
+ readonly createMessagePort: CreateMessagePort;
86
+ }
87
+ /** Common dependencies for worker entry points. */
88
+ export type WorkerDeps = ConsoleDep & ConsoleStoreOutputEntryDep & CreateMessagePortDep;
89
+ /**
90
+ * Platform-agnostic MessageChannel.
91
+ *
92
+ * Creates two entangled ports: keep one and transfer the other (e.g., to a
93
+ * SharedWorker via `postMessage` with `transfer`). Messages sent to one port
94
+ * are received by the other.
95
+ *
96
+ * Messages are queued until `onMessage` is assigned, enabling safe async
97
+ * initialization. The sender can post messages immediately while the receiver
98
+ * performs async setup — no manual buffering required.
99
+ *
100
+ * For one-way communication, omit `Output` (defaults to `never`).
101
+ *
102
+ * ### Example
103
+ *
104
+ * Transfer a channel port to a SharedWorker for async initialization:
105
+ *
106
+ * ```ts
107
+ * // Main thread: create channel, transfer port1, use port2 immediately.
108
+ * const channel = createMessageChannel<EvoluRequest, EvoluResponse>();
109
+ *
110
+ * sharedWorker.port.postMessage(
111
+ * { type: "CreateEvolu", port: channel.port1.native },
112
+ * [channel.port1.native],
113
+ * );
114
+ *
115
+ * // Safe to send immediately — messages queue until worker is ready.
116
+ * channel.port2.postMessage({ type: "Query", query });
117
+ * channel.port2.onMessage = (response) => {
118
+ * handleResponse(response);
119
+ * };
120
+ * ```
121
+ *
122
+ * ```ts
123
+ * // Worker: receive the port, do async init, then start listening.
124
+ * const evoluPort = createMessagePort<EvoluResponse, EvoluRequest>(
125
+ * message.port,
126
+ * );
127
+ * await openDatabase(name);
128
+ * evoluPort.onMessage = (request) => {
129
+ * handleRequest(request);
130
+ * };
131
+ * // Queued messages are now delivered in order.
132
+ * ```
133
+ *
134
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel
135
+ */
136
+ export interface MessageChannel<Input, Output = never> extends Disposable {
137
+ /** The first port of the channel. */
138
+ readonly port1: MessagePort<Input, Output>;
139
+ /** The second port of the channel. */
140
+ readonly port2: MessagePort<Output, Input>;
141
+ }
142
+ /** Factory function to create a {@link MessageChannel}. */
143
+ export type CreateMessageChannel = <Input, Output = never>() => MessageChannel<Input, Output>;
144
+ export interface CreateMessageChannelDep {
145
+ readonly createMessageChannel: CreateMessageChannel;
146
+ }
147
+ /**
148
+ * Typed `self` for code running inside a dedicated worker.
149
+ *
150
+ * This is the worker-side counterpart to {@link Worker} — a typed
151
+ * {@link MessagePort} that wraps `self` inside the worker.
152
+ */
153
+ export interface WorkerSelf<Input, Output = never> extends MessagePort<Output, Input> {
154
+ }
155
+ /**
156
+ * Typed `self` for code running inside a shared worker.
157
+ *
158
+ * This is the worker-side counterpart to {@link SharedWorker}. It wraps `self`
159
+ * inside the shared worker, providing typed `onConnect` callbacks.
160
+ */
161
+ export interface SharedWorkerSelf<Input, Output = never> extends Disposable {
162
+ onConnect: ((port: MessagePort<Output, Input>) => void) | null;
163
+ }
51
164
  /**
52
- * Creates a {@link Worker} with type-safe message handlers for each message
53
- * type. This provides better type safety and organization compared to a single
54
- * onMessage handler.
55
- */
56
- export declare const createInitializedWorkerWithHandlers: <Input extends {
57
- readonly type: string;
58
- } & HasInit<Input>, Output extends {
59
- readonly type: string;
60
- } & HasWorkerErrorOutput<Output>, Deps>({ init, handlers, }: {
61
- readonly init: (initMessage: Extract<Input, {
62
- type: "init";
63
- }>, postMessage: (msg: Output) => void, withErrorReporting: WithErrorReporting) => Promise<Deps | null>;
64
- readonly handlers: Omit<MessageHandlers<Input, Deps>, "init">;
65
- }) => Worker<Input, Output>;
165
+ * Creates an in-memory {@link Worker}.
166
+ *
167
+ * This is a memory-only fallback for platforms without native worker support.
168
+ * Message delivery is asynchronous in-process.
169
+ */
170
+ export declare const createWorker: <Input, Output = never>(initWorker: (self: WorkerSelf<Input, Output>) => void) => Worker<Input, Output>;
171
+ /**
172
+ * Creates an in-memory {@link SharedWorker}.
173
+ *
174
+ * This is a memory-only fallback for platforms without native SharedWorker
175
+ * support. Connection is synchronous while message delivery is asynchronous
176
+ * in-process.
177
+ *
178
+ * Intended usage is one shared worker instance per process/app runtime.
179
+ */
180
+ export declare const createSharedWorker: <Input, Output = never>(initWorker: (self: SharedWorkerSelf<Input, Output>) => void) => SharedWorker<Input, Output>;
181
+ /**
182
+ * Creates an in-memory {@link MessageChannel}.
183
+ *
184
+ * This is a memory-only fallback for platforms without native MessageChannel
185
+ * support. Message delivery is asynchronous in-process.
186
+ */
187
+ export declare const createMessageChannel: CreateMessageChannel;
188
+ /**
189
+ * Creates an in-memory {@link MessagePort} from a native token.
190
+ *
191
+ * This is a memory-only fallback for platforms without native MessagePort
192
+ * support. Message delivery through returned ports is asynchronous in-process.
193
+ */
194
+ export declare const createMessagePort: CreateMessagePort;
195
+ /**
196
+ * Test {@link Worker} with access to its paired worker-side `self`.
197
+ *
198
+ * Use `self` to simulate messages and behavior from inside the worker.
199
+ */
200
+ export interface TestWorker<Input, Output = never> extends Worker<Input, Output> {
201
+ /** Typed `self` counterpart for worker-side testing assertions. */
202
+ readonly self: WorkerSelf<Input, Output>;
203
+ }
204
+ /**
205
+ * Test {@link SharedWorker} with direct access to `self` and `connect`.
206
+ *
207
+ * Call `connect()` to simulate a client connection and trigger
208
+ * `self.onConnect`.
209
+ */
210
+ export interface TestSharedWorker<Input, Output = never> extends SharedWorker<Input, Output> {
211
+ readonly self: SharedWorkerSelf<Input, Output>;
212
+ readonly connect: () => void;
213
+ }
214
+ /** {@link MessageChannel} with disposal tracking for testing. */
215
+ export interface TestMessageChannel<Input, Output = never> extends MessageChannel<Input, Output> {
216
+ readonly isDisposed: () => boolean;
217
+ }
218
+ /**
219
+ * Creates a connected {@link TestWorker} for testing.
220
+ *
221
+ * The returned worker includes its typed {@link TestWorker.self} counterpart, so
222
+ * tests can exercise dedicated worker communication without a real thread.
223
+ */
224
+ export declare const testCreateWorker: <Input, Output = never>() => TestWorker<Input, Output>;
225
+ /**
226
+ * Creates a connected {@link TestSharedWorker} for testing.
227
+ *
228
+ * The returned worker includes `self` and `connect` so tests can exercise the
229
+ * full worker ↔ client pipeline without a real worker thread.
230
+ */
231
+ export declare const testCreateSharedWorker: <Input, Output = never>() => TestSharedWorker<Input, Output>;
232
+ /**
233
+ * Creates an in-memory {@link MessageChannel} for testing.
234
+ *
235
+ * Messages are queued until `onMessage` is assigned, matching the browser
236
+ * MessagePort behavior where the port message queue starts disabled.
237
+ *
238
+ * Both ports are registered in the native port registry so
239
+ * {@link testCreateMessagePort} can look them up by their native token.
240
+ */
241
+ export declare const testCreateMessageChannel: <Input, Output = never>() => TestMessageChannel<Input, Output>;
242
+ /** Creates an in-memory {@link CreateMessagePort} for testing. */
243
+ export declare const testCreateMessagePort: CreateMessagePort;
244
+ /**
245
+ * Waits long enough for multi-hop in-memory worker message delivery in tests.
246
+ *
247
+ * Some flows require several queued macrotasks across worker/message-port
248
+ * boundaries; this helper advances that pipeline deterministically.
249
+ */
250
+ export declare const testWaitForWorkerMessage: () => Promise<void>;
66
251
  export {};
67
252
  //# sourceMappingURL=Worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"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"}
@@ -1,79 +1,235 @@
1
+ /**
2
+ * Platform-agnostic Worker abstractions.
3
+ *
4
+ * @module
5
+ */
1
6
  import { assert } from "./Assert.js";
2
- import { createTransferableError } from "./Error.js";
7
+ import { testWaitForMacrotask } from "./Test.js";
8
+ /**
9
+ * Creates an in-memory {@link Worker}.
10
+ *
11
+ * This is a memory-only fallback for platforms without native worker support.
12
+ * Message delivery is asynchronous in-process.
13
+ */
14
+ export const createWorker = (initWorker) => {
15
+ const { worker, self } = createMemoryWorkerPair();
16
+ initWorker(self);
17
+ return worker;
18
+ };
19
+ /**
20
+ * Creates an in-memory {@link SharedWorker}.
21
+ *
22
+ * This is a memory-only fallback for platforms without native SharedWorker
23
+ * support. Connection is synchronous while message delivery is asynchronous
24
+ * in-process.
25
+ *
26
+ * Intended usage is one shared worker instance per process/app runtime.
27
+ */
28
+ export const createSharedWorker = (initWorker) => {
29
+ const { worker, self, connect } = createMemorySharedWorkerPair();
30
+ initWorker(self);
31
+ connect();
32
+ return worker;
33
+ };
34
+ /**
35
+ * Creates an in-memory {@link MessageChannel}.
36
+ *
37
+ * This is a memory-only fallback for platforms without native MessageChannel
38
+ * support. Message delivery is asynchronous in-process.
39
+ */
40
+ export const createMessageChannel = () => {
41
+ const state1 = {
42
+ handler: null,
43
+ queue: [],
44
+ flushScheduled: false,
45
+ };
46
+ const state2 = {
47
+ handler: null,
48
+ queue: [],
49
+ flushScheduled: false,
50
+ };
51
+ const native1 = createNativeMessagePortToken();
52
+ const native2 = createNativeMessagePortToken();
53
+ const port1 = createTestPort(state1, state2, native1);
54
+ const port2 = createTestPort(state2, state1, native2);
55
+ nativePortRegistry.set(native1, port1);
56
+ nativePortRegistry.set(native2, port2);
57
+ return {
58
+ port1,
59
+ port2,
60
+ [Symbol.dispose]: () => {
61
+ port1[Symbol.dispose]();
62
+ port2[Symbol.dispose]();
63
+ },
64
+ };
65
+ };
66
+ /**
67
+ * Creates an in-memory {@link MessagePort} from a native token.
68
+ *
69
+ * This is a memory-only fallback for platforms without native MessagePort
70
+ * support. Message delivery through returned ports is asynchronous in-process.
71
+ */
72
+ export const createMessagePort = (nativePort) => {
73
+ const pair = nativePortRegistry.get(nativePort);
74
+ assert(pair, "Unknown native port — did you transfer it?");
75
+ return pair;
76
+ };
77
+ /**
78
+ * Creates a connected {@link TestWorker} for testing.
79
+ *
80
+ * The returned worker includes its typed {@link TestWorker.self} counterpart, so
81
+ * tests can exercise dedicated worker communication without a real thread.
82
+ */
83
+ export const testCreateWorker = () => {
84
+ let self;
85
+ const worker = createWorker((nextSelf) => {
86
+ self = nextSelf;
87
+ });
88
+ return Object.assign(worker, { self });
89
+ };
90
+ /**
91
+ * Creates a connected {@link TestSharedWorker} for testing.
92
+ *
93
+ * The returned worker includes `self` and `connect` so tests can exercise the
94
+ * full worker ↔ client pipeline without a real worker thread.
95
+ */
96
+ export const testCreateSharedWorker = () => {
97
+ const { worker, self, connect } = createMemorySharedWorkerPair();
98
+ return Object.assign(worker, {
99
+ self,
100
+ connect,
101
+ });
102
+ };
3
103
  /**
4
- * Creates a {@link Worker} that supports initialization with dependencies and
5
- * safe error handling.
104
+ * Creates an in-memory {@link MessageChannel} for testing.
105
+ *
106
+ * Messages are queued until `onMessage` is assigned, matching the browser
107
+ * MessagePort behavior where the port message queue starts disabled.
108
+ *
109
+ * Both ports are registered in the native port registry so
110
+ * {@link testCreateMessagePort} can look them up by their native token.
6
111
  */
7
- export const createInitializedWorker = ({ init, onMessage, }) => {
8
- let onMessageCallback = null;
9
- let deps = null;
10
- const pendingMessages = [];
11
- let initializing = false;
12
- const postMessage = (msg) => {
13
- assert(onMessageCallback != null, "The onMessage wasn't set");
14
- onMessageCallback(msg);
112
+ export const testCreateMessageChannel = () => {
113
+ const channel = createMessageChannel();
114
+ let disposed = false;
115
+ return {
116
+ port1: channel.port1,
117
+ port2: channel.port2,
118
+ isDisposed: () => disposed,
119
+ [Symbol.dispose]: () => {
120
+ disposed = true;
121
+ channel[Symbol.dispose]();
122
+ },
15
123
  };
16
- const postMessageTransferableError = (error) => {
17
- postMessage({
18
- type: "onError",
19
- error: createTransferableError(error),
20
- });
124
+ };
125
+ /** Creates an in-memory {@link CreateMessagePort} for testing. */
126
+ export const testCreateMessagePort = (nativePort) => createMessagePort(nativePort);
127
+ /**
128
+ * Waits long enough for multi-hop in-memory worker message delivery in tests.
129
+ *
130
+ * Some flows require several queued macrotasks across worker/message-port
131
+ * boundaries; this helper advances that pipeline deterministically.
132
+ */
133
+ export const testWaitForWorkerMessage = async () => {
134
+ await testWaitForMacrotask();
135
+ await testWaitForMacrotask();
136
+ };
137
+ const createMemoryWorkerPair = () => {
138
+ const channel = createMessageChannel();
139
+ const self = {
140
+ postMessage: channel.port2.postMessage,
141
+ get onMessage() {
142
+ return channel.port2.onMessage;
143
+ },
144
+ set onMessage(value) {
145
+ channel.port2.onMessage = value;
146
+ },
147
+ native: channel.port2.native,
148
+ [Symbol.dispose]: () => {
149
+ channel.port2[Symbol.dispose]();
150
+ },
151
+ };
152
+ const worker = {
153
+ postMessage: channel.port1.postMessage,
154
+ get onMessage() {
155
+ return channel.port1.onMessage;
156
+ },
157
+ set onMessage(value) {
158
+ channel.port1.onMessage = value;
159
+ },
160
+ native: channel.port1.native,
161
+ [Symbol.dispose]: () => {
162
+ channel[Symbol.dispose]();
163
+ },
21
164
  };
22
- /**
23
- * Wraps function to catch errors and send them to the main thread instead of
24
- * crashing the worker.
25
- */
26
- const withErrorReporting = (handler) => (...args) => {
27
- try {
28
- handler(...args);
29
- }
30
- catch (error) {
31
- postMessageTransferableError(error);
32
- }
165
+ return { worker, self };
166
+ };
167
+ const createMemorySharedWorkerPair = () => {
168
+ const channel = createMessageChannel();
169
+ const self = {
170
+ onConnect: null,
171
+ [Symbol.dispose]: () => {
172
+ self.onConnect = null;
173
+ },
33
174
  };
34
175
  const worker = {
35
- postMessage: (message) => {
36
- if (message.type !== "init") {
37
- if (!deps) {
38
- pendingMessages.push(message);
39
- }
40
- else {
41
- withErrorReporting(onMessage(deps))(message);
42
- }
176
+ port: channel.port1,
177
+ [Symbol.dispose]: () => {
178
+ channel[Symbol.dispose]();
179
+ },
180
+ };
181
+ const connect = () => {
182
+ assert(self.onConnect, "onConnect must be set before receiving connections");
183
+ self.onConnect(channel.port2);
184
+ };
185
+ return { worker, self, connect };
186
+ };
187
+ const createPort = (receive, peerReceive, native) => {
188
+ const scheduleFlush = (state) => {
189
+ if (state.flushScheduled)
190
+ return;
191
+ state.flushScheduled = true;
192
+ // Native worker messages are task-queued; use macrotask timing.
193
+ setTimeout(() => {
194
+ state.flushScheduled = false;
195
+ const handler = state.handler;
196
+ if (!handler)
43
197
  return;
198
+ for (const message of state.queue.splice(0)) {
199
+ handler(message);
44
200
  }
45
- if (initializing)
46
- return;
47
- initializing = true;
48
- init(message, postMessage, withErrorReporting)
49
- .then((_deps) => {
50
- if (_deps == null)
51
- return;
52
- deps = _deps;
53
- for (const message of pendingMessages) {
54
- withErrorReporting(onMessage(deps))(message);
55
- }
56
- pendingMessages.length = 0;
57
- })
58
- .catch(postMessageTransferableError);
201
+ }, 0);
202
+ };
203
+ return {
204
+ postMessage: (message) => {
205
+ peerReceive.queue.push(message);
206
+ scheduleFlush(peerReceive);
59
207
  },
60
- onMessage: (callback) => {
61
- onMessageCallback = callback;
208
+ get onMessage() {
209
+ return receive.handler;
210
+ },
211
+ set onMessage(fn) {
212
+ receive.handler = fn;
213
+ if (fn)
214
+ scheduleFlush(receive);
215
+ },
216
+ native,
217
+ [Symbol.dispose]: () => {
218
+ receive.handler = null;
219
+ receive.flushScheduled = false;
62
220
  },
63
221
  };
64
- return worker;
65
222
  };
223
+ const createTestPort = (receive, peerReceive, native) => createPort(receive, peerReceive, native);
224
+ const createNativeMessagePortToken = () => ({});
66
225
  /**
67
- * Creates a {@link Worker} with type-safe message handlers for each message
68
- * type. This provides better type safety and organization compared to a single
69
- * onMessage handler.
226
+ * Registry mapping native port tokens to their in-memory port counterparts.
227
+ *
228
+ * When {@link testCreateMessageChannel} creates a pair, both ports are
229
+ * registered here. When {@link testCreateMessagePort} wraps a native token
230
+ * (received via `postMessage` transfer), it looks up the actual port.
231
+ *
232
+ * Uses `WeakMap` so entries are garbage collected when the native token is no
233
+ * longer referenced.
70
234
  */
71
- export const createInitializedWorkerWithHandlers = ({ init, handlers, }) => createInitializedWorker({
72
- init,
73
- onMessage: (deps) => (message) => {
74
- const messageType = message.type;
75
- const handler = handlers[messageType];
76
- // TypeScript knows handler exists because handlers covers all non-init message types
77
- handler(deps)(message);
78
- },
79
- });
235
+ const nativePortRegistry = new WeakMap();