// Single-writer/single-reader latest-sample mailbox. Header: state, UTF-8 byte length. // State 0 = empty, 1 = owned by a reader/writer, 2 = complete sample. // Neither side waits: an unread sample can be replaced, and a busy publication is skipped. export class SharedProfile { constructor(buffer = new SharedArrayBuffer(1024 * 1024)) { this.buffer = buffer; this.header = new Int32Array(buffer, 0, 2); this.bytes = new Uint8Array(buffer, 8); this.encoder = new TextEncoder(); this.decoder = new TextDecoder(); } write(json) { const bytes = this.encoder.encode(json); if (bytes.length > this.bytes.length) return false; const state = Atomics.load(this.header, 0); if ( state === 1 || Atomics.compareExchange(this.header, 0, state, 1) !== state ) return false; this.bytes.set(bytes); this.header[1] = bytes.length; Atomics.store(this.header, 0, 2); return true; } read() { if (Atomics.compareExchange(this.header, 0, 2, 1) !== 2) return; let bytes; try { bytes = this.bytes.slice(0, this.header[1]); } finally { Atomics.store(this.header, 0, 0); } return JSON.parse(this.decoder.decode(bytes)); } clear() { Atomics.compareExchange(this.header, 0, 2, 0); } }