{"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 const write = (\n  data: unknown,\n  buffer: SharedArrayBuffer,\n  { timeout = 5000 }: Options = {}\n) => {\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\n  const header = new Int32Array(buffer);\n  header[Handshake.TOTAL_SIZE] = totalSize;\n  header[Handshake.TOTAL_CHUNKS] = totalChunks;\n\n  Atomics.store(header, SEMAPHORE, Semaphore.HANDSHAKE);\n  Atomics.notify(header, SEMAPHORE);\n\n  try {\n    if (\n      Atomics.wait(header, SEMAPHORE, Semaphore.HANDSHAKE, timeout) ===\n      \"timed-out\"\n    ) {\n      throw new Error(\"Reader handshake timeout\");\n    }\n\n    const payload = new Uint8Array(buffer, HEADER_SIZE);\n\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\n      payload.set(serialized.subarray(start, end), 0);\n\n      header[Header.CHUNK_INDEX] = i;\n      header[Header.CHUNK_OFFSET] = start;\n      header[Header.CHUNK_SIZE] = size;\n\n      Atomics.store(header, SEMAPHORE, Semaphore.PAYLOAD);\n      Atomics.notify(header, SEMAPHORE);\n\n      if (\n        Atomics.wait(header, SEMAPHORE, Semaphore.PAYLOAD, timeout) ===\n        \"timed-out\"\n      ) {\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 const read = (buffer: SharedArrayBuffer,\n  { timeout = 5000 }: Options = {}\n): unknown => {\n  const header = new Int32Array(buffer);\n  if (\n    Atomics.wait(header, SEMAPHORE, Semaphore.READY, timeout) === \"timed-out\"\n  ) {\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    if (\n      Atomics.wait(header, SEMAPHORE, Semaphore.READY, timeout) === \"timed-out\"\n    ) {\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);\n};\n"],"names":["HEADER_SIZE","HEADER_VALUES","Handshake","Header","SEMAPHORE","Semaphore","read","write","Math","max","Object","values","length","Uint32Array","BYTES_PER_ELEMENT","data","buffer","timeout","serialized","serialize","chunkSize","byteLength","totalSize","totalChunks","ceil","header","Int32Array","Atomics","store","notify","wait","Error","payload","Uint8Array","i","start","end","min","size","set","subarray","chunkIndex","offset","deserialize"],"mappings":"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"}