swarpc 0.9.0 → 0.11.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.
package/dist/types.d.ts CHANGED
@@ -48,7 +48,7 @@ export type CancelablePromise<T = unknown> = {
48
48
  * Abort the request.
49
49
  * @param reason The reason for cancelling the request.
50
50
  */
51
- cancel: (reason: string) => Promise<void>;
51
+ cancel: (reason: string) => void;
52
52
  };
53
53
  /**
54
54
  * An implementation of a procedure
@@ -105,6 +105,12 @@ export type Hooks<Procedures extends ProceduresMap> = {
105
105
  */
106
106
  progress?: <Procedure extends keyof ProceduresMap>(procedure: Procedure, data: Procedures[Procedure]["progress"]["inferOut"]) => void;
107
107
  };
108
+ export declare const PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
109
+ by: "sw&rpc";
110
+ functionName: "#initialize";
111
+ localStorageData: Record<string, unknown>;
112
+ }, {}>;
113
+ export type PayloadInitialize = typeof PayloadInitializeSchema.infer;
108
114
  /**
109
115
  * @source
110
116
  */
@@ -150,7 +156,7 @@ export type PayloadCore<PM extends ProceduresMap, Name extends keyof PM = keyof
150
156
  /**
151
157
  * @source
152
158
  */
153
- export declare const PayloadSchema: import("arktype").Generic<[["Name", string], ["I", unknown], ["P", unknown], ["S", unknown]], readonly ["PayloadHeaderSchema<Name>", "&", "PayloadCoreSchema<I, P, S>"], {
159
+ export declare const PayloadSchema: import("arktype").Generic<[["Name", string], ["I", unknown], ["P", unknown], ["S", unknown]], readonly [readonly ["PayloadHeaderSchema<Name>", "&", "PayloadCoreSchema<I, P, S>"], "|", "PayloadInitializeSchema"], {
154
160
  PayloadCoreSchema: import("arktype/internal/scope.ts").bindGenericToScope<import("@ark/schema").GenericAst<[["I", unknown], ["P", unknown], ["S", unknown]], {
155
161
  readonly "input?": "I";
156
162
  readonly "progress?": "P";
@@ -178,6 +184,17 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
178
184
  readonly functionName: "Name";
179
185
  readonly requestId: "string >= 1";
180
186
  }, {}, {}>;
187
+ PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
188
+ by: "sw&rpc";
189
+ functionName: "#initialize";
190
+ localStorageData: Record<string, unknown>;
191
+ }, {}> & {
192
+ readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
193
+ by: "sw&rpc";
194
+ functionName: "#initialize";
195
+ localStorageData: Record<string, unknown>;
196
+ }, {}>, "unparsed"];
197
+ };
181
198
  } & {}>;
182
199
  PayloadHeaderSchema: import("arktype/internal/scope.ts").bindGenericToScope<import("@ark/schema").GenericAst<[["Name", string]], {
183
200
  readonly by: "\"sw&rpc\"";
@@ -200,7 +217,23 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
200
217
  readonly functionName: "Name";
201
218
  readonly requestId: "string >= 1";
202
219
  }, {}, {}>;
220
+ PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
221
+ by: "sw&rpc";
222
+ functionName: "#initialize";
223
+ localStorageData: Record<string, unknown>;
224
+ }, {}> & {
225
+ readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
226
+ by: "sw&rpc";
227
+ functionName: "#initialize";
228
+ localStorageData: Record<string, unknown>;
229
+ }, {}>, "unparsed"];
230
+ };
203
231
  } & {}>;
232
+ PayloadInitializeSchema: {
233
+ by: "sw&rpc";
234
+ functionName: "#initialize";
235
+ localStorageData: Record<string, unknown>;
236
+ };
204
237
  }, {
205
238
  PayloadCoreSchema: import("arktype/internal/scope.ts").bindGenericToScope<import("@ark/schema").GenericAst<[["I", unknown], ["P", unknown], ["S", unknown]], {
206
239
  readonly "input?": "I";
@@ -229,6 +262,17 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
229
262
  readonly functionName: "Name";
230
263
  readonly requestId: "string >= 1";
231
264
  }, {}, {}>;
265
+ PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
266
+ by: "sw&rpc";
267
+ functionName: "#initialize";
268
+ localStorageData: Record<string, unknown>;
269
+ }, {}> & {
270
+ readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
271
+ by: "sw&rpc";
272
+ functionName: "#initialize";
273
+ localStorageData: Record<string, unknown>;
274
+ }, {}>, "unparsed"];
275
+ };
232
276
  } & {}>;
233
277
  PayloadHeaderSchema: import("arktype/internal/scope.ts").bindGenericToScope<import("@ark/schema").GenericAst<[["Name", string]], {
234
278
  readonly by: "\"sw&rpc\"";
@@ -251,12 +295,28 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
251
295
  readonly functionName: "Name";
252
296
  readonly requestId: "string >= 1";
253
297
  }, {}, {}>;
298
+ PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
299
+ by: "sw&rpc";
300
+ functionName: "#initialize";
301
+ localStorageData: Record<string, unknown>;
302
+ }, {}> & {
303
+ readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
304
+ by: "sw&rpc";
305
+ functionName: "#initialize";
306
+ localStorageData: Record<string, unknown>;
307
+ }, {}>, "unparsed"];
308
+ };
254
309
  } & {}>;
310
+ PayloadInitializeSchema: {
311
+ by: "sw&rpc";
312
+ functionName: "#initialize";
313
+ localStorageData: Record<string, unknown>;
314
+ };
255
315
  }>;
256
316
  /**
257
317
  * The effective payload as sent by the server to the client
258
318
  */
259
- export type Payload<PM extends ProceduresMap, Name extends keyof PM = keyof PM> = PayloadHeader<PM, Name> & PayloadCore<PM, Name>;
319
+ export type Payload<PM extends ProceduresMap, Name extends keyof PM = keyof PM> = (PayloadHeader<PM, Name> & PayloadCore<PM, Name>) | PayloadInitialize;
260
320
  /**
261
321
  * A procedure's corresponding method on the client instance -- used to call the procedure. If you want to be able to cancel the request, you can use the `cancelable` method instead of running the procedure directly.
262
322
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -3,6 +3,11 @@
3
3
  * @mergeModuleWith <project>
4
4
  */
5
5
  import { type } from "arktype";
6
+ export const PayloadInitializeSchema = type({
7
+ by: '"sw&rpc"',
8
+ functionName: '"#initialize"',
9
+ localStorageData: "Record<string, unknown>",
10
+ });
6
11
  /**
7
12
  * @source
8
13
  */
@@ -25,11 +30,11 @@ export const PayloadCoreSchema = type("<I, P, S>", {
25
30
  * @source
26
31
  */
27
32
  export const PayloadSchema = type
28
- .scope({ PayloadCoreSchema, PayloadHeaderSchema })
33
+ .scope({ PayloadCoreSchema, PayloadHeaderSchema, PayloadInitializeSchema })
29
34
  .type("<Name extends string, I, P, S>", [
30
- "PayloadHeaderSchema<Name>",
31
- "&",
32
- "PayloadCoreSchema<I, P, S>",
35
+ ["PayloadHeaderSchema<Name>", "&", "PayloadCoreSchema<I, P, S>"],
36
+ "|",
37
+ "PayloadInitializeSchema",
33
38
  ]);
34
39
  /**
35
40
  * Symbol used as the key for the procedures map on the server instance
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarpc",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Full type-safe RPC library for service worker -- move things off of the UI thread with ease!",
5
5
  "keywords": [
6
6
  "service-workers",
@@ -48,15 +48,15 @@
48
48
  "nodemon": "^3.1.10",
49
49
  "prettier": "^3.6.2",
50
50
  "sirv-cli": "^3.0.1",
51
- "typedoc": "^0.28.9",
51
+ "typedoc": "^0.28.11",
52
52
  "typedoc-material-theme": "^1.4.0",
53
- "typedoc-plugin-dt-links": "^2.0.12",
53
+ "typedoc-plugin-dt-links": "^2.0.16",
54
54
  "typedoc-plugin-extras": "^4.0.1",
55
55
  "typedoc-plugin-inline-sources": "^1.3.0",
56
- "typedoc-plugin-mdn-links": "^5.0.6",
56
+ "typedoc-plugin-mdn-links": "^5.0.9",
57
57
  "typedoc-plugin-redirect": "^1.2.0",
58
58
  "typescript": "^5.9.2",
59
- "vite": "^7.0.6",
59
+ "vite": "^7.1.3",
60
60
  "vitest": "^3.2.4"
61
61
  },
62
62
  "volta": {
package/src/client.ts CHANGED
@@ -25,6 +25,20 @@ export type SwarpcClient<Procedures extends ProceduresMap> = {
25
25
  [F in keyof Procedures]: ClientMethod<Procedures[F]>
26
26
  }
27
27
 
28
+ /**
29
+ * Context for passing around data useful for requests
30
+ */
31
+ type Context<Procedures extends ProceduresMap> = {
32
+ /** A logger, bound to the client */
33
+ logger: Logger
34
+ /** The worker instance to use */
35
+ worker: Worker | SharedWorker | undefined
36
+ /** Hooks defined by the client */
37
+ hooks: Hooks<Procedures>
38
+ /** Local storage data defined by the client for the faux local storage */
39
+ localStorage: Record<string, any>
40
+ }
41
+
28
42
  /**
29
43
  * Pending requests are stored in a map, where the key is the request ID.
30
44
  * Each request has a set of handlers: resolve, reject, and onProgress.
@@ -45,9 +59,14 @@ let _clientListenerStarted = false
45
59
  *
46
60
  * @param procedures procedures the client will be able to call, see {@link ProceduresMap}
47
61
  * @param options various options
48
- * @param options.worker if provided, the client will use this worker to post messages.
49
- * @param options.hooks hooks to run on messages received from the server
50
- * @param options.restartListener if true, will force the listener to restart even if it has already been started
62
+ * @param options.worker The instantiated worker object. If not provided, the client will use the service worker.
63
+ * Example: `new Worker("./worker.js")`
64
+ * See {@link Worker} (used by both dedicated workers and service workers), {@link SharedWorker}, and
65
+ * the different [worker types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API#worker_types) that exist
66
+ * @param options.hooks Hooks to run on messages received from the server. See {@link Hooks}
67
+ * @param options.loglevel Maximum log level to use, defaults to "debug" (shows everything). "info" will not show debug messages, "warn" will only show warnings and errors, "error" will only show errors.
68
+ * @param options.restartListener If true, will force the listener to restart even if it has already been started. You should probably leave this to false, unless you are testing and want to reset the client state.
69
+ * @param options.localStorage Define a in-memory localStorage with the given key-value pairs. Allows code called on the server to access localStorage (even though SharedWorkers don't have access to the browser's real localStorage)
51
70
  * @returns a sw&rpc client instance. Each property of the procedures map will be a method, that accepts an input and an optional onProgress callback, see {@link ClientMethod}
52
71
  *
53
72
  * An example of defining and using a client:
@@ -60,11 +79,13 @@ export function Client<Procedures extends ProceduresMap>(
60
79
  loglevel = "debug",
61
80
  restartListener = false,
62
81
  hooks = {},
82
+ localStorage = {},
63
83
  }: {
64
- worker?: Worker
84
+ worker?: Worker | SharedWorker
65
85
  hooks?: Hooks<Procedures>
66
86
  loglevel?: LogLevel
67
87
  restartListener?: boolean
88
+ localStorage?: Record<string, any>
68
89
  } = {}
69
90
  ): SwarpcClient<Procedures> {
70
91
  const l = createLogger("client", loglevel)
@@ -90,10 +111,15 @@ export function Client<Procedures extends ProceduresMap>(
90
111
  msg: PayloadCore<Procedures, typeof functionName>,
91
112
  options?: StructuredSerializeOptions
92
113
  ) => {
93
- return postMessage(
94
- l,
114
+ const ctx: Context<Procedures> = {
115
+ logger: l,
95
116
  worker,
96
117
  hooks,
118
+ localStorage,
119
+ }
120
+
121
+ return postMessage(
122
+ ctx,
97
123
  {
98
124
  ...msg,
99
125
  by: "sw&rpc",
@@ -133,7 +159,7 @@ export function Client<Procedures extends ProceduresMap>(
133
159
 
134
160
  // Post the message to the server
135
161
  l.debug(requestId, `Requesting ${functionName} with`, input)
136
- send(requestId, { input }, { transfer })
162
+ return send(requestId, { input }, { transfer })
137
163
  .then(() => {})
138
164
  .catch(reject)
139
165
  })
@@ -145,7 +171,7 @@ export function Client<Procedures extends ProceduresMap>(
145
171
  const requestId = makeRequestId()
146
172
  return {
147
173
  request: _runProcedure(input, onProgress, requestId),
148
- async cancel(reason: string) {
174
+ cancel(reason: string) {
149
175
  if (!pendingRequests.has(requestId)) {
150
176
  l.warn(
151
177
  requestId,
@@ -155,7 +181,12 @@ export function Client<Procedures extends ProceduresMap>(
155
181
  }
156
182
 
157
183
  l.debug(requestId, `Cancelling ${functionName} with`, reason)
158
- await send(requestId, { abort: { reason } })
184
+ postMessageSync(l, worker, {
185
+ by: "sw&rpc",
186
+ requestId,
187
+ functionName,
188
+ abort: { reason },
189
+ })
159
190
  pendingRequests.delete(requestId)
160
191
  },
161
192
  }
@@ -170,20 +201,56 @@ export function Client<Procedures extends ProceduresMap>(
170
201
  * @returns the worker to use
171
202
  */
172
203
  async function postMessage<Procedures extends ProceduresMap>(
173
- l: Logger,
174
- worker: Worker | undefined,
175
- hooks: Hooks<Procedures>,
204
+ ctx: Context<Procedures>,
176
205
  message: Payload<Procedures>,
177
206
  options?: StructuredSerializeOptions
178
207
  ) {
179
- await startClientListener(l, worker, hooks)
208
+ await startClientListener(ctx)
209
+
210
+ const { logger: l, worker } = ctx
180
211
 
181
212
  if (!worker && !navigator.serviceWorker.controller)
182
213
  l.warn("", "Service Worker is not controlling the page")
183
214
 
184
215
  // If no worker is provided, we use the service worker
185
216
  const w =
186
- worker ?? (await navigator.serviceWorker.ready.then((r) => r.active))
217
+ worker instanceof SharedWorker
218
+ ? worker.port
219
+ : worker === undefined
220
+ ? await navigator.serviceWorker.ready.then((r) => r.active)
221
+ : worker
222
+
223
+ if (!w) {
224
+ throw new Error("[SWARPC Client] No active service worker found")
225
+ }
226
+
227
+ w.postMessage(message, options)
228
+ }
229
+
230
+ /**
231
+ * A quicker version of postMessage that does not try to start the client listener, await the service worker, etc.
232
+ * esp. useful for abort logic that needs to not be... put behind everything else on the event loop.
233
+ * @param l
234
+ * @param worker
235
+ * @param message
236
+ * @param options
237
+ */
238
+ export function postMessageSync<Procedures extends ProceduresMap>(
239
+ l: Logger,
240
+ worker: Worker | SharedWorker | undefined,
241
+ message: Payload<Procedures>,
242
+ options?: StructuredSerializeOptions
243
+ ): void {
244
+ if (!worker && !navigator.serviceWorker.controller)
245
+ l.warn("", "Service Worker is not controlling the page")
246
+
247
+ // If no worker is provided, we use the service worker
248
+ const w =
249
+ worker instanceof SharedWorker
250
+ ? worker.port
251
+ : worker === undefined
252
+ ? navigator.serviceWorker.controller
253
+ : worker
187
254
 
188
255
  if (!w) {
189
256
  throw new Error("[SWARPC Client] No active service worker found")
@@ -194,17 +261,16 @@ async function postMessage<Procedures extends ProceduresMap>(
194
261
 
195
262
  /**
196
263
  * Starts the client listener, which listens for messages from the sw&rpc server.
197
- * @param worker if provided, the client will use this worker to listen for messages, instead of using the service worker
198
- * @param force if true, will force the listener to restart even if it has already been started
264
+ * @param ctx.worker if provided, the client will use this worker to listen for messages, instead of using the service worker
199
265
  * @returns
200
266
  */
201
267
  export async function startClientListener<Procedures extends ProceduresMap>(
202
- l: Logger,
203
- worker?: Worker,
204
- hooks: Hooks<Procedures> = {}
268
+ ctx: Context<Procedures>
205
269
  ) {
206
270
  if (_clientListenerStarted) return
207
271
 
272
+ const { logger: l, worker } = ctx
273
+
208
274
  // Get service worker registration if no worker is provided
209
275
  if (!worker) {
210
276
  const sw = await navigator.serviceWorker.ready
@@ -220,8 +286,8 @@ export async function startClientListener<Procedures extends ProceduresMap>(
220
286
  const w = worker ?? navigator.serviceWorker
221
287
 
222
288
  // Start listening for messages
223
- l.debug(null, "Starting client listener", { worker, w, hooks })
224
- w.addEventListener("message", (event) => {
289
+ l.debug(null, "Starting client listener", { w, ...ctx })
290
+ const listener = (event: Event): void => {
225
291
  // Get the data from the event
226
292
  const eventData = (event as MessageEvent).data || {}
227
293
 
@@ -229,7 +295,15 @@ export async function startClientListener<Procedures extends ProceduresMap>(
229
295
  if (eventData?.by !== "sw&rpc") return
230
296
 
231
297
  // We don't use a arktype schema here, we trust the server to send valid data
232
- const { requestId, ...data } = eventData as Payload<Procedures>
298
+ const payload = eventData as Payload<Procedures>
299
+
300
+ // Ignore #initialize request, it's client->server only
301
+ if ("localStorageData" in payload) {
302
+ l.warn(null, "Ignoring unexpected #initialize from server", payload)
303
+ return
304
+ }
305
+
306
+ const { requestId, ...data } = payload
233
307
 
234
308
  // Sanity check in case we somehow receive a message without requestId
235
309
  if (!requestId) {
@@ -240,27 +314,41 @@ export async function startClientListener<Procedures extends ProceduresMap>(
240
314
  const handlers = pendingRequests.get(requestId)
241
315
  if (!handlers) {
242
316
  throw new Error(
243
- `[SWARPC Client] ${requestId} has no active request handlers, cannot process ${JSON.stringify(data)}`,
317
+ `[SWARPC Client] ${requestId} has no active request handlers, cannot process ${JSON.stringify(data)}`
244
318
  )
245
319
  }
246
320
 
247
321
  // React to the data received: call hook, call handler,
248
322
  // and remove the request from pendingRequests (unless it's a progress update)
249
323
  if ("error" in data) {
250
- hooks.error?.(data.functionName, new Error(data.error.message))
324
+ ctx.hooks.error?.(data.functionName, new Error(data.error.message))
251
325
  handlers.reject(new Error(data.error.message))
252
326
  pendingRequests.delete(requestId)
253
327
  } else if ("progress" in data) {
254
- hooks.progress?.(data.functionName, data.progress)
328
+ ctx.hooks.progress?.(data.functionName, data.progress)
255
329
  handlers.onProgress(data.progress)
256
330
  } else if ("result" in data) {
257
- hooks.success?.(data.functionName, data.result)
331
+ ctx.hooks.success?.(data.functionName, data.result)
258
332
  handlers.resolve(data.result)
259
333
  pendingRequests.delete(requestId)
260
334
  }
261
- })
335
+ }
336
+
337
+ if (w instanceof SharedWorker) {
338
+ w.port.addEventListener("message", listener)
339
+ w.port.start()
340
+ } else {
341
+ w.addEventListener("message", listener)
342
+ }
262
343
 
263
344
  _clientListenerStarted = true
345
+
346
+ // Recursive terminal case is ensured by calling this *after* _clientListenerStarted is set to true: startClientListener() will therefore not be called in postMessage() again.
347
+ await postMessage(ctx, {
348
+ by: "sw&rpc",
349
+ functionName: "#initialize",
350
+ localStorageData: ctx.localStorage,
351
+ })
264
352
  }
265
353
 
266
354
  /**
@@ -0,0 +1,46 @@
1
+ export class FauxLocalStorage {
2
+ data: Record<string, any>
3
+ keysOrder: string[]
4
+
5
+ constructor(data: Record<string, any>) {
6
+ this.data = data
7
+ this.keysOrder = Object.keys(data)
8
+ }
9
+
10
+ setItem(key: string, value: string) {
11
+ if (!this.hasItem(key)) this.keysOrder.push(key)
12
+ this.data[key] = value
13
+ }
14
+
15
+ getItem(key: string) {
16
+ return this.data[key]
17
+ }
18
+
19
+ hasItem(key: string) {
20
+ return Object.hasOwn(this.data, key)
21
+ }
22
+
23
+ removeItem(key: string) {
24
+ if (!this.hasItem(key)) return
25
+ delete this.data[key]
26
+ this.keysOrder = this.keysOrder.filter((k) => k !== key)
27
+ }
28
+
29
+ clear() {
30
+ this.data = {}
31
+ this.keysOrder = []
32
+ }
33
+
34
+ key(index: number) {
35
+ return this.keysOrder[index]
36
+ }
37
+
38
+ get length() {
39
+ return this.keysOrder.length
40
+ }
41
+
42
+ register(subject: WorkerGlobalScope | SharedWorkerGlobalScope) {
43
+ // @ts-expect-error
44
+ subject.localStorage = this
45
+ }
46
+ }