{"version":3,"file":"node.mjs","names":[],"sources":["../src/io/node.ts","../src/io/node-fs.ts","../src/io/node-save.ts"],"sourcesContent":["// In-memory Node helpers.\n//\n// `fromBuffer` / `toBuffer` rely only on the global `Buffer` symbol — no\n// `node:*` imports — so they're safe to ship through the `@office-kit/xlsx/streaming`\n// browser-targeted entry too. Filesystem + Readable / Writable helpers live in\n// `./node-fs.ts` (re-exported via `@office-kit/xlsx/node`) where the `node:fs` /\n// `node:stream` imports stay out of the browser-safe surface.\n\nimport { OpenXmlIoError } from '../utils/exceptions';\nimport type { BufferedSinkWriter, XlsxSink } from './sink';\nimport type { XlsxSource } from './source';\n\n/**\n * Wrap a Buffer or Uint8Array as an XlsxSource. The underlying bytes are\n * referenced — no copy — so callers must not mutate them while the source is in\n * use.\n */\nexport function fromBuffer(buf: Buffer | Uint8Array): XlsxSource {\n  if (!(buf instanceof Uint8Array)) {\n    throw new OpenXmlIoError('fromBuffer expects a Buffer or Uint8Array');\n  }\n  // Buffer is a subclass of Uint8Array, so a single normalisation suffices.\n  const bytes: Uint8Array = buf instanceof Buffer ? new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength) : buf;\n  return {\n    async toBytes() {\n      return bytes;\n    },\n    toStream() {\n      return new ReadableStream<Uint8Array>({\n        start(controller) {\n          controller.enqueue(bytes);\n          controller.close();\n        },\n      });\n    },\n  };\n}\n\n/**\n * In-memory Buffer sink. The buffered path concatenates appended chunks into a\n * single allocation when {@link BufferedSinkWriter.finish} resolves; the\n * convenience `result()` returns it as a Node Buffer.\n */\nexport function toBuffer(): XlsxSink & { toBytes(): BufferedSinkWriter; result(): Buffer } {\n  const chunks: Uint8Array[] = [];\n  let finalised: Uint8Array | undefined;\n\n  const finalise = (): Uint8Array => {\n    if (finalised !== undefined) return finalised;\n    let total = 0;\n    for (const c of chunks) total += c.byteLength;\n    const out = new Uint8Array(total);\n    let off = 0;\n    for (const c of chunks) {\n      out.set(c, off);\n      off += c.byteLength;\n    }\n    finalised = out;\n    chunks.length = 0;\n    return out;\n  };\n\n  return {\n    toBytes(): BufferedSinkWriter {\n      return {\n        write(chunk: Uint8Array): void {\n          if (finalised !== undefined) {\n            throw new OpenXmlIoError('toBuffer sink: write after finish');\n          }\n          if (!(chunk instanceof Uint8Array)) {\n            throw new OpenXmlIoError('toBuffer sink: chunk is not a Uint8Array');\n          }\n          chunks.push(chunk);\n        },\n        async finish(): Promise<Uint8Array> {\n          return finalise();\n        },\n        abort(): void {\n          if (finalised !== undefined) return;\n          finalised = new Uint8Array(0);\n          chunks.length = 0;\n        },\n      };\n    },\n    result(): Buffer {\n      const bytes = finalise();\n      return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n    },\n  };\n}\n","// Node filesystem + Readable / Writable I/O helpers.\n//\n// Kept separate from `./node.ts` so the buffer-only entry stays free of\n// `node:fs` / `node:stream` imports — important for the `@office-kit/xlsx/streaming`\n// browser-targeted bundle, which can re-export `fromBuffer` / `toBuffer`\n// without dragging Node-only modules into the browser surface. Users who want\n// filesystem I/O reach this module directly (or through `@office-kit/xlsx/node` once\n// that subpath lands).\n\nimport { createReadStream, createWriteStream, readFileSync } from 'node:fs';\nimport { readFile, unlink } from 'node:fs/promises';\nimport { once } from 'node:events';\nimport { Readable, Writable } from 'node:stream';\nimport { OpenXmlIoError } from '../utils/exceptions';\nimport type { BufferedSinkWriter, XlsxSink } from './sink';\nimport type { XlsxSource } from './source';\n\nconst EMPTY_BYTES = new Uint8Array(0);\n\n/**\n * Wrap a filesystem path as an XlsxSource. `toBytes` reads the whole file into\n * memory; `toStream` opens a `fs.createReadStream` and bridges it to a Web\n * {@link ReadableStream} via `Readable.toWeb` so the ZIP reader can iterate\n * without loading the entire xlsx up front.\n */\nexport function fromFile(path: string): XlsxSource {\n  if (typeof path !== 'string' || path.length === 0) {\n    throw new OpenXmlIoError('fromFile expects a non-empty path string');\n  }\n  return {\n    async toBytes() {\n      try {\n        return new Uint8Array(await readFile(path));\n      } catch (cause) {\n        throw new OpenXmlIoError(`fromFile: failed to read \"${path}\"`, { cause });\n      }\n    },\n    toStream() {\n      const nodeStream = createReadStream(path);\n      return Readable.toWeb(nodeStream) as unknown as ReadableStream<Uint8Array>;\n    },\n  };\n}\n\n/**\n * Synchronous variant of {@link fromFile}. Convenience for tooling / scripts\n * where the cost of `await fs.readFile` outweighs the ergonomic gain. The\n * returned source's `toBytes` resolves immediately with the bytes already in\n * memory.\n */\nexport function fromFileSync(path: string): XlsxSource {\n  if (typeof path !== 'string' || path.length === 0) {\n    throw new OpenXmlIoError('fromFileSync expects a non-empty path string');\n  }\n  let bytes: Uint8Array;\n  try {\n    bytes = new Uint8Array(readFileSync(path));\n  } catch (cause) {\n    throw new OpenXmlIoError(`fromFileSync: failed to read \"${path}\"`, { cause });\n  }\n  return {\n    async toBytes() {\n      return bytes;\n    },\n    toStream() {\n      return new ReadableStream<Uint8Array>({\n        start(controller) {\n          controller.enqueue(bytes);\n          controller.close();\n        },\n      });\n    },\n  };\n}\n\n/**\n * Filesystem sink. Each `write(chunk)` call streams the bytes to disk via\n * `fs.createWriteStream`, honouring backpressure: the actual `writable.write`\n * for each chunk is queued behind any pending `drain`, so the writable's\n * internal buffer never grows past its `highWaterMark` (default 16 KB) no\n * matter how fast the producer hands chunks over.\n *\n * Note on the producer-side memory budget: the sink contract is\n * intentionally synchronous (`write(chunk): void`), so a producer that races\n * ahead without yielding will let chunk references pile up in the queue.\n * That keeps `writable`'s buffer bounded but does not bound the queue\n * itself. Producers that need a hard ceiling should yield between writes\n * (`await new Promise(setImmediate)` is enough) or use a sink with an async\n * write contract.\n *\n * `result()` returns the destination path; `finish()` resolves with an empty\n * `Uint8Array` once the stream has flushed. Callers that need the on-disk\n * bytes should `readFile()` the returned path themselves — re-reading inside\n * `finish()` would defeat the \"streamed to disk, never resident\" guarantee.\n */\nexport function toFile(path: string): XlsxSink & { toBytes(): BufferedSinkWriter; result(): string } {\n  if (typeof path !== 'string' || path.length === 0) {\n    throw new OpenXmlIoError('toFile expects a non-empty path string');\n  }\n  let stream: ReturnType<typeof createWriteStream> | undefined;\n  let streamCreated = false;\n  let finalised: Promise<Uint8Array> | undefined;\n  let pendingError: Error | undefined;\n  // Backpressure queue: every chunk's actual `writable.write` call is staged\n  // behind the previous chunk's completion. When a write returns `false` the\n  // queue parks on `drain` before the next chunk goes out, so the writable's\n  // internal buffer stays within its highWaterMark.\n  let writeQueue: Promise<void> = Promise.resolve();\n\n  const ensureStream = (): NonNullable<typeof stream> => {\n    if (!stream) {\n      stream = createWriteStream(path);\n      streamCreated = true;\n      stream.on('error', (err) => {\n        pendingError = err instanceof Error ? err : new Error(String(err));\n      });\n    }\n    return stream;\n  };\n\n  // Best-effort: remove a half-written file when finish() fails so callers\n  // don't mistake a corrupt artefact for a successful save. Swallows unlink\n  // errors because we're already in a failure path and the original cause\n  // is what the caller needs to see.\n  const cleanupOnFailure = async (): Promise<void> => {\n    if (!streamCreated) return;\n    try {\n      await unlink(path);\n    } catch {\n      // ignore — file may be gone, path may be on a read-only fs, etc.\n    }\n  };\n\n  return {\n    toBytes(): BufferedSinkWriter {\n      return {\n        write(chunk: Uint8Array): void {\n          if (finalised !== undefined) throw new OpenXmlIoError(`toFile sink: write after finish (\"${path}\")`);\n          if (!(chunk instanceof Uint8Array)) {\n            throw new OpenXmlIoError(`toFile sink: chunk is not a Uint8Array (\"${path}\")`);\n          }\n          if (pendingError) throw new OpenXmlIoError(`toFile sink: write error on \"${path}\"`, { cause: pendingError });\n          const s = ensureStream();\n          writeQueue = writeQueue.then(async () => {\n            // Skip remaining work once the stream has errored — the error\n            // surfaces from `finish()` so callers see one consistent failure.\n            if (pendingError) return;\n            const ok = s.write(chunk);\n            if (!ok) {\n              // Writable's internal buffer is over highWaterMark; wait for it\n              // to flush before the next queued chunk runs.\n              await once(s, 'drain');\n            }\n          });\n        },\n        async finish(): Promise<Uint8Array> {\n          if (finalised) return finalised;\n          finalised = (async () => {\n            const s = ensureStream();\n            try {\n              await writeQueue;\n              await new Promise<void>((resolve, reject) => {\n                s.end((err?: Error | null) => (err ? reject(err) : resolve()));\n              });\n              if (pendingError) {\n                throw new OpenXmlIoError(`toFile sink: write error on \"${path}\"`, { cause: pendingError });\n              }\n            } catch (err) {\n              await cleanupOnFailure();\n              throw err;\n            }\n            return EMPTY_BYTES;\n          })();\n          return finalised;\n        },\n        abort(): void {\n          // Idempotent: subsequent finish() / abort() calls become no-ops.\n          if (finalised) return;\n          finalised = Promise.resolve(EMPTY_BYTES);\n          if (stream) {\n            // destroy() releases the fd synchronously without flushing the\n            // pending buffer — exactly what we want for an aborted save.\n            stream.destroy();\n          }\n          // Fire-and-forget unlink — abort() is sync (void), and the caller\n          // is already on a failure path so any unlink error is noise.\n          void cleanupOnFailure();\n        },\n      };\n    },\n    result(): string {\n      return path;\n    },\n  };\n}\n\n/**\n * Wrap a Node.js {@link Readable} as an XlsxSource. `toBytes` consumes the\n * entire stream synchronously (collecting chunks); `toStream` bridges to a Web\n * ReadableStream via `Readable.toWeb` so the ZIP reader can pull chunks lazily.\n */\nexport function fromReadable(readable: Readable): XlsxSource {\n  if (!(readable instanceof Readable)) {\n    throw new OpenXmlIoError('fromReadable expects a Node Readable');\n  }\n  let bytes: Promise<Uint8Array> | undefined;\n  return {\n    async toBytes() {\n      if (bytes) return bytes;\n      bytes = (async () => {\n        const chunks: Uint8Array[] = [];\n        for await (const c of readable) {\n          chunks.push(c instanceof Uint8Array ? c : new Uint8Array(c));\n        }\n        let total = 0;\n        for (const c of chunks) total += c.byteLength;\n        const out = new Uint8Array(total);\n        let off = 0;\n        for (const c of chunks) {\n          out.set(c, off);\n          off += c.byteLength;\n        }\n        return out;\n      })();\n      return bytes;\n    },\n    toStream() {\n      return Readable.toWeb(readable) as unknown as ReadableStream<Uint8Array>;\n    },\n  };\n}\n\n/**\n * Wrap a Node.js {@link Writable} as an XlsxSink. The actual\n * `writable.write` for each chunk is queued behind any pending `drain`, so\n * the writable's internal buffer never exceeds its `highWaterMark` regardless\n * of how fast the producer is. See {@link toFile} for the same caveat about\n * producer-side memory: the synchronous `write(chunk)` API does not let\n * backpressure flow back to the caller, so a tight non-yielding producer can\n * still let chunk references accumulate in the queue.\n *\n * `result()` returns the writable itself for downstream chaining.\n */\nexport function toWritable(writable: Writable): XlsxSink & { toBytes(): BufferedSinkWriter; result(): Writable } {\n  if (!(writable instanceof Writable)) {\n    throw new OpenXmlIoError('toWritable expects a Node Writable');\n  }\n  let finalised: Promise<Uint8Array> | undefined;\n  let pendingError: Error | undefined;\n  let writeQueue: Promise<void> = Promise.resolve();\n  writable.on('error', (err) => {\n    pendingError = err instanceof Error ? err : new Error(String(err));\n  });\n\n  return {\n    toBytes(): BufferedSinkWriter {\n      return {\n        write(chunk: Uint8Array): void {\n          if (finalised !== undefined) throw new OpenXmlIoError('toWritable sink: write after finish');\n          if (!(chunk instanceof Uint8Array)) throw new OpenXmlIoError('toWritable sink: chunk is not a Uint8Array');\n          if (pendingError) throw new OpenXmlIoError('toWritable sink: write error', { cause: pendingError });\n          writeQueue = writeQueue.then(async () => {\n            if (pendingError) return;\n            const ok = writable.write(chunk);\n            if (!ok) {\n              await once(writable, 'drain');\n            }\n          });\n        },\n        async finish(): Promise<Uint8Array> {\n          if (finalised) return finalised;\n          finalised = (async () => {\n            await writeQueue;\n            await new Promise<void>((resolve, reject) => {\n              writable.end((err?: Error | null) => (err ? reject(err) : resolve()));\n            });\n            if (pendingError) throw new OpenXmlIoError('toWritable sink: write error', { cause: pendingError });\n            return EMPTY_BYTES;\n          })();\n          return finalised;\n        },\n        abort(cause?: unknown): void {\n          if (finalised) return;\n          finalised = Promise.resolve(EMPTY_BYTES);\n          // Pass the cause to destroy() so downstream `error` listeners can\n          // distinguish a deliberate abort from spontaneous fs/network errors.\n          writable.destroy(cause instanceof Error ? cause : undefined);\n        },\n      };\n    },\n    result(): Writable {\n      return writable;\n    },\n  };\n}\n","// Node-only counterpart to `workbookToBytes` in `./save`. Returns a Buffer\n// directly so Node consumers don't pay a `Buffer.from(uint8Array)` copy.\n\nimport type { Workbook } from '../workbook/workbook';\nimport { toBuffer } from './node';\nimport { saveWorkbook, type SaveOptions } from './save';\n\nexport async function workbookToBuffer(wb: Workbook, opts?: SaveOptions): Promise<Buffer> {\n  const sink = toBuffer();\n  await saveWorkbook(wb, sink, opts);\n  return sink.result();\n}\n"],"mappings":"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"}