readline-pager 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -60
- package/dist/main.cjs +12 -9
- package/dist/main.d.cts +1 -0
- package/dist/main.d.mts +1 -0
- package/dist/main.mjs +12 -9
- package/dist/worker.cjs +2 -3
- package/dist/worker.mjs +2 -3
- package/package.json +2 -1
- package/dist/constants-BNKQoOqH.mjs +0 -6
- package/dist/constants-Cyb_UQAC.cjs +0 -18
package/README.md
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
# 📄 readline-pager
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center"><img src="logo.webp" alt="logo" width="349"></p>
|
|
4
|
+
|
|
5
|
+
Memory-efficient, paginated file reader for Node.js with async iteration, prefetching, backward reading and optional worker support.
|
|
4
6
|
|
|
5
7
|
`readline-pager` reads large text files page-by-page without loading the entire file into memory.
|
|
6
8
|
|
|
7
9
|
- ✅ Zero dependencies
|
|
8
|
-
- ✅ Async iterator
|
|
10
|
+
- ✅ Async iterator (`for await...of`) + manual `next()` API
|
|
9
11
|
- ✅ Forward & backward reading (EOF → BOF)
|
|
10
12
|
- ✅ Optional worker thread mode (forward only)
|
|
11
13
|
- ✅ Up to ~3× faster than Node.js `readline`
|
|
12
14
|
- ✅ ~97% test coverage & fully typed (TypeScript)
|
|
13
15
|
|
|
16
|
+
> **Important:**
|
|
17
|
+
> Performance is heavily dependent on the `chunkSize` option; ensure you fine-tune it for your specific I/O hardware. A setting of **64 KB** is typically a good starting point. Increasing it might gradually improve read speeds, usually reaching an optimal peak depending on your hardware's capabilities.
|
|
18
|
+
|
|
14
19
|
---
|
|
15
20
|
|
|
16
21
|
## 📦 Installation
|
|
@@ -21,7 +26,7 @@ npm install readline-pager
|
|
|
21
26
|
|
|
22
27
|
---
|
|
23
28
|
|
|
24
|
-
## 🚀 Quick
|
|
29
|
+
## 🚀 Quick start
|
|
25
30
|
|
|
26
31
|
```ts
|
|
27
32
|
import { createPager } from "readline-pager";
|
|
@@ -35,24 +40,25 @@ for await (const page of pager) {
|
|
|
35
40
|
|
|
36
41
|
---
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
**Recommended for highest throughput:**
|
|
39
44
|
|
|
40
45
|
```ts
|
|
41
46
|
const pager = createPager("./bigfile.txt");
|
|
42
47
|
|
|
48
|
+
while (true) {
|
|
49
|
+
const page = await pager.next();
|
|
50
|
+
if (!page) break;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// or
|
|
43
54
|
let page;
|
|
44
55
|
while ((page = await pager.next()) !== null) {
|
|
45
|
-
// page: string[]
|
|
46
56
|
// process page
|
|
47
57
|
}
|
|
48
58
|
```
|
|
49
59
|
|
|
50
|
-
`
|
|
51
|
-
|
|
52
|
-
- `Promise<string[]>` — next page
|
|
53
|
-
- `Promise<null>` — end of file
|
|
54
|
-
|
|
55
|
-
> Use `while + next()` when raw throughput matters (see Iteration Performance Notes).
|
|
60
|
+
- `while + next()` is the fastest iteration method (avoids extra async-iterator overhead).
|
|
61
|
+
- `for await of` is more ergonomic and convenient.
|
|
56
62
|
|
|
57
63
|
---
|
|
58
64
|
|
|
@@ -60,19 +66,21 @@ while ((page = await pager.next()) !== null) {
|
|
|
60
66
|
|
|
61
67
|
```ts
|
|
62
68
|
createPager(filepath, {
|
|
69
|
+
chunkSize?: number, // default: 64 * 1024 (64 KiB)
|
|
63
70
|
pageSize?: number, // default: 1_000
|
|
64
|
-
delimiter?: string // default: "\n"
|
|
71
|
+
delimiter?: string, // default: "\n"
|
|
65
72
|
prefetch?: number, // default: 1
|
|
66
73
|
backward?: boolean, // default: false
|
|
67
74
|
useWorker?: boolean, // default: false (forward only)
|
|
68
75
|
});
|
|
69
76
|
```
|
|
70
77
|
|
|
78
|
+
- `chunkSize`: number of bytes read per I/O operation. **Tune this** — default is `64 * 1024`.
|
|
71
79
|
- `pageSize` — number of lines per page.
|
|
72
80
|
- `delimiter` — line separator.
|
|
73
|
-
- `prefetch` — max number of pages buffered internally.
|
|
81
|
+
- `prefetch` — max number of pages buffered internally. Not required for typical use; tuning has little effect once the engine is optimized.
|
|
74
82
|
- `backward` — read file from end → start (not supported with `useWorker`).
|
|
75
|
-
- `useWorker` — offload parsing to a worker thread (forward
|
|
83
|
+
- `useWorker` — offload parsing to a worker thread (forward only).
|
|
76
84
|
|
|
77
85
|
---
|
|
78
86
|
|
|
@@ -87,23 +95,15 @@ Returns the next page or `null` when finished. Empty lines are preserved.
|
|
|
87
95
|
- A completely empty file (`0` bytes) produces `[""]` on the first read.
|
|
88
96
|
- A file with multiple empty lines returns each line as an empty string (e.g., `["", ""]` for two empty lines). Node.js `readline` may emit fewer or no `line` events in these cases.
|
|
89
97
|
|
|
90
|
-
✅ Key points:
|
|
91
|
-
|
|
92
|
-
- A 0-byte file → `[""]`
|
|
93
|
-
- Consecutive `\n\n` → `["", ""]`
|
|
94
|
-
- Node.js `readline` may skip initial empty line(s) and emit nothing for empty files.
|
|
95
|
-
|
|
96
98
|
### `pager.close(): void`
|
|
97
99
|
|
|
98
100
|
Stops reading and releases resources immediately. Safe to call at any time.
|
|
99
101
|
|
|
100
|
-
###
|
|
102
|
+
### Read-only properties
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
pager.
|
|
104
|
-
pager.
|
|
105
|
-
pager.lastLine; // last line emitted (updated per page)
|
|
106
|
-
```
|
|
104
|
+
- `pager.lineCount` — lines emitted so far
|
|
105
|
+
- `pager.firstLine` — first emitted line (available after first read)
|
|
106
|
+
- `pager.lastLine` — last emitted line (updated per page)
|
|
107
107
|
|
|
108
108
|
---
|
|
109
109
|
|
|
@@ -115,49 +115,26 @@ Run the included benchmark:
|
|
|
115
115
|
# default run
|
|
116
116
|
node test/_benchmark.ts
|
|
117
117
|
|
|
118
|
-
# customize
|
|
119
|
-
node test/_benchmark.ts --lines=20000 --page-size=500 --
|
|
118
|
+
# or customize with args
|
|
119
|
+
node test/_benchmark.ts --lines=20000 --page-size=500 --backward
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
### Summary (averages)
|
|
125
|
-
|
|
126
|
-
| Lines | File Size (MB) | Implementation | Avg Time (ms) | Avg Throughput (MB/s) | Speedup vs `readline` |
|
|
127
|
-
| ----------- | -------------- | -------------- | ------------- | --------------------: | --------------------: |
|
|
128
|
-
| 1,000,000 | 35.29 MB | readline | 100.21 | 352.31 | — |
|
|
129
|
-
| 1,000,000 | 35.29 MB | readline-pager | 43.31 | 815.71 | **2.32× faster** |
|
|
130
|
-
| 10,000,000 | 352.86 MB | readline | 802.61 | 439.80 | — |
|
|
131
|
-
| 10,000,000 | 352.86 MB | readline-pager | 292.33 | 1207.77 | **2.75× faster** |
|
|
132
|
-
| 100,000,000 | 3528.59 MB | readline | 7777.52 | 453.75 | — |
|
|
133
|
-
| 100,000,000 | 3528.59 MB | readline-pager | 2742.99 | 1286.50 | **2.83× faster** |
|
|
134
|
-
|
|
135
|
-
**Key takeaways**
|
|
136
|
-
|
|
137
|
-
- `readline-pager` is consistently **~2.3×–2.8× faster** than Node.js `readline`.
|
|
138
|
-
- Relative performance gains increase with file size.
|
|
139
|
-
- Sustained throughput exceeds **1.2 GB/s** on large files (machine-dependent).
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## 🧠 Iteration Performance Notes
|
|
144
|
-
|
|
145
|
-
- **Fastest**: manual
|
|
146
|
-
`while ((page = await pager.next()) !== null) { ... }`
|
|
147
|
-
Avoids async-iterator protocol overhead and microtask churn.
|
|
122
|
+
> Test setup: generated text files with uuid, run on a fast NVMe machine with default options; values are averages from multiple runs. Results are machine-dependent.
|
|
148
123
|
|
|
149
|
-
-
|
|
150
|
-
|
|
151
|
-
|
|
124
|
+
| Lines | File MB | Node `readline` (MB/s) | Bun streaming (MB/s) | `readline-pager` (Node) (MB/s) |
|
|
125
|
+
| -----: | -------: | ---------------------: | -------------------: | -----------------------------: |
|
|
126
|
+
| 10M | 352.86 | ~423 | ~296 | **~1,327** |
|
|
127
|
+
| 100M | 3528.59 | ~441 | ~298 | **~1,378** |
|
|
128
|
+
| 1,000M | 35285.95 | ~426 | ~294 | **~1,168** |
|
|
152
129
|
|
|
153
|
-
**
|
|
130
|
+
**Takeaway:** `readline-pager` delivers multi-GB/s memory-to-memory throughput on large files on typical NVMe hardware; results vary with `chunkSize`, runtime (Node vs Bun), and CPU/OS.
|
|
154
131
|
|
|
155
132
|
---
|
|
156
133
|
|
|
157
134
|
## 🛠 Development & Contributing
|
|
158
135
|
|
|
159
|
-
- Minimum supported Node.js: **
|
|
160
|
-
- Development/test environment: **Node v25.6
|
|
136
|
+
- Minimum supported Node.js: **v18.12** (lts/hydrogen).
|
|
137
|
+
- Development/test environment: **Node v25.6**, **TypeScript v5.9**.
|
|
161
138
|
|
|
162
139
|
Run tests:
|
|
163
140
|
|
package/dist/main.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_constants = require('./constants-Cyb_UQAC.cjs');
|
|
3
2
|
let node_fs_promises = require("node:fs/promises");
|
|
4
3
|
let node_worker_threads = require("node:worker_threads");
|
|
5
4
|
|
|
@@ -32,7 +31,7 @@ function createPageQueue() {
|
|
|
32
31
|
//#endregion
|
|
33
32
|
//#region src/reader/backward.reader.ts
|
|
34
33
|
function createBackwardReader(filepath, options) {
|
|
35
|
-
const { pageSize, delimiter, prefetch } = options;
|
|
34
|
+
const { chunkSize, pageSize, delimiter, prefetch } = options;
|
|
36
35
|
const pageQueue = createPageQueue();
|
|
37
36
|
let fd = null;
|
|
38
37
|
let pos = 0;
|
|
@@ -54,11 +53,11 @@ function createBackwardReader(filepath, options) {
|
|
|
54
53
|
await init();
|
|
55
54
|
if (!fd) return;
|
|
56
55
|
while (pageQueue.queue.length < prefetch && pos > 0) {
|
|
57
|
-
const readSize = Math.min(
|
|
56
|
+
const readSize = Math.min(chunkSize, pos);
|
|
58
57
|
pos -= readSize;
|
|
59
58
|
const buf = Buffer.allocUnsafe(readSize);
|
|
60
59
|
await fd.read(buf, 0, readSize, pos);
|
|
61
|
-
buffer += buf.toString(
|
|
60
|
+
buffer += buf.toString("utf8");
|
|
62
61
|
let idx;
|
|
63
62
|
while ((idx = buffer.lastIndexOf(delimiter)) !== -1) {
|
|
64
63
|
const line = buffer.slice(idx + delimiter.length);
|
|
@@ -126,7 +125,7 @@ function createBackwardReader(filepath, options) {
|
|
|
126
125
|
//#endregion
|
|
127
126
|
//#region src/reader/forward.reader.ts
|
|
128
127
|
function createForwardReader(filepath, options) {
|
|
129
|
-
const { pageSize, delimiter, prefetch } = options;
|
|
128
|
+
const { chunkSize, pageSize, delimiter, prefetch } = options;
|
|
130
129
|
const pageQueue = createPageQueue();
|
|
131
130
|
let fd = null;
|
|
132
131
|
let pos = 0;
|
|
@@ -149,11 +148,11 @@ function createForwardReader(filepath, options) {
|
|
|
149
148
|
await init();
|
|
150
149
|
if (!fd) return;
|
|
151
150
|
while (pageQueue.queue.length < prefetch && pos < size) {
|
|
152
|
-
const readSize = Math.min(
|
|
151
|
+
const readSize = Math.min(chunkSize, size - pos);
|
|
153
152
|
const buf = Buffer.allocUnsafe(readSize);
|
|
154
153
|
const { bytesRead } = await fd.read(buf, 0, readSize, pos);
|
|
155
154
|
pos += bytesRead;
|
|
156
|
-
buffer += buf.toString(
|
|
155
|
+
buffer += buf.toString("utf8", 0, bytesRead);
|
|
157
156
|
let idx;
|
|
158
157
|
while ((idx = buffer.indexOf(delimiter)) !== -1) {
|
|
159
158
|
const line = buffer.slice(0, idx);
|
|
@@ -216,9 +215,10 @@ function createForwardReader(filepath, options) {
|
|
|
216
215
|
//#region src/reader/worker.reader.ts
|
|
217
216
|
const workerFile = typeof {} !== "undefined" ? new URL("./worker.mjs", require("url").pathToFileURL(__filename).href) : require.resolve("./worker.cjs");
|
|
218
217
|
function createWorkerReader(filepath, options) {
|
|
219
|
-
const { pageSize, delimiter, prefetch } = options;
|
|
218
|
+
const { chunkSize, pageSize, delimiter, prefetch } = options;
|
|
220
219
|
const worker = new node_worker_threads.Worker(new URL(workerFile, require("url").pathToFileURL(__filename).href), { workerData: {
|
|
221
220
|
filepath,
|
|
221
|
+
chunkSize,
|
|
222
222
|
pageSize,
|
|
223
223
|
delimiter
|
|
224
224
|
} });
|
|
@@ -274,20 +274,23 @@ function createWorkerReader(filepath, options) {
|
|
|
274
274
|
//#endregion
|
|
275
275
|
//#region src/main.ts
|
|
276
276
|
function createPager(filepath, options = {}) {
|
|
277
|
-
const { pageSize = 1e3, delimiter = "\n", prefetch = 1, backward = false, useWorker = false } = options;
|
|
277
|
+
const { chunkSize = 64 * 1024, pageSize = 1e3, delimiter = "\n", prefetch = 1, backward = false, useWorker = false } = options;
|
|
278
278
|
if (!filepath) throw new Error("filepath required");
|
|
279
279
|
if (pageSize <= 0) throw new RangeError("pageSize must be > 0");
|
|
280
280
|
if (prefetch <= 0) throw new RangeError("prefetch must be >= 1");
|
|
281
281
|
if (backward && useWorker) throw new Error("backward not supported with useWorker");
|
|
282
282
|
return useWorker ? createWorkerReader(filepath, {
|
|
283
|
+
chunkSize,
|
|
283
284
|
pageSize,
|
|
284
285
|
prefetch,
|
|
285
286
|
delimiter
|
|
286
287
|
}) : backward ? createBackwardReader(filepath, {
|
|
288
|
+
chunkSize,
|
|
287
289
|
pageSize,
|
|
288
290
|
prefetch,
|
|
289
291
|
delimiter
|
|
290
292
|
}) : createForwardReader(filepath, {
|
|
293
|
+
chunkSize,
|
|
291
294
|
pageSize,
|
|
292
295
|
prefetch,
|
|
293
296
|
delimiter
|
package/dist/main.d.cts
CHANGED
package/dist/main.d.mts
CHANGED
package/dist/main.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { n as ENCODING, t as CHUNK_SIZE } from "./constants-BNKQoOqH.mjs";
|
|
2
1
|
import { createRequire } from "node:module";
|
|
3
2
|
import { open } from "node:fs/promises";
|
|
4
3
|
import { Worker } from "node:worker_threads";
|
|
@@ -36,7 +35,7 @@ function createPageQueue() {
|
|
|
36
35
|
//#endregion
|
|
37
36
|
//#region src/reader/backward.reader.ts
|
|
38
37
|
function createBackwardReader(filepath, options) {
|
|
39
|
-
const { pageSize, delimiter, prefetch } = options;
|
|
38
|
+
const { chunkSize, pageSize, delimiter, prefetch } = options;
|
|
40
39
|
const pageQueue = createPageQueue();
|
|
41
40
|
let fd = null;
|
|
42
41
|
let pos = 0;
|
|
@@ -58,11 +57,11 @@ function createBackwardReader(filepath, options) {
|
|
|
58
57
|
await init();
|
|
59
58
|
if (!fd) return;
|
|
60
59
|
while (pageQueue.queue.length < prefetch && pos > 0) {
|
|
61
|
-
const readSize = Math.min(
|
|
60
|
+
const readSize = Math.min(chunkSize, pos);
|
|
62
61
|
pos -= readSize;
|
|
63
62
|
const buf = Buffer.allocUnsafe(readSize);
|
|
64
63
|
await fd.read(buf, 0, readSize, pos);
|
|
65
|
-
buffer += buf.toString(
|
|
64
|
+
buffer += buf.toString("utf8");
|
|
66
65
|
let idx;
|
|
67
66
|
while ((idx = buffer.lastIndexOf(delimiter)) !== -1) {
|
|
68
67
|
const line = buffer.slice(idx + delimiter.length);
|
|
@@ -130,7 +129,7 @@ function createBackwardReader(filepath, options) {
|
|
|
130
129
|
//#endregion
|
|
131
130
|
//#region src/reader/forward.reader.ts
|
|
132
131
|
function createForwardReader(filepath, options) {
|
|
133
|
-
const { pageSize, delimiter, prefetch } = options;
|
|
132
|
+
const { chunkSize, pageSize, delimiter, prefetch } = options;
|
|
134
133
|
const pageQueue = createPageQueue();
|
|
135
134
|
let fd = null;
|
|
136
135
|
let pos = 0;
|
|
@@ -153,11 +152,11 @@ function createForwardReader(filepath, options) {
|
|
|
153
152
|
await init();
|
|
154
153
|
if (!fd) return;
|
|
155
154
|
while (pageQueue.queue.length < prefetch && pos < size) {
|
|
156
|
-
const readSize = Math.min(
|
|
155
|
+
const readSize = Math.min(chunkSize, size - pos);
|
|
157
156
|
const buf = Buffer.allocUnsafe(readSize);
|
|
158
157
|
const { bytesRead } = await fd.read(buf, 0, readSize, pos);
|
|
159
158
|
pos += bytesRead;
|
|
160
|
-
buffer += buf.toString(
|
|
159
|
+
buffer += buf.toString("utf8", 0, bytesRead);
|
|
161
160
|
let idx;
|
|
162
161
|
while ((idx = buffer.indexOf(delimiter)) !== -1) {
|
|
163
162
|
const line = buffer.slice(0, idx);
|
|
@@ -220,9 +219,10 @@ function createForwardReader(filepath, options) {
|
|
|
220
219
|
//#region src/reader/worker.reader.ts
|
|
221
220
|
const workerFile = typeof import.meta !== "undefined" ? new URL("./worker.mjs", import.meta.url) : __require.resolve("./worker.cjs");
|
|
222
221
|
function createWorkerReader(filepath, options) {
|
|
223
|
-
const { pageSize, delimiter, prefetch } = options;
|
|
222
|
+
const { chunkSize, pageSize, delimiter, prefetch } = options;
|
|
224
223
|
const worker = new Worker(new URL(workerFile, import.meta.url), { workerData: {
|
|
225
224
|
filepath,
|
|
225
|
+
chunkSize,
|
|
226
226
|
pageSize,
|
|
227
227
|
delimiter
|
|
228
228
|
} });
|
|
@@ -278,20 +278,23 @@ function createWorkerReader(filepath, options) {
|
|
|
278
278
|
//#endregion
|
|
279
279
|
//#region src/main.ts
|
|
280
280
|
function createPager(filepath, options = {}) {
|
|
281
|
-
const { pageSize = 1e3, delimiter = "\n", prefetch = 1, backward = false, useWorker = false } = options;
|
|
281
|
+
const { chunkSize = 64 * 1024, pageSize = 1e3, delimiter = "\n", prefetch = 1, backward = false, useWorker = false } = options;
|
|
282
282
|
if (!filepath) throw new Error("filepath required");
|
|
283
283
|
if (pageSize <= 0) throw new RangeError("pageSize must be > 0");
|
|
284
284
|
if (prefetch <= 0) throw new RangeError("prefetch must be >= 1");
|
|
285
285
|
if (backward && useWorker) throw new Error("backward not supported with useWorker");
|
|
286
286
|
return useWorker ? createWorkerReader(filepath, {
|
|
287
|
+
chunkSize,
|
|
287
288
|
pageSize,
|
|
288
289
|
prefetch,
|
|
289
290
|
delimiter
|
|
290
291
|
}) : backward ? createBackwardReader(filepath, {
|
|
292
|
+
chunkSize,
|
|
291
293
|
pageSize,
|
|
292
294
|
prefetch,
|
|
293
295
|
delimiter
|
|
294
296
|
}) : createForwardReader(filepath, {
|
|
297
|
+
chunkSize,
|
|
295
298
|
pageSize,
|
|
296
299
|
prefetch,
|
|
297
300
|
delimiter
|
package/dist/worker.cjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
const require_constants = require('./constants-Cyb_UQAC.cjs');
|
|
2
1
|
let node_fs_promises = require("node:fs/promises");
|
|
3
2
|
let node_worker_threads = require("node:worker_threads");
|
|
4
3
|
|
|
5
4
|
//#region src/worker.ts
|
|
6
|
-
const { filepath, pageSize, delimiter } = node_worker_threads.workerData;
|
|
5
|
+
const { filepath, chunkSize, pageSize, delimiter } = node_worker_threads.workerData;
|
|
7
6
|
(async () => {
|
|
8
7
|
const fd = await (0, node_fs_promises.open)(filepath, "r");
|
|
9
8
|
const { size } = await fd.stat();
|
|
@@ -11,7 +10,7 @@ const { filepath, pageSize, delimiter } = node_worker_threads.workerData;
|
|
|
11
10
|
let buffer = "";
|
|
12
11
|
const local = [];
|
|
13
12
|
while (pos < size) {
|
|
14
|
-
const readSize = Math.min(
|
|
13
|
+
const readSize = Math.min(chunkSize, size - pos);
|
|
15
14
|
const buf = Buffer.allocUnsafe(readSize);
|
|
16
15
|
const { bytesRead } = await fd.read(buf, 0, readSize, pos);
|
|
17
16
|
pos += bytesRead;
|
package/dist/worker.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { t as CHUNK_SIZE } from "./constants-BNKQoOqH.mjs";
|
|
2
1
|
import { open } from "node:fs/promises";
|
|
3
2
|
import { parentPort, workerData } from "node:worker_threads";
|
|
4
3
|
|
|
5
4
|
//#region src/worker.ts
|
|
6
|
-
const { filepath, pageSize, delimiter } = workerData;
|
|
5
|
+
const { filepath, chunkSize, pageSize, delimiter } = workerData;
|
|
7
6
|
(async () => {
|
|
8
7
|
const fd = await open(filepath, "r");
|
|
9
8
|
const { size } = await fd.stat();
|
|
@@ -11,7 +10,7 @@ const { filepath, pageSize, delimiter } = workerData;
|
|
|
11
10
|
let buffer = "";
|
|
12
11
|
const local = [];
|
|
13
12
|
while (pos < size) {
|
|
14
|
-
const readSize = Math.min(
|
|
13
|
+
const readSize = Math.min(chunkSize, size - pos);
|
|
15
14
|
const buf = Buffer.allocUnsafe(readSize);
|
|
16
15
|
const { bytesRead } = await fd.read(buf, 0, readSize, pos);
|
|
17
16
|
pos += bytesRead;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "readline-pager",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "tsdown",
|
|
6
6
|
"pretest": "npm run build",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"prepublishOnly": "npm run build && npm run test"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
|
+
"@types/bun": "~1.3.9",
|
|
11
12
|
"@types/node": "~25.3.0",
|
|
12
13
|
"prettier": "~3.8.1",
|
|
13
14
|
"prettier-plugin-organize-imports": "~4.3.0",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/constants.ts
|
|
3
|
-
const CHUNK_SIZE = 64 * 1024;
|
|
4
|
-
const ENCODING = "utf8";
|
|
5
|
-
|
|
6
|
-
//#endregion
|
|
7
|
-
Object.defineProperty(exports, 'CHUNK_SIZE', {
|
|
8
|
-
enumerable: true,
|
|
9
|
-
get: function () {
|
|
10
|
-
return CHUNK_SIZE;
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
Object.defineProperty(exports, 'ENCODING', {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () {
|
|
16
|
-
return ENCODING;
|
|
17
|
-
}
|
|
18
|
-
});
|