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.

chore: merge cross-worker test files, remove redundant fixtures

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

+59 -102
-12
test/fixtures/shared-struct.ts
··· 1 - import { mo } from 'moroutine'; 2 - import type { SharedStruct, Int32 } from 'moroutine'; 3 - 4 - type Point = SharedStruct<{ x: Int32; y: Int32 }>; 5 - 6 - export const readPoint = mo(import.meta, (point: Point): { x: number; y: number } => { 7 - return point.load(); 8 - }); 9 - 10 - export const writePoint = mo(import.meta, (point: Point, x: number, y: number): void => { 11 - point.store({ x, y }); 12 - });
-83
test/shared/cross-worker-new.test.ts
··· 1 - import { describe, it } from 'node:test'; 2 - import assert from 'node:assert/strict'; 3 - import { workerPool, shared, int32, string, bool, bytes } from 'moroutine'; 4 - import { readValue, writeValue } from '../fixtures/shared-new.ts'; 5 - 6 - describe('new types across workers', () => { 7 - it('struct via shared() works across workers', async () => { 8 - const point = shared({ x: int32, y: int32 }); 9 - point.store({ x: 1, y: 2 }); 10 - 11 - const pool = workerPool(1); 12 - try { 13 - const result = await pool(readValue(point)); 14 - assert.deepEqual(result, { x: 1, y: 2 }); 15 - } finally { 16 - pool[Symbol.dispose](); 17 - } 18 - }); 19 - 20 - it('worker can write to struct via shared()', async () => { 21 - const point = shared({ x: int32, y: int32 }); 22 - 23 - const pool = workerPool(1); 24 - try { 25 - await pool(writeValue(point, { x: 10, y: 20 })); 26 - assert.deepEqual(point.load(), { x: 10, y: 20 }); 27 - } finally { 28 - pool[Symbol.dispose](); 29 - } 30 - }); 31 - 32 - it('tuple via shared() works across workers', async () => { 33 - const t = shared([int32, int32]); 34 - t.store([1, 2]); 35 - 36 - const pool = workerPool(1); 37 - try { 38 - const result = await pool(readValue(t)); 39 - assert.deepEqual(result, [1, 2]); 40 - } finally { 41 - pool[Symbol.dispose](); 42 - } 43 - }); 44 - 45 - it('string via shared() works across workers', async () => { 46 - const s = shared(string(32)); 47 - s.store('hello'); 48 - 49 - const pool = workerPool(1); 50 - try { 51 - const result = await pool(readValue(s)); 52 - assert.equal(result, 'hello'); 53 - } finally { 54 - pool[Symbol.dispose](); 55 - } 56 - }); 57 - 58 - it('bytes via shared() works across workers', async () => { 59 - const b = shared(bytes(4)); 60 - b.store(new Uint8Array([1, 2, 3, 4])); 61 - 62 - const pool = workerPool(1); 63 - try { 64 - const result = await pool(readValue(b)) as Uint8Array; 65 - assert.deepEqual([...result], [1, 2, 3, 4]); 66 - } finally { 67 - pool[Symbol.dispose](); 68 - } 69 - }); 70 - 71 - it('nested struct with string across workers', async () => { 72 - const entity = shared({ name: string(16), hp: int32 }); 73 - entity.store({ name: 'goblin', hp: 50 }); 74 - 75 - const pool = workerPool(1); 76 - try { 77 - const result = await pool(readValue(entity)); 78 - assert.deepEqual(result, { name: 'goblin', hp: 50 }); 79 - } finally { 80 - pool[Symbol.dispose](); 81 - } 82 - }); 83 - });
+59 -7
test/shared/cross-worker.test.ts
··· 1 1 import { describe, it } from 'node:test'; 2 2 import assert from 'node:assert/strict'; 3 - import { workerPool, int32atomic, mutex, rwlock, shared, int32 } from 'moroutine'; 3 + import { workerPool, int32atomic, mutex, rwlock, shared, int32, string, bytes } from 'moroutine'; 4 4 import { atomicAdd, mutexIncrement, rwlockRead } from '../fixtures/sync.ts'; 5 - import { readPoint, writePoint } from '../fixtures/shared-struct.ts'; 5 + import { readValue, writeValue } from '../fixtures/shared-new.ts'; 6 6 7 - describe('sync primitives across workers', () => { 7 + describe('shared primitives across workers', () => { 8 8 it('AtomicInt32 is shared across worker threads', async () => { 9 9 const counter = int32atomic(); 10 10 const pool = workerPool(2); ··· 51 51 } 52 52 }); 53 53 54 - it('SharedStruct is shared across worker threads', async () => { 54 + it('struct via shared() works across workers', async () => { 55 55 const point = shared({ x: int32, y: int32 }); 56 56 point.store({ x: 1, y: 2 }); 57 57 58 58 const pool = workerPool(1); 59 59 try { 60 - const result = await pool(readPoint(point)); 60 + const result = await pool(readValue(point)); 61 61 assert.deepEqual(result, { x: 1, y: 2 }); 62 62 } finally { 63 63 pool[Symbol.dispose](); 64 64 } 65 65 }); 66 66 67 - it('worker can write to SharedStruct', async () => { 67 + it('worker can write to struct via shared()', async () => { 68 68 const point = shared({ x: int32, y: int32 }); 69 69 70 70 const pool = workerPool(1); 71 71 try { 72 - await pool(writePoint(point, 10, 20)); 72 + await pool(writeValue(point, { x: 10, y: 20 })); 73 73 assert.deepEqual(point.load(), { x: 10, y: 20 }); 74 + } finally { 75 + pool[Symbol.dispose](); 76 + } 77 + }); 78 + 79 + it('tuple via shared() works across workers', async () => { 80 + const t = shared([int32, int32]); 81 + t.store([1, 2]); 82 + 83 + const pool = workerPool(1); 84 + try { 85 + const result = await pool(readValue(t)); 86 + assert.deepEqual(result, [1, 2]); 87 + } finally { 88 + pool[Symbol.dispose](); 89 + } 90 + }); 91 + 92 + it('string via shared() works across workers', async () => { 93 + const s = shared(string(32)); 94 + s.store('hello'); 95 + 96 + const pool = workerPool(1); 97 + try { 98 + const result = await pool(readValue(s)); 99 + assert.equal(result, 'hello'); 100 + } finally { 101 + pool[Symbol.dispose](); 102 + } 103 + }); 104 + 105 + it('bytes via shared() works across workers', async () => { 106 + const b = shared(bytes(4)); 107 + b.store(new Uint8Array([1, 2, 3, 4])); 108 + 109 + const pool = workerPool(1); 110 + try { 111 + const result = await pool(readValue(b)) as Uint8Array; 112 + assert.deepEqual([...result], [1, 2, 3, 4]); 113 + } finally { 114 + pool[Symbol.dispose](); 115 + } 116 + }); 117 + 118 + it('nested struct with string across workers', async () => { 119 + const entity = shared({ name: string(16), hp: int32 }); 120 + entity.store({ name: 'goblin', hp: 50 }); 121 + 122 + const pool = workerPool(1); 123 + try { 124 + const result = await pool(readValue(entity)); 125 + assert.deepEqual(result, { name: 'goblin', hp: 50 }); 74 126 } finally { 75 127 pool[Symbol.dispose](); 76 128 }