@naturalcycles/nodejs-lib 15.21.0 → 15.23.0

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.
Files changed (50) hide show
  1. package/dist/exec2/exec2.js +1 -0
  2. package/dist/stream/index.d.ts +2 -2
  3. package/dist/stream/index.js +2 -2
  4. package/dist/stream/ndjson/ndjsonMap.d.ts +1 -1
  5. package/dist/stream/ndjson/ndjsonMap.js +13 -15
  6. package/dist/stream/ndjson/ndjsonStreamForEach.d.ts +2 -2
  7. package/dist/stream/ndjson/ndjsonStreamForEach.js +9 -15
  8. package/dist/stream/ndjson/transformJsonParse.js +0 -1
  9. package/dist/stream/pipeline.d.ts +79 -0
  10. package/dist/stream/pipeline.js +220 -0
  11. package/dist/stream/readable/readableCombined.d.ts +30 -0
  12. package/dist/stream/readable/readableCombined.js +77 -0
  13. package/dist/stream/stream.util.d.ts +1 -3
  14. package/dist/stream/stream.util.js +1 -20
  15. package/dist/stream/transform/transformChunk.d.ts +5 -8
  16. package/dist/stream/transform/transformChunk.js +4 -2
  17. package/dist/stream/transform/transformFlatten.d.ts +1 -0
  18. package/dist/stream/transform/transformFlatten.js +15 -4
  19. package/dist/stream/transform/transformLimit.d.ts +3 -26
  20. package/dist/stream/transform/transformLimit.js +14 -23
  21. package/dist/stream/transform/transformMap.d.ts +15 -2
  22. package/dist/stream/transform/transformMap.js +25 -19
  23. package/dist/stream/transform/transformMapSync.d.ts +5 -3
  24. package/dist/stream/transform/transformMapSync.js +7 -8
  25. package/dist/stream/transform/transformTee.js +4 -2
  26. package/dist/stream/writable/writableForEach.d.ts +2 -1
  27. package/dist/stream/writable/writableFork.js +2 -2
  28. package/package.json +1 -1
  29. package/src/exec2/exec2.ts +1 -0
  30. package/src/stream/index.ts +2 -2
  31. package/src/stream/ndjson/ndjsonMap.ts +12 -22
  32. package/src/stream/ndjson/ndjsonStreamForEach.ts +8 -15
  33. package/src/stream/ndjson/transformJsonParse.ts +0 -1
  34. package/src/stream/pipeline.ts +301 -0
  35. package/src/stream/readable/readableCombined.ts +87 -0
  36. package/src/stream/stream.util.ts +1 -29
  37. package/src/stream/transform/transformChunk.ts +8 -11
  38. package/src/stream/transform/transformFlatten.ts +16 -4
  39. package/src/stream/transform/transformLimit.ts +20 -51
  40. package/src/stream/transform/transformMap.ts +45 -21
  41. package/src/stream/transform/transformMapSync.ts +14 -8
  42. package/src/stream/transform/transformTee.ts +5 -2
  43. package/src/stream/writable/writableForEach.ts +2 -2
  44. package/src/stream/writable/writableFork.ts +2 -2
  45. package/dist/stream/pipeline/pipeline.d.ts +0 -36
  46. package/dist/stream/pipeline/pipeline.js +0 -82
  47. package/dist/stream/readable/readableForEach.d.ts +0 -19
  48. package/dist/stream/readable/readableForEach.js +0 -30
  49. package/src/stream/pipeline/pipeline.ts +0 -114
  50. package/src/stream/readable/readableForEach.ts +0 -42
@@ -1,6 +1,4 @@
1
- import type { Readable } from 'node:stream';
2
- import type { CommonLogger } from '@naturalcycles/js-lib/log';
3
- import { AbortableTransform } from '../pipeline/pipeline.js';
1
+ import type { AbortableSignal } from '@naturalcycles/js-lib';
4
2
  import type { TransformOptions, TransformTyped } from '../stream.model.js';
5
3
  export interface TransformLimitOptions extends TransformOptions {
6
4
  /**
@@ -8,29 +6,8 @@ export interface TransformLimitOptions extends TransformOptions {
8
6
  */
9
7
  limit?: number;
10
8
  /**
11
- * If provided (recommended!) - it will call readable.destroy() on limit.
12
- * Without it - it will only stop the downstream consumers, but won't stop
13
- * the Readable ("source" of the stream).
14
- * It is almost always crucial to stop the Source too, so, please provide the Readable here!
9
+ * Allows to abort (gracefully stop) the stream from inside the Transform.
15
10
  */
16
- sourceReadable?: Readable;
17
- /**
18
- * Please provide it (a Promise that resolves when the Stream is done, e.g finished consuming things)
19
- * to be able to wait for Consumers before calling `readable.destroy`.
20
- * Has no effect if `readable` is not provided.
21
- */
22
- streamDone?: Promise<void>;
23
- logger?: CommonLogger;
24
- /**
25
- * Set to true to enable additional debug messages, e.g it'll log
26
- * when readable still emits values after the limit is reached.
27
- */
28
- debug?: boolean;
29
- }
30
- /**
31
- * Class only exists to be able to do `instanceof TransformLimit`
32
- * and to set sourceReadable+streamDone to it in `_pipeline`.
33
- */
34
- export declare class TransformLimit extends AbortableTransform {
11
+ signal: AbortableSignal;
35
12
  }
36
13
  export declare function transformLimit<IN>(opt: TransformLimitOptions): TransformTyped<IN, IN>;
@@ -1,41 +1,32 @@
1
- import { AbortableTransform } from '../pipeline/pipeline.js';
2
- import { pipelineClose } from '../stream.util.js';
1
+ import { Transform } from 'node:stream';
2
+ import { PIPELINE_GRACEFUL_ABORT } from '../stream.util.js';
3
3
  import { transformNoOp } from './transformNoOp.js';
4
- /**
5
- * Class only exists to be able to do `instanceof TransformLimit`
6
- * and to set sourceReadable+streamDone to it in `_pipeline`.
7
- */
8
- export class TransformLimit extends AbortableTransform {
9
- }
10
4
  export function transformLimit(opt) {
11
- const { logger = console, limit, debug } = opt;
5
+ const { limit, signal } = opt;
12
6
  if (!limit) {
13
- // No limit - returning pass-through transform
14
7
  return transformNoOp();
15
8
  }
16
9
  let i = 0; // so we start first chunk with 1
17
10
  let ended = false;
18
- return new TransformLimit({
11
+ return new Transform({
19
12
  objectMode: true,
20
13
  ...opt,
21
14
  transform(chunk, _, cb) {
15
+ if (ended) {
16
+ return;
17
+ }
22
18
  i++;
23
19
  if (i === limit) {
24
20
  ended = true;
25
- logger.log(`transformLimit of ${limit} reached`);
26
21
  this.push(chunk);
27
- pipelineClose('transformLimit', this, opt.sourceReadable || this.sourceReadable, opt.streamDone || this.streamDone, logger);
28
- cb(); // after pause
29
- }
30
- else if (!ended) {
31
- cb(null, chunk);
32
- }
33
- else {
34
- if (debug)
35
- logger.log(`transformLimit.transform after limit`, i);
36
- // If we ever HANG (don't call cb) - Node will do process.exit(0) to us
37
- cb(); // ended, don't emit anything
22
+ this.push(null); // tell downstream that we're done
23
+ cb();
24
+ queueMicrotask(() => {
25
+ signal.abort(new Error(PIPELINE_GRACEFUL_ABORT));
26
+ });
27
+ return;
38
28
  }
29
+ cb(null, chunk);
39
30
  },
40
31
  });
41
32
  }
@@ -1,6 +1,7 @@
1
+ import { type AbortableSignal } from '@naturalcycles/js-lib';
1
2
  import { ErrorMode } from '@naturalcycles/js-lib/error';
2
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log';
3
- import { type AbortableAsyncMapper, type AsyncPredicate, END, type Promisable, SKIP, type StringMap, type UnixTimestampMillis } from '@naturalcycles/js-lib/types';
4
+ import { type AbortableAsyncMapper, type AsyncPredicate, END, type PositiveInteger, type Promisable, SKIP, type StringMap, type UnixTimestampMillis } from '@naturalcycles/js-lib/types';
4
5
  import type { TransformTyped } from '../stream.model.js';
5
6
  export interface TransformMapOptions<IN = any, OUT = IN> {
6
7
  /**
@@ -21,7 +22,15 @@ export interface TransformMapOptions<IN = any, OUT = IN> {
21
22
  * UPD: changed back from 32 to 16, "to be on a safe side", as 32 sometimes
22
23
  * causes "Datastore timeout errors".
23
24
  */
24
- concurrency?: number;
25
+ concurrency?: PositiveInteger;
26
+ /**
27
+ * Defaults to 64 items.
28
+ * (objectMode default is 16, but we increased it)
29
+ *
30
+ * Affects both readable and writable highWaterMark (buffer).
31
+ * So, 64 means a total buffer of 128 (64 input and 64 output buffer).
32
+ */
33
+ highWaterMark?: PositiveInteger;
25
34
  /**
26
35
  * @default THROW_IMMEDIATELY
27
36
  */
@@ -49,6 +58,10 @@ export interface TransformMapOptions<IN = any, OUT = IN> {
49
58
  */
50
59
  metric?: string;
51
60
  logger?: CommonLogger;
61
+ /**
62
+ * Allows to abort (gracefully stop) the stream from inside the Transform.
63
+ */
64
+ signal?: AbortableSignal;
52
65
  }
53
66
  export interface TransformMapStats {
54
67
  /**
@@ -1,11 +1,11 @@
1
1
  import { _hc } from '@naturalcycles/js-lib';
2
2
  import { _since } from '@naturalcycles/js-lib/datetime/time.util.js';
3
- import { _anyToError, ErrorMode } from '@naturalcycles/js-lib/error';
3
+ import { _anyToError, _assert, ErrorMode } from '@naturalcycles/js-lib/error';
4
4
  import { _stringify } from '@naturalcycles/js-lib/string/stringify.js';
5
5
  import { END, SKIP, } from '@naturalcycles/js-lib/types';
6
6
  import through2Concurrent from 'through2-concurrent';
7
7
  import { yellow } from '../../colors/colors.js';
8
- import { pipelineClose } from '../stream.util.js';
8
+ import { PIPELINE_GRACEFUL_ABORT } from '../stream.util.js';
9
9
  // doesn't work, cause here we don't construct our Transform instance ourselves
10
10
  // export class TransformMap extends AbortableTransform {}
11
11
  /**
@@ -21,16 +21,19 @@ import { pipelineClose } from '../stream.util.js';
21
21
  * If an Array is returned by `mapper` - it will be flattened and multiple results will be emitted from it. Tested by Array.isArray().
22
22
  */
23
23
  export function transformMap(mapper, opt = {}) {
24
- const { concurrency = 16, predicate, // we now default to "no predicate" (meaning pass-everything)
25
- errorMode = ErrorMode.THROW_IMMEDIATELY, onError, onDone, metric = 'stream', logger = console, } = opt;
24
+ const { concurrency = 16, highWaterMark = 64, predicate, // we now default to "no predicate" (meaning pass-everything)
25
+ errorMode = ErrorMode.THROW_IMMEDIATELY, onError, onDone, metric = 'stream', logger = console, signal, } = opt;
26
26
  const started = Date.now();
27
27
  let index = -1;
28
28
  let countOut = 0;
29
29
  let isSettled = false;
30
+ let ok = true;
30
31
  let errors = 0;
31
32
  const collectedErrors = []; // only used if errorMode == THROW_AGGREGATED
32
33
  return through2Concurrent.obj({
33
34
  maxConcurrency: concurrency,
35
+ readableHighWaterMark: highWaterMark,
36
+ writableHighWaterMark: highWaterMark,
34
37
  async final(cb) {
35
38
  // console.log('transformMap final')
36
39
  logErrorStats(true);
@@ -55,7 +58,7 @@ export function transformMap(mapper, opt = {}) {
55
58
  // emit no error
56
59
  try {
57
60
  await onDone?.({
58
- ok: true,
61
+ ok,
59
62
  collectedErrors,
60
63
  countErrors: errors,
61
64
  countIn: index + 1,
@@ -82,7 +85,8 @@ export function transformMap(mapper, opt = {}) {
82
85
  if (res === END) {
83
86
  isSettled = true;
84
87
  logger.log(`transformMap END received at index ${currentIndex}`);
85
- pipelineClose('transformMap', this, this.sourceReadable, this.streamDone, logger);
88
+ _assert(signal, 'signal is required when using END');
89
+ signal.abort(new Error(PIPELINE_GRACEFUL_ABORT));
86
90
  return cb();
87
91
  }
88
92
  if (res === SKIP) {
@@ -108,19 +112,21 @@ export function transformMap(mapper, opt = {}) {
108
112
  }
109
113
  if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
110
114
  isSettled = true;
111
- try {
112
- await onDone?.({
113
- ok: false,
114
- collectedErrors,
115
- countErrors: errors,
116
- countIn: index + 1,
117
- countOut,
118
- started,
119
- });
120
- }
121
- catch (err) {
122
- logger.error(err);
123
- }
115
+ ok = false;
116
+ // Tests show that onDone is still called at `final` (second time),
117
+ // so, we no longer call it here
118
+ // try {
119
+ // await onDone?.({
120
+ // ok: false,
121
+ // collectedErrors,
122
+ // countErrors: errors,
123
+ // countIn: index + 1,
124
+ // countOut,
125
+ // started,
126
+ // })
127
+ // } catch (err) {
128
+ // logger.error(err)
129
+ // }
124
130
  return cb(err); // Emit error immediately
125
131
  }
126
132
  if (errorMode === ErrorMode.THROW_AGGREGATED) {
@@ -1,8 +1,8 @@
1
+ import type { AbortableSignal } from '@naturalcycles/js-lib';
1
2
  import { ErrorMode } from '@naturalcycles/js-lib/error';
2
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log';
3
4
  import type { IndexedMapper, Predicate } from '@naturalcycles/js-lib/types';
4
5
  import { END, SKIP } from '@naturalcycles/js-lib/types';
5
- import { AbortableTransform } from '../pipeline/pipeline.js';
6
6
  import type { TransformTyped } from '../stream.model.js';
7
7
  import type { TransformMapStats } from './transformMap.js';
8
8
  export interface TransformMapSyncOptions<IN = any, OUT = IN> {
@@ -45,8 +45,10 @@ export interface TransformMapSyncOptions<IN = any, OUT = IN> {
45
45
  */
46
46
  metric?: string;
47
47
  logger?: CommonLogger;
48
- }
49
- export declare class TransformMapSync extends AbortableTransform {
48
+ /**
49
+ * Allows to abort (gracefully stop) the stream from inside the Transform.
50
+ */
51
+ signal?: AbortableSignal;
50
52
  }
51
53
  /**
52
54
  * Sync (not async) version of transformMap.
@@ -1,24 +1,22 @@
1
- import { _anyToError, ErrorMode } from '@naturalcycles/js-lib/error';
1
+ import { Transform } from 'node:stream';
2
+ import { _anyToError, _assert, ErrorMode } from '@naturalcycles/js-lib/error';
2
3
  import { END, SKIP } from '@naturalcycles/js-lib/types';
3
4
  import { yellow } from '../../colors/colors.js';
4
- import { AbortableTransform } from '../pipeline/pipeline.js';
5
- import { pipelineClose } from '../stream.util.js';
6
- export class TransformMapSync extends AbortableTransform {
7
- }
5
+ import { PIPELINE_GRACEFUL_ABORT } from '../stream.util.js';
8
6
  /**
9
7
  * Sync (not async) version of transformMap.
10
8
  * Supposedly faster, for cases when async is not needed.
11
9
  */
12
10
  export function transformMapSync(mapper, opt = {}) {
13
11
  const { predicate, // defaults to "no predicate" (pass everything)
14
- errorMode = ErrorMode.THROW_IMMEDIATELY, onError, onDone, metric = 'stream', objectMode = true, logger = console, } = opt;
12
+ errorMode = ErrorMode.THROW_IMMEDIATELY, onError, onDone, metric = 'stream', objectMode = true, logger = console, signal, } = opt;
15
13
  const started = Date.now();
16
14
  let index = -1;
17
15
  let countOut = 0;
18
16
  let isSettled = false;
19
17
  let errors = 0;
20
18
  const collectedErrors = []; // only used if errorMode == THROW_AGGREGATED
21
- return new TransformMapSync({
19
+ return new Transform({
22
20
  objectMode,
23
21
  ...opt,
24
22
  transform(chunk, _, cb) {
@@ -32,7 +30,8 @@ export function transformMapSync(mapper, opt = {}) {
32
30
  if (v === END) {
33
31
  isSettled = true; // will be checked later
34
32
  logger.log(`transformMapSync END received at index ${currentIndex}`);
35
- pipelineClose('transformMapSync', this, this.sourceReadable, this.streamDone, logger);
33
+ _assert(signal, 'signal is required when using END');
34
+ signal.abort(new Error(PIPELINE_GRACEFUL_ABORT));
36
35
  return cb();
37
36
  }
38
37
  if (v === SKIP) {
@@ -1,5 +1,5 @@
1
1
  import { Transform } from 'node:stream';
2
- import { _pipeline } from '../pipeline/pipeline.js';
2
+ import { pipeline } from 'node:stream/promises';
3
3
  import { readableCreate } from '../readable/readableCreate.js';
4
4
  /**
5
5
  * Allows to "tee"/"fork" away from the "main pipeline" into the "secondary pipeline".
@@ -12,10 +12,12 @@ import { readableCreate } from '../readable/readableCreate.js';
12
12
  */
13
13
  export function transformTee(streams) {
14
14
  const readable = readableCreate();
15
- const secondPipelinePromise = _pipeline([readable, ...streams]);
15
+ const secondPipelinePromise = pipeline([readable, ...streams]);
16
16
  return new Transform({
17
17
  objectMode: true,
18
18
  transform(chunk, _, cb) {
19
+ // todo: it's possible to start respecting backpressure,
20
+ // if we start to listen to the boolean output of .push()
19
21
  // pass to the "secondary" pipeline
20
22
  readable.push(chunk);
21
23
  // pass through to the "main" pipeline
@@ -1,6 +1,7 @@
1
1
  import type { AsyncIndexedMapper, IndexedMapper } from '@naturalcycles/js-lib/types';
2
2
  import type { WritableTyped } from '../stream.model.js';
3
3
  import { type TransformMapOptions } from '../transform/transformMap.js';
4
+ import { type TransformMapSyncOptions } from '../transform/transformMapSync.js';
4
5
  /**
5
6
  * Just an alias to transformMap that declares OUT as void.
6
7
  */
@@ -8,4 +9,4 @@ export declare function writableForEach<IN = any>(mapper: AsyncIndexedMapper<IN,
8
9
  /**
9
10
  * Just an alias to transformMap that declares OUT as void.
10
11
  */
11
- export declare function writableForEachSync<IN = any>(mapper: IndexedMapper<IN, void>, opt?: TransformMapOptions<IN, void>): WritableTyped<IN>;
12
+ export declare function writableForEachSync<IN = any>(mapper: IndexedMapper<IN, void>, opt?: TransformMapSyncOptions<IN, void>): WritableTyped<IN>;
@@ -1,5 +1,5 @@
1
1
  import { Writable } from 'node:stream';
2
- import { _pipeline } from '../pipeline/pipeline.js';
2
+ import { pipeline } from 'node:stream/promises';
3
3
  import { readableCreate } from '../readable/readableCreate.js';
4
4
  /**
5
5
  * Allows "forking" a stream inside pipeline into a number of pipeline chains (2 or more).
@@ -14,7 +14,7 @@ export function writableFork(chains, opt) {
14
14
  const allChainsDone = Promise.all(chains.map(async (chain) => {
15
15
  const readable = readableCreate();
16
16
  readables.push(readable);
17
- return await _pipeline([readable, ...chain]);
17
+ return await pipeline([readable, ...chain]);
18
18
  })).catch(err => {
19
19
  console.error(err); // ensure the error is logged
20
20
  throw err;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.21.0",
4
+ "version": "15.23.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@types/js-yaml": "^4",
@@ -288,6 +288,7 @@ class Exec2 {
288
288
  [
289
289
  ' ',
290
290
  dimGrey(envString),
291
+ // todo: only before first space
291
292
  white(_substringAfterLast(cmd, '/')),
292
293
  ...((opt as SpawnOptions).args || []),
293
294
  ]
@@ -5,10 +5,10 @@ export * from './ndjson/ndjsonMap.js'
5
5
  export * from './ndjson/ndjsonStreamForEach.js'
6
6
  export * from './ndjson/transformJsonParse.js'
7
7
  export * from './ndjson/transformToNDJson.js'
8
- export * from './pipeline/pipeline.js'
8
+ export * from './pipeline.js'
9
9
  export * from './progressLogger.js'
10
+ export * from './readable/readableCombined.js'
10
11
  export * from './readable/readableCreate.js'
11
- export * from './readable/readableForEach.js'
12
12
  export * from './readable/readableFromArray.js'
13
13
  export * from './readable/readableToArray.js'
14
14
  export * from './stream.model.js'
@@ -1,13 +1,7 @@
1
1
  import { ErrorMode } from '@naturalcycles/js-lib/error/errorMode.js'
2
2
  import type { AbortableAsyncMapper } from '@naturalcycles/js-lib/types'
3
- import {
4
- createReadStreamAsNDJSON,
5
- createWriteStreamAsNDJSON,
6
- transformFlatten,
7
- type TransformLogProgressOptions,
8
- type TransformMapOptions,
9
- } from '../index.js'
10
- import { _pipeline, transformLimit, transformLogProgress, transformMap } from '../index.js'
3
+ import type { TransformLogProgressOptions, TransformMapOptions } from '../index.js'
4
+ import { Pipeline } from '../pipeline.js'
11
5
 
12
6
  export interface NDJSONMapOptions<IN = any, OUT = IN>
13
7
  extends TransformMapOptions<IN, OUT>,
@@ -39,20 +33,16 @@ export async function ndjsonMap<IN = any, OUT = any>(
39
33
  outputFilePath,
40
34
  })
41
35
 
42
- const readable = createReadStreamAsNDJSON(inputFilePath).take(
43
- limitInput || Number.POSITIVE_INFINITY,
44
- )
45
-
46
- await _pipeline([
47
- readable,
48
- transformLogProgress({ metric: 'read', ...opt }),
49
- transformMap(mapper, {
36
+ await Pipeline.fromNDJsonFile<IN>(inputFilePath)
37
+ .limitSource(limitInput)
38
+ .logProgress({ metric: 'read', ...opt })
39
+ .map(mapper, {
50
40
  errorMode: ErrorMode.SUPPRESS,
51
41
  ...opt,
52
- }),
53
- transformFlatten(),
54
- transformLimit({ limit: limitOutput, sourceReadable: readable }),
55
- transformLogProgress({ metric: 'saved', logEvery: logEveryOutput }),
56
- ...createWriteStreamAsNDJSON(outputFilePath),
57
- ])
42
+ })
43
+ .flattenIfNeeded()
44
+ // .typeCastAs<OUT>()
45
+ .limit(limitOutput)
46
+ .logProgress({ metric: 'saved', logEvery: logEveryOutput })
47
+ .toNDJsonFile(outputFilePath)
58
48
  }
@@ -1,13 +1,8 @@
1
1
  import { ErrorMode } from '@naturalcycles/js-lib/error/errorMode.js'
2
2
  import type { AbortableAsyncMapper } from '@naturalcycles/js-lib/types'
3
- import { _pipeline } from '../pipeline/pipeline.js'
4
- import {
5
- transformLogProgress,
6
- type TransformLogProgressOptions,
7
- } from '../transform/transformLogProgress.js'
8
- import { transformMap, type TransformMapOptions } from '../transform/transformMap.js'
9
- import { writableVoid } from '../writable/writableVoid.js'
10
- import { createReadStreamAsNDJSON } from './createReadStreamAsNDJSON.js'
3
+ import { Pipeline } from '../pipeline.js'
4
+ import type { TransformLogProgressOptions } from '../transform/transformLogProgress.js'
5
+ import type { TransformMapOptions } from '../transform/transformMap.js'
11
6
 
12
7
  export interface NDJSONStreamForEachOptions<IN = any>
13
8
  extends TransformMapOptions<IN, void>,
@@ -22,14 +17,12 @@ export async function ndjsonStreamForEach<T>(
22
17
  mapper: AbortableAsyncMapper<T, void>,
23
18
  opt: NDJSONStreamForEachOptions<T>,
24
19
  ): Promise<void> {
25
- await _pipeline([
26
- createReadStreamAsNDJSON(opt.inputFilePath),
27
- transformMap<T, any>(mapper, {
20
+ await Pipeline.fromNDJsonFile<T>(opt.inputFilePath)
21
+ .map(mapper, {
28
22
  errorMode: ErrorMode.THROW_AGGREGATED,
29
23
  ...opt,
30
24
  predicate: () => true, // to log progress properly
31
- }),
32
- transformLogProgress(opt),
33
- writableVoid(),
34
- ])
25
+ })
26
+ .logProgress(opt)
27
+ .run()
35
28
  }
@@ -36,7 +36,6 @@ export function transformJsonParse<ROW = any>(
36
36
  writableObjectMode: false,
37
37
  readableObjectMode: true,
38
38
  // highWatermark increased, because it's proven to be faster: https://github.com/nodejs/node/pull/52037
39
- // todo: it'll be default in Node 22, then we can remove this
40
39
  writableHighWaterMark: 64 * 1024,
41
40
  transform(chunk: string, _, cb) {
42
41
  try {