39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
import type { IChunkSource } from "../types";
|
|
|
|
export class FileChunkSource implements IChunkSource {
|
|
private readonly path: string;
|
|
private readonly chunkSize: number;
|
|
|
|
public constructor(path: string, chunkSize: number = 64 * 1024) {
|
|
this.path = path;
|
|
this.chunkSize = Math.max(1024, chunkSize);
|
|
}
|
|
|
|
public async *chunks(): AsyncIterable<string> {
|
|
// Prefer Bun if available; fall back to Node streams to keep portability
|
|
if (typeof Bun !== "undefined" && typeof Bun.file === "function") {
|
|
const file = Bun.file(this.path);
|
|
const reader = file.stream().getReader();
|
|
try {
|
|
while (true) {
|
|
const { value, done } = await reader.read();
|
|
if (done) break;
|
|
if (value) yield Buffer.from(value).toString("utf8");
|
|
}
|
|
} finally {
|
|
reader.releaseLock();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Node.js fallback
|
|
const { createReadStream } = await import("node:fs");
|
|
const stream = createReadStream(this.path, { encoding: "utf8", highWaterMark: this.chunkSize });
|
|
for await (const chunk of stream) {
|
|
yield chunk as string;
|
|
}
|
|
}
|
|
}
|
|
|
|
|