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 59 lines 1.9 kB view raw
1import type { Loadable } from './loadable.ts'; 2 3const SHARED = Symbol.for('moroutine.shared'); 4const encoder = new TextEncoder(); 5const decoder = new TextDecoder(); 6 7/** A variable-length shared UTF-8 string with a max byte capacity, backed by SharedArrayBuffer. */ 8export class SharedString implements Loadable<string> { 9 readonly maxBytes: number; 10 private readonly lengthView: Uint32Array; 11 private readonly dataView: Uint8Array; 12 13 static byteAlignment = 4; 14 15 constructor(maxBytes: number, buffer?: SharedArrayBuffer, byteOffset?: number) { 16 this.maxBytes = maxBytes; 17 const totalSize = 4 + maxBytes; 18 const buf = buffer ?? new SharedArrayBuffer(totalSize); 19 const offset = byteOffset ?? 0; 20 this.lengthView = new Uint32Array(buf, offset, 1); 21 this.dataView = new Uint8Array(buf, offset + 4, maxBytes); 22 } 23 24 /** 25 * Decodes and returns the stored string. 26 * @returns The UTF-8 decoded string. 27 */ 28 load(): string { 29 const len = this.lengthView[0]; 30 if (len === 0) return ''; 31 return decoder.decode(this.dataView.subarray(0, len)); 32 } 33 34 /** 35 * Encodes and stores a string. Throws if the encoded bytes exceed the max capacity. 36 * @param value - The string to encode and store. 37 */ 38 store(value: string): void { 39 if (value === '') { 40 this.lengthView[0] = 0; 41 return; 42 } 43 const encoded = encoder.encode(value); 44 if (encoded.length > this.maxBytes) { 45 throw new RangeError(`Encoded string (${encoded.length} bytes) exceeds max ${this.maxBytes} bytes`); 46 } 47 this.dataView.set(encoded); 48 this.lengthView[0] = encoded.length; 49 } 50 51 [SHARED](): { tag: string; buffer: SharedArrayBuffer; byteOffset: number; maxBytes: number } { 52 return { 53 tag: 'SharedString', 54 buffer: this.lengthView.buffer as SharedArrayBuffer, 55 byteOffset: this.lengthView.byteOffset, 56 maxBytes: this.maxBytes, 57 }; 58 } 59}