@naturalcycles/nodejs-lib 12.59.0 → 12.60.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 (43) hide show
  1. package/dist/stream/ndjson/transformJsonParse.js +3 -3
  2. package/dist/stream/ndjson/transformToNDJson.js +2 -2
  3. package/dist/stream/sizeStack.d.ts +9 -0
  4. package/dist/stream/sizeStack.js +48 -0
  5. package/dist/stream/transform/transformBuffer.js +1 -1
  6. package/dist/stream/transform/transformFilter.d.ts +3 -4
  7. package/dist/stream/transform/transformFilter.js +5 -20
  8. package/dist/stream/transform/transformLogProgress.d.ts +20 -0
  9. package/dist/stream/transform/transformLogProgress.js +36 -18
  10. package/dist/stream/transform/transformMap.d.ts +2 -4
  11. package/dist/stream/transform/transformMap.js +6 -11
  12. package/dist/stream/transform/transformMapSimple.js +1 -1
  13. package/dist/stream/transform/transformMapSync.d.ts +5 -3
  14. package/dist/stream/transform/transformMapSync.js +28 -22
  15. package/dist/stream/transform/transformNoOp.js +1 -1
  16. package/dist/stream/transform/transformTap.js +3 -3
  17. package/dist/stream/transform/transformToArray.js +1 -1
  18. package/dist/stream/transform/transformToString.js +2 -2
  19. package/dist/stream/transform/worker/transformMultiThreaded.js +1 -1
  20. package/dist/stream/writable/writableFork.js +1 -1
  21. package/dist/stream/writable/writablePushToArray.js +1 -1
  22. package/dist/stream/writable/writableVoid.js +1 -1
  23. package/dist/util/zip.util.d.ts +10 -2
  24. package/dist/util/zip.util.js +10 -3
  25. package/package.json +1 -1
  26. package/src/stream/ndjson/transformJsonParse.ts +3 -3
  27. package/src/stream/ndjson/transformToNDJson.ts +2 -2
  28. package/src/stream/sizeStack.ts +56 -0
  29. package/src/stream/transform/transformBuffer.ts +1 -1
  30. package/src/stream/transform/transformFilter.ts +6 -20
  31. package/src/stream/transform/transformLogProgress.ts +72 -23
  32. package/src/stream/transform/transformMap.ts +7 -14
  33. package/src/stream/transform/transformMapSimple.ts +1 -1
  34. package/src/stream/transform/transformMapSync.ts +40 -26
  35. package/src/stream/transform/transformNoOp.ts +1 -1
  36. package/src/stream/transform/transformTap.ts +3 -3
  37. package/src/stream/transform/transformToArray.ts +1 -1
  38. package/src/stream/transform/transformToString.ts +2 -2
  39. package/src/stream/transform/worker/transformMultiThreaded.ts +1 -1
  40. package/src/stream/writable/writableFork.ts +1 -1
  41. package/src/stream/writable/writablePushToArray.ts +1 -1
  42. package/src/stream/writable/writableVoid.ts +1 -1
  43. package/src/util/zip.util.ts +11 -3
@@ -33,17 +33,17 @@ export function transformJsonParse<OUT = any>(
33
33
  const { strict = true, reviver } = opt
34
34
 
35
35
  return new Transform({
36
- objectMode: false,
36
+ writableObjectMode: false,
37
37
  readableObjectMode: true,
38
- transform(chunk: string, _encoding, cb) {
38
+ transform(chunk: string, _, cb) {
39
39
  try {
40
40
  const data = JSON.parse(chunk, reviver)
41
41
  cb(null, data)
42
42
  } catch (err) {
43
- // console.error(err)
44
43
  if (strict) {
45
44
  cb(err as Error) // emit error
46
45
  } else {
46
+ console.error(err)
47
47
  cb() // emit no error, but no result neither
48
48
  }
49
49
  }
@@ -37,9 +37,9 @@ export function transformToNDJson<IN = any>(
37
37
  const { strict = true, separator = '\n', sortObjects = false, useFlatstr = false } = opt
38
38
 
39
39
  return new Transform({
40
- objectMode: true,
40
+ writableObjectMode: true,
41
41
  readableObjectMode: false,
42
- transform(chunk: IN, _encoding, cb) {
42
+ transform(chunk: IN, _, cb) {
43
43
  try {
44
44
  if (sortObjects) {
45
45
  chunk = _sortObjectDeep(chunk as any)
@@ -0,0 +1,56 @@
1
+ import { _hb, CommonLogger, NumberStack } from '@naturalcycles/js-lib'
2
+ import { yellow } from '../colors'
3
+ import { gzipBuffer } from '../util/zip.util'
4
+
5
+ export class SizeStack extends NumberStack {
6
+ constructor(public name: string, size: number) {
7
+ super(size)
8
+ }
9
+
10
+ total = 0
11
+
12
+ override push(item: any): this {
13
+ this.total += item
14
+ return super.push(item)
15
+ }
16
+
17
+ getStats(): string {
18
+ const pcs = this.percentiles([50, 90])
19
+
20
+ return [
21
+ this.name,
22
+ 'avg',
23
+ yellow(_hb(this.avg())),
24
+ 'p50',
25
+ yellow(_hb(pcs[50])),
26
+ 'p90',
27
+ yellow(_hb(pcs[90])),
28
+ 'total',
29
+ yellow(_hb(this.total)),
30
+ ].join(' ')
31
+ }
32
+
33
+ static async countItem(
34
+ item: any,
35
+ logger: CommonLogger,
36
+ sizes?: SizeStack,
37
+ sizesZipped?: SizeStack,
38
+ ): Promise<void> {
39
+ if (!sizes) return
40
+
41
+ // try-catch, because we don't want to fail the pipeline on logProgress
42
+ try {
43
+ const buf = Buffer.from(JSON.stringify(item))
44
+ sizes.push(buf.byteLength)
45
+
46
+ if (sizesZipped) {
47
+ const { byteLength } = await gzipBuffer(buf)
48
+ sizesZipped.push(byteLength)
49
+ }
50
+ } catch (err) {
51
+ logger.warn(
52
+ `transformLogProgress failed to JSON.stringify the chunk: ${(err as Error).message}`,
53
+ )
54
+ }
55
+ }
56
+ }
@@ -18,7 +18,7 @@ export function transformBuffer<IN = any>(opt: TransformBufferOptions): Transfor
18
18
  return new Transform({
19
19
  objectMode: true,
20
20
  ...opt,
21
- transform(chunk, _encoding, cb) {
21
+ transform(chunk, _, cb) {
22
22
  buf.push(chunk)
23
23
 
24
24
  if (buf.length >= batchSize) {
@@ -1,32 +1,18 @@
1
1
  import { Transform } from 'stream'
2
2
  import { AsyncPredicate, Predicate } from '@naturalcycles/js-lib'
3
3
  import { TransformOptions, TransformTyped } from '../stream.model'
4
+ import { transformMap, TransformMapOptions } from './transformMap'
4
5
 
5
6
  /**
6
- * Note, that currently it's NOT concurrent! (concurrency = 1)
7
- * So, it's recommended to use transformMap instead, that is both concurrent and has
8
- * filtering feature by default.
7
+ * Just a convenience wrapper around `transformMap` that has built-in predicate filtering support.
9
8
  */
10
9
  export function transformFilter<IN = any>(
11
10
  predicate: AsyncPredicate<IN>,
12
- opt: TransformOptions = {},
11
+ opt: TransformMapOptions = {},
13
12
  ): TransformTyped<IN, IN> {
14
- let index = 0
15
-
16
- return new Transform({
17
- objectMode: true,
13
+ return transformMap(v => v, {
14
+ predicate,
18
15
  ...opt,
19
- async transform(chunk: IN, _encoding, cb) {
20
- try {
21
- if (await predicate(chunk, index++)) {
22
- cb(null, chunk) // pass through
23
- } else {
24
- cb() // signal that we've finished processing, but emit no output here
25
- }
26
- } catch (err) {
27
- cb(err as Error)
28
- }
29
- },
30
16
  })
31
17
  }
32
18
 
@@ -42,7 +28,7 @@ export function transformFilterSync<IN = any>(
42
28
  return new Transform({
43
29
  objectMode: true,
44
30
  ...opt,
45
- async transform(chunk: IN, _encoding, cb) {
31
+ transform(chunk: IN, _, cb) {
46
32
  try {
47
33
  if (predicate(chunk, index++)) {
48
34
  cb(null, chunk) // pass through
@@ -4,6 +4,7 @@ import { SimpleMovingAverage, _mb, _since, AnyObject, CommonLogger } from '@natu
4
4
  import { dayjs } from '@naturalcycles/time-lib'
5
5
  import { boldWhite, dimGrey, white, yellow } from '../../colors'
6
6
  import { hasColors } from '../../colors/colors'
7
+ import { SizeStack } from '../sizeStack'
7
8
  import { TransformOptions, TransformTyped } from '../stream.model'
8
9
 
9
10
  export interface TransformLogProgressOptions<IN = any> extends TransformOptions {
@@ -103,6 +104,41 @@ export interface TransformLogProgressOptions<IN = any> extends TransformOptions
103
104
  * Defaults to 1.
104
105
  */
105
106
  batchSize?: number
107
+
108
+ /**
109
+ * Experimental logging of item (shunk) sizes, when json-stringified.
110
+ *
111
+ * Defaults to false.
112
+ *
113
+ * @experimental
114
+ */
115
+ logSizes?: boolean
116
+
117
+ /**
118
+ * How many last item sizes to keep in a buffer, to calculate stats (p50, p90, avg, etc).
119
+ * Defaults to 100_000.
120
+ * Cannot be Infinity.
121
+ */
122
+ logSizesBuffer?: number
123
+
124
+ /**
125
+ * Works in addition to `logSizes`. Adds "zipped sizes".
126
+ *
127
+ * @experimental
128
+ */
129
+ logZippedSizes?: boolean
130
+ }
131
+
132
+ interface LogItem extends AnyObject {
133
+ heapUsed?: number
134
+ heapTotal?: number
135
+ rss?: number
136
+ peakRSS?: number
137
+ rssMinusHeap?: number
138
+ external?: number
139
+ arrayBuffers?: number
140
+ rps10?: number
141
+ rpsTotal?: number
106
142
  }
107
143
 
108
144
  const inspectOpt: InspectOptions = {
@@ -124,6 +160,9 @@ export function transformLogProgress<IN = any>(
124
160
  peakRSS: logPeakRSS = true,
125
161
  logRPS = true,
126
162
  logEvery = 1000,
163
+ logSizes = false,
164
+ logSizesBuffer = 100_000,
165
+ logZippedSizes = false,
127
166
  batchSize = 1,
128
167
  extra,
129
168
  logger = console,
@@ -138,15 +177,23 @@ export function transformLogProgress<IN = any>(
138
177
  let progress = 0
139
178
  let peakRSS = 0
140
179
 
180
+ const sizes = logSizes ? new SizeStack('json', logSizesBuffer) : undefined
181
+ const sizesZipped = logZippedSizes ? new SizeStack('json.gz', logSizesBuffer) : undefined
182
+
141
183
  logStats() // initial
142
184
 
143
185
  return new Transform({
144
186
  objectMode: true,
145
187
  ...opt,
146
- transform(chunk: IN, _encoding, cb) {
188
+ transform(chunk: IN, _, cb) {
147
189
  progress++
148
190
  processedLastSecond++
149
191
 
192
+ if (sizes) {
193
+ // Check it, cause gzipping might be delayed here..
194
+ void SizeStack.countItem(chunk, logger, sizes, sizesZipped)
195
+ }
196
+
150
197
  if (logProgress && progress % logEvery === 0) {
151
198
  logStats(chunk, false, progress % logEvery10 === 0)
152
199
  }
@@ -175,28 +222,30 @@ export function transformLogProgress<IN = any>(
175
222
  const rps10 = Math.round(sma.push(lastRPS))
176
223
  if (mem.rss > peakRSS) peakRSS = mem.rss
177
224
 
178
- logger.log(
179
- inspect(
180
- {
181
- [final ? `${metric}_final` : metric]: batchedProgress,
182
- ...(extra ? extra(chunk, progress) : {}),
183
- ...(logHeapUsed ? { heapUsed: _mb(mem.heapUsed) } : {}),
184
- ...(logHeapTotal ? { heapTotal: _mb(mem.heapTotal) } : {}),
185
- ...(logRss ? { rss: _mb(mem.rss) } : {}),
186
- ...(logPeakRSS ? { peakRSS: _mb(peakRSS) } : {}),
187
- ...(opt.rssMinusHeap ? { rssMinusHeap: _mb(mem.rss - mem.heapTotal) } : {}),
188
- ...(opt.external ? { external: _mb(mem.external) } : {}),
189
- ...(opt.arrayBuffers ? { arrayBuffers: _mb(mem.arrayBuffers || 0) } : {}),
190
- ...(logRPS
191
- ? {
192
- rps10,
193
- rpsTotal,
194
- }
195
- : {}),
196
- },
197
- inspectOpt,
198
- ),
199
- )
225
+ const o: LogItem = {
226
+ [final ? `${metric}_final` : metric]: batchedProgress,
227
+ }
228
+
229
+ if (extra) Object.assign(o, extra(chunk, progress))
230
+ if (logHeapUsed) o.heapUsed = _mb(mem.heapUsed)
231
+ if (logHeapTotal) o.heapTotal = _mb(mem.heapTotal)
232
+ if (logRss) o.rss = _mb(mem.rss)
233
+ if (logPeakRSS) o.peakRSS = _mb(peakRSS)
234
+ if (opt.rssMinusHeap) o.rssMinusHeap = _mb(mem.rss - mem.heapTotal)
235
+ if (opt.external) o.external = _mb(mem.external)
236
+ if (opt.arrayBuffers) o.arrayBuffers = _mb(mem.arrayBuffers || 0)
237
+
238
+ if (logRPS) Object.assign(o, { rps10, rpsTotal })
239
+
240
+ logger.log(inspect(o, inspectOpt))
241
+
242
+ if (sizes?.items.length) {
243
+ logger.log(sizes.getStats())
244
+
245
+ if (sizesZipped?.items.length) {
246
+ logger.log(sizesZipped.getStats())
247
+ }
248
+ }
200
249
 
201
250
  if (tenx) {
202
251
  let perHour: number | string =
@@ -26,9 +26,8 @@ export interface TransformMapOptions<IN = any, OUT = IN> {
26
26
  * Predicate to filter outgoing results (after mapper).
27
27
  * Allows to not emit all results.
28
28
  *
29
- * Set to `r => r` (passthrough predicate) to pass ANY value (including undefined/null)
30
- *
31
- * @default to filter out undefined/null values, but pass anything else
29
+ * Defaults to "pass everything" (including null, undefined, etc).
30
+ * Simpler way to exclude certain cases is to return SKIP symbol from the mapper.
32
31
  */
33
32
  predicate?: AsyncPredicate<OUT>
34
33
 
@@ -60,10 +59,6 @@ export interface TransformMapOptions<IN = any, OUT = IN> {
60
59
  logger?: CommonLogger
61
60
  }
62
61
 
63
- export function notNullishPredicate(item: any): boolean {
64
- return item !== undefined && item !== null
65
- }
66
-
67
62
  // doesn't work, cause here we don't construct our Transform instance ourselves
68
63
  // export class TransformMap extends AbortableTransform {}
69
64
 
@@ -85,7 +80,7 @@ export function transformMap<IN = any, OUT = IN>(
85
80
  ): TransformTyped<IN, OUT> {
86
81
  const {
87
82
  concurrency = 16,
88
- predicate = notNullishPredicate,
83
+ predicate, // we now default to "no predicate" (meaning pass-everything)
89
84
  errorMode = ErrorMode.THROW_IMMEDIATELY,
90
85
  flattenArrayOutput,
91
86
  onError,
@@ -116,14 +111,12 @@ export function transformMap<IN = any, OUT = IN>(
116
111
  },
117
112
  },
118
113
  async function transformMapFn(this: AbortableTransform, chunk: IN, _, cb) {
119
- index++
120
- // console.log({chunk, _encoding})
121
-
122
114
  // Stop processing if isSettled (either THROW_IMMEDIATELY was fired or END received)
123
115
  if (isSettled) return cb()
124
116
 
117
+ const currentIndex = ++index
118
+
125
119
  try {
126
- const currentIndex = index // because we need to pass it to 2 functions - mapper and predicate. Refers to INPUT index (since it may return multiple outputs)
127
120
  const res = await mapper(chunk, currentIndex)
128
121
  const passedResults = await pFilter(
129
122
  flattenArrayOutput && Array.isArray(res) ? res : [res],
@@ -132,14 +125,14 @@ export function transformMap<IN = any, OUT = IN>(
132
125
  isSettled = true // will be checked later
133
126
  return false
134
127
  }
135
- return r !== SKIP && (await predicate(r, currentIndex))
128
+ return r !== SKIP && (!predicate || (await predicate(r, currentIndex)))
136
129
  },
137
130
  )
138
131
 
139
132
  passedResults.forEach(r => this.push(r))
140
133
 
141
134
  if (isSettled) {
142
- logger.log(`transformMap END received at index ${index}`)
135
+ logger.log(`transformMap END received at index ${currentIndex}`)
143
136
  pipelineClose('transformMap', this, this.sourceReadable, this.streamDone, logger)
144
137
  }
145
138
 
@@ -31,7 +31,7 @@ export function transformMapSimple<IN = any, OUT = IN>(
31
31
 
32
32
  return new Transform({
33
33
  objectMode: true,
34
- transform(chunk: IN, _encoding, cb) {
34
+ transform(chunk: IN, _, cb) {
35
35
  try {
36
36
  cb(null, mapper(chunk, ++index))
37
37
  } catch (err) {
@@ -1,8 +1,16 @@
1
- import { Transform } from 'stream'
2
- import { AggregatedError, CommonLogger, ErrorMode, Mapper, Predicate } from '@naturalcycles/js-lib'
1
+ import {
2
+ AggregatedError,
3
+ CommonLogger,
4
+ END,
5
+ ErrorMode,
6
+ Mapper,
7
+ Predicate,
8
+ SKIP,
9
+ } from '@naturalcycles/js-lib'
3
10
  import { yellow } from '../../colors'
11
+ import { AbortableTransform } from '../pipeline/pipeline'
4
12
  import { TransformTyped } from '../stream.model'
5
- import { notNullishPredicate } from './transformMap'
13
+ import { pipelineClose } from '../stream.util'
6
14
 
7
15
  export interface TransformMapSyncOptions<IN = any, OUT = IN> {
8
16
  /**
@@ -20,9 +28,8 @@ export interface TransformMapSyncOptions<IN = any, OUT = IN> {
20
28
  * Predicate to filter outgoing results (after mapper).
21
29
  * Allows to not emit all results.
22
30
  *
23
- * @default to filter out undefined/null values, but pass anything else
24
- *
25
- * Set to `r => r` (passthrough predicate) to pass ANY value (including undefined/null)
31
+ * Defaults to "pass everything".
32
+ * Simpler way to skip individual entries is to return SKIP symbol.
26
33
  */
27
34
  predicate?: Predicate<OUT>
28
35
 
@@ -47,6 +54,8 @@ export interface TransformMapSyncOptions<IN = any, OUT = IN> {
47
54
  logger?: CommonLogger
48
55
  }
49
56
 
57
+ export class TransformMapSync extends AbortableTransform {}
58
+
50
59
  /**
51
60
  * Sync (not async) version of transformMap.
52
61
  * Supposedly faster, for cases when async is not needed.
@@ -58,7 +67,7 @@ export function transformMapSync<IN = any, OUT = IN>(
58
67
  let index = -1
59
68
 
60
69
  const {
61
- predicate = notNullishPredicate,
70
+ predicate, // defaults to "no predicate" (pass everything)
62
71
  errorMode = ErrorMode.THROW_IMMEDIATELY,
63
72
  flattenArrayOutput = false,
64
73
  onError,
@@ -66,34 +75,39 @@ export function transformMapSync<IN = any, OUT = IN>(
66
75
  objectMode = true,
67
76
  logger = console,
68
77
  } = opt
69
- let isRejected = false
78
+ let isSettled = false
70
79
  let errors = 0
71
80
  const collectedErrors: Error[] = [] // only used if errorMode == THROW_AGGREGATED
72
81
 
73
- return new Transform({
82
+ return new TransformMapSync({
74
83
  objectMode,
75
84
  ...opt,
76
- transform(this: Transform, chunk: IN, _encoding, cb) {
77
- // Stop processing if THROW_IMMEDIATELY mode is used
78
- if (isRejected && errorMode === ErrorMode.THROW_IMMEDIATELY) {
79
- return cb()
80
- }
85
+ transform(this: AbortableTransform, chunk: IN, _, cb) {
86
+ // Stop processing if isSettled
87
+ if (isSettled) return cb()
81
88
 
82
- try {
83
- if (!predicate(chunk, ++index)) {
84
- cb() // signal that we've finished processing, but emit no output here
85
- return
86
- }
89
+ const currentIndex = ++index
87
90
 
91
+ try {
88
92
  // map and pass through
89
- const v = mapper(chunk, index)
93
+ const v = mapper(chunk, currentIndex)
94
+
95
+ const passedResults = (flattenArrayOutput && Array.isArray(v) ? v : [v]).filter(r => {
96
+ if (r === END) {
97
+ isSettled = true // will be checked later
98
+ return false
99
+ }
100
+ return r !== SKIP && (!predicate || predicate(r, currentIndex))
101
+ })
90
102
 
91
- if (flattenArrayOutput && Array.isArray(v)) {
92
- // Pass each item individually
93
- v.forEach(item => this.push(item))
94
- } else {
95
- cb(null, v)
103
+ passedResults.forEach(r => this.push(r))
104
+
105
+ if (isSettled) {
106
+ logger.log(`transformMapSync END received at index ${currentIndex}`)
107
+ pipelineClose('transformMapSync', this, this.sourceReadable, this.streamDone, logger)
96
108
  }
109
+
110
+ cb() // done processing
97
111
  } catch (err) {
98
112
  logger.error(err)
99
113
  errors++
@@ -107,7 +121,7 @@ export function transformMapSync<IN = any, OUT = IN>(
107
121
  }
108
122
 
109
123
  if (errorMode === ErrorMode.THROW_IMMEDIATELY) {
110
- isRejected = true
124
+ isSettled = true
111
125
  // Emit error immediately
112
126
  return cb(err as Error)
113
127
  }
@@ -9,7 +9,7 @@ import { TransformTyped } from '../stream.model'
9
9
  export function transformNoOp<T = any>(): TransformTyped<T, T> {
10
10
  return new Transform({
11
11
  objectMode: true,
12
- transform(chunk: T, _encoding, cb) {
12
+ transform(chunk: T, _, cb) {
13
13
  cb(null, chunk)
14
14
  },
15
15
  })
@@ -17,16 +17,16 @@ export function transformTap<IN>(
17
17
  opt: TransformTapOptions = {},
18
18
  ): TransformTyped<IN, IN> {
19
19
  const { logger = console } = opt
20
- let index = 0
20
+ let index = -1
21
21
 
22
22
  return new Transform({
23
23
  objectMode: true,
24
24
  ...opt,
25
- async transform(chunk: IN, _encoding, cb) {
25
+ async transform(chunk: IN, _, cb) {
26
26
  // console.log('tap', chunk)
27
27
 
28
28
  try {
29
- await fn(chunk, index++)
29
+ await fn(chunk, ++index)
30
30
  } catch (err) {
31
31
  logger.error(err)
32
32
  // suppressed error
@@ -10,7 +10,7 @@ export function transformToArray<IN>(opt: TransformOptions = {}): TransformTyped
10
10
  return new Transform({
11
11
  objectMode: true,
12
12
  ...opt,
13
- transform(chunk: IN, _encoding, cb) {
13
+ transform(chunk: IN, _, cb) {
14
14
  res.push(chunk)
15
15
  // callback to signal that we processed input, but not emitting any output
16
16
  cb()
@@ -14,8 +14,8 @@ export function transformToString(): TransformTyped<Buffer, string> {
14
14
  return new Transform({
15
15
  objectMode: false,
16
16
  readableObjectMode: true,
17
- transform(chunk: Buffer, _encoding, cb) {
18
- // console.log(`enc: ${_encoding}`, chunk.toString())
17
+ transform(chunk: Buffer, _, cb) {
18
+ // console.log(`enc: ${_}`, chunk.toString())
19
19
  cb(null, chunk.toString())
20
20
  },
21
21
  })
@@ -115,7 +115,7 @@ export function transformMultiThreaded<IN, OUT>(
115
115
  }
116
116
  },
117
117
  },
118
- async function transformMapFn(chunk: IN, _encoding, cb) {
118
+ async function transformMapFn(chunk: IN, _, cb) {
119
119
  // Freezing the index, because it may change due to concurrency
120
120
  const currentIndex = ++index
121
121
 
@@ -31,7 +31,7 @@ export function writableFork<T>(
31
31
  return new Writable({
32
32
  objectMode: true,
33
33
  ...opt,
34
- write(chunk: T, _encoding, cb) {
34
+ write(chunk: T, _, cb) {
35
35
  // Push/fork to all sub-streams
36
36
  // No backpressure is ensured here, it'll push regardless of the
37
37
  readables.forEach(readable => readable.push(chunk))
@@ -8,7 +8,7 @@ export function writablePushToArray<IN>(arr: IN[], opt: TransformOptions = {}):
8
8
  return new Writable({
9
9
  objectMode: true,
10
10
  ...opt,
11
- write(chunk: IN, _encoding, cb) {
11
+ write(chunk: IN, _, cb) {
12
12
  arr.push(chunk)
13
13
  // callback to signal that we processed input, but not emitting any output
14
14
  cb()
@@ -18,7 +18,7 @@ export function writableVoid(opt: WritableVoidOptions = {}): Writable {
18
18
  return new Writable({
19
19
  objectMode: true,
20
20
  ...opt,
21
- write(chunk, _encoding, cb) {
21
+ write(chunk, _, cb) {
22
22
  cb()
23
23
  },
24
24
  final(cb) {
@@ -8,9 +8,10 @@ const gzip = promisify(zlib.gzip.bind(zlib))
8
8
  const gunzip = promisify(zlib.gunzip.bind(zlib))
9
9
 
10
10
  // string > zip
11
+
11
12
  /**
12
13
  * zipBuffer uses `deflate`.
13
- * It's 9 bytes shorter than gzip.
14
+ * It's 9 bytes shorter than `gzip`.
14
15
  */
15
16
  export async function zipBuffer(buf: Buffer, options: ZlibOptions = {}): Promise<Buffer> {
16
17
  return await deflate(buf, options)
@@ -18,7 +19,7 @@ export async function zipBuffer(buf: Buffer, options: ZlibOptions = {}): Promise
18
19
 
19
20
  /**
20
21
  * gzipBuffer uses `gzip`
21
- * It's 9 bytes longer than deflate.
22
+ * It's 9 bytes longer than `deflate`.
22
23
  */
23
24
  export async function gzipBuffer(buf: Buffer, options: ZlibOptions = {}): Promise<Buffer> {
24
25
  return await gzip(buf, options)
@@ -33,11 +34,18 @@ export async function gunzipBuffer(buf: Buffer, options: ZlibOptions = {}): Prom
33
34
  return await gunzip(buf, options)
34
35
  }
35
36
 
36
- // convenience
37
+ /**
38
+ * zipString uses `deflate`.
39
+ * It's 9 bytes shorter than `gzip`.
40
+ */
37
41
  export async function zipString(s: string, options?: ZlibOptions): Promise<Buffer> {
38
42
  return await zipBuffer(Buffer.from(s), options)
39
43
  }
40
44
 
45
+ /**
46
+ * gzipString uses `gzip`.
47
+ * It's 9 bytes longer than `deflate`.
48
+ */
41
49
  export async function gzipString(s: string, options?: ZlibOptions): Promise<Buffer> {
42
50
  return await gzipBuffer(Buffer.from(s), options)
43
51
  }