moroutine#
1.0.0#
Major Changes#
- e46aca0: Unify Task and StreamTask under a single
Task<T>typeTask<T>isPromiseLike<T>for value tasks,AsyncIterable<T>for streaming tasks, or just the base dispatch shape when unparameterizedBalancer.select()receivesTaskinstead ofTask<any> | StreamTask<any>Arg<T>simplifies toT | Task<T>- Classes renamed to
PromiseLikeTask<T>andAsyncIterableTask<T>(internal, preferTask<T>in type annotations)
Minor Changes#
-
9ab6016: Graceful async worker pool shutdown
await using run = workers(4)waits for in-flight tasks to settle before terminating workersrun.signalis anAbortSignalthat fires when the pool starts disposing — thread it into tasks for cooperative cancellationworkers(size, { shutdownTimeout: ms })force-terminates workers if graceful shutdown exceeds the timeout- Existing
using run(sync dispose) still terminates immediately
-
3612d52: Include main-thread call site in error stack traces
Errors thrown during task dispatch now have stack traces that show where
run(),exec(), orawait taskwas called. The original worker-side error is preserved aserr.causewith its own stack pointing to the moroutine source.Error: boom at trackValue (worker-pool.ts:52:15) at async loadUser (user-code.ts:7:3) at async main (user-code.ts:11:3) { [cause]: Error: boom at fixtures/math.ts:6:9 // original throw site on the worker at MessagePort.<anonymous> (worker-entry.ts:173:25) }Built-in error subclass identity (
TypeError,RangeError, etc.) is preserved on the outer wrapper. -
5137201: Preserve error details across worker boundary
Errors thrown in moroutines now transfer with
message,stack,cause, and built-in subclass identity (TypeError,RangeError, etc.) preserved via structured clone. Previously only the message string was kept. -
d13cd40: Configurable load balancing for worker pools
workers(size, { balance: leastBusy() })routes tasks to the worker with the fewest in-flight tasksroundRobin()cycles through workers in order (default, same as before)- Custom balancers implement
Balancer.select(workers, task)for full control over scheduling
-
cdccfdb: Per-worker dispatch with
assign()andrun.workersrun.workersexposes a read-only array ofWorkerHandles, one per pool workerassign(worker, task)returns a copy of the task pinned to a specific workerworker.exec(task)dispatches directly to a specific worker- Channel fan-out no longer requires knowing the worker count
Patch Changes#
-
e2dabc1: Fix pool workers exiting early with top-level await
Pool workers are now ref'd for the lifetime of the pool, preventing the Node.js event loop from exiting prematurely when using
using run = workers()with top-levelawait. Dedicated workers continue to ref only while tasks are in-flight.
0.1.1#
Patch Changes#
-
5068c96: Auto-detect and transfer AbortSignal arguments to workers
AbortSignal args are automatically detected, marked transferable via
util.transferableAbortSignal(), and transferred to the worker. Works with regular tasks, streaming moroutines, and dedicated workers.
0.1.0#
Minor Changes#
- b6d4275: Initial version of moroutine: offload functions to worker threads with shared memory primitives for Node.js.