API потоків Node.js
Нативна прив’язка pdf-oxide надає читні потоки для результатів пошуку, сторінок і таблиць — ідіоматичні для конвеєрів Node.js та ощадливі до пам’яті на великих документах.
Усі потоки реалізують стандартний інтерфейс Readable Node.js в об’єктному режимі, підтримують backpressure, інтегруються з pipe() і працюють з асинхронною ітерацією for await.
Потоки є нативними для прив’язки Node.js. Для збірки WASM ітеруйте синхронно.
SearchStream
Видає по одному SearchResult за раз, у міру того як базовий SearchManager знаходить збіги.
const { PdfDocument, SearchManager, SearchStream } = require("pdf-oxide");
const doc = new PdfDocument("large.pdf");
const manager = new SearchManager(doc);
const stream = new SearchStream(manager, "invoice");
stream.on("data", (r) => {
console.log(`page ${r.pageIndex + 1}: ${r.text}`);
});
stream.on("end", () => {
console.log("search complete");
doc.close();
});
stream.on("error", (err) => {
console.error(err);
doc.close();
});
Пошук з урахуванням регістру
const stream = new SearchStream(manager, "Invoice", { caseSensitive: true });
Асинхронна ітерація
for await (const result of stream) {
if (result.pageIndex > 50) break;
console.log(result.text);
}
Сумісність з pipe()
const { Writable } = require("stream");
const sink = new Writable({
objectMode: true,
write(result, _enc, cb) {
console.log(`${result.pageIndex}:${result.text}`);
cb();
},
});
stream.pipe(sink);
PageIteratorStream
Видає видобутий текст по одній сторінці за раз. Зручно для порядкового виводу або коли ви передаєте дані LLM через чергу з обмеженням швидкості.
const { PageIteratorStream } = require("pdf-oxide");
const stream = new PageIteratorStream(doc, { format: "markdown" });
for await (const { pageIndex, content } of stream) {
await indexPage(pageIndex, content);
}
format приймає "text" (за замовчуванням), "markdown", "html", "plain".
TableStream
Видає по одній таблиці за раз, у міру їх виявлення.
const { TableStream } = require("pdf-oxide");
const stream = new TableStream(doc);
stream.on("data", (table) => {
console.log(`${table.rows.length}x${table.rows[0].length} on page ${table.pageIndex}`);
});
Backpressure
Усі потоки реалізують стандартний backpressure Node.js. Якщо ваш споживач повільний, потік призупиняє видобування, доки .read() не відновить його:
stream.on("data", async (result) => {
stream.pause();
await slowIndex(result);
stream.resume();
});
Або скористайтеся for await, який обробляє призупинення автоматично.
Обробка помилок
Помилки під час видобування передаються як стандартні події error:
stream.on("error", (err) => {
if (err.code === "PDF_INVALID_PAGE") {
console.warn("skipping invalid page", err.pageIndex);
} else {
throw err;
}
});
Ефективність використання пам’яті
Потоки тримають в обробці лише один результат за раз. На PDF з 10 000 сторінок, що дає 50 000 збігів, SearchStream використовує сталий обсяг пам’яті — увесь набір результатів ніколи не матеріалізується.
Очищення
Закриття батьківського PdfDocument завершує всі прикріплені потоки. Потоки також звільняють посилання на свій менеджер при подіях end / error.
const doc = new PdfDocument("big.pdf");
const stream = new SearchStream(new SearchManager(doc), "TODO");
stream.on("end", () => doc.close());
stream.on("error", () => doc.close());
Для Node.js 22+ ключове слово using звільняє документ при виході з області видимості:
{
using doc = new PdfDocument("big.pdf");
const stream = new SearchStream(new SearchManager(doc), "TODO");
for await (const r of stream) console.log(r);
} // doc.close() викликається автоматично
Пов’язані сторінки
- Перші кроки з Node.js — встановлення, швидкий старт
- Довідник API для Node.js
- Пошук — непотокові параметри пошуку