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 64 lines 1.8 kB view raw
1import type { Loadable } from './loadable.ts'; 2 3type LoadableKeys<T extends Record<string, unknown>> = { 4 [K in keyof T]: T[K] extends Loadable<any> ? K : never; 5}[keyof T]; 6 7type Simplify<T> = { [K in keyof T]: T[K] } & {}; 8 9type FieldValues<T extends Record<string, unknown>> = Simplify<{ 10 [K in LoadableKeys<T>]: T[K] extends Loadable<infer V> ? V : never; 11}>; 12 13function isLoadable(value: unknown): value is Loadable<unknown> { 14 return ( 15 typeof value === 'object' && 16 value !== null && 17 typeof (value as any).load === 'function' && 18 typeof (value as any).store === 'function' 19 ); 20} 21 22const SHARED = Symbol.for('moroutine.shared'); 23 24/** A named group of shared-memory fields with bulk `load()`/`store()` access. */ 25export class SharedStruct<T extends Record<string, unknown>> implements Loadable<FieldValues<T>> { 26 readonly fields: T; 27 28 constructor(fields: T) { 29 this.fields = fields; 30 } 31 32 load(): FieldValues<T> { 33 const result = {} as any; 34 for (const key in this.fields) { 35 const field = this.fields[key]; 36 if (isLoadable(field)) { 37 result[key] = field.load(); 38 } 39 } 40 return result; 41 } 42 43 store(values: FieldValues<T>): void { 44 for (const key in this.fields) { 45 const field = this.fields[key]; 46 if (isLoadable(field)) { 47 if (key in (values as any)) { 48 field.store((values as any)[key]); 49 } 50 } 51 } 52 } 53 54 [SHARED](): { tag: string; fields: Record<string, unknown> } { 55 const serializedFields: Record<string, unknown> = {}; 56 for (const key in this.fields) { 57 const field = this.fields[key]; 58 if (typeof field === 'object' && field !== null && SHARED in field) { 59 serializedFields[key] = (field as any)[SHARED](); 60 } 61 } 62 return { tag: 'SharedStruct', fields: serializedFields }; 63 } 64}