UNPKG

swarpc

Version:

Full type-safe RPC library for service worker -- move things off of the UI thread with ease!

152 lines (151 loc) 5.69 kB
/** * @module * @mergeModuleWith <project> */ import type { StandardSchemaV1 as Schema } from "./standardschema.js"; /** * A procedure declaration */ export type Procedure<I extends Schema, P extends Schema, S extends Schema> = { /** * ArkType type for the input (first argument) of the procedure, when calling it from the client. */ input: I; /** * ArkType type for the data as the first argument given to the `onProgress` callback * when calling the procedure from the client. */ progress: P; /** * ArkType type for the output (return value) of the procedure, when calling it from the client. */ success: S; /** * When should the procedure automatically add ArrayBuffers and other transferable objects * to the [transfer list](https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/postMessage#transfer) * when sending messages, both from the client to the server and vice versa. * * Transferring objects can improve performance by avoiding copies of large objects, * but _moves_ them to the other context, meaning that they cannot be used in the original context after being sent. * * 'output-only' by default: only transferables sent from the server to the client will be transferred. */ autotransfer?: "always" | "never" | "output-only"; }; /** * A promise that you can cancel by calling `.cancel(reason)` on it: * * ```js * const { request, cancel } = client.runProcedure.cancelable(input, onProgress) * setTimeout(() => cancel("Cancelled by user"), 1000) * const result = await request * ``` */ export type CancelablePromise<T = unknown> = { request: Promise<T>; /** * Abort the request. * @param reason The reason for cancelling the request. */ cancel: (reason: string) => void; }; /** * An implementation of a procedure */ export type ProcedureImplementation<I extends Schema, P extends Schema, S extends Schema> = ( /** * Input data for the procedure */ input: Schema.InferOutput<I>, /** * Callback to call with progress updates. */ onProgress: (progress: Schema.InferInput<P>) => void, /** * Additional tools useful when implementing the procedure. */ tools: { /** * AbortSignal that can be used to handle request cancellation -- see [Make cancellable requests](https://swarpc.js.org/#make-cancelable-requests) */ abortSignal?: AbortSignal; /** * ID of the Node the request is being processed on. */ nodeId: string; }) => Promise<Schema.InferInput<S>>; /** * Declarations of procedures by name. * * An example of declaring procedures: * {@includeCode ../example/src/lib/procedures.ts} */ export type ProceduresMap = Record<string, Procedure<Schema, Schema, Schema>>; type ProcedureNameAndData<Procedures extends ProceduresMap, Key extends "progress" | "success"> = { [K in keyof Procedures]: { procedure: K; data: Schema.InferOutput<Procedures[K][Key]>; }; }[keyof Procedures]; /** * Declaration of hooks to run on messages received from the server */ export type Hooks<Procedures extends ProceduresMap> = { /** * Called when a procedure call has been successful. */ success?: (arg: ProcedureNameAndData<Procedures, "success">) => void; /** * Called when a procedure call has failed. */ error?: (arg: { procedure: keyof Procedures; error: Error; }) => void; /** * Called when a procedure call sends progress updates. */ progress?: (arg: ProcedureNameAndData<Procedures, "progress">) => void; }; export type PayloadCore<PM extends ProceduresMap, Name extends keyof PM = keyof PM> = { input: Schema.InferOutput<PM[Name]["input"]>; } | { progress: Schema.InferOutput<PM[Name]["progress"]>; } | { result: Schema.InferOutput<PM[Name]["success"]>; } | { abort: { reason: string; }; } | { error: { message: string; }; }; /** * 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. */ export type ClientMethod<P extends Procedure<Schema, Schema, Schema>> = ((input: Schema.InferInput<P["input"]>, onProgress?: (progress: Schema.InferOutput<P["progress"]>) => void) => Promise<Schema.InferOutput<P["success"]>>) & { /** * A method that returns a `CancelablePromise`. Cancel it by calling `.cancel(reason)` on it, and wait for the request to resolve by awaiting the `request` property on the returned object. */ cancelable: (input: Schema.InferInput<P["input"]>, onProgress?: (progress: Schema.InferOutput<P["progress"]>) => void, requestId?: string) => CancelablePromise<Schema.InferOutput<P["success"]>>; /** * Send the request to specific nodes, or all nodes. * Returns an array of results, one for each node the request was sent to. * Each result is a {@link PromiseSettledResult}, with also an additional property, the node ID of the request */ broadcast: (input: Schema.InferInput<P["input"]>, onProgress?: ( /** Map of node IDs to their progress updates */ progresses: Map<string, Schema.InferOutput<P["progress"]>>) => void, /** Number of nodes to send the request to. Leave undefined to send to all nodes */ nodes?: number) => Promise<Array<PromiseSettledResult<Schema.InferOutput<P["success"]>> & { node: string; }>>; }; export type WorkerConstructor<T extends Worker | SharedWorker = Worker | SharedWorker> = { new (opts?: { name?: string; }): T; }; export {};