readline-pager 0.4.10 → 0.6.2

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/dist/main.mjs CHANGED
@@ -6,7 +6,7 @@ import { Worker } from "node:worker_threads";
6
6
  //#region \0rolldown/runtime.js
7
7
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
8
8
  //#endregion
9
- //#region src/queue.ts
9
+ //#region src/helper.ts
10
10
  function createRingBuffer(capacity) {
11
11
  if (!Number.isFinite(capacity) || capacity <= 0) throw new RangeError("capacity must be a positive number");
12
12
  let buf = new Array(capacity);
@@ -102,115 +102,99 @@ function createBackwardReader(filepath, options) {
102
102
  let buffer = "";
103
103
  let done = false;
104
104
  let closed = false;
105
+ let flushed = false;
105
106
  let startsWithDelimiter = false;
107
+ function consumeBuffer() {
108
+ let idx;
109
+ while ((idx = buffer.lastIndexOf(delimiter)) !== -1) {
110
+ const line = buffer.slice(idx + delimiter.length);
111
+ buffer = buffer.slice(0, idx);
112
+ local.push(line);
113
+ while (local.length >= pageSize) pageQueue.push(local.splice(0, pageSize));
114
+ }
115
+ }
116
+ function flushTail() {
117
+ if (flushed) return;
118
+ flushed = true;
119
+ if (buffer.length > 0) local.push(buffer);
120
+ else if (startsWithDelimiter) local.push("");
121
+ buffer = "";
122
+ while (local.length > 0) {
123
+ const page = local.slice(local.length - Math.min(pageSize, local.length));
124
+ local.length -= page.length;
125
+ pageQueue.push(page);
126
+ }
127
+ done = true;
128
+ pageQueue.wake();
129
+ }
106
130
  fdSync = openSync(filepath, "r");
107
131
  pos = statSync(filepath).size;
108
132
  if (pos === 0) {
109
- pageQueue.push([buffer]);
133
+ pageQueue.push([""]);
110
134
  done = true;
135
+ flushed = true;
111
136
  pageQueue.wake();
112
137
  }
113
138
  (async () => {
114
- try {
115
- fd = await open(filepath, "r");
116
- pos = (await fd.stat()).size;
117
- if (pos === 0) {
118
- if (!done) {
119
- pageQueue.push([buffer]);
120
- done = true;
121
- }
122
- if (fd) {
123
- await fd.close();
124
- fd = null;
125
- }
126
- pageQueue.wake();
127
- return;
139
+ fd = await open(filepath, "r");
140
+ pos = (await fd.stat()).size;
141
+ if (pos === 0) {
142
+ if (!done) {
143
+ pageQueue.push([""]);
144
+ done = true;
145
+ flushed = true;
128
146
  }
129
- while (!done && !closed) {
130
- while (pageQueue.count < prefetch && pos > 0 && !closed) {
131
- const readSize = Math.min(chunkSize, pos);
132
- pos -= readSize;
133
- const buf = Buffer.allocUnsafe(readSize);
134
- await fd.read(buf, 0, readSize, pos);
135
- buffer = buf.toString("utf8") + buffer;
136
- if (pos === 0 && buffer.startsWith(delimiter)) startsWithDelimiter = true;
137
- let idx;
138
- while ((idx = buffer.lastIndexOf(delimiter)) !== -1) {
139
- const line = buffer.slice(idx + delimiter.length);
140
- buffer = buffer.slice(0, idx);
141
- local.push(line);
142
- while (local.length >= pageSize) {
143
- const page = local.splice(0, pageSize);
144
- pageQueue.push(page);
145
- }
146
- }
147
- }
148
- if (pos === 0 && !done) {
149
- if (buffer.length > 0) local.push(buffer);
150
- else if (startsWithDelimiter) local.push("");
151
- buffer = "";
152
- while (local.length > 0 && !closed) {
153
- const page = local.slice(local.length - Math.min(pageSize, local.length));
154
- local.length -= page.length;
155
- pageQueue.push(page);
156
- }
157
- done = true;
158
- if (fd) {
159
- await fd.close();
160
- fd = null;
161
- }
162
- pageQueue.wake();
163
- break;
164
- }
165
- if (!done && !closed) await new Promise((r) => setImmediate(r));
147
+ if (fd) {
148
+ try {
149
+ await fd.close();
150
+ } catch {}
151
+ fd = null;
166
152
  }
167
- } catch {
168
- done = true;
169
153
  pageQueue.wake();
170
- try {
154
+ return;
155
+ }
156
+ while (!done && !closed) {
157
+ while (pageQueue.count < prefetch && pos > 0 && !closed) {
158
+ const readSize = Math.min(chunkSize, pos);
159
+ pos -= readSize;
160
+ const buf = Buffer.allocUnsafe(readSize);
161
+ const { bytesRead } = await fd.read(buf, 0, readSize, pos);
162
+ buffer = buf.toString("utf8", 0, bytesRead) + buffer;
163
+ if (pos === 0 && buffer.startsWith(delimiter)) startsWithDelimiter = true;
164
+ consumeBuffer();
165
+ }
166
+ if (pos === 0 && !flushed) {
167
+ flushTail();
171
168
  if (fd) {
172
- await fd.close();
169
+ try {
170
+ await fd.close();
171
+ } catch {}
173
172
  fd = null;
174
173
  }
175
- } catch {}
174
+ break;
175
+ }
176
+ if (!done && !closed) await new Promise((r) => setImmediate(r));
176
177
  }
177
178
  })();
178
179
  function fillSync() {
179
- if (done || closed) return;
180
- if (fdSync === null) return;
180
+ if (done || closed || !fdSync) return;
181
181
  while (pageQueue.count < prefetch && pos > 0 && !closed) {
182
182
  const readSize = Math.min(chunkSize, pos);
183
183
  pos -= readSize;
184
184
  const buf = Buffer.allocUnsafe(readSize);
185
- readSync(fdSync, buf, 0, readSize, pos);
186
- buffer = buf.toString("utf8") + buffer;
185
+ const bytesRead = readSync(fdSync, buf, 0, readSize, pos);
186
+ buffer = buf.toString("utf8", 0, bytesRead) + buffer;
187
187
  if (pos === 0 && buffer.startsWith(delimiter)) startsWithDelimiter = true;
188
- let idx;
189
- while ((idx = buffer.lastIndexOf(delimiter)) !== -1) {
190
- const line = buffer.slice(idx + delimiter.length);
191
- buffer = buffer.slice(0, idx);
192
- local.push(line);
193
- while (local.length >= pageSize) {
194
- const page = local.splice(0, pageSize);
195
- pageQueue.push(page);
196
- }
197
- }
188
+ consumeBuffer();
198
189
  }
199
- if (pos === 0 && !done) {
200
- if (buffer.length > 0) local.push(buffer);
201
- else if (startsWithDelimiter) local.push("");
202
- buffer = "";
203
- while (local.length > 0) {
204
- const page = local.slice(local.length - Math.min(pageSize, local.length));
205
- local.length -= page.length;
206
- pageQueue.push(page);
207
- }
208
- done = true;
209
- if (fdSync !== null) {
210
- closeSync(fdSync);
190
+ if (pos === 0 && !flushed) {
191
+ flushTail();
192
+ if (fdSync) {
193
+ try {
194
+ closeSync(fdSync);
195
+ } catch {}
211
196
  fdSync = null;
212
197
  }
213
- pageQueue.wake();
214
198
  }
215
199
  }
216
200
  async function next() {
@@ -223,20 +207,21 @@ function createBackwardReader(filepath, options) {
223
207
  return pageQueue.shiftSync();
224
208
  }
225
209
  async function close() {
210
+ if (closed) return;
226
211
  closed = true;
227
212
  done = true;
228
213
  pageQueue.clear();
229
- if (fd) {
214
+ if (fdSync) {
230
215
  try {
231
- await fd.close();
216
+ closeSync(fdSync);
232
217
  } catch {}
233
- fd = null;
218
+ fdSync = null;
234
219
  }
235
- if (fdSync !== null) {
220
+ if (fd) {
236
221
  try {
237
- closeSync(fdSync);
222
+ await fd.close();
238
223
  } catch {}
239
- fdSync = null;
224
+ fd = null;
240
225
  }
241
226
  }
242
227
  return {
@@ -265,14 +250,18 @@ function createBackwardReader(filepath, options) {
265
250
  closed = true;
266
251
  done = true;
267
252
  pageQueue.clear();
268
- try {
269
- if (fdSync) closeSync(fdSync);
270
- } catch {}
271
- fdSync = null;
272
- try {
273
- if (fd?.fd) closeSync(fd.fd);
274
- } catch {}
275
- fd = null;
253
+ if (fdSync) {
254
+ try {
255
+ closeSync(fdSync);
256
+ } catch {}
257
+ fdSync = null;
258
+ }
259
+ if (fd?.fd) {
260
+ try {
261
+ closeSync(fd.fd);
262
+ } catch {}
263
+ fd = null;
264
+ }
276
265
  }
277
266
  }
278
267
  };
@@ -291,106 +280,90 @@ function createForwardReader(filepath, options) {
291
280
  let done = false;
292
281
  let closed = false;
293
282
  let flushed = false;
283
+ function consumeBuffer() {
284
+ let idx;
285
+ while ((idx = buffer.indexOf(delimiter)) !== -1) {
286
+ const line = buffer.slice(0, idx);
287
+ buffer = buffer.slice(idx + delimiter.length);
288
+ local.push(line);
289
+ while (local.length >= pageSize) pageQueue.push(local.splice(0, pageSize));
290
+ }
291
+ }
292
+ function flushTail() {
293
+ if (flushed) return;
294
+ flushed = true;
295
+ local.push(buffer.length > 0 ? buffer : "");
296
+ buffer = "";
297
+ while (local.length > 0) pageQueue.push(local.splice(0, pageSize));
298
+ done = true;
299
+ pageQueue.wake();
300
+ }
294
301
  fdSync = openSync(filepath, "r");
295
302
  size = statSync(filepath).size;
296
303
  if (size === 0) {
297
- pageQueue.push([buffer]);
304
+ pageQueue.push([""]);
298
305
  done = true;
306
+ flushed = true;
299
307
  pageQueue.wake();
300
308
  }
301
309
  (async () => {
302
- try {
303
- fd = await open(filepath, "r");
304
- size = (await fd.stat()).size;
305
- if (size === 0) {
306
- if (!done) {
307
- pageQueue.push([buffer]);
308
- done = true;
309
- }
310
- if (fd) {
311
- await fd.close();
312
- fd = null;
313
- }
314
- pageQueue.wake();
315
- return;
310
+ fd = await open(filepath, "r");
311
+ size = (await fd.stat()).size;
312
+ if (size === 0) {
313
+ if (!done) {
314
+ pageQueue.push([""]);
315
+ done = true;
316
+ flushed = true;
316
317
  }
317
- while (!done && !closed) {
318
- while (pageQueue.count < prefetch && pos < size && !closed) {
319
- const readSize = Math.min(chunkSize, size - pos);
320
- const buf = Buffer.allocUnsafe(readSize);
321
- const { bytesRead } = await fd.read(buf, 0, readSize, pos);
322
- pos += bytesRead;
323
- buffer = buffer + buf.toString("utf8", 0, bytesRead);
324
- let idx;
325
- while ((idx = buffer.indexOf(delimiter)) !== -1) {
326
- const line = buffer.slice(0, idx);
327
- buffer = buffer.slice(idx + delimiter.length);
328
- local.push(line);
329
- while (local.length >= pageSize) pageQueue.push(local.splice(0, pageSize));
330
- }
331
- }
332
- if (pos >= size && !flushed) {
333
- flushed = true;
334
- local.push(buffer.length > 0 ? buffer : "");
335
- buffer = "";
336
- while (local.length > 0 && !closed) {
337
- const page = local.slice(0, pageSize);
338
- local.length -= page.length;
339
- pageQueue.push(page);
340
- }
341
- done = true;
342
- if (fd) {
343
- await fd.close();
344
- fd = null;
345
- }
346
- pageQueue.wake();
347
- break;
348
- }
349
- if (!done && !closed) await new Promise((r) => setImmediate(r));
318
+ if (fd) {
319
+ try {
320
+ await fd.close();
321
+ } catch {}
322
+ fd = null;
350
323
  }
351
- } catch {
352
- done = true;
353
324
  pageQueue.wake();
354
- try {
325
+ return;
326
+ }
327
+ while (!done && !closed) {
328
+ while (pageQueue.count < prefetch && pos < size && !closed) {
329
+ const readSize = Math.min(chunkSize, size - pos);
330
+ const buf = Buffer.allocUnsafe(readSize);
331
+ const { bytesRead } = await fd.read(buf, 0, readSize, pos);
332
+ pos += bytesRead;
333
+ buffer = buffer + buf.toString("utf8", 0, bytesRead);
334
+ consumeBuffer();
335
+ }
336
+ if (pos >= size && !flushed) {
337
+ flushTail();
355
338
  if (fd) {
356
- await fd.close();
339
+ try {
340
+ await fd.close();
341
+ } catch {}
357
342
  fd = null;
358
343
  }
359
- } catch {}
344
+ break;
345
+ }
346
+ if (!done && !closed) await new Promise((r) => setImmediate(r));
360
347
  }
361
348
  })();
362
349
  function fillSync() {
363
- if (done || closed) return;
364
- if (fdSync === null) return;
350
+ if (done || closed || !fdSync) return;
365
351
  while (pageQueue.count < prefetch && pos < size && !closed) {
366
352
  const readSize = Math.min(chunkSize, size - pos);
367
353
  const buf = Buffer.allocUnsafe(readSize);
368
354
  const bytesRead = readSync(fdSync, buf, 0, readSize, pos);
369
355
  pos += bytesRead;
370
356
  buffer = buffer + buf.toString("utf8", 0, bytesRead);
371
- let idx;
372
- while ((idx = buffer.indexOf(delimiter)) !== -1) {
373
- const line = buffer.slice(0, idx);
374
- buffer = buffer.slice(idx + delimiter.length);
375
- local.push(line);
376
- while (local.length >= pageSize) pageQueue.push(local.splice(0, pageSize));
377
- }
357
+ consumeBuffer();
378
358
  }
379
359
  if (pos >= size && !flushed) {
380
- flushed = true;
381
- local.push(buffer.length > 0 ? buffer : "");
382
- buffer = "";
383
- while (local.length > 0) {
384
- const page = local.slice(0, pageSize);
385
- local.length -= page.length;
386
- pageQueue.push(page);
387
- }
388
- done = true;
389
- if (fdSync !== null) {
390
- closeSync(fdSync);
360
+ flushTail();
361
+ if (fdSync) {
362
+ try {
363
+ closeSync(fdSync);
364
+ } catch {}
391
365
  fdSync = null;
392
366
  }
393
- pageQueue.wake();
394
367
  }
395
368
  }
396
369
  async function next() {
@@ -403,20 +376,21 @@ function createForwardReader(filepath, options) {
403
376
  return pageQueue.shiftSync();
404
377
  }
405
378
  async function close() {
379
+ if (closed) return;
406
380
  closed = true;
407
381
  done = true;
408
382
  pageQueue.clear();
409
- if (fd) {
383
+ if (fdSync) {
410
384
  try {
411
- await fd.close();
385
+ closeSync(fdSync);
412
386
  } catch {}
413
- fd = null;
387
+ fdSync = null;
414
388
  }
415
- if (fdSync !== null) {
389
+ if (fd) {
416
390
  try {
417
- closeSync(fdSync);
391
+ await fd.close();
418
392
  } catch {}
419
- fdSync = null;
393
+ fd = null;
420
394
  }
421
395
  }
422
396
  return {
@@ -445,14 +419,18 @@ function createForwardReader(filepath, options) {
445
419
  closed = true;
446
420
  done = true;
447
421
  pageQueue.clear();
448
- try {
449
- if (fdSync !== null) closeSync(fdSync);
450
- } catch {}
451
- fdSync = null;
452
- try {
453
- if (fd?.fd) closeSync(fd.fd);
454
- } catch {}
455
- fd = null;
422
+ if (fdSync) {
423
+ try {
424
+ closeSync(fdSync);
425
+ } catch {}
426
+ fdSync = null;
427
+ }
428
+ if (fd?.fd) {
429
+ try {
430
+ closeSync(fd.fd);
431
+ } catch {}
432
+ fd = null;
433
+ }
456
434
  }
457
435
  }
458
436
  };
@@ -462,18 +440,23 @@ function createForwardReader(filepath, options) {
462
440
  const workerFile = typeof import.meta !== "undefined" ? new URL("./worker.mjs", import.meta.url) : __require.resolve("./worker.cjs");
463
441
  function createWorkerReader(filepath, options) {
464
442
  const { prefetch } = options;
465
- const pageQueue = createRingBuffer(Math.max(2, prefetch + 1));
466
443
  let done = false;
467
444
  let closed = false;
445
+ const pageQueue = createRingBuffer(Math.max(2, prefetch + 1));
468
446
  const worker = new Worker(new URL(workerFile, import.meta.url), { workerData: {
469
447
  filepath,
470
448
  options
471
449
  } });
472
450
  worker.on("message", (msg) => {
473
- if (msg.type === "page") pageQueue.push(msg.data);
474
- if (msg.type === "done") {
475
- done = true;
476
- pageQueue.wake();
451
+ switch (msg.type) {
452
+ case "page":
453
+ pageQueue.push(msg.data);
454
+ break;
455
+ case "done":
456
+ case "error":
457
+ done = true;
458
+ pageQueue.wake();
459
+ break;
477
460
  }
478
461
  });
479
462
  worker.on("error", () => {
@@ -493,10 +476,13 @@ function createWorkerReader(filepath, options) {
493
476
  return pageQueue.shiftSync();
494
477
  }
495
478
  async function close() {
479
+ if (closed) return;
496
480
  closed = true;
497
481
  done = true;
498
482
  pageQueue.clear();
499
- await worker.terminate();
483
+ try {
484
+ await worker.terminate();
485
+ } catch {}
500
486
  }
501
487
  function tryClose() {
502
488
  close().catch(() => {});
@@ -532,18 +518,35 @@ function createWorkerReader(filepath, options) {
532
518
  //#endregion
533
519
  //#region src/main.ts
534
520
  function createPager(filepath, options = {}) {
535
- const { chunkSize = 64 * 1024, pageSize = 1e3, delimiter = "\n", prefetch = 8, backward = false, useWorker = false } = options;
521
+ const { chunkSize = 64 * 1024, pageSize = 1e3, delimiter = "\n", prefetch = 8, backward = false, useWorker = false, tryNative = true } = options;
536
522
  if (!filepath) throw new Error("filepath required");
537
523
  if (pageSize < 1) throw new RangeError("pageSize must be >= 1");
538
524
  if (prefetch < 1) throw new RangeError("prefetch must be >= 1");
539
- if (backward && useWorker) throw new Error("backward not supported with useWorker");
525
+ if (useWorker) {
526
+ if (backward) throw new Error("backward not supported with useWorker");
527
+ if (tryNative) throw new Error("tryNative not supported with useWorker");
528
+ }
529
+ if (tryNative) {
530
+ if (delimiter.length !== 1) throw new RangeError("native reader only supports single-character delimiters");
531
+ }
540
532
  const _options = {
541
533
  chunkSize,
542
534
  pageSize,
543
535
  prefetch,
544
536
  delimiter
545
537
  };
546
- const reader = useWorker ? createWorkerReader(filepath, _options) : backward ? createBackwardReader(filepath, _options) : createForwardReader(filepath, _options);
538
+ let nativeReader;
539
+ if (tryNative) {
540
+ const _nativeOptions = {
541
+ pageSize,
542
+ delimiter,
543
+ backward
544
+ };
545
+ try {
546
+ nativeReader = createNativePager(filepath, _nativeOptions);
547
+ } catch {}
548
+ }
549
+ const reader = tryNative && nativeReader ? nativeReader : useWorker ? createWorkerReader(filepath, _options) : backward ? createBackwardReader(filepath, _options) : createForwardReader(filepath, _options);
547
550
  if (process.env.TEST_CLEANUPS) {
548
551
  globalThis.__test_cleanups__ ??= [];
549
552
  globalThis.__test_cleanups__.push(reader.close);
@@ -0,0 +1,46 @@
1
+ //#region src/types.d.ts
2
+ interface ReaderOptions {
3
+ chunkSize: number;
4
+ pageSize: number;
5
+ delimiter: string;
6
+ prefetch: number;
7
+ }
8
+ interface PagerOptions extends Partial<ReaderOptions> {
9
+ backward?: boolean;
10
+ useWorker?: boolean;
11
+ tryNative?: boolean;
12
+ }
13
+ interface NativeReaderOptions {
14
+ pageSize: number;
15
+ delimiter: string;
16
+ backward: boolean;
17
+ }
18
+ type WorkerMessage = {
19
+ type: "page";
20
+ data: string[];
21
+ } | {
22
+ type: "error";
23
+ error: unknown;
24
+ } | {
25
+ type: "done";
26
+ };
27
+ type AddonFD = object | null;
28
+ type AddonData = Buffer | null;
29
+ interface NativeAddon {
30
+ open: (filepath: string, pageSize: number, delimiter: string, backward: boolean) => AddonFD;
31
+ next: (fd: AddonFD) => Promise<AddonData>;
32
+ nextSync: (fd: AddonFD) => AddonData;
33
+ close: (fd: AddonFD) => Promise<void>;
34
+ }
35
+ interface Pager {
36
+ next(): Promise<string[] | null>;
37
+ nextSync(): string[] | null;
38
+ close(): Promise<void>;
39
+ [Symbol.asyncIterator](): AsyncIterator<string[]>;
40
+ [Symbol.iterator](): Iterator<string[]>;
41
+ }
42
+ //#endregion
43
+ //#region src/native.d.ts
44
+ declare function createNativePager(filepath: string, options?: Partial<NativeReaderOptions>): Pager;
45
+ //#endregion
46
+ export { PagerOptions as a, Pager as i, NativeAddon as n, ReaderOptions as o, NativeReaderOptions as r, WorkerMessage as s, createNativePager as t };
@@ -0,0 +1,46 @@
1
+ //#region src/types.d.ts
2
+ interface ReaderOptions {
3
+ chunkSize: number;
4
+ pageSize: number;
5
+ delimiter: string;
6
+ prefetch: number;
7
+ }
8
+ interface PagerOptions extends Partial<ReaderOptions> {
9
+ backward?: boolean;
10
+ useWorker?: boolean;
11
+ tryNative?: boolean;
12
+ }
13
+ interface NativeReaderOptions {
14
+ pageSize: number;
15
+ delimiter: string;
16
+ backward: boolean;
17
+ }
18
+ type WorkerMessage = {
19
+ type: "page";
20
+ data: string[];
21
+ } | {
22
+ type: "error";
23
+ error: unknown;
24
+ } | {
25
+ type: "done";
26
+ };
27
+ type AddonFD = object | null;
28
+ type AddonData = Buffer | null;
29
+ interface NativeAddon {
30
+ open: (filepath: string, pageSize: number, delimiter: string, backward: boolean) => AddonFD;
31
+ next: (fd: AddonFD) => Promise<AddonData>;
32
+ nextSync: (fd: AddonFD) => AddonData;
33
+ close: (fd: AddonFD) => Promise<void>;
34
+ }
35
+ interface Pager {
36
+ next(): Promise<string[] | null>;
37
+ nextSync(): string[] | null;
38
+ close(): Promise<void>;
39
+ [Symbol.asyncIterator](): AsyncIterator<string[]>;
40
+ [Symbol.iterator](): Iterator<string[]>;
41
+ }
42
+ //#endregion
43
+ //#region src/native.d.ts
44
+ declare function createNativePager(filepath: string, options?: Partial<NativeReaderOptions>): Pager;
45
+ //#endregion
46
+ export { PagerOptions as a, Pager as i, NativeAddon as n, ReaderOptions as o, NativeReaderOptions as r, WorkerMessage as s, createNativePager as t };
package/dist/native.cjs CHANGED
@@ -29,36 +29,39 @@ function loadNativeAddon() {
29
29
  throw new Error(UNAVAILABLE);
30
30
  }
31
31
  }
32
- function createNativePager(filepath, { pageSize = 1e3, delimiter = "\n" } = {}) {
33
- const pagerNative = loadNativeAddon();
34
- let fd = null;
32
+ function createNativePager(filepath, options) {
33
+ const { pageSize = 1e3, delimiter = "\n", backward = false } = options ?? {};
34
+ if (!filepath) throw new Error("filepath required");
35
+ if (pageSize < 1) throw new RangeError("pageSize must be >= 1");
36
+ if (delimiter.length !== 1) throw new RangeError("native reader only supports single-character delimiters");
37
+ const nativePager = loadNativeAddon();
38
+ let fd = nativePager.open(filepath, pageSize, delimiter, backward);
35
39
  let closed = false;
36
- const init = () => {
37
- fd = pagerNative.open(filepath, pageSize, delimiter);
38
- };
39
40
  const next = async () => {
40
41
  if (closed || !fd) return null;
41
- const data = await pagerNative.next(fd);
42
+ const data = await nativePager.next(fd);
42
43
  if (!data) return null;
43
44
  return data.toString("utf8").split(delimiter);
44
45
  };
45
46
  const nextSync = () => {
46
47
  if (closed || !fd) return null;
47
- const data = pagerNative.nextSync(fd);
48
+ const data = nativePager.nextSync(fd);
48
49
  if (!data) return null;
49
50
  return data.toString("utf8").split(delimiter);
50
51
  };
51
52
  const close = async () => {
52
- if (!closed || fd) {
53
- closed = true;
54
- await pagerNative.close(fd);
53
+ if (closed) return;
54
+ closed = true;
55
+ if (fd) {
56
+ try {
57
+ await nativePager.close(fd);
58
+ } catch {}
55
59
  fd = null;
56
60
  }
57
61
  };
58
62
  function tryClose() {
59
63
  close().catch(() => {});
60
64
  }
61
- init();
62
65
  return {
63
66
  next,
64
67
  nextSync,
package/dist/native.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createNativePager } from "./native-BNwCco1j.cjs";
1
+ import { t as createNativePager } from "./native-_NmVYcF6.cjs";
2
2
  export { createNativePager };