@naturalcycles/nodejs-lib 15.17.0 → 15.18.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.
- package/dist/csv/csvWriter.js +5 -1
- package/dist/fs/fs2.js +3 -1
- package/dist/fs/kpy.js +2 -2
- package/dist/stream/transform/transformMap.js +29 -9
- package/dist/stream/transform/transformMapSync.js +9 -6
- package/dist/stream/transform/worker/transformMultiThreaded.js +3 -1
- package/package.json +1 -1
- package/src/csv/csvWriter.ts +5 -1
- package/src/fs/fs2.ts +3 -1
- package/src/fs/kpy.ts +2 -2
- package/src/stream/transform/transformMap.ts +30 -12
- package/src/stream/transform/transformMapSync.ts +14 -8
- package/src/stream/transform/worker/transformMultiThreaded.ts +3 -1
package/dist/csv/csvWriter.js
CHANGED
|
@@ -47,6 +47,10 @@ export function arrayToCSVString(arr, cfg = {}) {
|
|
|
47
47
|
*/
|
|
48
48
|
export function arrayToCSVColumns(arr) {
|
|
49
49
|
const cols = new Set();
|
|
50
|
-
|
|
50
|
+
for (const row of arr) {
|
|
51
|
+
for (const col of Object.keys(row)) {
|
|
52
|
+
cols.add(col);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
51
55
|
return [...cols];
|
|
52
56
|
}
|
package/dist/fs/fs2.js
CHANGED
|
@@ -192,7 +192,9 @@ class FS2 {
|
|
|
192
192
|
this.ensureDir(dirPath);
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
195
|
-
|
|
195
|
+
for (const item of items) {
|
|
196
|
+
this.removePath(path.join(dirPath, item));
|
|
197
|
+
}
|
|
196
198
|
}
|
|
197
199
|
async emptyDirAsync(dirPath) {
|
|
198
200
|
let items;
|
package/dist/fs/kpy.js
CHANGED
|
@@ -41,7 +41,7 @@ export function kpySync(opt) {
|
|
|
41
41
|
});
|
|
42
42
|
kpyLogFilenames(opt, filenames);
|
|
43
43
|
const overwrite = !opt.noOverwrite;
|
|
44
|
-
|
|
44
|
+
for (const filename of filenames) {
|
|
45
45
|
const basename = path.basename(filename);
|
|
46
46
|
const srcFilename = path.resolve(opt.baseDir, filename);
|
|
47
47
|
const destFilename = path.resolve(opt.outputDir, opt.flat ? basename : filename);
|
|
@@ -56,7 +56,7 @@ export function kpySync(opt) {
|
|
|
56
56
|
if (opt.verbose) {
|
|
57
57
|
console.log(grey(` ${filename}`));
|
|
58
58
|
}
|
|
59
|
-
}
|
|
59
|
+
}
|
|
60
60
|
kpyLogResult(opt, filenames, started);
|
|
61
61
|
}
|
|
62
62
|
function kpyPrepare(opt) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _hc } from '@naturalcycles/js-lib';
|
|
2
2
|
import { _since } from '@naturalcycles/js-lib/datetime/time.util.js';
|
|
3
3
|
import { _anyToError, ErrorMode } from '@naturalcycles/js-lib/error';
|
|
4
|
-
import {
|
|
4
|
+
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js';
|
|
5
5
|
import { _stringify } from '@naturalcycles/js-lib/string/stringify.js';
|
|
6
6
|
import { END, SKIP, } from '@naturalcycles/js-lib/types';
|
|
7
7
|
import through2Concurrent from 'through2-concurrent';
|
|
@@ -77,15 +77,35 @@ export function transformMap(mapper, opt = {}) {
|
|
|
77
77
|
const currentIndex = ++index;
|
|
78
78
|
try {
|
|
79
79
|
const res = await mapper(chunk, currentIndex);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
// todo: consider retiring flattenArrayOutput from here
|
|
81
|
+
// and implementing it as a separate .flat transform/operator
|
|
82
|
+
const resInput = (flattenArrayOutput && Array.isArray(res) ? res : [res]);
|
|
83
|
+
if (predicate) {
|
|
84
|
+
await pMap(resInput, async (r) => {
|
|
85
|
+
if (r === END) {
|
|
86
|
+
isSettled = true; // will be checked later
|
|
87
|
+
return END;
|
|
88
|
+
}
|
|
89
|
+
if (r === SKIP)
|
|
90
|
+
return;
|
|
91
|
+
if (await predicate(r, currentIndex)) {
|
|
92
|
+
countOut++;
|
|
93
|
+
this.push(r);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
for (const r of resInput) {
|
|
99
|
+
if (r === END) {
|
|
100
|
+
isSettled = true; // will be checked later
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
if (r === SKIP)
|
|
104
|
+
continue;
|
|
105
|
+
countOut++;
|
|
106
|
+
this.push(r);
|
|
84
107
|
}
|
|
85
|
-
|
|
86
|
-
});
|
|
87
|
-
countOut += passedResults.length;
|
|
88
|
-
passedResults.forEach(r => this.push(r));
|
|
108
|
+
}
|
|
89
109
|
if (isSettled) {
|
|
90
110
|
logger.log(`transformMap END received at index ${currentIndex}`);
|
|
91
111
|
pipelineClose('transformMap', this, this.sourceReadable, this.streamDone, logger);
|
|
@@ -29,15 +29,18 @@ export function transformMapSync(mapper, opt = {}) {
|
|
|
29
29
|
try {
|
|
30
30
|
// map and pass through
|
|
31
31
|
const v = mapper(chunk, currentIndex);
|
|
32
|
-
|
|
32
|
+
// todo: consider retiring flattenArrayOutput option
|
|
33
|
+
const vInput = (flattenArrayOutput && Array.isArray(v) ? v : [v]);
|
|
34
|
+
for (const r of vInput) {
|
|
33
35
|
if (r === END) {
|
|
34
36
|
isSettled = true; // will be checked later
|
|
35
|
-
|
|
37
|
+
break;
|
|
36
38
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
if (r !== SKIP && (!predicate || predicate(r, currentIndex))) {
|
|
40
|
+
countOut++;
|
|
41
|
+
this.push(r);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
41
44
|
if (isSettled) {
|
|
42
45
|
logger.log(`transformMapSync END received at index ${currentIndex}`);
|
|
43
46
|
pipelineClose('transformMapSync', this, this.sourceReadable, this.streamDone, logger);
|
|
@@ -59,7 +59,9 @@ export function transformMultiThreaded(opt) {
|
|
|
59
59
|
async final(cb) {
|
|
60
60
|
try {
|
|
61
61
|
// Push null (complete) to all sub-streams
|
|
62
|
-
|
|
62
|
+
for (const worker of workers) {
|
|
63
|
+
worker.postMessage(null);
|
|
64
|
+
}
|
|
63
65
|
console.log(`transformMultiThreaded.final is waiting for all chains to be done`);
|
|
64
66
|
await Promise.all(workerDonePromises);
|
|
65
67
|
console.log(`transformMultiThreaded.final all chains done`);
|
package/package.json
CHANGED
package/src/csv/csvWriter.ts
CHANGED
|
@@ -78,6 +78,10 @@ export function arrayToCSVString(arr: AnyObject[], cfg: CSVWriterConfig = {}): s
|
|
|
78
78
|
*/
|
|
79
79
|
export function arrayToCSVColumns(arr: AnyObject[]): string[] {
|
|
80
80
|
const cols = new Set<string>()
|
|
81
|
-
|
|
81
|
+
for (const row of arr) {
|
|
82
|
+
for (const col of Object.keys(row)) {
|
|
83
|
+
cols.add(col)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
82
86
|
return [...cols]
|
|
83
87
|
}
|
package/src/fs/fs2.ts
CHANGED
|
@@ -219,7 +219,9 @@ class FS2 {
|
|
|
219
219
|
return
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
for (const item of items) {
|
|
223
|
+
this.removePath(path.join(dirPath, item))
|
|
224
|
+
}
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
async emptyDirAsync(dirPath: string): Promise<void> {
|
package/src/fs/kpy.ts
CHANGED
|
@@ -97,7 +97,7 @@ export function kpySync(opt: KpyOptions): void {
|
|
|
97
97
|
|
|
98
98
|
const overwrite = !opt.noOverwrite
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
for (const filename of filenames) {
|
|
101
101
|
const basename = path.basename(filename)
|
|
102
102
|
const srcFilename = path.resolve(opt.baseDir, filename)
|
|
103
103
|
const destFilename = path.resolve(opt.outputDir, opt.flat ? basename : filename)
|
|
@@ -113,7 +113,7 @@ export function kpySync(opt: KpyOptions): void {
|
|
|
113
113
|
if (opt.verbose) {
|
|
114
114
|
console.log(grey(` ${filename}`))
|
|
115
115
|
}
|
|
116
|
-
}
|
|
116
|
+
}
|
|
117
117
|
|
|
118
118
|
kpyLogResult(opt, filenames, started)
|
|
119
119
|
}
|
|
@@ -2,7 +2,7 @@ import { _hc } from '@naturalcycles/js-lib'
|
|
|
2
2
|
import { _since } from '@naturalcycles/js-lib/datetime/time.util.js'
|
|
3
3
|
import { _anyToError, ErrorMode } from '@naturalcycles/js-lib/error'
|
|
4
4
|
import type { CommonLogger } from '@naturalcycles/js-lib/log'
|
|
5
|
-
import {
|
|
5
|
+
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js'
|
|
6
6
|
import { _stringify } from '@naturalcycles/js-lib/string/stringify.js'
|
|
7
7
|
import {
|
|
8
8
|
type AbortableAsyncMapper,
|
|
@@ -203,20 +203,38 @@ export function transformMap<IN = any, OUT = IN>(
|
|
|
203
203
|
const currentIndex = ++index
|
|
204
204
|
|
|
205
205
|
try {
|
|
206
|
-
const res = await mapper(chunk, currentIndex)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
const res: OUT | typeof SKIP | typeof END = await mapper(chunk, currentIndex)
|
|
207
|
+
// todo: consider retiring flattenArrayOutput from here
|
|
208
|
+
// and implementing it as a separate .flat transform/operator
|
|
209
|
+
const resInput = (flattenArrayOutput && Array.isArray(res) ? res : [res]) as (
|
|
210
|
+
| OUT
|
|
211
|
+
| typeof SKIP
|
|
212
|
+
| typeof END
|
|
213
|
+
)[]
|
|
214
|
+
|
|
215
|
+
if (predicate) {
|
|
216
|
+
await pMap(resInput, async r => {
|
|
210
217
|
if (r === END) {
|
|
211
218
|
isSettled = true // will be checked later
|
|
212
|
-
return
|
|
219
|
+
return END
|
|
213
220
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
221
|
+
if (r === SKIP) return
|
|
222
|
+
if (await predicate(r, currentIndex)) {
|
|
223
|
+
countOut++
|
|
224
|
+
this.push(r)
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
} else {
|
|
228
|
+
for (const r of resInput) {
|
|
229
|
+
if (r === END) {
|
|
230
|
+
isSettled = true // will be checked later
|
|
231
|
+
break
|
|
232
|
+
}
|
|
233
|
+
if (r === SKIP) continue
|
|
234
|
+
countOut++
|
|
235
|
+
this.push(r)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
220
238
|
|
|
221
239
|
if (isSettled) {
|
|
222
240
|
logger.log(`transformMap END received at index ${currentIndex}`)
|
|
@@ -102,17 +102,23 @@ export function transformMapSync<IN = any, OUT = IN>(
|
|
|
102
102
|
try {
|
|
103
103
|
// map and pass through
|
|
104
104
|
const v = mapper(chunk, currentIndex)
|
|
105
|
-
|
|
106
|
-
const
|
|
105
|
+
// todo: consider retiring flattenArrayOutput option
|
|
106
|
+
const vInput = (flattenArrayOutput && Array.isArray(v) ? v : [v]) as (
|
|
107
|
+
| OUT
|
|
108
|
+
| typeof SKIP
|
|
109
|
+
| typeof END
|
|
110
|
+
)[]
|
|
111
|
+
|
|
112
|
+
for (const r of vInput) {
|
|
107
113
|
if (r === END) {
|
|
108
114
|
isSettled = true // will be checked later
|
|
109
|
-
|
|
115
|
+
break
|
|
110
116
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
if (r !== SKIP && (!predicate || predicate(r, currentIndex))) {
|
|
118
|
+
countOut++
|
|
119
|
+
this.push(r)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
116
122
|
|
|
117
123
|
if (isSettled) {
|
|
118
124
|
logger.log(`transformMapSync END received at index ${currentIndex}`)
|
|
@@ -104,7 +104,9 @@ export function transformMultiThreaded<IN, OUT>(
|
|
|
104
104
|
async final(cb) {
|
|
105
105
|
try {
|
|
106
106
|
// Push null (complete) to all sub-streams
|
|
107
|
-
|
|
107
|
+
for (const worker of workers) {
|
|
108
|
+
worker.postMessage(null)
|
|
109
|
+
}
|
|
108
110
|
|
|
109
111
|
console.log(`transformMultiThreaded.final is waiting for all chains to be done`)
|
|
110
112
|
await Promise.all(workerDonePromises)
|