import type { Loadable } from './loadable.ts'; type LoadableKeys> = { [K in keyof T]: T[K] extends Loadable ? K : never; }[keyof T]; type Simplify = { [K in keyof T]: T[K] } & {}; type FieldValues> = Simplify<{ [K in LoadableKeys]: T[K] extends Loadable ? V : never; }>; function isLoadable(value: unknown): value is Loadable { return ( typeof value === 'object' && value !== null && typeof (value as any).load === 'function' && typeof (value as any).store === 'function' ); } const SHARED = Symbol.for('moroutine.shared'); /** A named group of shared-memory fields with bulk `load()`/`store()` access. */ export class SharedStruct> implements Loadable> { readonly fields: T; constructor(fields: T) { this.fields = fields; } load(): FieldValues { const result = {} as any; for (const key in this.fields) { const field = this.fields[key]; if (isLoadable(field)) { result[key] = field.load(); } } return result; } store(values: FieldValues): void { for (const key in this.fields) { const field = this.fields[key]; if (isLoadable(field)) { if (key in (values as any)) { field.store((values as any)[key]); } } } } [SHARED](): { tag: string; fields: Record } { const serializedFields: Record = {}; for (const key in this.fields) { const field = this.fields[key]; if (typeof field === 'object' && field !== null && SHARED in field) { serializedFields[key] = (field as any)[SHARED](); } } return { tag: 'SharedStruct', fields: serializedFields }; } }