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.

at e46aca05dbf9a2204886d23f7ae3b34883f4e5c6 174 lines 5.9 kB view raw
1import { Bytes } from './bytes.ts'; 2import { SharedString } from './string.ts'; 3import { Int8 } from './int8.ts'; 4import { Uint8 } from './uint8.ts'; 5import { Int16 } from './int16.ts'; 6import { Uint16 } from './uint16.ts'; 7import { Int32 } from './int32.ts'; 8import { Uint32 } from './uint32.ts'; 9import { Int64 } from './int64.ts'; 10import { Uint64 } from './uint64.ts'; 11import { Bool } from './bool.ts'; 12import { Int8Atomic } from './int8-atomic.ts'; 13import { Uint8Atomic } from './uint8-atomic.ts'; 14import { Int16Atomic } from './int16-atomic.ts'; 15import { Uint16Atomic } from './uint16-atomic.ts'; 16import { Int32Atomic } from './int32-atomic.ts'; 17import { Uint32Atomic } from './uint32-atomic.ts'; 18import { Int64Atomic } from './int64-atomic.ts'; 19import { Uint64Atomic } from './uint64-atomic.ts'; 20import { BoolAtomic } from './bool-atomic.ts'; 21import { Mutex } from './mutex.ts'; 22import { RwLock } from './rwlock.ts'; 23 24/** A schema token describing a shared-memory type. Callable to create a standalone instance. */ 25export interface Descriptor<T> { 26 (): T; 27 byteSize: number; 28 byteAlignment: number; 29 _class: new (buffer: SharedArrayBuffer, byteOffset: number) => T; 30} 31 32function makeDescriptor<T>( 33 factory: () => T, 34 byteSize: number, 35 byteAlignment: number, 36 _class: new (buffer: SharedArrayBuffer, byteOffset: number) => T, 37): Descriptor<T> { 38 return Object.assign(factory, { byteSize, byteAlignment, _class }); 39} 40 41/** Non-atomic shared primitives. Use inside a lock for thread safety. */ 42export const int8: Descriptor<Int8> = makeDescriptor(() => new Int8(), Int8.byteSize, Int8.byteAlignment, Int8); 43export const uint8: Descriptor<Uint8> = makeDescriptor(() => new Uint8(), Uint8.byteSize, Uint8.byteAlignment, Uint8); 44export const int16: Descriptor<Int16> = makeDescriptor(() => new Int16(), Int16.byteSize, Int16.byteAlignment, Int16); 45export const uint16: Descriptor<Uint16> = makeDescriptor( 46 () => new Uint16(), 47 Uint16.byteSize, 48 Uint16.byteAlignment, 49 Uint16, 50); 51export const int32: Descriptor<Int32> = makeDescriptor(() => new Int32(), Int32.byteSize, Int32.byteAlignment, Int32); 52export const uint32: Descriptor<Uint32> = makeDescriptor( 53 () => new Uint32(), 54 Uint32.byteSize, 55 Uint32.byteAlignment, 56 Uint32, 57); 58export const int64: Descriptor<Int64> = makeDescriptor(() => new Int64(), Int64.byteSize, Int64.byteAlignment, Int64); 59export const uint64: Descriptor<Uint64> = makeDescriptor( 60 () => new Uint64(), 61 Uint64.byteSize, 62 Uint64.byteAlignment, 63 Uint64, 64); 65export const bool: Descriptor<Bool> = makeDescriptor(() => new Bool(), Bool.byteSize, Bool.byteAlignment, Bool); 66 67/** Atomic shared primitives. Thread-safe without a lock. */ 68export const int8atomic: Descriptor<Int8Atomic> = makeDescriptor( 69 () => new Int8Atomic(), 70 Int8Atomic.byteSize, 71 Int8Atomic.byteAlignment, 72 Int8Atomic, 73); 74export const uint8atomic: Descriptor<Uint8Atomic> = makeDescriptor( 75 () => new Uint8Atomic(), 76 Uint8Atomic.byteSize, 77 Uint8Atomic.byteAlignment, 78 Uint8Atomic, 79); 80export const int16atomic: Descriptor<Int16Atomic> = makeDescriptor( 81 () => new Int16Atomic(), 82 Int16Atomic.byteSize, 83 Int16Atomic.byteAlignment, 84 Int16Atomic, 85); 86export const uint16atomic: Descriptor<Uint16Atomic> = makeDescriptor( 87 () => new Uint16Atomic(), 88 Uint16Atomic.byteSize, 89 Uint16Atomic.byteAlignment, 90 Uint16Atomic, 91); 92export const int32atomic: Descriptor<Int32Atomic> = makeDescriptor( 93 () => new Int32Atomic(), 94 Int32Atomic.byteSize, 95 Int32Atomic.byteAlignment, 96 Int32Atomic, 97); 98export const uint32atomic: Descriptor<Uint32Atomic> = makeDescriptor( 99 () => new Uint32Atomic(), 100 Uint32Atomic.byteSize, 101 Uint32Atomic.byteAlignment, 102 Uint32Atomic, 103); 104export const int64atomic: Descriptor<Int64Atomic> = makeDescriptor( 105 () => new Int64Atomic(), 106 Int64Atomic.byteSize, 107 Int64Atomic.byteAlignment, 108 Int64Atomic, 109); 110export const uint64atomic: Descriptor<Uint64Atomic> = makeDescriptor( 111 () => new Uint64Atomic(), 112 Uint64Atomic.byteSize, 113 Uint64Atomic.byteAlignment, 114 Uint64Atomic, 115); 116export const boolatomic: Descriptor<BoolAtomic> = makeDescriptor( 117 () => new BoolAtomic(), 118 BoolAtomic.byteSize, 119 BoolAtomic.byteAlignment, 120 BoolAtomic, 121); 122 123/** Shared-memory locks. */ 124export const mutex: Descriptor<Mutex> = makeDescriptor(() => new Mutex(), Mutex.byteSize, Mutex.byteAlignment, Mutex); 125export const rwlock: Descriptor<RwLock> = makeDescriptor( 126 () => new RwLock(), 127 RwLock.byteSize, 128 RwLock.byteAlignment, 129 RwLock, 130); 131 132export interface BytesDescriptor extends Bytes { 133 byteSize: number; 134 byteAlignment: number; 135 _class: typeof Bytes; 136 _size: number; 137} 138 139/** 140 * Creates a fixed-size shared byte buffer. Acts as both a standalone factory and a schema descriptor. 141 * @param size - The buffer capacity in bytes. 142 * @returns A {@link Bytes} instance with descriptor metadata for use with `shared()`. 143 */ 144export function bytes(size: number): BytesDescriptor { 145 const instance = new Bytes(size); 146 return Object.assign(instance, { 147 byteSize: size, 148 byteAlignment: Bytes.byteAlignment, 149 _class: Bytes, 150 _size: size, 151 }) as BytesDescriptor; 152} 153 154export interface StringDescriptor extends SharedString { 155 byteSize: number; 156 byteAlignment: number; 157 _class: typeof SharedString; 158 _maxBytes: number; 159} 160 161/** 162 * Creates a variable-length shared UTF-8 string with a max byte length. Acts as both a standalone factory and a schema descriptor. 163 * @param maxBytes - Maximum number of bytes for the encoded string. 164 * @returns A {@link SharedString} instance with descriptor metadata for use with `shared()`. 165 */ 166export function string(maxBytes: number): StringDescriptor { 167 const instance = new SharedString(maxBytes); 168 return Object.assign(instance, { 169 byteSize: 4 + maxBytes, 170 byteAlignment: SharedString.byteAlignment, 171 _class: SharedString, 172 _maxBytes: maxBytes, 173 }) as StringDescriptor; 174}