Skip to content

Worker Pool ​

createWorkerPool() (vue-worker-kit/pool) — for many small, independent tasks (resizing hundreds of images, etc.).

ts
import { createWorkerPool } from 'vue-worker-kit/pool'

const pool = createWorkerPool<typeof import('./resize.worker')>(
  () => new Worker(new URL('./resize.worker.ts', import.meta.url), { type: 'module' }),
)

// Pre-create all workers up to size (optional, avoids cold-start latency on first tasks)
await pool.warmup()

// Process array with per-item transfer and global cancellation signal
const thumbnails = await pool.map(files, {
  concurrency: 4,
  transfer: (file) => [file.buffer], // zero-copy per item
  signal: abortController.signal, // cancel all running tasks
})

const one = await pool.run(files[0])

Workers are created lazily, up to size, as tasks arrive — not all at once. size (option) defaults to navigator.hardwareConcurrency — the browser's own count of logical cores/threads on the machine actually running your app, not a number picked at development time. Pass size explicitly to override it (e.g. to cap it, or if navigator reports something you don't want to trust — some privacy-hardened browsers cap or round it). Falls back to 4 where navigator doesn't exist (SSR).

Methods ​

pool.run(input, options?) ​

(input: In, options?: RunOptions) => Promise<Out>

Queues the task on the first free worker.

  • transfer?: Transferable[] — zero-copy transfer list for this task
  • signal?: AbortSignal — cancels this task
  • onProgress?: (value: number) => void — receives this task's ctx.reportProgress() calls
  • onChunk?: (chunk: unknown) => void — receives this task's ctx.reportChunk() calls

pool.map(items, options?) ​

(items: In[], options?: MapOptions) => Promise<Out[]>

Processes an array with bounded parallelism, results in input order.

  • concurrency?: number — max parallel tasks (default: pool.size)
  • transfer?: (item: T) => Transferable[] — per-item zero-copy transfer function
  • signal?: AbortSignal — global cancellation signal for all items
  • onProgress?: (value: number) => void — one callback shared across every item in the batch
  • onChunk?: (chunk: unknown) => void — one callback shared across every item in the batch

Progress and chunk reporting ​

Unlike useWorker()/useSharedWorker(), the pool has no persistent progress/chunks ref — many tasks can be running across different slots at once, so there's no single value to expose. Instead, pass onProgress/onChunk directly to pool.run() or pool.map():

ts
await pool.run(input, {
  onProgress: (value) => console.log('progress', value),
  onChunk: (chunk) => console.log('chunk', chunk),
})

await pool.map(items, {
  onProgress: (value) => console.log('progress', value), // fires for whichever item is reporting
  onChunk: (chunk) => console.log('chunk', chunk),
})

For map(), the same onProgress/onChunk pair is shared across the whole batch — there's no per-item callback, so if you need to know which item a given progress value or chunk belongs to, include that information in the value/chunk itself (e.g. have the worker handler embed the input or an id in what it reports).

A handler written for useWorker()/useSharedWorker() that calls ctx.reportProgress()/ctx.reportChunk() works unchanged under a pool — it doesn't know which composable is driving it — but those calls are only observable if you pass onProgress/onChunk in RunOptions/MapOptions; otherwise they're dropped (see Streaming / Chunked Results for the dev-mode warning that fires in that case).

pool.stats ​

ComputedRef<{ busy: number; idle: number; queued: number }>

Reactive, used by the devtools panel.

pool.terminate() ​

() => void

Kills the whole pool.

pool.warmup() ​

() => Promise<void>

Pre-creates all workers up to size without executing tasks.

Vue Composable Variant ​

useWorkerPool()

The same API as createWorkerPool(), with onScopeDispose auto-termination for use directly in setup() — reach for this one instead of createWorkerPool() whenever the pool's lifetime should match the component's.