/** * CSV escaping and a buffered, backpressure-aware line writer. * * Rows are accumulated in memory and flushed in large blocks. Writing row by row * would issue millions of small stream writes, and ignoring the return value of * `write()` would let Node buffer the entire output in RAM — which for an hour of * 23-channel EEG is several hundred megabytes. */ import type { Writable } from 'node:stream'; /** * Flush once this many characters have accumulated. * * Exported because it is a budget for the whole conversion rather than a per-writer * constant: a mixed-rate recording opens one writer per rate, and each taking a megabyte * meant memory followed the number of tables. See writeSignalFiles. */ export declare const DEFAULT_FLUSH_THRESHOLD: number; /** * U+FEFF, written as EF BB BF, which is what `--bom` prepends to each CSV. * * Excel on Windows reads a CSV with no byte order mark in the system code page rather than * UTF-8, so `µV` — two bytes of UTF-8 for one character — shows up as `µ`. The mark tells * it the file is UTF-8. * * Opt-in because it is not free. pandas strips it either engine (checked against 3.0.5), * but Python's own `csv.reader` over a plain `open()` does not, and neither does * `fs.readFileSync(path, 'utf8')`: the first column name comes back as `\ufefftime_s`, and * a lookup of `time_s` misses. Readers that want it gone ask for `utf-8-sig`. */ export declare const UTF8_BOM = "\uFEFF"; /** Quote a field only when CSV requires it, doubling any embedded quotes. */ export declare function escapeCsvField(value: string): string; export declare function csvRow(cells: readonly string[]): string; /** * Accumulates text and flushes it to a stream, respecting backpressure. * * Call `push()` freely, then `await maybeFlush()` at a row boundary. Memory stays * bounded by the flush threshold plus whatever the stream has not yet drained. */ export declare class BufferedLineWriter { #private; constructor(stream: Writable, threshold?: number); /** True once the reader closed the pipe. Nothing more can reach the consumer. */ get hungUp(): boolean; /** Characters written to the stream so far, before any encoding expansion. */ get charsWritten(): number; /** * Bytes handed to the stream, counting a multi-byte character once per byte. * * `charsWritten` drives the progress meter, where the difference does not matter. This is * for checking that what was handed over actually arrived, which is a byte question: a * channel labelled in Cyrillic makes the two differ by hundreds of bytes on the header * line alone. */ get bytesOut(): number; push(text: string): void; pushLine(text: string): void; /** * Whether enough has accumulated to be worth writing out. * * A synchronous question, so a row loop can ask it every row without paying for a * microtask on the twenty million that answer no. */ get full(): boolean; /** Flush if enough has accumulated. Await this at row boundaries. */ maybeFlush(): Promise; flush(): Promise; /** Flush anything left and close the stream. */ end(): Promise; /** Close the stream without caring whether the data made it out. */ destroy(): void; }