"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SyncMessenger = void 0; /** * @param condition Condition to wait for, when true, the function returns. * @param ms Maximum time to wait in milliseconds. */ const sleepUntil = (condition, ms = 100) => { const start = Date.now(); while (!condition()) { const now = Date.now(); if (now - start > ms) throw new Error('Timeout'); } }; /** * `SyncMessenger` allows to execute asynchronous code synchronously. The * asynchronous code is executed in a Worker thread, while the main thread is * blocked until the asynchronous code is finished. * * First four 4-byte words is the header, where the first word is used for Atomics * notifications. The second word is used for spin-locking the main thread until * the asynchronous code is finished. The third word is used to specify payload * length. The fourth word is currently unused. * * The maximum payload size is the size of the SharedArrayBuffer minus the * header size. */ class SyncMessenger { constructor(sab) { this.sab = sab; this.int32 = new Int32Array(sab); this.uint8 = new Uint8Array(sab); this.headerSize = 4 * 4; this.dataSize = sab.byteLength - this.headerSize; } callSync(data) { const requestLength = data.length; const headerSize = this.headerSize; const int32 = this.int32; int32[1] = 0; int32[2] = requestLength; this.uint8.set(data, headerSize); Atomics.notify(int32, 0); sleepUntil(() => int32[1] === 1); const responseLength = int32[2]; const response = this.uint8.slice(headerSize, headerSize + responseLength); return response; } serveAsync(callback) { const headerSize = this.headerSize; (async () => { try { const int32 = this.int32; const res = Atomics.wait(int32, 0, 0); if (res !== 'ok') throw new Error(`Unexpected Atomics.wait result: ${res}`); const requestLength = this.int32[2]; const request = this.uint8.slice(headerSize, headerSize + requestLength); const response = await callback(request); const responseLength = response.length; int32[2] = responseLength; this.uint8.set(response, headerSize); int32[1] = 1; } catch (_a) { } this.serveAsync(callback); })().catch(() => { }); } } exports.SyncMessenger = SyncMessenger; //# sourceMappingURL=SyncMessenger.js.map