@naturalcycles/nodejs-lib 13.13.0 → 13.15.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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/stream/progressLogger.d.ts +4 -4
- package/dist/stream/progressLogger.js +4 -4
- package/dist/stream/transform/transformChunk.d.ts +14 -0
- package/dist/stream/transform/{transformBuffer.js → transformChunk.js} +8 -8
- package/dist/validation/joi/joi.shared.schemas.d.ts +1 -0
- package/dist/validation/joi/joi.shared.schemas.js +5 -1
- package/dist/validation/joi/string.extensions.js +2 -2
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/stream/progressLogger.ts +8 -8
- package/src/stream/transform/transformChunk.ts +44 -0
- package/src/validation/joi/joi.shared.schemas.ts +5 -0
- package/src/validation/joi/string.extensions.ts +2 -2
- package/dist/stream/transform/transformBuffer.d.ts +0 -10
- package/src/stream/transform/transformBuffer.ts +0 -40
package/dist/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export * from './stream/readable/readableFromArray';
|
|
|
34
34
|
export * from './stream/readable/readableToArray';
|
|
35
35
|
export * from './stream/stream.model';
|
|
36
36
|
export * from './stream/progressLogger';
|
|
37
|
-
export * from './stream/transform/
|
|
37
|
+
export * from './stream/transform/transformChunk';
|
|
38
38
|
export * from './stream/transform/transformFilter';
|
|
39
39
|
export * from './stream/transform/transformLimit';
|
|
40
40
|
export * from './stream/transform/transformLogProgress';
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,7 @@ tslib_1.__exportStar(require("./stream/readable/readableFromArray"), exports);
|
|
|
38
38
|
tslib_1.__exportStar(require("./stream/readable/readableToArray"), exports);
|
|
39
39
|
tslib_1.__exportStar(require("./stream/stream.model"), exports);
|
|
40
40
|
tslib_1.__exportStar(require("./stream/progressLogger"), exports);
|
|
41
|
-
tslib_1.__exportStar(require("./stream/transform/
|
|
41
|
+
tslib_1.__exportStar(require("./stream/transform/transformChunk"), exports);
|
|
42
42
|
tslib_1.__exportStar(require("./stream/transform/transformFilter"), exports);
|
|
43
43
|
tslib_1.__exportStar(require("./stream/transform/transformLimit"), exports);
|
|
44
44
|
tslib_1.__exportStar(require("./stream/transform/transformLogProgress"), exports);
|
|
@@ -78,12 +78,12 @@ export interface ProgressLoggerCfg<T = any> {
|
|
|
78
78
|
extra?: (chunk: T | undefined, index: number) => AnyObject;
|
|
79
79
|
/**
|
|
80
80
|
* If specified - will multiply the counter by this number.
|
|
81
|
-
* Useful e.g when using `
|
|
82
|
-
* it'll accurately represent the number of processed entries (not
|
|
81
|
+
* Useful e.g when using `transformChunk({ chunkSize: 500 })`, so
|
|
82
|
+
* it'll accurately represent the number of processed entries (not chunks).
|
|
83
83
|
*
|
|
84
84
|
* Defaults to 1.
|
|
85
85
|
*/
|
|
86
|
-
|
|
86
|
+
chunkSize?: number;
|
|
87
87
|
/**
|
|
88
88
|
* Experimental logging of item (shunk) sizes, when json-stringified.
|
|
89
89
|
*
|
|
@@ -121,7 +121,7 @@ export declare class ProgressLogger<T> implements Disposable {
|
|
|
121
121
|
cfg: ProgressLoggerCfg<T> & {
|
|
122
122
|
logEvery: number;
|
|
123
123
|
logSizesBuffer: number;
|
|
124
|
-
|
|
124
|
+
chunkSize: number;
|
|
125
125
|
metric: string;
|
|
126
126
|
logger: CommonLogger;
|
|
127
127
|
};
|
|
@@ -18,7 +18,7 @@ class ProgressLogger {
|
|
|
18
18
|
logRPS: true,
|
|
19
19
|
logEvery: 1000,
|
|
20
20
|
logSizesBuffer: 100_000,
|
|
21
|
-
|
|
21
|
+
chunkSize: 1,
|
|
22
22
|
logger: console,
|
|
23
23
|
logProgress: cfg.logProgress !== false && cfg.logEvery !== 0,
|
|
24
24
|
...cfg,
|
|
@@ -59,11 +59,11 @@ class ProgressLogger {
|
|
|
59
59
|
logStats(chunk, final = false, tenx = false) {
|
|
60
60
|
if (!this.cfg.logProgress)
|
|
61
61
|
return;
|
|
62
|
-
const { metric, extra,
|
|
62
|
+
const { metric, extra, chunkSize, heapUsed: logHeapUsed, heapTotal: logHeapTotal, rss: logRss, peakRSS: logPeakRss, rssMinusHeap, external, arrayBuffers, logRPS, logger, } = this.cfg;
|
|
63
63
|
const mem = process.memoryUsage();
|
|
64
64
|
const now = Date.now();
|
|
65
|
-
const batchedProgress = this.progress *
|
|
66
|
-
const lastRPS = (this.processedLastSecond *
|
|
65
|
+
const batchedProgress = this.progress * chunkSize;
|
|
66
|
+
const lastRPS = (this.processedLastSecond * chunkSize) / ((now - this.lastSecondStarted) / 1000) || 0;
|
|
67
67
|
const rpsTotal = Math.round(batchedProgress / ((now - this.started) / 1000)) || 0;
|
|
68
68
|
this.lastSecondStarted = now;
|
|
69
69
|
this.processedLastSecond = 0;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TransformOptions, TransformTyped } from '../stream.model';
|
|
2
|
+
export interface TransformChunkOptions extends TransformOptions {
|
|
3
|
+
/**
|
|
4
|
+
* How many items to include in each chunk.
|
|
5
|
+
* Last chunk will contain the remaining items, possibly less than chunkSize.
|
|
6
|
+
*/
|
|
7
|
+
chunkSize: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Similar to RxJS bufferCount(),
|
|
11
|
+
* allows to "chunk" the input stream into chunks of `opt.chunkSize` size.
|
|
12
|
+
* Last chunk will contain the remaining items, possibly less than chunkSize.
|
|
13
|
+
*/
|
|
14
|
+
export declare function transformChunk<IN = any>(opt: TransformChunkOptions): TransformTyped<IN, IN[]>;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.transformChunk = void 0;
|
|
4
4
|
const node_stream_1 = require("node:stream");
|
|
5
5
|
/**
|
|
6
|
-
* Similar to RxJS bufferCount()
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Similar to RxJS bufferCount(),
|
|
7
|
+
* allows to "chunk" the input stream into chunks of `opt.chunkSize` size.
|
|
8
|
+
* Last chunk will contain the remaining items, possibly less than chunkSize.
|
|
9
9
|
*/
|
|
10
|
-
function
|
|
11
|
-
const {
|
|
10
|
+
function transformChunk(opt) {
|
|
11
|
+
const { chunkSize } = opt;
|
|
12
12
|
let buf = [];
|
|
13
13
|
return new node_stream_1.Transform({
|
|
14
14
|
objectMode: true,
|
|
15
15
|
...opt,
|
|
16
16
|
transform(chunk, _, cb) {
|
|
17
17
|
buf.push(chunk);
|
|
18
|
-
if (buf.length >=
|
|
18
|
+
if (buf.length >= chunkSize) {
|
|
19
19
|
cb(null, buf);
|
|
20
20
|
buf = [];
|
|
21
21
|
}
|
|
@@ -32,4 +32,4 @@ function transformBuffer(opt) {
|
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
exports.
|
|
35
|
+
exports.transformChunk = transformChunk;
|
|
@@ -14,6 +14,7 @@ export declare const percentageSchema: NumberSchema<number>;
|
|
|
14
14
|
export declare const dateStringSchema: StringSchema<string>;
|
|
15
15
|
export declare const binarySchema: import("joi").BinarySchema<Buffer>;
|
|
16
16
|
export declare const dateObjectSchema: ObjectSchema<any>;
|
|
17
|
+
export declare const dateIntervalStringSchema: StringSchema<string>;
|
|
17
18
|
/**
|
|
18
19
|
* Allows all values of a String Enum.
|
|
19
20
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.baseDBEntitySchema = exports.ipAddressSchema = exports.utcOffsetSchema = exports.userAgentSchema = exports.semVerSchema = exports.SEM_VER_REGEX = exports.emailSchema = exports.verSchema = exports.unixTimestampMillis2000Schema = exports.unixTimestampMillisSchema = exports.unixTimestamp2000Schema = exports.unixTimestampSchema = exports.slugSchema = exports.SLUG_REGEX = exports.idBase64UrlSchema = exports.idBase64Schema = exports.idBase62Schema = exports.idSchema = exports.jwtSchema = exports.JWT_REGEX = exports.base64UrlSchema = exports.base64Schema = exports.base62Schema = exports.BASE64URL_REGEX = exports.BASE64_REGEX = exports.BASE62_REGEX = exports.anyObjectSchema = exports.anySchema = exports.oneOfSchema = exports.objectSchema = exports.arraySchema = exports.urlSchema = exports.numberEnumKeySchema = exports.numberEnumValueSchema = exports.stringEnumKeySchema = exports.stringEnumValueSchema = exports.dateObjectSchema = exports.binarySchema = exports.dateStringSchema = exports.percentageSchema = exports.integerSchema = exports.numberSchemaTyped = exports.numberSchema = exports.stringSchemaTyped = exports.stringSchema = exports.booleanDefaultToFalseSchema = exports.booleanSchema = void 0;
|
|
3
|
+
exports.baseDBEntitySchema = exports.ipAddressSchema = exports.utcOffsetSchema = exports.userAgentSchema = exports.semVerSchema = exports.SEM_VER_REGEX = exports.emailSchema = exports.verSchema = exports.unixTimestampMillis2000Schema = exports.unixTimestampMillisSchema = exports.unixTimestamp2000Schema = exports.unixTimestampSchema = exports.slugSchema = exports.SLUG_REGEX = exports.idBase64UrlSchema = exports.idBase64Schema = exports.idBase62Schema = exports.idSchema = exports.jwtSchema = exports.JWT_REGEX = exports.base64UrlSchema = exports.base64Schema = exports.base62Schema = exports.BASE64URL_REGEX = exports.BASE64_REGEX = exports.BASE62_REGEX = exports.anyObjectSchema = exports.anySchema = exports.oneOfSchema = exports.objectSchema = exports.arraySchema = exports.urlSchema = exports.numberEnumKeySchema = exports.numberEnumValueSchema = exports.stringEnumKeySchema = exports.stringEnumValueSchema = exports.dateIntervalStringSchema = exports.dateObjectSchema = exports.binarySchema = exports.dateStringSchema = exports.percentageSchema = exports.integerSchema = exports.numberSchemaTyped = exports.numberSchema = exports.stringSchemaTyped = exports.stringSchema = exports.booleanDefaultToFalseSchema = exports.booleanSchema = void 0;
|
|
4
4
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
5
|
const joi_extensions_1 = require("./joi.extensions");
|
|
6
6
|
exports.booleanSchema = joi_extensions_1.Joi.boolean();
|
|
@@ -16,6 +16,10 @@ exports.percentageSchema = joi_extensions_1.Joi.number().integer().min(0).max(10
|
|
|
16
16
|
exports.dateStringSchema = exports.stringSchema.dateString();
|
|
17
17
|
exports.binarySchema = joi_extensions_1.Joi.binary();
|
|
18
18
|
exports.dateObjectSchema = joi_extensions_1.Joi.object().instance(Date);
|
|
19
|
+
const DATE_INTERVAL_REGEX = /^\d{4}-\d{2}-\d{2}\/\d{4}-\d{2}-\d{2}$/;
|
|
20
|
+
exports.dateIntervalStringSchema = exports.stringSchema.regex(DATE_INTERVAL_REGEX).messages({
|
|
21
|
+
'string.pattern.base': `must be a DateInterval string`,
|
|
22
|
+
});
|
|
19
23
|
/**
|
|
20
24
|
* Allows all values of a String Enum.
|
|
21
25
|
*/
|
|
@@ -41,10 +41,10 @@ function stringExtensions(joi) {
|
|
|
41
41
|
let { min, max } = args;
|
|
42
42
|
// Today allows +-14 hours gap to account for different timezones
|
|
43
43
|
if (max === 'today') {
|
|
44
|
-
max = (0, js_lib_1.localTimeNow)().
|
|
44
|
+
max = (0, js_lib_1.localTimeNow)().plus(14, 'hour').toISODate();
|
|
45
45
|
}
|
|
46
46
|
if (min === 'today') {
|
|
47
|
-
min = (0, js_lib_1.localTimeNow)().
|
|
47
|
+
min = (0, js_lib_1.localTimeNow)().minus(14, 'hour').toISODate();
|
|
48
48
|
}
|
|
49
49
|
// console.log('min/max', min, max)
|
|
50
50
|
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -44,7 +44,7 @@ export * from './stream/readable/readableFromArray'
|
|
|
44
44
|
export * from './stream/readable/readableToArray'
|
|
45
45
|
export * from './stream/stream.model'
|
|
46
46
|
export * from './stream/progressLogger'
|
|
47
|
-
export * from './stream/transform/
|
|
47
|
+
export * from './stream/transform/transformChunk'
|
|
48
48
|
export * from './stream/transform/transformFilter'
|
|
49
49
|
export * from './stream/transform/transformLimit'
|
|
50
50
|
export * from './stream/transform/transformLogProgress'
|
|
@@ -103,12 +103,12 @@ export interface ProgressLoggerCfg<T = any> {
|
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* If specified - will multiply the counter by this number.
|
|
106
|
-
* Useful e.g when using `
|
|
107
|
-
* it'll accurately represent the number of processed entries (not
|
|
106
|
+
* Useful e.g when using `transformChunk({ chunkSize: 500 })`, so
|
|
107
|
+
* it'll accurately represent the number of processed entries (not chunks).
|
|
108
108
|
*
|
|
109
109
|
* Defaults to 1.
|
|
110
110
|
*/
|
|
111
|
-
|
|
111
|
+
chunkSize?: number
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* Experimental logging of item (shunk) sizes, when json-stringified.
|
|
@@ -160,7 +160,7 @@ export class ProgressLogger<T> implements Disposable {
|
|
|
160
160
|
logRPS: true,
|
|
161
161
|
logEvery: 1000,
|
|
162
162
|
logSizesBuffer: 100_000,
|
|
163
|
-
|
|
163
|
+
chunkSize: 1,
|
|
164
164
|
logger: console,
|
|
165
165
|
logProgress: cfg.logProgress !== false && cfg.logEvery !== 0,
|
|
166
166
|
...cfg,
|
|
@@ -174,7 +174,7 @@ export class ProgressLogger<T> implements Disposable {
|
|
|
174
174
|
cfg!: ProgressLoggerCfg<T> & {
|
|
175
175
|
logEvery: number
|
|
176
176
|
logSizesBuffer: number
|
|
177
|
-
|
|
177
|
+
chunkSize: number
|
|
178
178
|
metric: string
|
|
179
179
|
logger: CommonLogger
|
|
180
180
|
}
|
|
@@ -230,7 +230,7 @@ export class ProgressLogger<T> implements Disposable {
|
|
|
230
230
|
const {
|
|
231
231
|
metric,
|
|
232
232
|
extra,
|
|
233
|
-
|
|
233
|
+
chunkSize,
|
|
234
234
|
heapUsed: logHeapUsed,
|
|
235
235
|
heapTotal: logHeapTotal,
|
|
236
236
|
rss: logRss,
|
|
@@ -245,9 +245,9 @@ export class ProgressLogger<T> implements Disposable {
|
|
|
245
245
|
const mem = process.memoryUsage()
|
|
246
246
|
|
|
247
247
|
const now = Date.now()
|
|
248
|
-
const batchedProgress = this.progress *
|
|
248
|
+
const batchedProgress = this.progress * chunkSize
|
|
249
249
|
const lastRPS =
|
|
250
|
-
(this.processedLastSecond *
|
|
250
|
+
(this.processedLastSecond * chunkSize) / ((now - this.lastSecondStarted) / 1000) || 0
|
|
251
251
|
const rpsTotal = Math.round(batchedProgress / ((now - this.started) / 1000)) || 0
|
|
252
252
|
this.lastSecondStarted = now
|
|
253
253
|
this.processedLastSecond = 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Transform } from 'node:stream'
|
|
2
|
+
import { TransformOptions, TransformTyped } from '../stream.model'
|
|
3
|
+
|
|
4
|
+
export interface TransformChunkOptions extends TransformOptions {
|
|
5
|
+
/**
|
|
6
|
+
* How many items to include in each chunk.
|
|
7
|
+
* Last chunk will contain the remaining items, possibly less than chunkSize.
|
|
8
|
+
*/
|
|
9
|
+
chunkSize: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Similar to RxJS bufferCount(),
|
|
14
|
+
* allows to "chunk" the input stream into chunks of `opt.chunkSize` size.
|
|
15
|
+
* Last chunk will contain the remaining items, possibly less than chunkSize.
|
|
16
|
+
*/
|
|
17
|
+
export function transformChunk<IN = any>(opt: TransformChunkOptions): TransformTyped<IN, IN[]> {
|
|
18
|
+
const { chunkSize } = opt
|
|
19
|
+
|
|
20
|
+
let buf: IN[] = []
|
|
21
|
+
|
|
22
|
+
return new Transform({
|
|
23
|
+
objectMode: true,
|
|
24
|
+
...opt,
|
|
25
|
+
transform(chunk, _, cb) {
|
|
26
|
+
buf.push(chunk)
|
|
27
|
+
|
|
28
|
+
if (buf.length >= chunkSize) {
|
|
29
|
+
cb(null, buf)
|
|
30
|
+
buf = []
|
|
31
|
+
} else {
|
|
32
|
+
cb()
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
final(this: Transform, cb) {
|
|
36
|
+
if (buf.length) {
|
|
37
|
+
this.push(buf)
|
|
38
|
+
buf = []
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
cb()
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
}
|
|
@@ -24,6 +24,11 @@ export const dateStringSchema = stringSchema.dateString()
|
|
|
24
24
|
export const binarySchema = Joi.binary()
|
|
25
25
|
export const dateObjectSchema = Joi.object().instance(Date)
|
|
26
26
|
|
|
27
|
+
const DATE_INTERVAL_REGEX = /^\d{4}-\d{2}-\d{2}\/\d{4}-\d{2}-\d{2}$/
|
|
28
|
+
export const dateIntervalStringSchema = stringSchema.regex(DATE_INTERVAL_REGEX).messages({
|
|
29
|
+
'string.pattern.base': `must be a DateInterval string`,
|
|
30
|
+
})
|
|
31
|
+
|
|
27
32
|
/**
|
|
28
33
|
* Allows all values of a String Enum.
|
|
29
34
|
*/
|
|
@@ -51,10 +51,10 @@ export function stringExtensions(joi: typeof Joi): Extension {
|
|
|
51
51
|
|
|
52
52
|
// Today allows +-14 hours gap to account for different timezones
|
|
53
53
|
if (max === 'today') {
|
|
54
|
-
max = localTimeNow().
|
|
54
|
+
max = localTimeNow().plus(14, 'hour').toISODate()
|
|
55
55
|
}
|
|
56
56
|
if (min === 'today') {
|
|
57
|
-
min = localTimeNow().
|
|
57
|
+
min = localTimeNow().minus(14, 'hour').toISODate()
|
|
58
58
|
}
|
|
59
59
|
// console.log('min/max', min, max)
|
|
60
60
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { TransformOptions, TransformTyped } from '../stream.model';
|
|
2
|
-
export interface TransformBufferOptions extends TransformOptions {
|
|
3
|
-
batchSize: number;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Similar to RxJS bufferCount()
|
|
7
|
-
*
|
|
8
|
-
* @default batchSize is 10
|
|
9
|
-
*/
|
|
10
|
-
export declare function transformBuffer<IN = any>(opt: TransformBufferOptions): TransformTyped<IN, IN[]>;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Transform } from 'node:stream'
|
|
2
|
-
import { TransformOptions, TransformTyped } from '../stream.model'
|
|
3
|
-
|
|
4
|
-
export interface TransformBufferOptions extends TransformOptions {
|
|
5
|
-
batchSize: number
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Similar to RxJS bufferCount()
|
|
10
|
-
*
|
|
11
|
-
* @default batchSize is 10
|
|
12
|
-
*/
|
|
13
|
-
export function transformBuffer<IN = any>(opt: TransformBufferOptions): TransformTyped<IN, IN[]> {
|
|
14
|
-
const { batchSize } = opt
|
|
15
|
-
|
|
16
|
-
let buf: IN[] = []
|
|
17
|
-
|
|
18
|
-
return new Transform({
|
|
19
|
-
objectMode: true,
|
|
20
|
-
...opt,
|
|
21
|
-
transform(chunk, _, cb) {
|
|
22
|
-
buf.push(chunk)
|
|
23
|
-
|
|
24
|
-
if (buf.length >= batchSize) {
|
|
25
|
-
cb(null, buf)
|
|
26
|
-
buf = []
|
|
27
|
-
} else {
|
|
28
|
-
cb()
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
final(this: Transform, cb) {
|
|
32
|
-
if (buf.length) {
|
|
33
|
-
this.push(buf)
|
|
34
|
-
buf = []
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
cb()
|
|
38
|
-
},
|
|
39
|
-
})
|
|
40
|
-
}
|