···11export type { Loadable } from './loadable.ts';
22-export type { Bytes } from './bytes.ts';
33-export { Int8 } from './int8.ts';
44-export { Uint8 } from './uint8.ts';
55-export { Int16 } from './int16.ts';
66-export { Uint16 } from './uint16.ts';
77-export { Int32 } from './int32.ts';
88-export { Uint32 } from './uint32.ts';
99-export { Int64 } from './int64.ts';
1010-export { Uint64 } from './uint64.ts';
1111-export { Bool } from './bool.ts';
1212-export { AtomicBool } from './atomic-bool.ts';
1313-export { AtomicInt8 } from './atomic-int8.ts';
1414-export { AtomicUint8 } from './atomic-uint8.ts';
1515-export { AtomicInt16 } from './atomic-int16.ts';
1616-export { AtomicUint16 } from './atomic-uint16.ts';
1717-export { AtomicInt32 } from './atomic-int32.ts';
1818-export { AtomicUint32 } from './atomic-uint32.ts';
1919-export { AtomicInt64 } from './atomic-int64.ts';
2020-export { AtomicUint64 } from './atomic-uint64.ts';
2121-export { Mutex, MutexGuard } from './mutex.ts';
2222-export { RwLock, ReadGuard, WriteGuard } from './rwlock.ts';
2323-export { slab } from './slab.ts';
2424-export { SharedStruct } from './shared-struct.ts';
2525-export { Tuple } from './tuple.ts';
2626-export { shared } from './shared.ts';
2727-export { string } from './descriptors.ts';
2828-export type { SharedString } from './string.ts';
292export {
303 int8, uint8, int16, uint16, int32, uint32, int64, uint64, bool,
314 int8atomic, uint8atomic, int16atomic, uint16atomic, int32atomic, uint32atomic, int64atomic, uint64atomic, boolatomic,
325 mutex, rwlock,
3333- bytes,
66+ bytes, string,
347} from './descriptors.ts';
358export type { Descriptor, BytesDescriptor, StringDescriptor } from './descriptors.ts';
99+export { shared } from './shared.ts';
1010+export type { Int8 } from './int8.ts';
1111+export type { Uint8 } from './uint8.ts';
1212+export type { Int16 } from './int16.ts';
1313+export type { Uint16 } from './uint16.ts';
1414+export type { Int32 } from './int32.ts';
1515+export type { Uint32 } from './uint32.ts';
1616+export type { Int64 } from './int64.ts';
1717+export type { Uint64 } from './uint64.ts';
1818+export type { Bool } from './bool.ts';
1919+export type { AtomicInt8 } from './atomic-int8.ts';
2020+export type { AtomicUint8 } from './atomic-uint8.ts';
2121+export type { AtomicInt16 } from './atomic-int16.ts';
2222+export type { AtomicUint16 } from './atomic-uint16.ts';
2323+export type { AtomicInt32 } from './atomic-int32.ts';
2424+export type { AtomicUint32 } from './atomic-uint32.ts';
2525+export type { AtomicInt64 } from './atomic-int64.ts';
2626+export type { AtomicUint64 } from './atomic-uint64.ts';
2727+export type { AtomicBool } from './atomic-bool.ts';
2828+export type { Mutex, MutexGuard } from './mutex.ts';
2929+export type { RwLock, ReadGuard, WriteGuard } from './rwlock.ts';
3030+export type { SharedStruct } from './shared-struct.ts';
3131+export type { Bytes } from './bytes.ts';
3232+export type { SharedString } from './string.ts';
3333+export type { Tuple } from './tuple.ts';
+15-22
test/shared/atomic-bool.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicBool } from 'moroutine';
33+import { boolatomic } from 'moroutine';
4455describe('AtomicBool', () => {
66 it('self-allocates and initializes to false', () => {
77- const a = new AtomicBool();
77+ const a = boolatomic();
88 assert.equal(a.load(), false);
99 });
10101111 it('stores and loads true', () => {
1212- const a = new AtomicBool();
1212+ const a = boolatomic();
1313 a.store(true);
1414 assert.equal(a.load(), true);
1515 });
16161717 it('stores and loads false', () => {
1818- const a = new AtomicBool();
1818+ const a = boolatomic();
1919 a.store(true);
2020 a.store(false);
2121 assert.equal(a.load(), false);
2222 });
23232424- it('accepts an external buffer and byteOffset', () => {
2525- const buffer = new SharedArrayBuffer(4);
2626- const a = new AtomicBool(buffer, 2);
2727- a.store(true);
2828- assert.equal(new Uint8Array(buffer)[2], 1);
2929- });
3030-3131- it('exposes static byteSize of 1', () => {
3232- assert.equal(AtomicBool.byteSize, 1);
2424+ it('exposes byteSize of 1', () => {
2525+ assert.equal(boolatomic.byteSize, 1);
3326 });
34273528 it('and(false) clears, returns previous', () => {
3636- const a = new AtomicBool();
2929+ const a = boolatomic();
3730 a.store(true);
3831 assert.equal(a.and(false), true);
3932 assert.equal(a.load(), false);
4033 });
41344235 it('and(true) preserves, returns previous', () => {
4343- const a = new AtomicBool();
3636+ const a = boolatomic();
4437 a.store(true);
4538 assert.equal(a.and(true), true);
4639 assert.equal(a.load(), true);
4740 });
48414942 it('or(true) sets, returns previous', () => {
5050- const a = new AtomicBool();
4343+ const a = boolatomic();
5144 assert.equal(a.or(true), false);
5245 assert.equal(a.load(), true);
5346 });
54475548 it('or(false) preserves, returns previous', () => {
5656- const a = new AtomicBool();
4949+ const a = boolatomic();
5750 a.store(true);
5851 assert.equal(a.or(false), true);
5952 assert.equal(a.load(), true);
6053 });
61546255 it('xor(true) toggles, returns previous', () => {
6363- const a = new AtomicBool();
5656+ const a = boolatomic();
6457 a.store(true);
6558 assert.equal(a.xor(true), true);
6659 assert.equal(a.load(), false);
6760 });
68616962 it('xor(false) preserves, returns previous', () => {
7070- const a = new AtomicBool();
6363+ const a = boolatomic();
7164 a.store(true);
7265 assert.equal(a.xor(false), true);
7366 assert.equal(a.load(), true);
7467 });
75687669 it('exchange returns previous value', () => {
7777- const a = new AtomicBool();
7070+ const a = boolatomic();
7871 a.store(true);
7972 assert.equal(a.exchange(false), true);
8073 assert.equal(a.load(), false);
8174 });
82758376 it('compareExchange succeeds when expected matches', () => {
8484- const a = new AtomicBool();
7777+ const a = boolatomic();
8578 a.store(true);
8679 assert.equal(a.compareExchange(true, false), true);
8780 assert.equal(a.load(), false);
8881 });
89829083 it('compareExchange fails when expected does not match', () => {
9191- const a = new AtomicBool();
8484+ const a = boolatomic();
9285 a.store(true);
9386 assert.equal(a.compareExchange(false, false), true);
9487 assert.equal(a.load(), true);
+13-28
test/shared/atomic-int16.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicInt16 } from 'moroutine';
33+import { int16atomic } from 'moroutine';
4455describe('AtomicInt16', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicInt16();
77+ const a = int16atomic();
88 assert.equal(a.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicInt16();
1212+ const a = int16atomic();
1313 a.store(1000);
1414 assert.equal(a.load(), 1000);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(8);
1919- const a = new AtomicInt16(buffer, 4);
2020- a.store(1000);
2121- const view = new Int16Array(buffer, 4, 1);
2222- assert.equal(view[0], 1000);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(2);
2727- const a = new AtomicInt16(buffer);
2828- a.store(7);
2929- assert.equal(new Int16Array(buffer)[0], 7);
3030- });
3131-3232- it('exposes static byteSize of 2', () => {
3333- assert.equal(AtomicInt16.byteSize, 2);
1717+ it('exposes byteSize of 2', () => {
1818+ assert.equal(int16atomic.byteSize, 2);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicInt16();
2222+ const a = int16atomic();
3823 a.store(10);
3924 const prev = a.add(5);
4025 assert.equal(prev, 10);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicInt16();
3030+ const a = int16atomic();
4631 a.store(10);
4732 const prev = a.sub(3);
4833 assert.equal(prev, 10);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicInt16();
3838+ const a = int16atomic();
5439 a.store(0b1100);
5540 const prev = a.and(0b1010);
5641 assert.equal(prev, 0b1100);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicInt16();
4646+ const a = int16atomic();
6247 a.store(0b1100);
6348 const prev = a.or(0b0011);
6449 assert.equal(prev, 0b1100);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicInt16();
5454+ const a = int16atomic();
7055 a.store(0b1100);
7156 const prev = a.xor(0b1010);
7257 assert.equal(prev, 0b1100);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicInt16();
6262+ const a = int16atomic();
7863 a.store(1000);
7964 const prev = a.exchange(2000);
8065 assert.equal(prev, 1000);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicInt16();
7070+ const a = int16atomic();
8671 a.store(1000);
8772 const actual = a.compareExchange(1000, 2000);
8873 assert.equal(actual, 1000);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicInt16();
7878+ const a = int16atomic();
9479 a.store(1000);
9580 const actual = a.compareExchange(0, 2000);
9681 assert.equal(actual, 1000);
+13-28
test/shared/atomic-int32.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicInt32 } from 'moroutine';
33+import { int32atomic } from 'moroutine';
4455describe('AtomicInt32', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicInt32();
77+ const a = int32atomic();
88 assert.equal(a.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicInt32();
1212+ const a = int32atomic();
1313 a.store(42);
1414 assert.equal(a.load(), 42);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const a = new AtomicInt32(buffer, 4);
2020- a.store(99);
2121- const view = new Int32Array(buffer, 4, 1);
2222- assert.equal(view[0], 99);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(4);
2727- const a = new AtomicInt32(buffer);
2828- a.store(7);
2929- assert.equal(new Int32Array(buffer)[0], 7);
3030- });
3131-3232- it('exposes static byteSize of 4', () => {
3333- assert.equal(AtomicInt32.byteSize, 4);
1717+ it('exposes byteSize of 4', () => {
1818+ assert.equal(int32atomic.byteSize, 4);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicInt32();
2222+ const a = int32atomic();
3823 a.store(10);
3924 const prev = a.add(5);
4025 assert.equal(prev, 10);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicInt32();
3030+ const a = int32atomic();
4631 a.store(10);
4732 const prev = a.sub(3);
4833 assert.equal(prev, 10);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicInt32();
3838+ const a = int32atomic();
5439 a.store(0b1100);
5540 const prev = a.and(0b1010);
5641 assert.equal(prev, 0b1100);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicInt32();
4646+ const a = int32atomic();
6247 a.store(0b1100);
6348 const prev = a.or(0b0011);
6449 assert.equal(prev, 0b1100);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicInt32();
5454+ const a = int32atomic();
7055 a.store(0b1100);
7156 const prev = a.xor(0b1010);
7257 assert.equal(prev, 0b1100);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicInt32();
6262+ const a = int32atomic();
7863 a.store(42);
7964 const prev = a.exchange(99);
8065 assert.equal(prev, 42);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicInt32();
7070+ const a = int32atomic();
8671 a.store(42);
8772 const actual = a.compareExchange(42, 99);
8873 assert.equal(actual, 42);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicInt32();
7878+ const a = int32atomic();
9479 a.store(42);
9580 const actual = a.compareExchange(0, 99);
9681 assert.equal(actual, 42);
+13-28
test/shared/atomic-int64.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicInt64 } from 'moroutine';
33+import { int64atomic } from 'moroutine';
4455describe('AtomicInt64', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicInt64();
77+ const a = int64atomic();
88 assert.equal(a.load(), 0n);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicInt64();
1212+ const a = int64atomic();
1313 a.store(9000000000000n);
1414 assert.equal(a.load(), 9000000000000n);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const a = new AtomicInt64(buffer, 8);
2020- a.store(9000000000000n);
2121- const view = new BigInt64Array(buffer, 8, 1);
2222- assert.equal(view[0], 9000000000000n);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(8);
2727- const a = new AtomicInt64(buffer);
2828- a.store(7n);
2929- assert.equal(new BigInt64Array(buffer)[0], 7n);
3030- });
3131-3232- it('exposes static byteSize of 8', () => {
3333- assert.equal(AtomicInt64.byteSize, 8);
1717+ it('exposes byteSize of 8', () => {
1818+ assert.equal(int64atomic.byteSize, 8);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicInt64();
2222+ const a = int64atomic();
3823 a.store(10n);
3924 const prev = a.add(5n);
4025 assert.equal(prev, 10n);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicInt64();
3030+ const a = int64atomic();
4631 a.store(10n);
4732 const prev = a.sub(3n);
4833 assert.equal(prev, 10n);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicInt64();
3838+ const a = int64atomic();
5439 a.store(0b1100n);
5540 const prev = a.and(0b1010n);
5641 assert.equal(prev, 0b1100n);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicInt64();
4646+ const a = int64atomic();
6247 a.store(0b1100n);
6348 const prev = a.or(0b0011n);
6449 assert.equal(prev, 0b1100n);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicInt64();
5454+ const a = int64atomic();
7055 a.store(0b1100n);
7156 const prev = a.xor(0b1010n);
7257 assert.equal(prev, 0b1100n);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicInt64();
6262+ const a = int64atomic();
7863 a.store(9000000000000n);
7964 const prev = a.exchange(99n);
8065 assert.equal(prev, 9000000000000n);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicInt64();
7070+ const a = int64atomic();
8671 a.store(9000000000000n);
8772 const actual = a.compareExchange(9000000000000n, 99n);
8873 assert.equal(actual, 9000000000000n);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicInt64();
7878+ const a = int64atomic();
9479 a.store(9000000000000n);
9580 const actual = a.compareExchange(0n, 99n);
9681 assert.equal(actual, 9000000000000n);
+13-28
test/shared/atomic-int8.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicInt8 } from 'moroutine';
33+import { int8atomic } from 'moroutine';
4455describe('AtomicInt8', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicInt8();
77+ const a = int8atomic();
88 assert.equal(a.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicInt8();
1212+ const a = int8atomic();
1313 a.store(42);
1414 assert.equal(a.load(), 42);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(8);
1919- const a = new AtomicInt8(buffer, 4);
2020- a.store(42);
2121- const view = new Int8Array(buffer, 4, 1);
2222- assert.equal(view[0], 42);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(1);
2727- const a = new AtomicInt8(buffer);
2828- a.store(7);
2929- assert.equal(new Int8Array(buffer)[0], 7);
3030- });
3131-3232- it('exposes static byteSize of 1', () => {
3333- assert.equal(AtomicInt8.byteSize, 1);
1717+ it('exposes byteSize of 1', () => {
1818+ assert.equal(int8atomic.byteSize, 1);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicInt8();
2222+ const a = int8atomic();
3823 a.store(10);
3924 const prev = a.add(5);
4025 assert.equal(prev, 10);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicInt8();
3030+ const a = int8atomic();
4631 a.store(10);
4732 const prev = a.sub(3);
4833 assert.equal(prev, 10);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicInt8();
3838+ const a = int8atomic();
5439 a.store(0b1100);
5540 const prev = a.and(0b1010);
5641 assert.equal(prev, 0b1100);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicInt8();
4646+ const a = int8atomic();
6247 a.store(0b1100);
6348 const prev = a.or(0b0011);
6449 assert.equal(prev, 0b1100);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicInt8();
5454+ const a = int8atomic();
7055 a.store(0b1100);
7156 const prev = a.xor(0b1010);
7257 assert.equal(prev, 0b1100);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicInt8();
6262+ const a = int8atomic();
7863 a.store(42);
7964 const prev = a.exchange(99);
8065 assert.equal(prev, 42);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicInt8();
7070+ const a = int8atomic();
8671 a.store(42);
8772 const actual = a.compareExchange(42, 99);
8873 assert.equal(actual, 42);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicInt8();
7878+ const a = int8atomic();
9479 a.store(42);
9580 const actual = a.compareExchange(0, 99);
9681 assert.equal(actual, 42);
+13-28
test/shared/atomic-uint16.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicUint16 } from 'moroutine';
33+import { uint16atomic } from 'moroutine';
4455describe('AtomicUint16', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicUint16();
77+ const a = uint16atomic();
88 assert.equal(a.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicUint16();
1212+ const a = uint16atomic();
1313 a.store(50000);
1414 assert.equal(a.load(), 50000);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(8);
1919- const a = new AtomicUint16(buffer, 4);
2020- a.store(50000);
2121- const view = new Uint16Array(buffer, 4, 1);
2222- assert.equal(view[0], 50000);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(2);
2727- const a = new AtomicUint16(buffer);
2828- a.store(7);
2929- assert.equal(new Uint16Array(buffer)[0], 7);
3030- });
3131-3232- it('exposes static byteSize of 2', () => {
3333- assert.equal(AtomicUint16.byteSize, 2);
1717+ it('exposes byteSize of 2', () => {
1818+ assert.equal(uint16atomic.byteSize, 2);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicUint16();
2222+ const a = uint16atomic();
3823 a.store(10);
3924 const prev = a.add(5);
4025 assert.equal(prev, 10);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicUint16();
3030+ const a = uint16atomic();
4631 a.store(10);
4732 const prev = a.sub(3);
4833 assert.equal(prev, 10);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicUint16();
3838+ const a = uint16atomic();
5439 a.store(0b1100);
5540 const prev = a.and(0b1010);
5641 assert.equal(prev, 0b1100);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicUint16();
4646+ const a = uint16atomic();
6247 a.store(0b1100);
6348 const prev = a.or(0b0011);
6449 assert.equal(prev, 0b1100);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicUint16();
5454+ const a = uint16atomic();
7055 a.store(0b1100);
7156 const prev = a.xor(0b1010);
7257 assert.equal(prev, 0b1100);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicUint16();
6262+ const a = uint16atomic();
7863 a.store(50000);
7964 const prev = a.exchange(100);
8065 assert.equal(prev, 50000);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicUint16();
7070+ const a = uint16atomic();
8671 a.store(50000);
8772 const actual = a.compareExchange(50000, 100);
8873 assert.equal(actual, 50000);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicUint16();
7878+ const a = uint16atomic();
9479 a.store(50000);
9580 const actual = a.compareExchange(0, 100);
9681 assert.equal(actual, 50000);
+13-28
test/shared/atomic-uint32.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicUint32 } from 'moroutine';
33+import { uint32atomic } from 'moroutine';
4455describe('AtomicUint32', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicUint32();
77+ const a = uint32atomic();
88 assert.equal(a.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicUint32();
1212+ const a = uint32atomic();
1313 a.store(3000000000);
1414 assert.equal(a.load(), 3000000000);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const a = new AtomicUint32(buffer, 4);
2020- a.store(3000000000);
2121- const view = new Uint32Array(buffer, 4, 1);
2222- assert.equal(view[0], 3000000000);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(4);
2727- const a = new AtomicUint32(buffer);
2828- a.store(7);
2929- assert.equal(new Uint32Array(buffer)[0], 7);
3030- });
3131-3232- it('exposes static byteSize of 4', () => {
3333- assert.equal(AtomicUint32.byteSize, 4);
1717+ it('exposes byteSize of 4', () => {
1818+ assert.equal(uint32atomic.byteSize, 4);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicUint32();
2222+ const a = uint32atomic();
3823 a.store(10);
3924 const prev = a.add(5);
4025 assert.equal(prev, 10);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicUint32();
3030+ const a = uint32atomic();
4631 a.store(10);
4732 const prev = a.sub(3);
4833 assert.equal(prev, 10);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicUint32();
3838+ const a = uint32atomic();
5439 a.store(0b1100);
5540 const prev = a.and(0b1010);
5641 assert.equal(prev, 0b1100);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicUint32();
4646+ const a = uint32atomic();
6247 a.store(0b1100);
6348 const prev = a.or(0b0011);
6449 assert.equal(prev, 0b1100);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicUint32();
5454+ const a = uint32atomic();
7055 a.store(0b1100);
7156 const prev = a.xor(0b1010);
7257 assert.equal(prev, 0b1100);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicUint32();
6262+ const a = uint32atomic();
7863 a.store(3000000000);
7964 const prev = a.exchange(99);
8065 assert.equal(prev, 3000000000);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicUint32();
7070+ const a = uint32atomic();
8671 a.store(3000000000);
8772 const actual = a.compareExchange(3000000000, 99);
8873 assert.equal(actual, 3000000000);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicUint32();
7878+ const a = uint32atomic();
9479 a.store(3000000000);
9580 const actual = a.compareExchange(0, 99);
9681 assert.equal(actual, 3000000000);
+13-28
test/shared/atomic-uint64.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicUint64 } from 'moroutine';
33+import { uint64atomic } from 'moroutine';
4455describe('AtomicUint64', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicUint64();
77+ const a = uint64atomic();
88 assert.equal(a.load(), 0n);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicUint64();
1212+ const a = uint64atomic();
1313 a.store(18000000000000000000n);
1414 assert.equal(a.load(), 18000000000000000000n);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const a = new AtomicUint64(buffer, 8);
2020- a.store(18000000000000000000n);
2121- const view = new BigUint64Array(buffer, 8, 1);
2222- assert.equal(view[0], 18000000000000000000n);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(8);
2727- const a = new AtomicUint64(buffer);
2828- a.store(7n);
2929- assert.equal(new BigUint64Array(buffer)[0], 7n);
3030- });
3131-3232- it('exposes static byteSize of 8', () => {
3333- assert.equal(AtomicUint64.byteSize, 8);
1717+ it('exposes byteSize of 8', () => {
1818+ assert.equal(uint64atomic.byteSize, 8);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicUint64();
2222+ const a = uint64atomic();
3823 a.store(10n);
3924 const prev = a.add(5n);
4025 assert.equal(prev, 10n);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicUint64();
3030+ const a = uint64atomic();
4631 a.store(10n);
4732 const prev = a.sub(3n);
4833 assert.equal(prev, 10n);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicUint64();
3838+ const a = uint64atomic();
5439 a.store(0b1100n);
5540 const prev = a.and(0b1010n);
5641 assert.equal(prev, 0b1100n);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicUint64();
4646+ const a = uint64atomic();
6247 a.store(0b1100n);
6348 const prev = a.or(0b0011n);
6449 assert.equal(prev, 0b1100n);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicUint64();
5454+ const a = uint64atomic();
7055 a.store(0b1100n);
7156 const prev = a.xor(0b1010n);
7257 assert.equal(prev, 0b1100n);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicUint64();
6262+ const a = uint64atomic();
7863 a.store(18000000000000000000n);
7964 const prev = a.exchange(99n);
8065 assert.equal(prev, 18000000000000000000n);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicUint64();
7070+ const a = uint64atomic();
8671 a.store(18000000000000000000n);
8772 const actual = a.compareExchange(18000000000000000000n, 99n);
8873 assert.equal(actual, 18000000000000000000n);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicUint64();
7878+ const a = uint64atomic();
9479 a.store(18000000000000000000n);
9580 const actual = a.compareExchange(0n, 99n);
9681 assert.equal(actual, 18000000000000000000n);
+13-28
test/shared/atomic-uint8.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { AtomicUint8 } from 'moroutine';
33+import { uint8atomic } from 'moroutine';
4455describe('AtomicUint8', () => {
66 it('self-allocates and initializes to zero', () => {
77- const a = new AtomicUint8();
77+ const a = uint8atomic();
88 assert.equal(a.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const a = new AtomicUint8();
1212+ const a = uint8atomic();
1313 a.store(200);
1414 assert.equal(a.load(), 200);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(8);
1919- const a = new AtomicUint8(buffer, 4);
2020- a.store(200);
2121- const view = new Uint8Array(buffer, 4, 1);
2222- assert.equal(view[0], 200);
2323- });
2424-2525- it('defaults byteOffset to 0', () => {
2626- const buffer = new SharedArrayBuffer(1);
2727- const a = new AtomicUint8(buffer);
2828- a.store(7);
2929- assert.equal(new Uint8Array(buffer)[0], 7);
3030- });
3131-3232- it('exposes static byteSize of 1', () => {
3333- assert.equal(AtomicUint8.byteSize, 1);
1717+ it('exposes byteSize of 1', () => {
1818+ assert.equal(uint8atomic.byteSize, 1);
3419 });
35203621 it('add returns previous value and updates', () => {
3737- const a = new AtomicUint8();
2222+ const a = uint8atomic();
3823 a.store(10);
3924 const prev = a.add(5);
4025 assert.equal(prev, 10);
···4227 });
43284429 it('sub returns previous value and updates', () => {
4545- const a = new AtomicUint8();
3030+ const a = uint8atomic();
4631 a.store(10);
4732 const prev = a.sub(3);
4833 assert.equal(prev, 10);
···5035 });
51365237 it('and returns previous value and updates', () => {
5353- const a = new AtomicUint8();
3838+ const a = uint8atomic();
5439 a.store(0b1100);
5540 const prev = a.and(0b1010);
5641 assert.equal(prev, 0b1100);
···5843 });
59446045 it('or returns previous value and updates', () => {
6161- const a = new AtomicUint8();
4646+ const a = uint8atomic();
6247 a.store(0b1100);
6348 const prev = a.or(0b0011);
6449 assert.equal(prev, 0b1100);
···6651 });
67526853 it('xor returns previous value and updates', () => {
6969- const a = new AtomicUint8();
5454+ const a = uint8atomic();
7055 a.store(0b1100);
7156 const prev = a.xor(0b1010);
7257 assert.equal(prev, 0b1100);
···7459 });
75607661 it('exchange returns previous value and sets new', () => {
7777- const a = new AtomicUint8();
6262+ const a = uint8atomic();
7863 a.store(200);
7964 const prev = a.exchange(100);
8065 assert.equal(prev, 200);
···8267 });
83688469 it('compareExchange succeeds when expected matches', () => {
8585- const a = new AtomicUint8();
7070+ const a = uint8atomic();
8671 a.store(200);
8772 const actual = a.compareExchange(200, 100);
8873 assert.equal(actual, 200);
···9075 });
91769277 it('compareExchange fails when expected does not match', () => {
9393- const a = new AtomicUint8();
7878+ const a = uint8atomic();
9479 a.store(200);
9580 const actual = a.compareExchange(0, 100);
9681 assert.equal(actual, 200);
+9-23
test/shared/bool.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { Bool } from 'moroutine';
33+import { bool } from 'moroutine';
4455describe('Bool', () => {
66 it('self-allocates and initializes to false', () => {
77- const v = new Bool();
77+ const v = bool();
88 assert.equal(v.load(), false);
99 });
10101111 it('stores and loads true', () => {
1212- const v = new Bool();
1212+ const v = bool();
1313 v.store(true);
1414 assert.equal(v.load(), true);
1515 });
16161717 it('stores and loads false', () => {
1818- const v = new Bool();
1818+ const v = bool();
1919 v.store(true);
2020 v.store(false);
2121 assert.equal(v.load(), false);
2222 });
23232424 it('round-trips true/false', () => {
2525- const v = new Bool();
2525+ const v = bool();
2626 v.store(true);
2727 assert.equal(v.load(), true);
2828 v.store(false);
2929 assert.equal(v.load(), false);
3030 });
31313232- it('accepts an external buffer and byteOffset', () => {
3333- const buffer = new SharedArrayBuffer(8);
3434- const v = new Bool(buffer, 1);
3535- v.store(true);
3636- assert.equal(new Uint8Array(buffer, 1, 1)[0], 1);
3737- });
3838-3939- it('defaults byteOffset to 0', () => {
4040- const buffer = new SharedArrayBuffer(1);
4141- const v = new Bool(buffer);
4242- v.store(true);
4343- assert.equal(new Uint8Array(buffer)[0], 1);
4444- });
4545-4646- it('exposes static byteSize of 1', () => {
4747- assert.equal(Bool.byteSize, 1);
3232+ it('exposes byteSize of 1', () => {
3333+ assert.equal(bool.byteSize, 1);
4834 });
49355050- it('exposes static byteAlignment of 1', () => {
5151- assert.equal(Bool.byteAlignment, 1);
3636+ it('exposes byteAlignment of 1', () => {
3737+ assert.equal(bool.byteAlignment, 1);
5238 });
5339});
+12-14
test/shared/cross-worker.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { workerPool, AtomicInt32, Mutex, RwLock, SharedStruct, Int32, slab } from 'moroutine';
33+import { workerPool, int32atomic, mutex, rwlock, shared, int32 } from 'moroutine';
44import { atomicAdd, mutexIncrement, rwlockRead } from '../fixtures/sync.ts';
55import { readPoint, writePoint } from '../fixtures/shared-struct.ts';
6677describe('sync primitives across workers', () => {
88 it('AtomicInt32 is shared across worker threads', async () => {
99- const counter = new AtomicInt32();
99+ const counter = int32atomic();
1010 const pool = workerPool(2);
1111 try {
1212 await Promise.all([
···2020 });
21212222 it('Mutex serializes access across workers', async () => {
2323- const mutex = new Mutex();
2424- const counter = new AtomicInt32();
2323+ const m = mutex();
2424+ const counter = int32atomic();
2525 const pool = workerPool(2);
2626 try {
2727 await Promise.all([
2828- pool(mutexIncrement(mutex, counter, 100)),
2929- pool(mutexIncrement(mutex, counter, 100)),
2828+ pool(mutexIncrement(m, counter, 100)),
2929+ pool(mutexIncrement(m, counter, 100)),
3030 ]);
3131 assert.equal(counter.load(), 200);
3232 } finally {
···3535 });
36363737 it('RwLock allows concurrent reads from workers', async () => {
3838- const rwlock = new RwLock();
3939- const counter = new AtomicInt32();
3838+ const rw = rwlock();
3939+ const counter = int32atomic();
4040 counter.store(42);
4141 const pool = workerPool(2);
4242 try {
4343 const [a, b] = await Promise.all([
4444- pool(rwlockRead(rwlock, counter)),
4545- pool(rwlockRead(rwlock, counter)),
4444+ pool(rwlockRead(rw, counter)),
4545+ pool(rwlockRead(rw, counter)),
4646 ]);
4747 assert.equal(a, 42);
4848 assert.equal(b, 42);
···5252 });
53535454 it('SharedStruct is shared across worker threads', async () => {
5555- const [x, y] = slab(Int32, Int32);
5656- const point = new SharedStruct({ x, y });
5555+ const point = shared({ x: int32, y: int32 });
5756 point.store({ x: 1, y: 2 });
58575958 const pool = workerPool(1);
···6665 });
67666867 it('worker can write to SharedStruct', async () => {
6969- const [x, y] = slab(Int32, Int32);
7070- const point = new SharedStruct({ x, y });
6868+ const point = shared({ x: int32, y: int32 });
71697270 const pool = workerPool(1);
7371 try {
+7-21
test/shared/int16.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { Int16 } from 'moroutine';
33+import { int16 } from 'moroutine';
4455describe('Int16', () => {
66 it('self-allocates and initializes to zero', () => {
77- const v = new Int16();
77+ const v = int16();
88 assert.equal(v.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const v = new Int16();
1212+ const v = int16();
1313 v.store(42);
1414 assert.equal(v.load(), 42);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const v = new Int16(buffer, 2);
2020- v.store(99);
2121- assert.equal(new Int16Array(buffer, 2, 1)[0], 99);
2222- });
2323-2424- it('defaults byteOffset to 0', () => {
2525- const buffer = new SharedArrayBuffer(2);
2626- const v = new Int16(buffer);
2727- v.store(7);
2828- assert.equal(new Int16Array(buffer)[0], 7);
2929- });
3030-3131- it('exposes static byteSize of 2', () => {
3232- assert.equal(Int16.byteSize, 2);
1717+ it('exposes byteSize of 2', () => {
1818+ assert.equal(int16.byteSize, 2);
3319 });
34203535- it('exposes static byteAlignment of 2', () => {
3636- assert.equal(Int16.byteAlignment, 2);
2121+ it('exposes byteAlignment of 2', () => {
2222+ assert.equal(int16.byteAlignment, 2);
3723 });
3824});
+7-29
test/shared/int32.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { Int32 } from 'moroutine';
33+import { int32 } from 'moroutine';
4455describe('Int32', () => {
66 it('self-allocates and initializes to zero', () => {
77- const v = new Int32();
77+ const v = int32();
88 assert.equal(v.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const v = new Int32();
1212+ const v = int32();
1313 v.store(42);
1414 assert.equal(v.load(), 42);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const v = new Int32(buffer, 4);
2020- v.store(99);
2121- assert.equal(new Int32Array(buffer, 4, 1)[0], 99);
2222- });
2323-2424- it('defaults byteOffset to 0', () => {
2525- const buffer = new SharedArrayBuffer(4);
2626- const v = new Int32(buffer);
2727- v.store(7);
2828- assert.equal(new Int32Array(buffer)[0], 7);
2929- });
3030-3131- it('exposes static byteSize of 4', () => {
3232- assert.equal(Int32.byteSize, 4);
3333- });
3434-3535- it('exposes static byteAlignment of 4', () => {
3636- assert.equal(Int32.byteAlignment, 4);
1717+ it('exposes byteSize of 4', () => {
1818+ assert.equal(int32.byteSize, 4);
3719 });
38203939- it('does not use Atomics (plain read/write)', () => {
4040- const buffer = new SharedArrayBuffer(4);
4141- const v = new Int32(buffer);
4242- v.store(123);
4343- const raw = new Int32Array(buffer);
4444- assert.equal(raw[0], 123);
2121+ it('exposes byteAlignment of 4', () => {
2222+ assert.equal(int32.byteAlignment, 4);
4523 });
4624});
+7-21
test/shared/int64.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { Int64 } from 'moroutine';
33+import { int64 } from 'moroutine';
4455describe('Int64', () => {
66 it('self-allocates and initializes to zero', () => {
77- const v = new Int64();
77+ const v = int64();
88 assert.equal(v.load(), 0n);
99 });
10101111 it('stores and loads a value', () => {
1212- const v = new Int64();
1212+ const v = int64();
1313 v.store(99n);
1414 assert.equal(v.load(), 99n);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(16);
1919- const v = new Int64(buffer, 8);
2020- v.store(42n);
2121- assert.equal(new BigInt64Array(buffer, 8, 1)[0], 42n);
2222- });
2323-2424- it('defaults byteOffset to 0', () => {
2525- const buffer = new SharedArrayBuffer(8);
2626- const v = new Int64(buffer);
2727- v.store(7n);
2828- assert.equal(new BigInt64Array(buffer)[0], 7n);
2929- });
3030-3131- it('exposes static byteSize of 8', () => {
3232- assert.equal(Int64.byteSize, 8);
1717+ it('exposes byteSize of 8', () => {
1818+ assert.equal(int64.byteSize, 8);
3319 });
34203535- it('exposes static byteAlignment of 8', () => {
3636- assert.equal(Int64.byteAlignment, 8);
2121+ it('exposes byteAlignment of 8', () => {
2222+ assert.equal(int64.byteAlignment, 8);
3723 });
3824});
+7-21
test/shared/int8.test.ts
···11import { describe, it } from 'node:test';
22import assert from 'node:assert/strict';
33-import { Int8 } from 'moroutine';
33+import { int8 } from 'moroutine';
4455describe('Int8', () => {
66 it('self-allocates and initializes to zero', () => {
77- const v = new Int8();
77+ const v = int8();
88 assert.equal(v.load(), 0);
99 });
10101111 it('stores and loads a value', () => {
1212- const v = new Int8();
1212+ const v = int8();
1313 v.store(42);
1414 assert.equal(v.load(), 42);
1515 });
16161717- it('accepts an external buffer and byteOffset', () => {
1818- const buffer = new SharedArrayBuffer(8);
1919- const v = new Int8(buffer, 1);
2020- v.store(99);
2121- assert.equal(new Int8Array(buffer, 1, 1)[0], 99);
2222- });
2323-2424- it('defaults byteOffset to 0', () => {
2525- const buffer = new SharedArrayBuffer(1);
2626- const v = new Int8(buffer);
2727- v.store(7);
2828- assert.equal(new Int8Array(buffer)[0], 7);
2929- });
3030-3131- it('exposes static byteSize of 1', () => {
3232- assert.equal(Int8.byteSize, 1);
1717+ it('exposes byteSize of 1', () => {
1818+ assert.equal(int8.byteSize, 1);
3319 });
34203535- it('exposes static byteAlignment of 1', () => {
3636- assert.equal(Int8.byteAlignment, 1);
2121+ it('exposes byteAlignment of 1', () => {
2222+ assert.equal(int8.byteAlignment, 1);
3723 });
3824});