Worker Pool
createWorkerPool() (vue-worker-kit/pool) — for many small, independent tasks (resizing hundreds of images, etc.).
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 tasksignal?: AbortSignal— cancels this taskonProgress?: (value: number) => void— receives this task'sctx.reportProgress()callsonChunk?: (chunk: unknown) => void— receives this task'sctx.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 functionsignal?: AbortSignal— global cancellation signal for all itemsonProgress?: (value: number) => void— one callback shared across every item in the batchonChunk?: (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():
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.