···66export type { ChannelOptions } from './channel.ts';
77export { workers } from './worker-pool.ts';
88export { transfer } from './transfer.ts';
99-export type { Runner, WorkerOptions } from './runner.ts';
99+export type { Runner, WorkerHandle, WorkerOptions } from './runner.ts';
1010export {
1111 shared,
1212 int8,
+10
src/runner.ts
···1010 shutdownTimeout?: number;
1111}
12121313+/** A handle to a specific worker in a pool. */
1414+export interface WorkerHandle {
1515+ /** Dispatches a task pinned to this worker. */
1616+ exec<T>(task: Task<T>): Promise<T>;
1717+ /** Dispatches a streaming task pinned to this worker. */
1818+ exec<T>(task: StreamTask<T>, opts?: ChannelOptions): AsyncIterable<T>;
1919+}
2020+1321/**
1422 * A callable that dispatches tasks to a worker pool. Disposable via `using` or `[Symbol.dispose]()`.
1523 *
···2533 <T>(task: StreamTask<T>, opts?: ChannelOptions): AsyncIterable<T>;
2634 /** AbortSignal that fires when the pool starts disposing. */
2735 readonly signal: AbortSignal;
3636+ /** Read-only array of worker handles, one per pool worker. */
3737+ readonly workers: readonly WorkerHandle[];
2838 /** Terminates all workers immediately. */
2939 [Symbol.dispose](): void;
3040 /** Aborts signal, waits for in-flight tasks to settle, then terminates workers. */
+21-1
src/worker-pool.ts
···55import type { Task } from './task.ts';
66import { StreamTask } from './stream-task.ts';
77import type { ChannelOptions } from './channel.ts';
88-import type { Runner, WorkerOptions } from './runner.ts';
88+import type { Runner, WorkerHandle, WorkerOptions } from './runner.ts';
991010const workerEntryUrl = new URL('./worker-entry.ts', import.meta.url);
1111···4949 return track(execute<T>(worker, task.id, task.args));
5050 }
51515252+ function makeWorkerHandle(worker: Worker): WorkerHandle {
5353+ return {
5454+ exec<T>(task: Task<T> | StreamTask<T>, opts?: ChannelOptions): any {
5555+ if (task instanceof StreamTask) {
5656+ if (disposed) throw new Error('Worker pool is disposed');
5757+ const { iterable, done } = dispatchStream(worker, task.id, task.args, opts);
5858+ track(done);
5959+ return iterable;
6060+ }
6161+ if (disposed) return Promise.reject(new Error('Worker pool is disposed'));
6262+ return track(execute<T>(worker, task.id, task.args));
6363+ },
6464+ };
6565+ }
6666+6767+ const workerHandles: readonly WorkerHandle[] = pool.map(makeWorkerHandle);
6868+5269 const run: Runner = Object.assign(
5370 (taskOrTasks: Task<any> | Task<any>[] | StreamTask<any>, channelOpts?: ChannelOptions): any => {
5471 if (taskOrTasks instanceof StreamTask) {
···6784 {
6885 get signal() {
6986 return ac.signal;
8787+ },
8888+ get workers() {
8989+ return workerHandles;
7090 },
7191 [Symbol.dispose]() {
7292 disposed = true;