{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { serialize, deserialize } from \"node:v8\";\n\nexport const SEMAPHORE = 0;\n\nexport enum Semaphore {\n  READY,\n  HANDSHAKE,\n  PAYLOAD,\n}\n\nexport enum Handshake {\n  TOTAL_SIZE = 1,\n  TOTAL_CHUNKS,\n}\n\nexport enum Header {\n  CHUNK_INDEX = 1,\n  CHUNK_OFFSET,\n  CHUNK_SIZE,\n}\n\nexport const HEADER_VALUES =\n  1 +\n  Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;\nexport const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;\n\nexport interface Options {\n  timeout?: number;\n}\n\nexport interface WaitRequest {\n  target: Int32Array;\n  index: number;\n  value: number;\n  timeout?: number;\n}\n\nexport type WaitResponse = ReturnType<typeof Atomics.wait>;\n\nexport function* writeGenerator(\n  data: unknown,\n  buffer: SharedArrayBuffer,\n  { timeout = 5000 }: Options = {},\n): Generator<WaitRequest, void, WaitResponse> {\n  const serialized = serialize(data);\n  const chunkSize = buffer.byteLength - HEADER_SIZE;\n  const totalSize = serialized.length;\n  const totalChunks = Math.ceil(totalSize / chunkSize);\n  const header = new Int32Array(buffer);\n\n  header[Handshake.TOTAL_SIZE] = totalSize;\n  header[Handshake.TOTAL_CHUNKS] = totalChunks;\n  Atomics.store(header, SEMAPHORE, Semaphore.HANDSHAKE);\n  Atomics.notify(header, SEMAPHORE);\n\n  try {\n    const handshakeResult: WaitResponse = yield {\n      target: header,\n      index: SEMAPHORE,\n      value: Semaphore.HANDSHAKE,\n      timeout,\n    };\n    if (handshakeResult === \"timed-out\") {\n      throw new Error(\"Reader handshake timeout\");\n    }\n\n    const payload = new Uint8Array(buffer, HEADER_SIZE);\n    for (let i = 0; i < totalChunks; i++) {\n      const start = i * chunkSize;\n      const end = Math.min(start + chunkSize, totalSize);\n      const size = end - start;\n      payload.set(serialized.subarray(start, end), 0);\n      header[Header.CHUNK_INDEX] = i;\n      header[Header.CHUNK_OFFSET] = start;\n      header[Header.CHUNK_SIZE] = size;\n      Atomics.store(header, SEMAPHORE, Semaphore.PAYLOAD);\n      Atomics.notify(header, SEMAPHORE);\n\n      const chunkResult: WaitResponse = yield {\n        target: header,\n        index: SEMAPHORE,\n        value: Semaphore.PAYLOAD,\n        timeout,\n      };\n      if (chunkResult === \"timed-out\") {\n        throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);\n      }\n    }\n  } finally {\n    Atomics.store(header, SEMAPHORE, Semaphore.READY);\n  }\n}\n\nexport function* readGenerator(\n  buffer: SharedArrayBuffer,\n  { timeout = 5000 }: Options = {},\n): Generator<WaitRequest, unknown, WaitResponse> {\n  const header = new Int32Array(buffer);\n\n  const handshakeResult: WaitResponse = yield {\n    target: header,\n    index: SEMAPHORE,\n    value: Semaphore.READY,\n    timeout,\n  };\n  if (handshakeResult === \"timed-out\") {\n    throw new Error(\"Handshake timeout\");\n  }\n  if (header[SEMAPHORE] !== Semaphore.HANDSHAKE) {\n    throw new Error(\"Invalid handshake state\");\n  }\n\n  const totalSize = header[Handshake.TOTAL_SIZE];\n  const totalChunks = header[Handshake.TOTAL_CHUNKS];\n  const data = new Uint8Array(totalSize);\n\n  Atomics.store(header, SEMAPHORE, Semaphore.READY);\n  Atomics.notify(header, SEMAPHORE);\n\n  const payload = new Uint8Array(buffer, HEADER_SIZE);\n  for (let i = 0; i < totalChunks; i++) {\n    const chunkResult: WaitResponse = yield {\n      target: header,\n      index: SEMAPHORE,\n      value: Semaphore.READY,\n      timeout,\n    };\n    if (chunkResult === \"timed-out\") {\n      throw new Error(`Writer timeout waiting for chunk ${i}`);\n    }\n    // @ts-expect-error does not infer number\n    if (header[SEMAPHORE] !== Semaphore.PAYLOAD) {\n      throw new Error(\n        `Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`,\n      );\n    }\n    const chunkIndex = header[Header.CHUNK_INDEX];\n    if (i !== chunkIndex) {\n      throw new Error(\n        `Reader integrity failure for chunk ${chunkIndex} expected ${i}`,\n      );\n    }\n    const offset = header[Header.CHUNK_OFFSET];\n    const size = header[Header.CHUNK_SIZE];\n    data.set(payload.subarray(0, size), offset);\n    Atomics.store(header, SEMAPHORE, Semaphore.READY);\n    Atomics.notify(header, SEMAPHORE);\n  }\n  return deserialize(data) as unknown;\n}\n\nexport const writeSync = (\n  data: unknown,\n  buffer: SharedArrayBuffer,\n  options?: Options,\n) => {\n  const gen = writeGenerator(data, buffer, options);\n  let result = gen.next();\n  while (!result.done) {\n    const waitResult = Atomics.wait(\n      result.value.target,\n      result.value.index,\n      result.value.value,\n      result.value.timeout,\n    );\n    result = gen.next(waitResult);\n  }\n};\n\nexport const write = async (\n  data: unknown,\n  buffer: SharedArrayBuffer,\n  options?: Options,\n) => {\n  const gen = writeGenerator(data, buffer, options);\n  let result = gen.next();\n  while (!result.done) {\n    const request = result.value;\n    const waitResult = await Atomics.waitAsync(\n      request.target,\n      request.index,\n      request.value,\n      request.timeout,\n    ).value;\n    result = gen.next(waitResult);\n  }\n};\n\nexport const readSync = (\n  buffer: SharedArrayBuffer,\n  options?: Options,\n): unknown => {\n  const gen = readGenerator(buffer, options);\n  let result = gen.next();\n  while (!result.done) {\n    const waitResult = Atomics.wait(\n      result.value.target,\n      result.value.index,\n      result.value.value,\n      result.value.timeout,\n    );\n    result = gen.next(waitResult);\n  }\n  return result.value;\n};\n\nexport const read = async (\n  buffer: SharedArrayBuffer,\n  options?: Options,\n): Promise<unknown> => {\n  const gen = readGenerator(buffer, options);\n  let result = gen.next();\n  while (!result.done) {\n    const request = result.value;\n    const waitResult = await Atomics.waitAsync(\n      request.target,\n      request.index,\n      request.value,\n      request.timeout,\n    ).value;\n    result = gen.next(waitResult);\n  }\n  return result.value;\n};\n"],"names":["HEADER_SIZE","HEADER_VALUES","Handshake","Header","SEMAPHORE","Semaphore","read","readGenerator","readSync","write","writeGenerator","writeSync","Math","max","Object","values","length","Uint32Array","BYTES_PER_ELEMENT","data","buffer","timeout","serialized","serialize","chunkSize","byteLength","totalSize","totalChunks","ceil","header","Int32Array","Atomics","store","notify","handshakeResult","target","index","value","Error","payload","Uint8Array","i","start","end","min","size","set","subarray","chunkResult","chunkIndex","offset","deserialize","options","gen","result","next","done","waitResult","wait","request","waitAsync"],"mappings":"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"}