swarpc 0.12.0 → 0.14.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/README.md CHANGED
@@ -24,7 +24,11 @@ RPC for Service Workers -- move that heavy computation off of your UI thread!
24
24
  npm add swarpc arktype
25
25
  ```
26
26
 
27
- ### Bleeding edge
27
+ <details>
28
+ <summary>
29
+ Bleeding edge
30
+
31
+ </summary>
28
32
 
29
33
  If you want to use the latest commit instead of a published version, you can, either by using the Git URL:
30
34
 
@@ -42,6 +46,8 @@ npm add file:vendored/swarpc
42
46
 
43
47
  This works thanks to the fact that `dist/` is published on the repository (and kept up to date with a CI workflow).
44
48
 
49
+ </details>
50
+
45
51
  ## Usage
46
52
 
47
53
  ### 1. Declare your procedures in a shared file
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,kBAAkB,EAClB,KAAK,MAAM,EACX,KAAK,QAAQ,EACd,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,YAAY,EACZ,KAAK,EACL,OAAO,EAEP,iBAAiB,EACjB,WAAW,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB;;;;GAIG;AACH,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,aAAa,IAAI;IAC3D,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;CAC3B,GAAG;KACD,CAAC,IAAI,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,KAAK,OAAO,CAAC,UAAU,SAAS,aAAa,IAAI;IAC/C,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,kCAAkC;IAClC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACzB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC,CAAC;AAQF,MAAM,MAAM,cAAc,GAAG;IAC3B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC7B,UAAU,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAChC,CAAC;AAKF,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,UAAU,SAAS,aAAa,EACrD,UAAU,EAAE,UAAU,EACtB,EACE,MAAM,EACN,KAAK,EAAE,SAAS,EAChB,QAAkB,EAClB,eAAuB,EACvB,KAAU,EACV,YAAiB,GAClB,GAAE;IACD,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B,GACL,YAAY,CAAC,UAAU,CAAC,CAgK1B;AAiCD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,UAAU,SAAS,aAAa,EAC9D,CAAC,EAAE,kBAAkB,EACrB,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,EACzC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,0BAA0B,GACnC,IAAI,CAiBN;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,SAAS,aAAa,EACxE,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,iBAoFzB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,kBAAkB,EAClB,KAAK,MAAM,EACX,KAAK,QAAQ,EACd,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,YAAY,EACZ,KAAK,EACL,OAAO,EAEP,iBAAiB,EACjB,WAAW,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB;;;;GAIG;AACH,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,aAAa,IAAI;IAC3D,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;CAC3B,GAAG;KACD,CAAC,IAAI,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,KAAK,OAAO,CAAC,UAAU,SAAS,aAAa,IAAI;IAC/C,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,kCAAkC;IAClC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACzB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC,CAAC;AAQF,MAAM,MAAM,cAAc,GAAG;IAC3B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC7B,UAAU,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAChC,CAAC;AAKF,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,UAAU,SAAS,aAAa,EACrD,UAAU,EAAE,UAAU,EACtB,EACE,MAAM,EACN,KAAK,EAAE,SAAS,EAChB,QAAkB,EAClB,eAAuB,EACvB,KAAU,EACV,YAAiB,GAClB,GAAE;IACD,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B,GACL,YAAY,CAAC,UAAU,CAAC,CA2K1B;AAiCD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,UAAU,SAAS,aAAa,EAC9D,CAAC,EAAE,kBAAkB,EACrB,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,EACzC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,EAC5B,OAAO,CAAC,EAAE,0BAA0B,GACnC,IAAI,CAiBN;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,SAAS,aAAa,EACxE,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,iBAsFzB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
package/dist/client.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * @mergeModuleWith <project>
4
4
  */
5
5
  import { createLogger, } from "./log.js";
6
- import { makeNodeId, whoToSendTo } from "./nodes.js";
6
+ import { makeNodeId, nodeIdOrSW, whoToSendTo } from "./nodes.js";
7
7
  import { zProcedures, } from "./types.js";
8
8
  import { findTransferables } from "./utils.js";
9
9
  /**
@@ -80,7 +80,7 @@ export function Client(procedures, { worker, nodes: nodeCount, loglevel = "debug
80
80
  // Choose which node to use
81
81
  nodeId ??= whoToSendTo(nodes, pendingRequests);
82
82
  const node = nodes && nodeId ? nodes[nodeId] : undefined;
83
- const l = createLogger("client", loglevel, nodeId ?? "(SW)", requestId);
83
+ const l = createLogger("client", loglevel, nodeIdOrSW(nodeId), requestId);
84
84
  return new Promise((resolve, reject) => {
85
85
  // Store promise handlers (as well as progress updates handler)
86
86
  // so the client listener can resolve/reject the promise (and react to progress updates)
@@ -104,19 +104,28 @@ export function Client(procedures, { worker, nodes: nodeCount, loglevel = "debug
104
104
  };
105
105
  // @ts-expect-error
106
106
  instance[functionName] = _runProcedure;
107
- instance[functionName].broadcast = async (input, onProgress, nodesCount) => {
107
+ instance[functionName].broadcast = async (input, onProgresses, nodesCount) => {
108
108
  let nodesToUse = [undefined];
109
109
  if (nodes)
110
110
  nodesToUse = Object.keys(nodes);
111
111
  if (nodesCount)
112
112
  nodesToUse = nodesToUse.slice(0, nodesCount);
113
- const results = await Promise.allSettled(nodesToUse.map(async (id) => _runProcedure(input, onProgress, undefined, id)));
114
- return results.map((r, i) => ({ ...r, node: nodesToUse[i] ?? "(SW)" }));
113
+ const progresses = new Map();
114
+ function onProgress(nodeId) {
115
+ if (!onProgresses)
116
+ return (_) => { };
117
+ return (progress) => {
118
+ progresses.set(nodeIdOrSW(nodeId), progress);
119
+ onProgresses(progresses);
120
+ };
121
+ }
122
+ const results = await Promise.allSettled(nodesToUse.map(async (id) => _runProcedure(input, onProgress(id), undefined, id)));
123
+ return results.map((r, i) => ({ ...r, node: nodeIdOrSW(nodesToUse[i]) }));
115
124
  };
116
125
  instance[functionName].cancelable = (input, onProgress) => {
117
126
  const requestId = makeRequestId();
118
127
  const nodeId = whoToSendTo(nodes, pendingRequests);
119
- const l = createLogger("client", loglevel, nodeId ?? "(SW)", requestId);
128
+ const l = createLogger("client", loglevel, nodeIdOrSW(nodeId), requestId);
120
129
  return {
121
130
  request: _runProcedure(input, onProgress, requestId, nodeId),
122
131
  cancel(reason) {
@@ -186,7 +195,7 @@ export function postMessageSync(l, worker, message, options) {
186
195
  * @returns
187
196
  */
188
197
  export async function startClientListener(ctx) {
189
- if (_clientListenerStarted.has(ctx.nodeId ?? "(SW)"))
198
+ if (_clientListenerStarted.has(nodeIdOrSW(ctx.nodeId)))
190
199
  return;
191
200
  const { logger: l, node: worker } = ctx;
192
201
  // Get service worker registration if no worker is provided
@@ -211,7 +220,7 @@ export async function startClientListener(ctx) {
211
220
  // We don't use a arktype schema here, we trust the server to send valid data
212
221
  const payload = eventData;
213
222
  // Ignore #initialize request, it's client->server only
214
- if ("localStorageData" in payload) {
223
+ if ("isInitializeRequest" in payload) {
215
224
  l.warn(null, "Ignoring unexpected #initialize from server", payload);
216
225
  return;
217
226
  }
@@ -249,12 +258,14 @@ export async function startClientListener(ctx) {
249
258
  else {
250
259
  w.addEventListener("message", listener);
251
260
  }
252
- _clientListenerStarted.add(ctx.nodeId ?? "(SW)");
261
+ _clientListenerStarted.add(nodeIdOrSW(ctx.nodeId));
253
262
  // Recursive terminal case is ensured by calling this *after* _clientListenerStarted is set to true: startClientListener() will therefore not be called in postMessage() again.
254
263
  await postMessage(ctx, {
255
264
  by: "sw&rpc",
256
265
  functionName: "#initialize",
266
+ isInitializeRequest: true,
257
267
  localStorageData: ctx.localStorage,
268
+ nodeId: nodeIdOrSW(ctx.nodeId),
258
269
  });
259
270
  }
260
271
  /**
package/dist/log.d.ts CHANGED
@@ -25,5 +25,10 @@ export type RequestBoundLogger = {
25
25
  /** @source */
26
26
  declare const LOG_LEVELS: readonly ["debug", "info", "warn", "error"];
27
27
  export type LogLevel = (typeof LOG_LEVELS)[number];
28
+ /**
29
+ *
30
+ * @param scope
31
+ */
32
+ export declare function injectIntoConsoleGlobal(scope: WorkerGlobalScope | SharedWorkerGlobalScope, nodeId: string): void;
28
33
  export {};
29
34
  //# sourceMappingURL=log.d.ts.map
package/dist/log.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,EACzB,KAAK,EAAE,QAAQ,EACf,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,CAAC;AACV,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,EACzB,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,kBAAkB,CAAC;AA2BtB;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACtE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACrE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACrE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACjD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,cAAc;AACd,QAAA,MAAM,UAAU,6CAA8C,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,EACzB,KAAK,EAAE,QAAQ,EACf,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,CAAC;AACV,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,EACzB,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,kBAAkB,CAAC;AA2BtB;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACtE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACrE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACrE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACjD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,cAAc;AACd,QAAA,MAAM,UAAU,6CAA8C,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AA8EnD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,GAAG,uBAAuB,EAClD,MAAM,EAAE,MAAM,QAKf"}
package/dist/log.js CHANGED
@@ -22,22 +22,32 @@ export function createLogger(side, level = "debug", nid, rqid) {
22
22
  }
23
23
  /** @source */
24
24
  const LOG_LEVELS = ["debug", "info", "warn", "error"];
25
- function logger(severity, side, ids) {
25
+ const PATCHABLE_LOG_METHODS = [
26
+ "debug",
27
+ "info",
28
+ "warn",
29
+ "error",
30
+ "log",
31
+ ];
32
+ function logger(method, side, ids) {
26
33
  if (ids === undefined || typeof ids === "string") {
27
34
  const nid = ids ?? null;
28
- return (rqid, message, ...args) => log(severity, side, { nid, rqid }, message, ...args);
35
+ return (rqid, ...args) => log(method, side, { nid, rqid }, ...args);
29
36
  }
30
- return (message, ...args) => log(severity, side, ids, message, ...args);
37
+ return (...args) => log(method, side, ids, ...args);
31
38
  }
39
+ const originalConsole = PATCHABLE_LOG_METHODS.reduce((result, method) => {
40
+ result[method] = console[method];
41
+ return result;
42
+ }, {});
32
43
  /**
33
44
  * Send log messages to the console, with a helpful prefix.
34
- * @param severity
45
+ * @param method
35
46
  * @param side
36
47
  * @param ids request ID and node ID
37
- * @param message
38
48
  * @param args passed to console methods directly
39
49
  */
40
- function log(severity, side, { rqid, nid }, message, ...args) {
50
+ function log(method, side, { rqid, nid }, ...args) {
41
51
  const prefix = [
42
52
  `[SWARPC ${side}]`,
43
53
  rqid ? `%c${rqid}%c` : "",
@@ -50,16 +60,14 @@ function log(severity, side, { rqid, nid }, message, ...args) {
50
60
  prefixStyles.push("color: cyan", "color: inherit");
51
61
  if (nid)
52
62
  prefixStyles.push("color: hotpink", "color: inherit");
53
- if (severity === "debug") {
54
- console.debug(prefix, ...prefixStyles, message, ...args);
55
- }
56
- else if (severity === "info") {
57
- console.info(prefix, ...prefixStyles, message, ...args);
58
- }
59
- else if (severity === "warn") {
60
- console.warn(prefix, ...prefixStyles, message, ...args);
61
- }
62
- else if (severity === "error") {
63
- console.error(prefix, ...prefixStyles, message, ...args);
63
+ return originalConsole[method](prefix, ...prefixStyles, ...args);
64
+ }
65
+ /**
66
+ *
67
+ * @param scope
68
+ */
69
+ export function injectIntoConsoleGlobal(scope, nodeId) {
70
+ for (const method of PATCHABLE_LOG_METHODS) {
71
+ scope.self.console[method] = logger(method, "server", nodeId);
64
72
  }
65
73
  }
package/dist/nodes.d.ts CHANGED
@@ -9,4 +9,7 @@ export declare function nodeIdFromScope(scope: WorkerGlobalScope, _scopeType?: "
9
9
  * @source
10
10
  */
11
11
  export declare function makeNodeId(): string;
12
+ export declare const serviceWorkerNodeId: "(SW)";
13
+ export declare function isServiceWorkerNodeId(id: string): id is "(SW)";
14
+ export declare function nodeIdOrSW(id: string | undefined): string | typeof serviceWorkerNodeId;
12
15
  //# sourceMappingURL=nodes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,SAAS,GAAG,MAAM,CA0BpB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,iBAAiB,EACxB,UAAU,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,GAC9C,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
1
+ {"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,SAAS,GAAG,MAAM,CA0BpB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,iBAAiB,EACxB,UAAU,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,GAC9C,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,eAAO,MAAM,mBAAmB,EAAG,MAAe,CAAC;AAEnD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,gBAE/C;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,GAAG,SAAS,GACrB,MAAM,GAAG,OAAO,mBAAmB,CAErC"}
package/dist/nodes.js CHANGED
@@ -34,3 +34,10 @@ export function nodeIdFromScope(scope, _scopeType) {
34
34
  export function makeNodeId() {
35
35
  return "N" + Math.random().toString(16).substring(2, 5).toUpperCase();
36
36
  }
37
+ export const serviceWorkerNodeId = "(SW)"; // Fixed ID for the service worker, as there's only one
38
+ export function isServiceWorkerNodeId(id) {
39
+ return id === serviceWorkerNodeId;
40
+ }
41
+ export function nodeIdOrSW(id) {
42
+ return id ?? serviceWorkerNodeId;
43
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EACL,kBAAkB,EAMlB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,aAAa,IAAI;IAC3D,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC1B,CAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,GAAG;KACD,CAAC,IAAI,MAAM,UAAU,GAAG,CACvB,IAAI,EAAE,uBAAuB,CAC3B,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EACtB,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EACzB,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CACzB,KACE,IAAI;CACV,CAAC;AAKF;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,UAAU,SAAS,aAAa,EACrD,UAAU,EAAE,UAAU,EACtB,EACE,QAAkB,EAClB,KAAK,EACL,UAAU,GACX,GAAE;IACD,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,UAAU,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC5C,GACL,YAAY,CAAC,UAAU,CAAC,CA2M1B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAyC,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EACL,kBAAkB,EAMlB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,aAAa,IAAI;IAC3D,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC1B,CAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,GAAG;KACD,CAAC,IAAI,MAAM,UAAU,GAAG,CACvB,IAAI,EAAE,uBAAuB,CAC3B,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EACtB,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EACzB,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CACzB,KACE,IAAI;CACV,CAAC;AAKF;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,UAAU,SAAS,aAAa,EACrD,UAAU,EAAE,UAAU,EACtB,EACE,QAAkB,EAClB,KAAK,EACL,UAAU,GACX,GAAE;IACD,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,UAAU,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC5C,GACL,YAAY,CAAC,UAAU,CAAC,CA6M1B"}
package/dist/server.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  /// <reference lib="webworker" />
6
6
  import { type } from "arktype";
7
- import { createLogger } from "./log.js";
7
+ import { createLogger, injectIntoConsoleGlobal } from "./log.js";
8
8
  import { PayloadHeaderSchema, PayloadInitializeSchema, PayloadSchema, zImplementations, zProcedures, } from "./types.js";
9
9
  import { findTransferables } from "./utils.js";
10
10
  import { FauxLocalStorage } from "./localstorage.js";
@@ -85,9 +85,10 @@ export function Server(procedures, { loglevel = "debug", scope, _scopeType, } =
85
85
  };
86
86
  const listener = async (event) => {
87
87
  if (PayloadInitializeSchema.allows(event.data)) {
88
- const { localStorageData } = event.data;
88
+ const { localStorageData, nodeId } = event.data;
89
89
  l.debug(null, "Setting up faux localStorage", localStorageData);
90
90
  new FauxLocalStorage(localStorageData).register(scope);
91
+ injectIntoConsoleGlobal(scope, nodeId);
91
92
  return;
92
93
  }
93
94
  // Decode the payload
@@ -120,7 +121,7 @@ export function Server(procedures, { loglevel = "debug", scope, _scopeType, } =
120
121
  }
121
122
  // Define payload schema for incoming messages
122
123
  const payload = PayloadSchema(type(`"${functionName}"`), schemas.input, schemas.progress, schemas.success).assert(event.data);
123
- if ("localStorageData" in payload)
124
+ if ("isInitializeRequest" in payload)
124
125
  throw "Unreachable: #initialize request payload should've been handled already";
125
126
  // Handle abortion requests (pro-choice ftw!!)
126
127
  if (payload.abort) {
@@ -142,6 +143,7 @@ export function Server(procedures, { loglevel = "debug", scope, _scopeType, } =
142
143
  // l.debug(requestId, `Progress for ${functionName}`, progress);
143
144
  await postMsg({ progress });
144
145
  }, {
146
+ nodeId,
145
147
  abortSignal: abortControllers.get(requestId)?.signal,
146
148
  logger: createLogger("server", loglevel, nodeId, requestId),
147
149
  });
package/dist/types.d.ts CHANGED
@@ -74,6 +74,10 @@ tools: {
74
74
  * Logger instance to use for logging messages related to this procedure call, using the same format as SWARPC's built-in logging.
75
75
  */
76
76
  logger: RequestBoundLogger;
77
+ /**
78
+ * ID of the Node the request is being processed on.
79
+ */
80
+ nodeId: string;
77
81
  }) => Promise<S["inferIn"]>;
78
82
  /**
79
83
  * Declarations of procedures by name.
@@ -108,7 +112,9 @@ export type Hooks<Procedures extends ProceduresMap> = {
108
112
  export declare const PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
109
113
  by: "sw&rpc";
110
114
  functionName: "#initialize";
115
+ isInitializeRequest: true;
111
116
  localStorageData: Record<string, unknown>;
117
+ nodeId: string;
112
118
  }, {}>;
113
119
  export type PayloadInitialize = typeof PayloadInitializeSchema.infer;
114
120
  /**
@@ -187,12 +193,16 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
187
193
  PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
188
194
  by: "sw&rpc";
189
195
  functionName: "#initialize";
196
+ isInitializeRequest: true;
190
197
  localStorageData: Record<string, unknown>;
198
+ nodeId: string;
191
199
  }, {}> & {
192
200
  readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
193
201
  by: "sw&rpc";
194
202
  functionName: "#initialize";
203
+ isInitializeRequest: true;
195
204
  localStorageData: Record<string, unknown>;
205
+ nodeId: string;
196
206
  }, {}>, "unparsed"];
197
207
  };
198
208
  } & {}>;
@@ -220,19 +230,25 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
220
230
  PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
221
231
  by: "sw&rpc";
222
232
  functionName: "#initialize";
233
+ isInitializeRequest: true;
223
234
  localStorageData: Record<string, unknown>;
235
+ nodeId: string;
224
236
  }, {}> & {
225
237
  readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
226
238
  by: "sw&rpc";
227
239
  functionName: "#initialize";
240
+ isInitializeRequest: true;
228
241
  localStorageData: Record<string, unknown>;
242
+ nodeId: string;
229
243
  }, {}>, "unparsed"];
230
244
  };
231
245
  } & {}>;
232
246
  PayloadInitializeSchema: {
233
247
  by: "sw&rpc";
234
248
  functionName: "#initialize";
249
+ isInitializeRequest: true;
235
250
  localStorageData: Record<string, unknown>;
251
+ nodeId: string;
236
252
  };
237
253
  }, {
238
254
  PayloadCoreSchema: import("arktype/internal/scope.ts").bindGenericToScope<import("@ark/schema").GenericAst<[["I", unknown], ["P", unknown], ["S", unknown]], {
@@ -265,12 +281,16 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
265
281
  PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
266
282
  by: "sw&rpc";
267
283
  functionName: "#initialize";
284
+ isInitializeRequest: true;
268
285
  localStorageData: Record<string, unknown>;
286
+ nodeId: string;
269
287
  }, {}> & {
270
288
  readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
271
289
  by: "sw&rpc";
272
290
  functionName: "#initialize";
291
+ isInitializeRequest: true;
273
292
  localStorageData: Record<string, unknown>;
293
+ nodeId: string;
274
294
  }, {}>, "unparsed"];
275
295
  };
276
296
  } & {}>;
@@ -298,19 +318,25 @@ export declare const PayloadSchema: import("arktype").Generic<[["Name", string],
298
318
  PayloadInitializeSchema: import("arktype/internal/methods/object.ts").ObjectType<{
299
319
  by: "sw&rpc";
300
320
  functionName: "#initialize";
321
+ isInitializeRequest: true;
301
322
  localStorageData: Record<string, unknown>;
323
+ nodeId: string;
302
324
  }, {}> & {
303
325
  readonly " brand": [import("arktype/internal/methods/object.ts").ObjectType<{
304
326
  by: "sw&rpc";
305
327
  functionName: "#initialize";
328
+ isInitializeRequest: true;
306
329
  localStorageData: Record<string, unknown>;
330
+ nodeId: string;
307
331
  }, {}>, "unparsed"];
308
332
  };
309
333
  } & {}>;
310
334
  PayloadInitializeSchema: {
311
335
  by: "sw&rpc";
312
336
  functionName: "#initialize";
337
+ isInitializeRequest: true;
313
338
  localStorageData: Record<string, unknown>;
339
+ nodeId: string;
314
340
  };
315
341
  }>;
316
342
  /**
@@ -330,7 +356,9 @@ export type ClientMethod<P extends Procedure<Type, Type, Type>> = ((input: P["in
330
356
  * Returns an array of results, one for each node the request was sent to.
331
357
  * Each result is a {@link PromiseSettledResult}, with also an additional property, the node ID of the request
332
358
  */
333
- broadcast: (input: P["input"]["inferIn"], onProgress?: (progress: P["progress"]["inferOut"]) => void,
359
+ broadcast: (input: P["input"]["inferIn"], onProgress?: (
360
+ /** Map of node IDs to their progress updates */
361
+ progresses: Map<string, P["progress"]["inferOut"]>) => void,
334
362
  /** Number of nodes to send the request to. Leave undefined to send to all nodes */
335
363
  nodes?: number) => Promise<Array<PromiseSettledResult<P["success"]["inferOut"]> & {
336
364
  node: string;
@@ -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
@@ -6,7 +6,9 @@ import { type } from "arktype";
6
6
  export const PayloadInitializeSchema = type({
7
7
  by: '"sw&rpc"',
8
8
  functionName: '"#initialize"',
9
+ isInitializeRequest: "true",
9
10
  localStorageData: "Record<string, unknown>",
11
+ nodeId: "string",
10
12
  });
11
13
  /**
12
14
  * @source
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swarpc",
3
- "version": "0.12.0",
3
+ "version": "0.14.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",
@@ -40,12 +40,14 @@
40
40
  "typedoc:withplugins": "npm run typedoc:plugins && npm run typedoc",
41
41
  "prepare": "husky"
42
42
  },
43
- "dependencies": {
43
+ "peerDependencies": {
44
44
  "arktype": "^2.1.22"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@8hobbies/typedoc-plugin-plausible": "^2.2.0",
48
+ "@playwright/test": "^1.55.0",
48
49
  "@vitest/web-worker": "^3.2.4",
50
+ "date-fns": "^4.1.0",
49
51
  "husky": "^9.1.7",
50
52
  "kacl": "^1.1.1",
51
53
  "knip": "^5.63.1",
package/src/client.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  type Logger,
10
10
  type LogLevel,
11
11
  } from "./log.js";
12
- import { makeNodeId, whoToSendTo } from "./nodes.js";
12
+ import { makeNodeId, nodeIdOrSW, whoToSendTo } from "./nodes.js";
13
13
  import {
14
14
  ClientMethod,
15
15
  Hooks,
@@ -186,7 +186,7 @@ export function Client<Procedures extends ProceduresMap>(
186
186
  nodeId ??= whoToSendTo(nodes, pendingRequests);
187
187
  const node = nodes && nodeId ? nodes[nodeId] : undefined;
188
188
 
189
- const l = createLogger("client", loglevel, nodeId ?? "(SW)", requestId);
189
+ const l = createLogger("client", loglevel, nodeIdOrSW(nodeId), requestId);
190
190
 
191
191
  return new Promise((resolve, reject) => {
192
192
  // Store promise handlers (as well as progress updates handler)
@@ -217,26 +217,37 @@ export function Client<Procedures extends ProceduresMap>(
217
217
  instance[functionName] = _runProcedure;
218
218
  instance[functionName]!.broadcast = async (
219
219
  input,
220
- onProgress,
220
+ onProgresses,
221
221
  nodesCount,
222
222
  ) => {
223
223
  let nodesToUse: Array<string | undefined> = [undefined];
224
224
  if (nodes) nodesToUse = Object.keys(nodes);
225
225
  if (nodesCount) nodesToUse = nodesToUse.slice(0, nodesCount);
226
226
 
227
+ const progresses = new Map<string, unknown>();
228
+
229
+ function onProgress(nodeId: string | undefined) {
230
+ if (!onProgresses) return (_: unknown) => {};
231
+
232
+ return (progress: unknown) => {
233
+ progresses.set(nodeIdOrSW(nodeId), progress);
234
+ onProgresses(progresses);
235
+ };
236
+ }
237
+
227
238
  const results = await Promise.allSettled(
228
239
  nodesToUse.map(async (id) =>
229
- _runProcedure(input, onProgress, undefined, id),
240
+ _runProcedure(input, onProgress(id), undefined, id),
230
241
  ),
231
242
  );
232
243
 
233
- return results.map((r, i) => ({ ...r, node: nodesToUse[i] ?? "(SW)" }));
244
+ return results.map((r, i) => ({ ...r, node: nodeIdOrSW(nodesToUse[i]) }));
234
245
  };
235
246
  instance[functionName]!.cancelable = (input, onProgress) => {
236
247
  const requestId = makeRequestId();
237
248
  const nodeId = whoToSendTo(nodes, pendingRequests);
238
249
 
239
- const l = createLogger("client", loglevel, nodeId ?? "(SW)", requestId);
250
+ const l = createLogger("client", loglevel, nodeIdOrSW(nodeId), requestId);
240
251
 
241
252
  return {
242
253
  request: _runProcedure(input, onProgress, requestId, nodeId),
@@ -336,7 +347,7 @@ export function postMessageSync<Procedures extends ProceduresMap>(
336
347
  export async function startClientListener<Procedures extends ProceduresMap>(
337
348
  ctx: Context<Procedures>,
338
349
  ) {
339
- if (_clientListenerStarted.has(ctx.nodeId ?? "(SW)")) return;
350
+ if (_clientListenerStarted.has(nodeIdOrSW(ctx.nodeId))) return;
340
351
 
341
352
  const { logger: l, node: worker } = ctx;
342
353
 
@@ -367,7 +378,7 @@ export async function startClientListener<Procedures extends ProceduresMap>(
367
378
  const payload = eventData as Payload<Procedures>;
368
379
 
369
380
  // Ignore #initialize request, it's client->server only
370
- if ("localStorageData" in payload) {
381
+ if ("isInitializeRequest" in payload) {
371
382
  l.warn(null, "Ignoring unexpected #initialize from server", payload);
372
383
  return;
373
384
  }
@@ -410,13 +421,15 @@ export async function startClientListener<Procedures extends ProceduresMap>(
410
421
  w.addEventListener("message", listener);
411
422
  }
412
423
 
413
- _clientListenerStarted.add(ctx.nodeId ?? "(SW)");
424
+ _clientListenerStarted.add(nodeIdOrSW(ctx.nodeId));
414
425
 
415
426
  // Recursive terminal case is ensured by calling this *after* _clientListenerStarted is set to true: startClientListener() will therefore not be called in postMessage() again.
416
427
  await postMessage(ctx, {
417
428
  by: "sw&rpc",
418
429
  functionName: "#initialize",
430
+ isInitializeRequest: true,
419
431
  localStorageData: ctx.localStorage,
432
+ nodeId: nodeIdOrSW(ctx.nodeId),
420
433
  });
421
434
  }
422
435
 
package/src/log.ts CHANGED
@@ -65,51 +65,65 @@ const LOG_LEVELS = ["debug", "info", "warn", "error"] as const;
65
65
 
66
66
  export type LogLevel = (typeof LOG_LEVELS)[number];
67
67
 
68
+ const PATCHABLE_LOG_METHODS = [
69
+ "debug",
70
+ "info",
71
+ "warn",
72
+ "error",
73
+ "log",
74
+ ] as const;
75
+ type LogMethod = (typeof PATCHABLE_LOG_METHODS)[number];
76
+
68
77
  /**
69
78
  * Creates partially-applied logging functions given the first 2 or 3 args
70
- * @param severity
79
+ * @param method
71
80
  * @param side
72
81
  * @param ids request ID, {reqid, nodeId}, or null to not bind it
73
82
  * @returns
74
83
  */
75
84
  function logger(
76
- severity: LogLevel,
85
+ method: LogMethod,
77
86
  side: "server" | "client",
78
87
  ids: { rqid: string; nid: string },
79
- ): (message: string, ...args: any[]) => void;
88
+ ): (...args: any[]) => void;
80
89
  function logger(
81
- severity: LogLevel,
90
+ method: LogMethod,
82
91
  side: "server" | "client",
83
92
  nid?: string,
84
- ): (rqid: string | null, message: string, ...args: any[]) => void;
93
+ ): (rqid: string | null, ...args: any[]) => void;
85
94
  function logger(
86
- severity: LogLevel,
95
+ method: LogMethod,
87
96
  side: "server" | "client",
88
97
  ids?: string | { rqid: string; nid: string },
89
98
  ) {
90
99
  if (ids === undefined || typeof ids === "string") {
91
100
  const nid = ids ?? null;
92
- return (rqid: string | null, message: string, ...args: any[]) =>
93
- log(severity, side, { nid, rqid }, message, ...args);
101
+ return (rqid: string | null, ...args: any[]) =>
102
+ log(method, side, { nid, rqid }, ...args);
94
103
  }
95
104
 
96
- return (message: string, ...args: any[]) =>
97
- log(severity, side, ids, message, ...args);
105
+ return (...args: any[]) => log(method, side, ids, ...args);
98
106
  }
99
107
 
108
+ const originalConsole = PATCHABLE_LOG_METHODS.reduce(
109
+ (result, method) => {
110
+ result[method] = console[method];
111
+ return result;
112
+ },
113
+ {} as Pick<typeof console, LogMethod>,
114
+ );
115
+
100
116
  /**
101
117
  * Send log messages to the console, with a helpful prefix.
102
- * @param severity
118
+ * @param method
103
119
  * @param side
104
120
  * @param ids request ID and node ID
105
- * @param message
106
121
  * @param args passed to console methods directly
107
122
  */
108
123
  function log(
109
- severity: "debug" | "info" | "warn" | "error",
124
+ method: LogMethod,
110
125
  side: "server" | "client",
111
126
  { rqid, nid }: { rqid: string | null; nid: string | null },
112
- message: string,
113
127
  ...args: any[]
114
128
  ) {
115
129
  const prefix = [
@@ -124,13 +138,18 @@ function log(
124
138
  if (rqid) prefixStyles.push("color: cyan", "color: inherit");
125
139
  if (nid) prefixStyles.push("color: hotpink", "color: inherit");
126
140
 
127
- if (severity === "debug") {
128
- console.debug(prefix, ...prefixStyles, message, ...args);
129
- } else if (severity === "info") {
130
- console.info(prefix, ...prefixStyles, message, ...args);
131
- } else if (severity === "warn") {
132
- console.warn(prefix, ...prefixStyles, message, ...args);
133
- } else if (severity === "error") {
134
- console.error(prefix, ...prefixStyles, message, ...args);
141
+ return originalConsole[method](prefix, ...prefixStyles, ...args);
142
+ }
143
+
144
+ /**
145
+ *
146
+ * @param scope
147
+ */
148
+ export function injectIntoConsoleGlobal(
149
+ scope: WorkerGlobalScope | SharedWorkerGlobalScope,
150
+ nodeId: string,
151
+ ) {
152
+ for (const method of PATCHABLE_LOG_METHODS) {
153
+ scope.self.console[method] = logger(method, "server", nodeId);
135
154
  }
136
155
  }
package/src/nodes.ts CHANGED
@@ -53,3 +53,15 @@ export function nodeIdFromScope(
53
53
  export function makeNodeId(): string {
54
54
  return "N" + Math.random().toString(16).substring(2, 5).toUpperCase();
55
55
  }
56
+
57
+ export const serviceWorkerNodeId = "(SW)" as const; // Fixed ID for the service worker, as there's only one
58
+
59
+ export function isServiceWorkerNodeId(id: string) {
60
+ return id === serviceWorkerNodeId;
61
+ }
62
+
63
+ export function nodeIdOrSW(
64
+ id: string | undefined,
65
+ ): string | typeof serviceWorkerNodeId {
66
+ return id ?? serviceWorkerNodeId;
67
+ }
package/src/server.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /// <reference lib="webworker" />
7
7
  import { type } from "arktype";
8
- import { createLogger, type LogLevel } from "./log.js";
8
+ import { createLogger, injectIntoConsoleGlobal, type LogLevel } from "./log.js";
9
9
  import {
10
10
  ImplementationsMap,
11
11
  Payload,
@@ -141,9 +141,10 @@ export function Server<Procedures extends ProceduresMap>(
141
141
  event: MessageEvent<any> | ExtendableMessageEvent,
142
142
  ): Promise<void> => {
143
143
  if (PayloadInitializeSchema.allows(event.data)) {
144
- const { localStorageData } = event.data;
144
+ const { localStorageData, nodeId } = event.data;
145
145
  l.debug(null, "Setting up faux localStorage", localStorageData);
146
146
  new FauxLocalStorage(localStorageData).register(scope);
147
+ injectIntoConsoleGlobal(scope, nodeId);
147
148
  return;
148
149
  }
149
150
 
@@ -194,7 +195,7 @@ export function Server<Procedures extends ProceduresMap>(
194
195
  schemas.success,
195
196
  ).assert(event.data);
196
197
 
197
- if ("localStorageData" in payload)
198
+ if ("isInitializeRequest" in payload)
198
199
  throw "Unreachable: #initialize request payload should've been handled already";
199
200
 
200
201
  // Handle abortion requests (pro-choice ftw!!)
@@ -225,6 +226,7 @@ export function Server<Procedures extends ProceduresMap>(
225
226
  await postMsg({ progress });
226
227
  },
227
228
  {
229
+ nodeId,
228
230
  abortSignal: abortControllers.get(requestId)?.signal,
229
231
  logger: createLogger("server", loglevel, nodeId, requestId),
230
232
  },
package/src/types.ts CHANGED
@@ -82,6 +82,10 @@ export type ProcedureImplementation<
82
82
  * Logger instance to use for logging messages related to this procedure call, using the same format as SWARPC's built-in logging.
83
83
  */
84
84
  logger: RequestBoundLogger;
85
+ /**
86
+ * ID of the Node the request is being processed on.
87
+ */
88
+ nodeId: string;
85
89
  },
86
90
  ) => Promise<S["inferIn"]>;
87
91
 
@@ -134,7 +138,9 @@ export type Hooks<Procedures extends ProceduresMap> = {
134
138
  export const PayloadInitializeSchema = type({
135
139
  by: '"sw&rpc"',
136
140
  functionName: '"#initialize"',
141
+ isInitializeRequest: "true",
137
142
  localStorageData: "Record<string, unknown>",
143
+ nodeId: "string",
138
144
  });
139
145
 
140
146
  export type PayloadInitialize = typeof PayloadInitializeSchema.infer;
@@ -229,7 +235,10 @@ export type ClientMethod<P extends Procedure<Type, Type, Type>> = ((
229
235
  */
230
236
  broadcast: (
231
237
  input: P["input"]["inferIn"],
232
- onProgress?: (progress: P["progress"]["inferOut"]) => void,
238
+ onProgress?: (
239
+ /** Map of node IDs to their progress updates */
240
+ progresses: Map<string, P["progress"]["inferOut"]>,
241
+ ) => void,
233
242
  /** Number of nodes to send the request to. Leave undefined to send to all nodes */
234
243
  nodes?: number,
235
244
  ) => Promise<