swarpc 0.15.0 → 0.16.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
@@ -3,7 +3,7 @@
3
3
  <img src="./logo.svg" alt="sw&rpc" />
4
4
  </h1>
5
5
 
6
- RPC for Service Workers -- move that heavy computation off of your UI thread!
6
+ RPC for Service (and other types of) Workers -- move that heavy computation off of your UI thread!
7
7
 
8
8
  </div>
9
9
 
@@ -12,11 +12,13 @@ RPC for Service Workers -- move that heavy computation off of your UI thread!
12
12
  ## Features
13
13
 
14
14
  - Fully typesafe
15
+ - Lightweight: no dependencies, less than 5 kB (minified+gzipped)
15
16
  - Supports any [Standard Schema](https://standardschema.dev)-compliant validation library (ArkType, Zod, Valibot, etc.)
16
17
  - Cancelable requests
17
18
  - Parallelization with multiple worker instances
18
19
  - Automatic [transfer](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects) of transferable values from- and to- worker code
19
20
  - A way to polyfill a pre-filled `localStorage` to be accessed within the worker code
21
+ - First-class support for signaling progress updates (and e.g. display a progress bar)
20
22
  - Supports [Service workers](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker), [Shared workers](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker) and [Dedicated workers](https://developer.mozilla.org/en-US/docs/Web/API/Worker)
21
23
 
22
24
  ## Installation
@@ -83,9 +85,9 @@ export const procedures = {
83
85
  } as const satisfies ProceduresMap;
84
86
  ```
85
87
 
86
- ### 2. Register your procedures in the service worker
88
+ ### 2. Register your procedures in worker
87
89
 
88
- In your service worker file:
90
+ In your worker file:
89
91
 
90
92
  ```javascript
91
93
  import fetchProgress from "fetch-progress"
@@ -152,6 +154,30 @@ Here's a Svelte example!
152
154
  </ul>
153
155
  ```
154
156
 
157
+ ### 4. Registering your worker
158
+
159
+ #### Service Workers
160
+
161
+ If you use SvelteKit, [just name your service worker file `src/service-worker.ts`](https://svelte.dev/docs/kit/service-workers)
162
+
163
+ _If you use any other (meta) framework, please contribute usage documentation here :)_
164
+
165
+ #### Dedicated or Shared Workers
166
+
167
+ Preferred over service workers for heavy computations, since you can run multiple instances of them (see [Configure parallelism](#configure-parallelism))
168
+
169
+ If you use Vite, you can [import files as Web Worker classes](https://vite.dev/guide/features.html#web-workers):
170
+
171
+ ```ts
172
+ import { Client } from "swarpc";
173
+ import { procedures } from "$lib/off-thread/procedures.ts";
174
+ import OffThreadWorker from "$lib/off-thread/worker.ts?worker";
175
+
176
+ const client = Client(procedures, {
177
+ worker: OffThreadWorker, // don't instanciate the class, sw&rpc does it
178
+ });
179
+ ```
180
+
155
181
  ### Configure parallelism
156
182
 
157
183
  By default, when a `worker` is passed to the `Client`'s options, the client will automatically spin up `navigator.hardwareConcurrency` worker instances and distribute requests among them. You can customize this behavior by setting the `Client:options.nodes` option to control the number of _nodes_ (worker instances).
@@ -166,7 +192,7 @@ For example:
166
192
 
167
193
  ```ts
168
194
  const client = Client(procedures, {
169
- worker: "./worker.js",
195
+ worker: MyWorker,
170
196
  nodes: 4,
171
197
  });
172
198
 
package/dist/client.d.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  * @module
3
3
  * @mergeModuleWith <project>
4
4
  */
5
- import { RequestBoundLogger, type Logger, type LogLevel } from "./log.js";
6
- import { ClientMethod, Hooks, Payload, WorkerConstructor, zProcedures, type ProceduresMap } from "./types.js";
5
+ import { type LogLevel } from "./log.js";
6
+ import { ClientMethod, Hooks, WorkerConstructor, zProcedures, type ProceduresMap } from "./types.js";
7
7
  /**
8
8
  * The sw&rpc client instance, which provides {@link ClientMethod | methods to call procedures}.
9
9
  * Each property of the procedures map will be a method, that accepts an input, an optional onProgress callback and an optional request ID.
@@ -14,30 +14,6 @@ export type SwarpcClient<Procedures extends ProceduresMap> = {
14
14
  } & {
15
15
  [F in keyof Procedures]: ClientMethod<Procedures[F]>;
16
16
  };
17
- /**
18
- * Context for passing around data useful for requests
19
- */
20
- type Context<Procedures extends ProceduresMap> = {
21
- /** A logger, bound to the client */
22
- logger: Logger;
23
- /** The node to use */
24
- node: Worker | SharedWorker | undefined;
25
- /** The ID of the node to use */
26
- nodeId: string | undefined;
27
- /** Hooks defined by the client */
28
- hooks: Hooks<Procedures>;
29
- /** Local storage data defined by the client for the faux local storage */
30
- localStorage: Record<string, any>;
31
- };
32
- export type PendingRequest = {
33
- /** ID of the node the request was sent to. udefined if running on a service worker */
34
- nodeId?: string;
35
- functionName: string;
36
- reject: (err: Error) => void;
37
- onProgress: (progress: any) => void;
38
- resolve: (result: any) => void;
39
- };
40
- export type ClientOptions = Parameters<typeof Client>[1];
41
17
  /**
42
18
  *
43
19
  * @param procedures procedures the client will be able to call, see {@link ProceduresMap}
@@ -64,26 +40,3 @@ export declare function Client<Procedures extends ProceduresMap>(procedures: Pro
64
40
  restartListener?: boolean;
65
41
  localStorage?: Record<string, any>;
66
42
  }): SwarpcClient<Procedures>;
67
- /**
68
- * A quicker version of postMessage that does not try to start the client listener, await the service worker, etc.
69
- * esp. useful for abort logic that needs to not be... put behind everything else on the event loop.
70
- * @param l
71
- * @param worker
72
- * @param message
73
- * @param options
74
- */
75
- export declare function postMessageSync<Procedures extends ProceduresMap>(l: RequestBoundLogger, worker: Worker | SharedWorker | undefined, message: Payload<Procedures>, options?: StructuredSerializeOptions): void;
76
- /**
77
- * Starts the client listener, which listens for messages from the sw&rpc server.
78
- * @param ctx.worker if provided, the client will use this worker to listen for messages, instead of using the service worker
79
- * @returns
80
- */
81
- export declare function startClientListener<Procedures extends ProceduresMap>(ctx: Context<Procedures>): Promise<void>;
82
- /**
83
- * Generate a random request ID, used to identify requests between client and server.
84
- * @source
85
- * @returns a 6-character hexadecimal string
86
- */
87
- export declare function makeRequestId(): string;
88
- export {};
89
- //# sourceMappingURL=client.d.ts.map
package/dist/client.js CHANGED
@@ -1,42 +1,13 @@
1
- /**
2
- * @module
3
- * @mergeModuleWith <project>
4
- */
5
1
  import { createLogger, } from "./log.js";
6
2
  import { makeNodeId, nodeIdOrSW, whoToSendTo } from "./nodes.js";
7
3
  import { zProcedures, } from "./types.js";
8
4
  import { findTransferables } from "./utils.js";
9
- /**
10
- * Pending requests are stored in a map, where the key is the request ID.
11
- * Each request has a set of handlers: resolve, reject, and onProgress.
12
- * This allows having a single listener for the client, and having multiple in-flight calls to the same procedure.
13
- */
14
5
  const pendingRequests = new Map();
15
- // Have we started the client listener?
16
6
  let _clientListenerStarted = new Set();
17
- /**
18
- *
19
- * @param procedures procedures the client will be able to call, see {@link ProceduresMap}
20
- * @param options various options
21
- * @param options.worker The worker class, **not instantiated**, or a path to the source code. If not provided, the client will use the service worker. If a string is provided, it'll instantiate a regular `Worker`, not a `SharedWorker`.
22
- * Example: `"./worker.js"`
23
- * See {@link Worker} (used by both dedicated workers and service workers), {@link SharedWorker}, and
24
- * the different [worker types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API#worker_types) that exist
25
- * @param options.hooks Hooks to run on messages received from the server. See {@link Hooks}
26
- * @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.
27
- * @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.
28
- * @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)
29
- * @param options.nodes the number of workers to use for the server, defaults to {@link navigator.hardwareConcurrency}.
30
- * @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}
31
- *
32
- * An example of defining and using a client:
33
- * {@includeCode ../example/src/routes/+page.svelte}
34
- */
35
7
  export function Client(procedures, { worker, nodes: nodeCount, loglevel = "debug", restartListener = false, hooks = {}, localStorage = {}, } = {}) {
36
8
  const l = createLogger("client", loglevel);
37
9
  if (restartListener)
38
10
  _clientListenerStarted.clear();
39
- // Store procedures on a symbol key, to avoid conflicts with procedure names
40
11
  const instance = { [zProcedures]: procedures };
41
12
  nodeCount ??= navigator.hardwareConcurrency || 1;
42
13
  let nodes;
@@ -72,23 +43,17 @@ export function Client(procedures, { worker, nodes: nodeCount, loglevel = "debug
72
43
  functionName,
73
44
  }, options);
74
45
  };
75
- // Set the method on the instance
76
46
  const _runProcedure = async (input, onProgress = () => { }, reqid, nodeId) => {
77
- // Validate the input against the procedure's input schema
78
47
  const validation = procedures[functionName].input["~standard"].validate(input);
79
48
  if (validation instanceof Promise)
80
49
  throw new Error("Validations must not be async");
81
50
  if (validation.issues)
82
51
  throw new Error(`Invalid input: ${validation.issues}`);
83
52
  const requestId = reqid ?? makeRequestId();
84
- // Choose which node to use
85
53
  nodeId ??= whoToSendTo(nodes, pendingRequests);
86
54
  const node = nodes && nodeId ? nodes[nodeId] : undefined;
87
55
  const l = createLogger("client", loglevel, nodeIdOrSW(nodeId), requestId);
88
56
  return new Promise((resolve, reject) => {
89
- // Store promise handlers (as well as progress updates handler)
90
- // so the client listener can resolve/reject the promise (and react to progress updates)
91
- // when the server sends messages back
92
57
  pendingRequests.set(requestId, {
93
58
  nodeId,
94
59
  functionName,
@@ -99,14 +64,12 @@ export function Client(procedures, { worker, nodes: nodeCount, loglevel = "debug
99
64
  const transfer = procedures[functionName].autotransfer === "always"
100
65
  ? findTransferables(input)
101
66
  : [];
102
- // Post the message to the server
103
67
  l.debug(`Requesting ${functionName} with`, input);
104
68
  return send(node, nodeId, requestId, { input }, { transfer })
105
69
  .then(() => { })
106
70
  .catch(reject);
107
71
  });
108
72
  };
109
- // @ts-expect-error
110
73
  instance[functionName] = _runProcedure;
111
74
  instance[functionName].broadcast = async (input, onProgresses, nodesCount) => {
112
75
  let nodesToUse = [undefined];
@@ -151,16 +114,11 @@ export function Client(procedures, { worker, nodes: nodeCount, loglevel = "debug
151
114
  }
152
115
  return instance;
153
116
  }
154
- /**
155
- * Warms up the client by starting the listener and getting the worker, then posts a message to the worker.
156
- * @returns the worker to use
157
- */
158
117
  async function postMessage(ctx, message, options) {
159
118
  await startClientListener(ctx);
160
119
  const { logger: l, node: worker } = ctx;
161
120
  if (!worker && !navigator.serviceWorker.controller)
162
121
  l.warn("", "Service Worker is not controlling the page");
163
- // If no worker is provided, we use the service worker
164
122
  const w = worker instanceof SharedWorker
165
123
  ? worker.port
166
124
  : worker === undefined
@@ -171,18 +129,9 @@ async function postMessage(ctx, message, options) {
171
129
  }
172
130
  w.postMessage(message, options);
173
131
  }
174
- /**
175
- * A quicker version of postMessage that does not try to start the client listener, await the service worker, etc.
176
- * esp. useful for abort logic that needs to not be... put behind everything else on the event loop.
177
- * @param l
178
- * @param worker
179
- * @param message
180
- * @param options
181
- */
182
- export function postMessageSync(l, worker, message, options) {
132
+ function postMessageSync(l, worker, message, options) {
183
133
  if (!worker && !navigator.serviceWorker.controller)
184
134
  l.warn("Service Worker is not controlling the page");
185
- // If no worker is provided, we use the service worker
186
135
  const w = worker instanceof SharedWorker
187
136
  ? worker.port
188
137
  : worker === undefined
@@ -193,16 +142,10 @@ export function postMessageSync(l, worker, message, options) {
193
142
  }
194
143
  w.postMessage(message, options);
195
144
  }
196
- /**
197
- * Starts the client listener, which listens for messages from the sw&rpc server.
198
- * @param ctx.worker if provided, the client will use this worker to listen for messages, instead of using the service worker
199
- * @returns
200
- */
201
- export async function startClientListener(ctx) {
145
+ async function startClientListener(ctx) {
202
146
  if (_clientListenerStarted.has(nodeIdOrSW(ctx.nodeId)))
203
147
  return;
204
148
  const { logger: l, node: worker } = ctx;
205
- // Get service worker registration if no worker is provided
206
149
  if (!worker) {
207
150
  const sw = await navigator.serviceWorker.ready;
208
151
  if (!sw?.active) {
@@ -213,33 +156,24 @@ export async function startClientListener(ctx) {
213
156
  }
214
157
  }
215
158
  const w = worker ?? navigator.serviceWorker;
216
- // Start listening for messages
217
159
  l.debug(null, "Starting client listener", { w, ...ctx });
218
160
  const listener = (event) => {
219
- // Get the data from the event
220
161
  const eventData = event.data || {};
221
- // Ignore other messages that aren't for us
222
162
  if (eventData?.by !== "sw&rpc")
223
163
  return;
224
- // We don't use a schema here, we trust the server to send valid data
225
164
  const payload = eventData;
226
- // Ignore #initialize request, it's client->server only
227
165
  if ("isInitializeRequest" in payload) {
228
166
  l.warn(null, "Ignoring unexpected #initialize from server", payload);
229
167
  return;
230
168
  }
231
169
  const { requestId, ...data } = payload;
232
- // Sanity check in case we somehow receive a message without requestId
233
170
  if (!requestId) {
234
171
  throw new Error("[SWARPC Client] Message received without requestId");
235
172
  }
236
- // Get the associated pending request handlers
237
173
  const handlers = pendingRequests.get(requestId);
238
174
  if (!handlers) {
239
175
  throw new Error(`[SWARPC Client] ${requestId} has no active request handlers, cannot process ${JSON.stringify(data)}`);
240
176
  }
241
- // React to the data received: call hook, call handler,
242
- // and remove the request from pendingRequests (unless it's a progress update)
243
177
  if ("error" in data) {
244
178
  ctx.hooks.error?.(data.functionName, new Error(data.error.message));
245
179
  handlers.reject(new Error(data.error.message));
@@ -263,7 +197,6 @@ export async function startClientListener(ctx) {
263
197
  w.addEventListener("message", listener);
264
198
  }
265
199
  _clientListenerStarted.add(nodeIdOrSW(ctx.nodeId));
266
- // Recursive terminal case is ensured by calling this *after* _clientListenerStarted is set to true: startClientListener() will therefore not be called in postMessage() again.
267
200
  await postMessage(ctx, {
268
201
  by: "sw&rpc",
269
202
  functionName: "#initialize",
@@ -272,11 +205,6 @@ export async function startClientListener(ctx) {
272
205
  nodeId: nodeIdOrSW(ctx.nodeId),
273
206
  });
274
207
  }
275
- /**
276
- * Generate a random request ID, used to identify requests between client and server.
277
- * @source
278
- * @returns a 6-character hexadecimal string
279
- */
280
- export function makeRequestId() {
208
+ function makeRequestId() {
281
209
  return Math.random().toString(16).substring(2, 8).toUpperCase();
282
210
  }
package/dist/index.d.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  * @mergeModuleWith <project>
4
4
  */
5
5
  import "./polyfills.js";
6
- export * from "./client.js";
7
- export * from "./server.js";
8
6
  export type { ProceduresMap, CancelablePromise } from "./types.js";
9
- //# sourceMappingURL=index.d.ts.map
7
+ export { Client } from "./client.js";
8
+ export type { SwarpcClient } from "./client.js";
9
+ export { Server } from "./server.js";
10
+ export type { SwarpcServer } from "./server.js";
package/dist/index.js CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * @module
3
- * @mergeModuleWith <project>
4
- */
5
1
  import "./polyfills.js";
6
- export * from "./client.js";
7
- export * from "./server.js";
2
+ export { Client } from "./client.js";
3
+ export { Server } from "./server.js";
@@ -1,14 +1 @@
1
- export declare class FauxLocalStorage {
2
- data: Record<string, any>;
3
- keysOrder: string[];
4
- constructor(data: Record<string, any>);
5
- setItem(key: string, value: string): void;
6
- getItem(key: string): any;
7
- hasItem(key: string): boolean;
8
- removeItem(key: string): void;
9
- clear(): void;
10
- key(index: number): string;
11
- get length(): number;
12
- register(subject: WorkerGlobalScope | SharedWorkerGlobalScope): void;
13
- }
14
- //# sourceMappingURL=localstorage.d.ts.map
1
+ export {};
@@ -33,7 +33,6 @@ export class FauxLocalStorage {
33
33
  return this.keysOrder.length;
34
34
  }
35
35
  register(subject) {
36
- // @ts-expect-error
37
36
  subject.localStorage = this;
38
37
  }
39
38
  }
package/dist/log.d.ts CHANGED
@@ -2,33 +2,4 @@
2
2
  * @module
3
3
  * @mergeModuleWith <project>
4
4
  */
5
- /**
6
- * @ignore
7
- */
8
- export declare function createLogger(side: "server" | "client", level: LogLevel, nid?: string): Logger;
9
- export declare function createLogger(side: "server" | "client", level: LogLevel, nid: string, rqid: string): RequestBoundLogger;
10
- /**
11
- * @ignore
12
- */
13
- export type Logger = {
14
- debug: (rqid: string | null, message: string, ...args: any[]) => void;
15
- info: (rqid: string | null, message: string, ...args: any[]) => void;
16
- warn: (rqid: string | null, message: string, ...args: any[]) => void;
17
- error: (rqid: string | null, message: string, ...args: any[]) => void;
18
- };
19
- export type RequestBoundLogger = {
20
- debug: (message: string, ...args: any[]) => void;
21
- info: (message: string, ...args: any[]) => void;
22
- warn: (message: string, ...args: any[]) => void;
23
- error: (message: string, ...args: any[]) => void;
24
- };
25
- /** @source */
26
- declare const LOG_LEVELS: readonly ["debug", "info", "warn", "error"];
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;
33
5
  export {};
34
- //# sourceMappingURL=log.d.ts.map
package/dist/log.js CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * @module
3
- * @mergeModuleWith <project>
4
- */
5
1
  export function createLogger(side, level = "debug", nid, rqid) {
6
2
  const lvls = LOG_LEVELS.slice(LOG_LEVELS.indexOf(level));
7
3
  if (rqid && nid) {
@@ -20,7 +16,6 @@ export function createLogger(side, level = "debug", nid, rqid) {
20
16
  error: lvls.includes("error") ? logger("error", side, nid) : () => { },
21
17
  };
22
18
  }
23
- /** @source */
24
19
  const LOG_LEVELS = ["debug", "info", "warn", "error"];
25
20
  const PATCHABLE_LOG_METHODS = [
26
21
  "debug",
@@ -40,13 +35,6 @@ const originalConsole = PATCHABLE_LOG_METHODS.reduce((result, method) => {
40
35
  result[method] = console[method];
41
36
  return result;
42
37
  }, {});
43
- /**
44
- * Send log messages to the console, with a helpful prefix.
45
- * @param method
46
- * @param side
47
- * @param ids request ID and node ID
48
- * @param args passed to console methods directly
49
- */
50
38
  function log(method, side, { rqid, nid }, ...args) {
51
39
  const prefix = [
52
40
  `[SWARPC ${side}]`,
@@ -62,12 +50,8 @@ function log(method, side, { rqid, nid }, ...args) {
62
50
  prefixStyles.push("color: hotpink", "color: inherit");
63
51
  return originalConsole[method](prefix, ...prefixStyles, ...args);
64
52
  }
65
- /**
66
- *
67
- * @param scope
68
- */
69
- export function injectIntoConsoleGlobal(scope, nodeId) {
53
+ export function injectIntoConsoleGlobal(scope, nodeId, requestId) {
70
54
  for (const method of PATCHABLE_LOG_METHODS) {
71
- scope.self.console[method] = logger(method, "server", nodeId);
55
+ scope.self.console[method] = (...args) => logger(method, "server", nodeId)(requestId, ...args);
72
56
  }
73
57
  }
package/dist/nodes.d.ts CHANGED
@@ -1,15 +1 @@
1
- import { PendingRequest } from "./client.js";
2
- /**
3
- * Returns to which node to send the next request, given the state of the currently pending requests
4
- */
5
- export declare function whoToSendTo(nodes: undefined | Record<string, unknown>, requests: Map<string, PendingRequest>): undefined | string;
6
- export declare function nodeIdFromScope(scope: WorkerGlobalScope, _scopeType?: "dedicated" | "shared" | "service"): string;
7
- /**
8
- * Generate a random request ID, used to identify nodes in the client
9
- * @source
10
- */
11
- export declare function makeNodeId(): string;
12
- declare const serviceWorkerNodeId: "(SW)";
13
- export declare function nodeIdOrSW(id: string | undefined): string | typeof serviceWorkerNodeId;
14
1
  export {};
15
- //# sourceMappingURL=nodes.d.ts.map
package/dist/nodes.js CHANGED
@@ -1,7 +1,4 @@
1
1
  import { scopeIsDedicated, scopeIsShared } from "./scopes.js";
2
- /**
3
- * Returns to which node to send the next request, given the state of the currently pending requests
4
- */
5
2
  export function whoToSendTo(nodes, requests) {
6
3
  if (!nodes)
7
4
  return undefined;
@@ -14,7 +11,6 @@ export function whoToSendTo(nodes, requests) {
14
11
  for (const [node, reqs] of requestsPerNode.entries()) {
15
12
  if (!node)
16
13
  continue;
17
- // Send to the least busy node
18
14
  if (reqs.length < requestsPerNode.get(chosen).length)
19
15
  chosen = node;
20
16
  }
@@ -27,14 +23,10 @@ export function nodeIdFromScope(scope, _scopeType) {
27
23
  }
28
24
  return "(SW)";
29
25
  }
30
- /**
31
- * Generate a random request ID, used to identify nodes in the client
32
- * @source
33
- */
34
26
  export function makeNodeId() {
35
27
  return "N" + Math.random().toString(16).substring(2, 5).toUpperCase();
36
28
  }
37
- const serviceWorkerNodeId = "(SW)"; // Fixed ID for the service worker, as there's only one
29
+ const serviceWorkerNodeId = "(SW)";
38
30
  export function nodeIdOrSW(id) {
39
31
  return id ?? serviceWorkerNodeId;
40
32
  }
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=polyfills.d.ts.map
package/dist/polyfills.js CHANGED
@@ -1,13 +1,3 @@
1
- /**
2
- * Groups elements from an iterable into a Map based on a callback function.
3
- *
4
- * @template K, T
5
- * @param {Iterable<T>} iterable - The iterable to group.
6
- * @param {function(T, number): K} callbackfn - The callback function to
7
- * determine the grouping key.
8
- * @returns {Map<K, T[]>} A Map where keys are the grouping keys and values are
9
- * arrays of grouped elements.
10
- */
11
1
  Map.groupBy ??= function groupBy(iterable, callbackfn) {
12
2
  const map = new Map();
13
3
  let i = 0;
package/dist/scopes.d.ts CHANGED
@@ -1,4 +1 @@
1
- export declare function scopeIsShared(scope: WorkerGlobalScope, _scopeType?: "dedicated" | "shared" | "service"): scope is SharedWorkerGlobalScope;
2
- export declare function scopeIsDedicated(scope: WorkerGlobalScope, _scopeType?: "dedicated" | "shared" | "service"): scope is DedicatedWorkerGlobalScope;
3
- export declare function scopeIsService(scope: WorkerGlobalScope, _scopeType?: "dedicated" | "shared" | "service"): scope is ServiceWorkerGlobalScope;
4
- //# sourceMappingURL=scopes.d.ts.map
1
+ export {};
package/dist/server.d.ts CHANGED
@@ -21,7 +21,7 @@ export type SwarpcServer<Procedures extends ProceduresMap> = {
21
21
  * @param options various options
22
22
  * @param options.scope The worker scope to use, defaults to the `self` of the file where Server() is called.
23
23
  * @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.
24
- * @param options._scopeType @internal Don't touch, this is used in testing environments because the mock is subpar. Manually overrides worker scope type detection.
24
+ * @param options._scopeType Don't touch, this is used in testing environments because the mock is subpar. Manually overrides worker scope type detection.
25
25
  * @returns a SwarpcServer instance. Each property of the procedures map will be a method, that accepts a function implementing the procedure (see {@link ProcedureImplementation}). There is also .start(), to be called after implementing all procedures.
26
26
  *
27
27
  * An example of defining a server:
@@ -32,4 +32,3 @@ export declare function Server<Procedures extends ProceduresMap>(procedures: Pro
32
32
  loglevel?: LogLevel;
33
33
  _scopeType?: "dedicated" | "shared" | "service";
34
34
  }): SwarpcServer<Procedures>;
35
- //# sourceMappingURL=server.d.ts.map