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.

feat: dedicated worker runner with integration tests

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

+56 -2
+1 -1
package.json
··· 5 5 "exports": "./src/index.ts", 6 6 "packageManager": "pnpm@10.33.0", 7 7 "scripts": { 8 - "test": "node --experimental-strip-types --test test/**/*.test.ts" 8 + "test": "node --experimental-strip-types --test --test-force-exit test/**/*.test.ts" 9 9 } 10 10 }
+21
src/dedicated-runner.ts
··· 1 + import { Worker } from 'node:worker_threads'; 2 + import { setupWorker, execute } from './execute.ts'; 3 + 4 + const workerEntryUrl = new URL('./worker-entry.ts', import.meta.url); 5 + const workers = new Map<string, Worker>(); 6 + 7 + function getWorker(id: string): Worker { 8 + let worker = workers.get(id); 9 + if (!worker) { 10 + worker = new Worker(workerEntryUrl); 11 + worker.unref(); 12 + setupWorker(worker); 13 + workers.set(id, worker); 14 + } 15 + return worker; 16 + } 17 + 18 + export function runOnDedicated<T>(id: string, args: unknown[]): Promise<T> { 19 + const worker = getWorker(id); 20 + return execute<T>(worker, id, args); 21 + }
+3 -1
src/task.ts
··· 1 + import { runOnDedicated } from './dedicated-runner.ts'; 2 + 1 3 export class Task<T> { 2 4 readonly id: string; 3 5 readonly args: unknown[]; ··· 11 13 onfulfilled?: ((value: T) => T1 | PromiseLike<T1>) | null, 12 14 onrejected?: ((reason: any) => T2 | PromiseLike<T2>) | null, 13 15 ): Promise<T1 | T2> { 14 - throw new Error('Not implemented: wire up dedicated runner'); 16 + return runOnDedicated<T>(this.id, this.args).then(onfulfilled, onrejected); 15 17 } 16 18 }
+27
test/dedicated.test.ts
··· 1 + import { describe, it } from 'node:test'; 2 + import assert from 'node:assert/strict'; 3 + import { double, add } from './fixtures/math.ts'; 4 + 5 + describe('dedicated runner', () => { 6 + it('executes a moroutine on a worker thread', async () => { 7 + const result = await double(2); 8 + assert.equal(result, 4); 9 + }); 10 + 11 + it('handles multiple arguments', async () => { 12 + const result = await add(3, 4); 13 + assert.equal(result, 7); 14 + }); 15 + 16 + it('handles sequential calls', async () => { 17 + const a = await double(5); 18 + const b = await double(10); 19 + assert.equal(a, 10); 20 + assert.equal(b, 20); 21 + }); 22 + 23 + it('handles concurrent calls', async () => { 24 + const results = await Promise.all([double(1), double(2), double(3)]); 25 + assert.deepEqual(results, [2, 4, 6]); 26 + }); 27 + });
+4
test/fixtures/math.ts
··· 1 + import { mo } from 'moroutine'; 2 + 3 + export const double = mo(import.meta, (x: number) => 2 * x); 4 + export const add = mo(import.meta, (a: number, b: number) => a + b);