Offload functions to worker threads with shared memory primitives for Node.js.
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: remove --test-force-exit, fix test hangs and unhandled rejections

- Move mo() calls from test files to fixtures (stream-context, stream-pipeline)
- Fix unhandled rejection from track().finally() in worker-pool
- Fix error test to use await using for clean disposal
- Drop --experimental-strip-types (Node 24 native) and --test-force-exit
- Quote test glob so Node expands it (shell ** misses top-level files)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+34 -34
+1 -1
package.json
··· 27 27 "release": "changeset version && changeset tag && git add -A && git commit -m \"chore: version $(node -p \"require('./package.json').version\")\" && git push --follow-tags", 28 28 "lint": "prettier --check .", 29 29 "lint:fix": "prettier --write .", 30 - "test": "node --test --test-force-exit 'test/**/*.test.ts'" 30 + "test": "node --test 'test/**/*.test.ts'" 31 31 }, 32 32 "devDependencies": { 33 33 "@changesets/cli": "^2.30.0",
+1 -1
src/worker-pool.ts
··· 31 31 32 32 function track<T>(promise: Promise<T>): Promise<T> { 33 33 inflight.add(promise); 34 - promise.finally(() => inflight.delete(promise)); 34 + promise.finally(() => inflight.delete(promise)).catch(() => {}); 35 35 return promise; 36 36 } 37 37
+4 -8
test/error.test.ts
··· 11 11 }); 12 12 13 13 it('rejects with error from pool worker', async () => { 14 - const run = workers(1); 15 - try { 16 - await assert.rejects(() => run(fail('pool boom')), { 17 - message: 'pool boom', 18 - }); 19 - } finally { 20 - run[Symbol.dispose](); 21 - } 14 + await using run = workers(1); 15 + await assert.rejects(() => run(fail('pool boom')), { 16 + message: 'pool boom', 17 + }); 22 18 }); 23 19 });
+11
test/fixtures/stream-context.ts
··· 1 + import { mo } from 'moroutine'; 2 + 3 + export const makeMultiplier = mo(import.meta, (factor: number): number => { 4 + return factor; 5 + }); 6 + 7 + export const streamMultiplied = mo(import.meta, async function* (factor: number, count: number) { 8 + for (let i = 0; i < count; i++) { 9 + yield i * factor; 10 + } 11 + });
+13
test/fixtures/stream-pipeline.ts
··· 1 + import { mo } from 'moroutine'; 2 + 3 + export const generate = mo(import.meta, async function* (n: number) { 4 + for (let i = 1; i <= n; i++) yield i; 5 + }); 6 + 7 + export const double = mo(import.meta, async function* (input: AsyncIterable<number>) { 8 + for await (const n of input) yield n * 2; 9 + }); 10 + 11 + export const square = mo(import.meta, async function* (input: AsyncIterable<number>) { 12 + for await (const n of input) yield n * n; 13 + });
+2 -11
test/stream-context.test.ts
··· 1 1 import { describe, it } from 'node:test'; 2 2 import assert from 'node:assert/strict'; 3 - import { mo, workers } from 'moroutine'; 4 - 5 - const makeMultiplier = mo(import.meta, (factor: number): number => { 6 - return factor; 7 - }); 8 - 9 - const streamMultiplied = mo(import.meta, async function* (factor: number, count: number) { 10 - for (let i = 0; i < count; i++) { 11 - yield i * factor; 12 - } 13 - }); 3 + import { workers } from 'moroutine'; 4 + import { makeMultiplier, streamMultiplied } from './fixtures/stream-context.ts'; 14 5 15 6 describe('streaming with task-args', () => { 16 7 it('resolves task-args before streaming', async () => {
+2 -13
test/stream-pipeline.test.ts
··· 1 1 import { describe, it } from 'node:test'; 2 2 import assert from 'node:assert/strict'; 3 - import { mo, channel } from 'moroutine'; 4 - 5 - const generate = mo(import.meta, async function* (n: number) { 6 - for (let i = 1; i <= n; i++) yield i; 7 - }); 8 - 9 - const double = mo(import.meta, async function* (input: AsyncIterable<number>) { 10 - for await (const n of input) yield n * 2; 11 - }); 12 - 13 - const square = mo(import.meta, async function* (input: AsyncIterable<number>) { 14 - for await (const n of input) yield n * n; 15 - }); 3 + import { channel } from 'moroutine'; 4 + import { generate, double, square } from './fixtures/stream-pipeline.ts'; 16 5 17 6 describe('streaming pipeline', () => { 18 7 it('chains two streaming moroutines', async () => {