@naturalcycles/nodejs-lib 15.28.0 → 15.29.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.
@@ -1,7 +1,7 @@
1
1
  import { type Transform } from 'node:stream';
2
2
  import type { ReadableStream as WebReadableStream } from 'node:stream/web';
3
3
  import { type ZlibOptions } from 'node:zlib';
4
- import type { AbortableAsyncMapper, AsyncIndexedMapper, AsyncPredicate, END, IndexedMapper, NonNegativeInteger, PositiveInteger, Predicate, SKIP } from '@naturalcycles/js-lib/types';
4
+ import { type AbortableAsyncMapper, type AsyncIndexedMapper, type AsyncPredicate, type END, type IndexedMapper, type NonNegativeInteger, type PositiveInteger, type Predicate, type SKIP } from '@naturalcycles/js-lib/types';
5
5
  import type { ReadableTyped, TransformOptions, TransformTyped, WritableTyped } from './stream.model.js';
6
6
  import { type TransformLogProgressOptions } from './transform/transformLogProgress.js';
7
7
  import { type TransformMapOptions } from './transform/transformMap.js';
@@ -63,7 +63,7 @@ export declare class Pipeline<T = unknown> {
63
63
  map<TO>(mapper: AbortableAsyncMapper<T, TO | typeof SKIP | typeof END>, opt?: TransformMapOptions<T, TO>): Pipeline<TO>;
64
64
  mapSync<TO>(mapper: IndexedMapper<T, TO | typeof SKIP | typeof END>, opt?: TransformMapSyncOptions): Pipeline<TO>;
65
65
  mapSimple<TO>(mapper: IndexedMapper<T, TO>, opt?: TransformMapSimpleOptions): Pipeline<TO>;
66
- filter(predicate: AsyncPredicate<T>, opt?: TransformMapOptions): this;
66
+ filter(asyncPredicate: AsyncPredicate<T>, opt?: TransformMapOptions): this;
67
67
  filterSync(predicate: Predicate<T>, opt?: TransformOptions): this;
68
68
  offset(opt: TransformOffsetOptions): this;
69
69
  tap(fn: AsyncIndexedMapper<T, any>, opt?: TransformOptions): this;
@@ -96,7 +96,7 @@ export declare class Pipeline<T = unknown> {
96
96
  toFile(outputFilePath: string): Promise<void>;
97
97
  toNDJsonFile(outputFilePath: string): Promise<void>;
98
98
  to(destination: WritableTyped<T>): Promise<void>;
99
- forEach(fn: AsyncIndexedMapper<T, void>, opt?: TransformMapOptions<T, void>): Promise<void>;
100
- forEachSync(fn: IndexedMapper<T, void>, opt?: TransformMapSyncOptions<T, void>): Promise<void>;
99
+ forEach(fn: AsyncIndexedMapper<T, void>, opt?: TransformMapOptions<T, void> & TransformLogProgressOptions<T>): Promise<void>;
100
+ forEachSync(fn: IndexedMapper<T, void>, opt?: TransformMapSyncOptions<T, void> & TransformLogProgressOptions<T>): Promise<void>;
101
101
  run(): Promise<void>;
102
102
  }
@@ -3,6 +3,7 @@ import { pipeline } from 'node:stream/promises';
3
3
  import { createUnzip } from 'node:zlib';
4
4
  import { createGzip } from 'node:zlib';
5
5
  import { createAbortableSignal } from '@naturalcycles/js-lib';
6
+ import { _passthroughPredicate, } from '@naturalcycles/js-lib/types';
6
7
  import { fs2 } from '../fs/fs2.js';
7
8
  import { createReadStreamAsNDJson } from './ndjson/createReadStreamAsNDJson.js';
8
9
  import { transformJsonParse } from './ndjson/transformJsonParse.js';
@@ -141,9 +142,9 @@ export class Pipeline {
141
142
  this.transforms.push(transformMapSimple(mapper, opt));
142
143
  return this;
143
144
  }
144
- filter(predicate, opt) {
145
+ filter(asyncPredicate, opt) {
145
146
  this.transforms.push(transformMap(v => v, {
146
- predicate,
147
+ asyncPredicate,
147
148
  ...opt,
148
149
  signal: this.abortableSignal,
149
150
  }));
@@ -270,18 +271,26 @@ export class Pipeline {
270
271
  this.destination = destination;
271
272
  await this.run();
272
273
  }
273
- async forEach(fn, opt) {
274
+ async forEach(fn, opt = {}) {
274
275
  this.transforms.push(transformMap(fn, {
276
+ predicate: opt.logEvery ? _passthroughPredicate : undefined, // for the logger to work
275
277
  ...opt,
276
278
  signal: this.abortableSignal,
277
279
  }));
280
+ if (opt.logEvery) {
281
+ this.transforms.push(transformLogProgress(opt));
282
+ }
278
283
  await this.run();
279
284
  }
280
- async forEachSync(fn, opt) {
285
+ async forEachSync(fn, opt = {}) {
281
286
  this.transforms.push(transformMapSync(fn, {
287
+ predicate: opt.logEvery ? _passthroughPredicate : undefined, // for the logger to work
282
288
  ...opt,
283
289
  signal: this.abortableSignal,
284
290
  }));
291
+ if (opt.logEvery) {
292
+ this.transforms.push(transformLogProgress(opt));
293
+ }
285
294
  await this.run();
286
295
  }
287
296
  async run() {
@@ -4,7 +4,7 @@ import type { TransformMapOptions } from './transformMap.js';
4
4
  /**
5
5
  * Just a convenience wrapper around `transformMap` that has built-in predicate filtering support.
6
6
  */
7
- export declare function transformFilter<IN = any>(predicate: AsyncPredicate<IN>, opt?: TransformMapOptions): TransformTyped<IN, IN>;
7
+ export declare function transformFilter<IN = any>(asyncPredicate: AsyncPredicate<IN>, opt?: TransformMapOptions): TransformTyped<IN, IN>;
8
8
  /**
9
9
  * Sync version of `transformFilter`
10
10
  */
@@ -3,9 +3,9 @@ import { transformMap } from './transformMap.js';
3
3
  /**
4
4
  * Just a convenience wrapper around `transformMap` that has built-in predicate filtering support.
5
5
  */
6
- export function transformFilter(predicate, opt = {}) {
6
+ export function transformFilter(asyncPredicate, opt = {}) {
7
7
  return transformMap(v => v, {
8
- predicate,
8
+ asyncPredicate,
9
9
  ...opt,
10
10
  });
11
11
  }
@@ -4,7 +4,7 @@ import { progressLogger } from '../progressLogger.js';
4
4
  * Pass-through transform that optionally logs progress.
5
5
  */
6
6
  export function transformLogProgress(opt = {}) {
7
- const { objectMode = true, highWaterMark } = opt;
7
+ const { objectMode = true, highWaterMark = 1 } = opt;
8
8
  const progress = progressLogger(opt);
9
9
  return new Transform({
10
10
  objectMode,
@@ -10,7 +10,8 @@ export interface TransformMapOptions<IN = any, OUT = IN> extends TransformOption
10
10
  * Defaults to "pass everything" (including null, undefined, etc).
11
11
  * Simpler way to exclude certain cases is to return SKIP symbol from the mapper.
12
12
  */
13
- predicate?: Predicate<OUT> | AsyncPredicate<OUT>;
13
+ predicate?: Predicate<OUT>;
14
+ asyncPredicate?: AsyncPredicate<OUT>;
14
15
  /**
15
16
  * Number of concurrently pending promises returned by `mapper`.
16
17
  *
@@ -23,7 +23,7 @@ import { PIPELINE_GRACEFUL_ABORT } from '../stream.util.js';
23
23
  */
24
24
  export function transformMap(mapper, opt = {}) {
25
25
  const { concurrency = 16, highWaterMark = 64, predicate, // we now default to "no predicate" (meaning pass-everything)
26
- errorMode = ErrorMode.THROW_IMMEDIATELY, onError, onDone, metric = 'stream', signal, } = opt;
26
+ asyncPredicate, errorMode = ErrorMode.THROW_IMMEDIATELY, onError, onDone, metric = 'stream', signal, } = opt;
27
27
  const started = Date.now();
28
28
  let index = -1;
29
29
  let countOut = 0;
@@ -94,8 +94,20 @@ export function transformMap(mapper, opt = {}) {
94
94
  // do nothing, don't push
95
95
  return cb();
96
96
  }
97
- if (!predicate || ((await predicate(res, currentIndex)) && !isSettled)) {
98
- // isSettled could have happened in parallel, hence the extra check
97
+ if (predicate) {
98
+ if (predicate(res, currentIndex)) {
99
+ countOut++;
100
+ this.push(res);
101
+ }
102
+ }
103
+ else if (asyncPredicate) {
104
+ if ((await asyncPredicate(res, currentIndex)) && !isSettled) {
105
+ // isSettled could have happened in parallel, hence the extra check
106
+ countOut++;
107
+ this.push(res);
108
+ }
109
+ }
110
+ else {
99
111
  countOut++;
100
112
  this.push(res);
101
113
  }
@@ -5,9 +5,10 @@ import { Writable } from 'node:stream';
5
5
  * Put it in the end of your pipeline in case it ends with Transform that needs a consumer.
6
6
  */
7
7
  export function writableVoid(opt = {}) {
8
+ const { objectMode = true, highWaterMark = 1 } = opt;
8
9
  return new Writable({
9
- objectMode: true,
10
- ...opt,
10
+ objectMode,
11
+ highWaterMark,
11
12
  write(_chunk, _, cb) {
12
13
  cb();
13
14
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.28.0",
4
+ "version": "15.29.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@types/js-yaml": "^4",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/through2-concurrent": "^2",
26
- "@naturalcycles/dev-lib": "19.37.0"
26
+ "@naturalcycles/dev-lib": "18.4.2"
27
27
  },
28
28
  "exports": {
29
29
  ".": "./dist/index.js",
@@ -4,17 +4,18 @@ import type { ReadableStream as WebReadableStream } from 'node:stream/web'
4
4
  import { createUnzip, type ZlibOptions } from 'node:zlib'
5
5
  import { createGzip } from 'node:zlib'
6
6
  import { createAbortableSignal } from '@naturalcycles/js-lib'
7
- import type {
8
- AbortableAsyncMapper,
9
- AsyncIndexedMapper,
10
- AsyncPredicate,
11
- END,
12
- IndexedMapper,
13
- Integer,
14
- NonNegativeInteger,
15
- PositiveInteger,
16
- Predicate,
17
- SKIP,
7
+ import {
8
+ _passthroughPredicate,
9
+ type AbortableAsyncMapper,
10
+ type AsyncIndexedMapper,
11
+ type AsyncPredicate,
12
+ type END,
13
+ type IndexedMapper,
14
+ type Integer,
15
+ type NonNegativeInteger,
16
+ type PositiveInteger,
17
+ type Predicate,
18
+ type SKIP,
18
19
  } from '@naturalcycles/js-lib/types'
19
20
  import { fs2 } from '../fs/fs2.js'
20
21
  import { createReadStreamAsNDJson } from './ndjson/createReadStreamAsNDJson.js'
@@ -200,10 +201,10 @@ export class Pipeline<T = unknown> {
200
201
  return this as any
201
202
  }
202
203
 
203
- filter(predicate: AsyncPredicate<T>, opt?: TransformMapOptions): this {
204
+ filter(asyncPredicate: AsyncPredicate<T>, opt?: TransformMapOptions): this {
204
205
  this.transforms.push(
205
206
  transformMap(v => v, {
206
- predicate,
207
+ asyncPredicate,
207
208
  ...opt,
208
209
  signal: this.abortableSignal,
209
210
  }),
@@ -362,27 +363,35 @@ export class Pipeline<T = unknown> {
362
363
 
363
364
  async forEach(
364
365
  fn: AsyncIndexedMapper<T, void>,
365
- opt?: TransformMapOptions<T, void>,
366
+ opt: TransformMapOptions<T, void> & TransformLogProgressOptions<T> = {},
366
367
  ): Promise<void> {
367
368
  this.transforms.push(
368
369
  transformMap(fn, {
370
+ predicate: opt.logEvery ? _passthroughPredicate : undefined, // for the logger to work
369
371
  ...opt,
370
372
  signal: this.abortableSignal,
371
373
  }),
372
374
  )
375
+ if (opt.logEvery) {
376
+ this.transforms.push(transformLogProgress(opt))
377
+ }
373
378
  await this.run()
374
379
  }
375
380
 
376
381
  async forEachSync(
377
382
  fn: IndexedMapper<T, void>,
378
- opt?: TransformMapSyncOptions<T, void>,
383
+ opt: TransformMapSyncOptions<T, void> & TransformLogProgressOptions<T> = {},
379
384
  ): Promise<void> {
380
385
  this.transforms.push(
381
386
  transformMapSync(fn, {
387
+ predicate: opt.logEvery ? _passthroughPredicate : undefined, // for the logger to work
382
388
  ...opt,
383
389
  signal: this.abortableSignal,
384
390
  }),
385
391
  )
392
+ if (opt.logEvery) {
393
+ this.transforms.push(transformLogProgress(opt))
394
+ }
386
395
  await this.run()
387
396
  }
388
397
 
@@ -8,11 +8,11 @@ import { transformMap } from './transformMap.js'
8
8
  * Just a convenience wrapper around `transformMap` that has built-in predicate filtering support.
9
9
  */
10
10
  export function transformFilter<IN = any>(
11
- predicate: AsyncPredicate<IN>,
11
+ asyncPredicate: AsyncPredicate<IN>,
12
12
  opt: TransformMapOptions = {},
13
13
  ): TransformTyped<IN, IN> {
14
14
  return transformMap(v => v, {
15
- predicate,
15
+ asyncPredicate,
16
16
  ...opt,
17
17
  })
18
18
  }
@@ -13,7 +13,7 @@ export interface TransformLogProgressOptions<IN = any>
13
13
  export function transformLogProgress<IN = any>(
14
14
  opt: TransformLogProgressOptions = {},
15
15
  ): TransformTyped<IN, IN> {
16
- const { objectMode = true, highWaterMark } = opt
16
+ const { objectMode = true, highWaterMark = 1 } = opt
17
17
  const progress = progressLogger(opt)
18
18
 
19
19
  return new Transform({
@@ -27,7 +27,9 @@ export interface TransformMapOptions<IN = any, OUT = IN> extends TransformOption
27
27
  * Defaults to "pass everything" (including null, undefined, etc).
28
28
  * Simpler way to exclude certain cases is to return SKIP symbol from the mapper.
29
29
  */
30
- predicate?: Predicate<OUT> | AsyncPredicate<OUT>
30
+ predicate?: Predicate<OUT>
31
+
32
+ asyncPredicate?: AsyncPredicate<OUT>
31
33
 
32
34
  /**
33
35
  * Number of concurrently pending promises returned by `mapper`.
@@ -138,6 +140,7 @@ export function transformMap<IN = any, OUT = IN>(
138
140
  concurrency = 16,
139
141
  highWaterMark = 64,
140
142
  predicate, // we now default to "no predicate" (meaning pass-everything)
143
+ asyncPredicate,
141
144
  errorMode = ErrorMode.THROW_IMMEDIATELY,
142
145
  onError,
143
146
  onDone,
@@ -227,8 +230,18 @@ export function transformMap<IN = any, OUT = IN>(
227
230
  return cb()
228
231
  }
229
232
 
230
- if (!predicate || ((await predicate(res, currentIndex)) && !isSettled)) {
231
- // isSettled could have happened in parallel, hence the extra check
233
+ if (predicate) {
234
+ if (predicate(res, currentIndex)) {
235
+ countOut++
236
+ this.push(res)
237
+ }
238
+ } else if (asyncPredicate) {
239
+ if ((await asyncPredicate(res, currentIndex)) && !isSettled) {
240
+ // isSettled could have happened in parallel, hence the extra check
241
+ countOut++
242
+ this.push(res)
243
+ }
244
+ } else {
232
245
  countOut++
233
246
  this.push(res)
234
247
  }
@@ -7,9 +7,10 @@ import type { TransformOptions } from '../stream.model.js'
7
7
  * Put it in the end of your pipeline in case it ends with Transform that needs a consumer.
8
8
  */
9
9
  export function writableVoid(opt: TransformOptions = {}): Writable {
10
+ const { objectMode = true, highWaterMark = 1 } = opt
10
11
  return new Writable({
11
- objectMode: true,
12
- ...opt,
12
+ objectMode,
13
+ highWaterMark,
13
14
  write(_chunk, _, cb) {
14
15
  cb()
15
16
  },