/** * Off-main-thread processing — `audiobox/worker`. * * The most-reported problem with existing JS audio encoders is that they freeze * the page: encoding a few minutes of audio is seconds of solid CPU, and on the * main thread that means a frozen UI and dropped frames. The usual advice is * "put it in a worker yourself", which pushes the whole message-protocol, * transferable-buffer, and cancellation problem onto every application. * * This module does that once. {@link runInWorker} takes an operation, ships the * sample buffers across as transferables (zero-copy, not a structured clone), * reports progress, and supports cancellation. * * ## Transferables * * `postMessage` clones by default — a 100 MB buffer becomes 200 MB and a long * pause. Passing the backing `ArrayBuffer`s in the transfer list moves ownership * instead, which is instant. The cost is that the sender's copy is *detached* * afterwards, so this module always transfers copies it owns, never the * caller's arrays. */ import { UnsupportedRuntimeError } from '../errors.js'; import type { AbortSignalLike } from '../types.js'; /** Work the pool knows how to run. */ export type WorkerOperation = { kind: 'encodeWav'; options?: Record; } | { kind: 'encodeFlac'; options?: Record; } | { kind: 'resample'; targetRate: number; options?: Record; } | { kind: 'normalize'; options?: Record; }; export interface RunOptions { signal?: AbortSignalLike; onProgress?: (progress: number) => void; } /** Detects which worker implementation, if any, this runtime provides. */ export declare function workerSupport(): 'web' | 'node' | 'none'; /** * Runs an operation off the main thread. * * Falls back to running inline when the runtime has no worker implementation, * so calling code does not need two paths. `usedWorker` in the result says which * happened — worth surfacing, because the inline path *does* block. */ export declare function runInWorker(channels: readonly Float32Array[], sampleRate: number, operation: WorkerOperation, options?: RunOptions): Promise<{ result: Uint8Array | Float32Array[]; usedWorker: boolean; }>; /** * Splits work into slices and yields to the event loop between them. * * A pragmatic alternative to a worker when one is not available or not worth * the setup: the work still happens on the main thread, but in chunks short * enough that the browser can paint and handle input between them. The total * time is slightly longer; the page stays responsive. * * @param sliceMs Target milliseconds of work per slice. Defaults to 8 — roughly * half a 60 fps frame, leaving room for rendering. */ export declare function runChunked(items: readonly T[], work: (item: T, index: number) => void, options?: RunOptions & { sliceMs?: number; }): Promise; /** * Message protocol for a worker script, exported so applications can build one * against a stable contract. * * ```js * // my-audio-worker.js * import { handleWorkerMessage } from 'audiobox/worker'; * self.onmessage = (e) => handleWorkerMessage(e.data, self.postMessage.bind(self)); * ``` */ export interface WorkerRequest { id: number; channels: Float32Array[]; sampleRate: number; operation: WorkerOperation; } export interface WorkerResponse { id: number; ok: boolean; result?: Uint8Array | Float32Array[]; error?: { code: string; message: string; }; progress?: number; } /** Runs one request inside a worker and reports the outcome. */ export declare function handleWorkerMessage(request: WorkerRequest, post: (response: WorkerResponse, transfer?: ArrayBuffer[]) => void): Promise; /** Thrown when a runtime lacks the APIs a worker path needs. */ export { UnsupportedRuntimeError }; //# sourceMappingURL=index.d.ts.map