@contrail/util 1.1.17-alpha.0 → 1.1.17-alpha.2
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/lib/compression-util/compression.d.ts +2 -0
- package/lib/compression-util/compression.js +25 -0
- package/lib/compression-util/index.d.ts +1 -0
- package/lib/compression-util/index.js +17 -0
- package/lib/date-util/getIsoDatePart/getIsoDatePart.js +1 -2
- package/lib/index.d.ts +7 -5
- package/lib/index.js +7 -5
- package/lib/object-util/applyChangesIfEqual/applyChangesIfEqual.js +7 -8
- package/lib/object-util/cloneDeep/cloneDeep.d.ts +5 -1
- package/lib/object-util/cloneDeep/cloneDeep.js +2 -4
- package/lib/object-util/cloneDeepPreserveDates/cloneDeepPreserveDates.d.ts +6 -0
- package/lib/object-util/cloneDeepPreserveDates/cloneDeepPreserveDates.js +37 -0
- package/lib/object-util/compareDeep/compareDeep.js +2 -3
- package/lib/object-util/isObject/isObject.js +1 -2
- package/lib/object-util/mergeDeep/mergeDeep.js +1 -2
- package/lib/object-util/object-util.d.ts +4 -0
- package/lib/object-util/object-util.js +4 -0
- package/lib/object-util/retainOnlyProperties/retainOnlyProperties.d.ts +8 -0
- package/lib/object-util/retainOnlyProperties/retainOnlyProperties.js +30 -0
- package/lib/performance-util/example-usage.d.ts +1 -0
- package/lib/performance-util/example-usage.js +298 -0
- package/lib/performance-util/performance-util.d.ts +35 -0
- package/lib/performance-util/performance-util.js +257 -0
- package/lib/promise-util/promise-util.d.ts +2 -2
- package/lib/promise-util/promise-util.js +13 -16
- package/lib/retry-util/retry-util.js +3 -4
- package/lib/string-util/string-util.d.ts +4 -2
- package/lib/string-util/string-util.js +14 -0
- package/lib/timer-util/timer-util.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compressIntoString = compressIntoString;
|
|
4
|
+
exports.decompressFromString = decompressFromString;
|
|
5
|
+
const fflate_1 = require("fflate");
|
|
6
|
+
function compressIntoString(obj) {
|
|
7
|
+
const jsonStr = JSON.stringify(obj === undefined ? null : obj);
|
|
8
|
+
if (typeof Buffer === 'undefined') {
|
|
9
|
+
console.warn('Buffer is not available. Compression will be skipped.');
|
|
10
|
+
return jsonStr;
|
|
11
|
+
}
|
|
12
|
+
const buffer = new TextEncoder().encode(jsonStr);
|
|
13
|
+
const compressed = (0, fflate_1.compressSync)(buffer);
|
|
14
|
+
return Buffer.from(compressed).toString('base64');
|
|
15
|
+
}
|
|
16
|
+
function decompressFromString(str) {
|
|
17
|
+
if (typeof Buffer === 'undefined') {
|
|
18
|
+
console.warn('Buffer is not available. Decompression will be skipped. Returning original string.');
|
|
19
|
+
return str;
|
|
20
|
+
}
|
|
21
|
+
const compressed = Buffer.from(str, 'base64');
|
|
22
|
+
const decompressed = (0, fflate_1.decompressSync)(compressed);
|
|
23
|
+
const originalText = new TextDecoder().decode(decompressed);
|
|
24
|
+
return JSON.parse(originalText);
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './compression';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./compression"), exports);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getIsoDatePart =
|
|
3
|
+
exports.getIsoDatePart = getIsoDatePart;
|
|
4
4
|
function getIsoDatePart(date) {
|
|
5
5
|
console.log('date 1: ', date.toISOString(), '\n\n\n\n\n\n\n\n');
|
|
6
6
|
let d = new Date(date);
|
|
@@ -14,4 +14,3 @@ function getIsoDatePart(date) {
|
|
|
14
14
|
}
|
|
15
15
|
return [year, month, day].join('-');
|
|
16
16
|
}
|
|
17
|
-
exports.getIsoDatePart = getIsoDatePart;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
1
|
+
export * from './app-util/app-util';
|
|
2
|
+
export * from './compression-util';
|
|
3
3
|
export * from './date-util/date-util';
|
|
4
4
|
export * from './map-util/map-util';
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './timer-util/timer-util';
|
|
7
|
-
export * from './promise-util/promise-util';
|
|
5
|
+
export * from './object-util/object-util';
|
|
8
6
|
export * from './order-util/order-util';
|
|
7
|
+
export * from './performance-util/performance-util';
|
|
8
|
+
export * from './promise-util/promise-util';
|
|
9
9
|
export * from './retry-util/retry-util';
|
|
10
|
+
export * from './string-util/string-util';
|
|
11
|
+
export * from './timer-util/timer-util';
|
package/lib/index.js
CHANGED
|
@@ -14,12 +14,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./app-util/app-util"), exports);
|
|
18
|
+
__exportStar(require("./compression-util"), exports);
|
|
19
19
|
__exportStar(require("./date-util/date-util"), exports);
|
|
20
20
|
__exportStar(require("./map-util/map-util"), exports);
|
|
21
|
-
__exportStar(require("./
|
|
22
|
-
__exportStar(require("./timer-util/timer-util"), exports);
|
|
23
|
-
__exportStar(require("./promise-util/promise-util"), exports);
|
|
21
|
+
__exportStar(require("./object-util/object-util"), exports);
|
|
24
22
|
__exportStar(require("./order-util/order-util"), exports);
|
|
23
|
+
__exportStar(require("./performance-util/performance-util"), exports);
|
|
24
|
+
__exportStar(require("./promise-util/promise-util"), exports);
|
|
25
25
|
__exportStar(require("./retry-util/retry-util"), exports);
|
|
26
|
+
__exportStar(require("./string-util/string-util"), exports);
|
|
27
|
+
__exportStar(require("./timer-util/timer-util"), exports);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.applyChangesIfEqual = applyChangesIfEqual;
|
|
4
|
+
exports.determineChangesIfEqual = determineChangesIfEqual;
|
|
5
|
+
exports.areItemPropertyValuesEqual = areItemPropertyValuesEqual;
|
|
4
6
|
const types_1 = require("@contrail/types");
|
|
5
7
|
const compareDeep_1 = require("../compareDeep/compareDeep");
|
|
6
8
|
function applyChangesIfEqual(target, priorSourceValues, newSourceValues, properties) {
|
|
@@ -9,7 +11,6 @@ function applyChangesIfEqual(target, priorSourceValues, newSourceValues, propert
|
|
|
9
11
|
Object.assign(target, changes);
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
|
-
exports.applyChangesIfEqual = applyChangesIfEqual;
|
|
13
14
|
function determineChangesIfEqual(target, priorSourceValues, newSourceValues, properties) {
|
|
14
15
|
const changes = {};
|
|
15
16
|
for (const property of properties) {
|
|
@@ -26,26 +27,24 @@ function determineChangesIfEqual(target, priorSourceValues, newSourceValues, pro
|
|
|
26
27
|
}
|
|
27
28
|
return changes;
|
|
28
29
|
}
|
|
29
|
-
exports.determineChangesIfEqual = determineChangesIfEqual;
|
|
30
30
|
function areItemPropertyValuesEqual(property, itemOne, itemTwo) {
|
|
31
|
-
var _a, _b;
|
|
31
|
+
var _a, _b, _c, _d;
|
|
32
32
|
const propertyKey = getPropertyKey(property);
|
|
33
|
-
const propertyValueOne = itemOne[propertyKey];
|
|
34
|
-
const propertyValueTwo = itemTwo[propertyKey];
|
|
33
|
+
const propertyValueOne = (_a = itemOne[propertyKey]) !== null && _a !== void 0 ? _a : null;
|
|
34
|
+
const propertyValueTwo = (_b = itemTwo[propertyKey]) !== null && _b !== void 0 ? _b : null;
|
|
35
35
|
if (property.propertyType === types_1.PropertyType.MultiSelect) {
|
|
36
36
|
const propertyValueOneAsArray = getMultiSelectValueAsArray(propertyValueOne);
|
|
37
37
|
const propertyValueTwoAsArray = getMultiSelectValueAsArray(propertyValueTwo);
|
|
38
38
|
return areArraysEqualIgnoreOrder(propertyValueOneAsArray, propertyValueTwoAsArray);
|
|
39
39
|
}
|
|
40
40
|
if (property.propertyType === types_1.PropertyType.SizeRange) {
|
|
41
|
-
const isOfSameSizeRangeTemplate = ((
|
|
41
|
+
const isOfSameSizeRangeTemplate = ((_c = itemOne === null || itemOne === void 0 ? void 0 : itemOne.sizeRangeTemplate) === null || _c === void 0 ? void 0 : _c.id) === ((_d = itemTwo === null || itemTwo === void 0 ? void 0 : itemTwo.sizeRangeTemplate) === null || _d === void 0 ? void 0 : _d.id);
|
|
42
42
|
if (!isOfSameSizeRangeTemplate)
|
|
43
43
|
return false;
|
|
44
44
|
return areSizeRangesEqual(propertyValueOne, propertyValueTwo);
|
|
45
45
|
}
|
|
46
46
|
return propertyValueOne === propertyValueTwo;
|
|
47
47
|
}
|
|
48
|
-
exports.areItemPropertyValuesEqual = areItemPropertyValuesEqual;
|
|
49
48
|
function areSizeRangesEqual(sizeRangeOne, sizeRangeTwo) {
|
|
50
49
|
var _a, _b;
|
|
51
50
|
if (!sizeRangeOne && !sizeRangeTwo) {
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export declare function cloneDeep(obj:
|
|
1
|
+
export declare function cloneDeep<T>(obj: T): DatesAsStrings<T> | null;
|
|
2
|
+
type DatesAsStrings<T> = T extends Date ? string : T extends (infer U)[] ? DatesAsStrings<U>[] : T extends object ? {
|
|
3
|
+
[K in keyof T]: DatesAsStrings<T[K]>;
|
|
4
|
+
} : T;
|
|
5
|
+
export {};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.cloneDeep =
|
|
3
|
+
exports.cloneDeep = cloneDeep;
|
|
4
4
|
function cloneDeep(obj) {
|
|
5
|
-
if (
|
|
5
|
+
if (obj == null)
|
|
6
6
|
return null;
|
|
7
|
-
}
|
|
8
7
|
return JSON.parse(JSON.stringify(obj));
|
|
9
8
|
}
|
|
10
|
-
exports.cloneDeep = cloneDeep;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function cloneDeepPreserveDates<T>(obj: T): T | null;
|
|
2
|
+
declare const DATE_TAG = "__$date";
|
|
3
|
+
export declare function tagDates(input: unknown): unknown;
|
|
4
|
+
export declare function reviveTaggedDates(_key: string, value: unknown): unknown;
|
|
5
|
+
export declare function isTaggedDate(v: unknown): v is Record<typeof DATE_TAG, string>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cloneDeepPreserveDates = cloneDeepPreserveDates;
|
|
4
|
+
exports.tagDates = tagDates;
|
|
5
|
+
exports.reviveTaggedDates = reviveTaggedDates;
|
|
6
|
+
exports.isTaggedDate = isTaggedDate;
|
|
7
|
+
function cloneDeepPreserveDates(obj) {
|
|
8
|
+
if (obj == null)
|
|
9
|
+
return null;
|
|
10
|
+
const tagged = tagDates(obj);
|
|
11
|
+
const json = JSON.stringify(tagged);
|
|
12
|
+
return JSON.parse(json, reviveTaggedDates);
|
|
13
|
+
}
|
|
14
|
+
const DATE_TAG = '__$date';
|
|
15
|
+
function tagDates(input) {
|
|
16
|
+
if (input instanceof Date)
|
|
17
|
+
return { [DATE_TAG]: input.toISOString() };
|
|
18
|
+
if (Array.isArray(input))
|
|
19
|
+
return input.map(tagDates);
|
|
20
|
+
if (input && typeof input === 'object') {
|
|
21
|
+
const out = {};
|
|
22
|
+
for (const [k, v] of Object.entries(input))
|
|
23
|
+
out[k] = tagDates(v);
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
return input;
|
|
27
|
+
}
|
|
28
|
+
function reviveTaggedDates(_key, value) {
|
|
29
|
+
return isTaggedDate(value) ? new Date(value[DATE_TAG]) : value;
|
|
30
|
+
}
|
|
31
|
+
function isTaggedDate(v) {
|
|
32
|
+
return (!!v &&
|
|
33
|
+
typeof v === 'object' &&
|
|
34
|
+
v !== null &&
|
|
35
|
+
DATE_TAG in v &&
|
|
36
|
+
typeof v[DATE_TAG] === 'string');
|
|
37
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getObjectDiffs = getObjectDiffs;
|
|
4
|
+
exports.getObjectDiff = getObjectDiff;
|
|
4
5
|
function getObjectDiffs(before, after, prefix) {
|
|
5
6
|
const diffs = [];
|
|
6
7
|
if (!before || !after) {
|
|
@@ -67,7 +68,6 @@ function getObjectDiffs(before, after, prefix) {
|
|
|
67
68
|
});
|
|
68
69
|
return diffs;
|
|
69
70
|
}
|
|
70
|
-
exports.getObjectDiffs = getObjectDiffs;
|
|
71
71
|
function getObjectDiff(before, after, name) {
|
|
72
72
|
const diff = {
|
|
73
73
|
propertyName: name,
|
|
@@ -76,7 +76,6 @@ function getObjectDiff(before, after, name) {
|
|
|
76
76
|
};
|
|
77
77
|
return diff;
|
|
78
78
|
}
|
|
79
|
-
exports.getObjectDiff = getObjectDiff;
|
|
80
79
|
function sortFunc(x, y) {
|
|
81
80
|
const pre = ['string', 'number', 'bool'];
|
|
82
81
|
if (typeof x !== typeof y)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isObject =
|
|
3
|
+
exports.isObject = isObject;
|
|
4
4
|
function isObject(item) {
|
|
5
5
|
return item && typeof item === 'object' && !Array.isArray(item);
|
|
6
6
|
}
|
|
7
|
-
exports.isObject = isObject;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mergeDeep =
|
|
3
|
+
exports.mergeDeep = mergeDeep;
|
|
4
4
|
const isObject_1 = require("../isObject/isObject");
|
|
5
5
|
function mergeDeep(target, ...sources) {
|
|
6
6
|
if (!sources.length)
|
|
@@ -20,7 +20,6 @@ function mergeDeep(target, ...sources) {
|
|
|
20
20
|
}
|
|
21
21
|
return mergeDeep(target, ...sources);
|
|
22
22
|
}
|
|
23
|
-
exports.mergeDeep = mergeDeep;
|
|
24
23
|
function isDate(object) {
|
|
25
24
|
return object != null && object instanceof Date;
|
|
26
25
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { cloneDeep } from './cloneDeep/cloneDeep';
|
|
2
|
+
import { cloneDeepPreserveDates } from './cloneDeepPreserveDates/cloneDeepPreserveDates';
|
|
2
3
|
import { isObject } from './isObject/isObject';
|
|
3
4
|
import { mergeDeep } from './mergeDeep/mergeDeep';
|
|
4
5
|
import { getObjectDiffs } from './compareDeep/compareDeep';
|
|
5
6
|
import { applyChangesIfEqual, determineChangesIfEqual, areItemPropertyValuesEqual } from './applyChangesIfEqual/applyChangesIfEqual';
|
|
7
|
+
import { retainOnlyProperties } from './retainOnlyProperties/retainOnlyProperties';
|
|
6
8
|
export { ObjectDiff } from './compareDeep/compareDeep';
|
|
7
9
|
export declare class ObjectUtil {
|
|
8
10
|
static getByPath(obj: any, path: string, def?: any): any;
|
|
@@ -13,8 +15,10 @@ export declare class ObjectUtil {
|
|
|
13
15
|
static isObject: typeof isObject;
|
|
14
16
|
static mergeDeep: typeof mergeDeep;
|
|
15
17
|
static cloneDeep: typeof cloneDeep;
|
|
18
|
+
static cloneDeepPreserveDates: typeof cloneDeepPreserveDates;
|
|
16
19
|
static compareDeep: typeof getObjectDiffs;
|
|
17
20
|
static applyChangesIfEqual: typeof applyChangesIfEqual;
|
|
18
21
|
static determineChangesIfEqual: typeof determineChangesIfEqual;
|
|
19
22
|
static areItemPropertyValuesEqual: typeof areItemPropertyValuesEqual;
|
|
23
|
+
static retainOnlyProperties: typeof retainOnlyProperties;
|
|
20
24
|
}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ObjectUtil = void 0;
|
|
4
4
|
const cloneDeep_1 = require("./cloneDeep/cloneDeep");
|
|
5
|
+
const cloneDeepPreserveDates_1 = require("./cloneDeepPreserveDates/cloneDeepPreserveDates");
|
|
5
6
|
const isObject_1 = require("./isObject/isObject");
|
|
6
7
|
const mergeDeep_1 = require("./mergeDeep/mergeDeep");
|
|
7
8
|
const compareDeep_1 = require("./compareDeep/compareDeep");
|
|
8
9
|
const applyChangesIfEqual_1 = require("./applyChangesIfEqual/applyChangesIfEqual");
|
|
10
|
+
const retainOnlyProperties_1 = require("./retainOnlyProperties/retainOnlyProperties");
|
|
9
11
|
class ObjectUtil {
|
|
10
12
|
static getByPath(obj, path, def = null) {
|
|
11
13
|
if (obj == undefined)
|
|
@@ -79,7 +81,9 @@ exports.ObjectUtil = ObjectUtil;
|
|
|
79
81
|
ObjectUtil.isObject = isObject_1.isObject;
|
|
80
82
|
ObjectUtil.mergeDeep = mergeDeep_1.mergeDeep;
|
|
81
83
|
ObjectUtil.cloneDeep = cloneDeep_1.cloneDeep;
|
|
84
|
+
ObjectUtil.cloneDeepPreserveDates = cloneDeepPreserveDates_1.cloneDeepPreserveDates;
|
|
82
85
|
ObjectUtil.compareDeep = compareDeep_1.getObjectDiffs;
|
|
83
86
|
ObjectUtil.applyChangesIfEqual = applyChangesIfEqual_1.applyChangesIfEqual;
|
|
84
87
|
ObjectUtil.determineChangesIfEqual = applyChangesIfEqual_1.determineChangesIfEqual;
|
|
85
88
|
ObjectUtil.areItemPropertyValuesEqual = applyChangesIfEqual_1.areItemPropertyValuesEqual;
|
|
89
|
+
ObjectUtil.retainOnlyProperties = retainOnlyProperties_1.retainOnlyProperties;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function retainOnlyProperties<T extends Record<string, any>, K extends readonly string[]>(obj: T[], keysToKeep: K, options?: {
|
|
2
|
+
shouldDeleteInPlace?: boolean;
|
|
3
|
+
skipKeys?: readonly string[];
|
|
4
|
+
}): Array<Pick<T, K[number]>>;
|
|
5
|
+
export declare function retainOnlyProperties<T extends Record<string, any>, K extends readonly string[]>(obj: T, keysToKeep: K, options?: {
|
|
6
|
+
shouldDeleteInPlace?: boolean;
|
|
7
|
+
skipKeys?: readonly string[];
|
|
8
|
+
}): Pick<T, K[number]>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.retainOnlyProperties = retainOnlyProperties;
|
|
4
|
+
const object_util_1 = require("../object-util");
|
|
5
|
+
function retainOnlyProperties(obj, keysToKeep, options = {}) {
|
|
6
|
+
const keepSet = new Set(keysToKeep);
|
|
7
|
+
const skipSet = new Set(options.skipKeys || []);
|
|
8
|
+
const shouldReturnAsIs = (value) => value === null || value === undefined || typeof value !== 'object' || value instanceof Date;
|
|
9
|
+
const retain = (target) => {
|
|
10
|
+
if (shouldReturnAsIs(target))
|
|
11
|
+
return target;
|
|
12
|
+
if (Array.isArray(target)) {
|
|
13
|
+
return target.map(retain);
|
|
14
|
+
}
|
|
15
|
+
for (const key in target) {
|
|
16
|
+
if (skipSet.has(key)) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (!keepSet.has(key)) {
|
|
20
|
+
delete target[key];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
target[key] = retain(target[key]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return target;
|
|
27
|
+
};
|
|
28
|
+
const objToModify = options.shouldDeleteInPlace ? obj : object_util_1.ObjectUtil.cloneDeepPreserveDates(obj);
|
|
29
|
+
return retain(objToModify);
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const performance_util_1 = require("./performance-util");
|
|
13
|
+
function demonstrateStartEndSpan() {
|
|
14
|
+
console.log('--- Demonstrating startSpan/endSpan functionality ---\n');
|
|
15
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
16
|
+
console.log('Example 1: Simple span');
|
|
17
|
+
(0, performance_util_1.startSpan)('Data Processing');
|
|
18
|
+
const start1 = performance.now();
|
|
19
|
+
while (performance.now() < start1 + 100) {
|
|
20
|
+
}
|
|
21
|
+
(0, performance_util_1.endSpan)('Data Processing');
|
|
22
|
+
(0, performance_util_1.displayTimingTree)();
|
|
23
|
+
console.log('\nExample 2: Nested spans');
|
|
24
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
25
|
+
(0, performance_util_1.startSpan)('Complete Task');
|
|
26
|
+
(0, performance_util_1.startSpan)('Initialization');
|
|
27
|
+
const start2 = performance.now();
|
|
28
|
+
while (performance.now() < start2 + 50) {
|
|
29
|
+
}
|
|
30
|
+
(0, performance_util_1.endSpan)('Initialization');
|
|
31
|
+
(0, performance_util_1.startSpan)('Main Processing');
|
|
32
|
+
(0, performance_util_1.startSpan)('Sub-task 1');
|
|
33
|
+
const start3 = performance.now();
|
|
34
|
+
while (performance.now() < start3 + 30) {
|
|
35
|
+
}
|
|
36
|
+
(0, performance_util_1.endSpan)('Sub-task 1');
|
|
37
|
+
(0, performance_util_1.startSpan)('Sub-task 2');
|
|
38
|
+
const start4 = performance.now();
|
|
39
|
+
while (performance.now() < start4 + 40) {
|
|
40
|
+
}
|
|
41
|
+
(0, performance_util_1.endSpan)('Sub-task 2');
|
|
42
|
+
(0, performance_util_1.endSpan)('Main Processing');
|
|
43
|
+
(0, performance_util_1.startSpan)('Cleanup');
|
|
44
|
+
const start5 = performance.now();
|
|
45
|
+
while (performance.now() < start5 + 20) {
|
|
46
|
+
}
|
|
47
|
+
(0, performance_util_1.endSpan)('Cleanup');
|
|
48
|
+
(0, performance_util_1.endSpan)('Complete Task');
|
|
49
|
+
(0, performance_util_1.displayTimingTree)();
|
|
50
|
+
console.log('\nExample 3: Multiple sequential spans');
|
|
51
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
52
|
+
(0, performance_util_1.startSpan)('Phase 1');
|
|
53
|
+
const start6 = performance.now();
|
|
54
|
+
while (performance.now() < start6 + 60) {
|
|
55
|
+
}
|
|
56
|
+
(0, performance_util_1.endSpan)('Phase 1');
|
|
57
|
+
(0, performance_util_1.startSpan)('Phase 2');
|
|
58
|
+
const start7 = performance.now();
|
|
59
|
+
while (performance.now() < start7 + 80) {
|
|
60
|
+
}
|
|
61
|
+
(0, performance_util_1.endSpan)('Phase 2');
|
|
62
|
+
(0, performance_util_1.startSpan)('Phase 3');
|
|
63
|
+
const start8 = performance.now();
|
|
64
|
+
while (performance.now() < start8 + 40) {
|
|
65
|
+
}
|
|
66
|
+
(0, performance_util_1.endSpan)('Phase 3');
|
|
67
|
+
(0, performance_util_1.displayTimingTree)();
|
|
68
|
+
}
|
|
69
|
+
function demonstrateWarningBehavior() {
|
|
70
|
+
console.log('\n--- Demonstrating Warning Behavior ---\n');
|
|
71
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
72
|
+
console.log('Example 4: Warning behavior');
|
|
73
|
+
(0, performance_util_1.startSpan)('Test Span');
|
|
74
|
+
console.log('Started "Test Span"');
|
|
75
|
+
(0, performance_util_1.startSpan)('Test Span');
|
|
76
|
+
console.log('Attempted to start "Test Span" again (should see warning above)');
|
|
77
|
+
(0, performance_util_1.endSpan)('Test Span');
|
|
78
|
+
console.log('Ended "Test Span"');
|
|
79
|
+
(0, performance_util_1.endSpan)('Non-existent Span');
|
|
80
|
+
console.log('Attempted to end "Non-existent Span" (should see warning above)');
|
|
81
|
+
(0, performance_util_1.displayTimingTree)();
|
|
82
|
+
}
|
|
83
|
+
function demonstrateParentNodeId() {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
console.log('\n--- Demonstrating parentNodeId Functionality ---\n');
|
|
86
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
87
|
+
console.log('Example 5: Concurrent async operations with explicit parent');
|
|
88
|
+
yield (0, performance_util_1.withTimingAsync)('Main Operation', () => __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
const mainOpId = (0, performance_util_1.getCurrentParentNodeId)();
|
|
90
|
+
console.log(`Main Operation ID: ${String(mainOpId)}`);
|
|
91
|
+
console.log('Starting concurrent operations...');
|
|
92
|
+
const results = yield Promise.all([
|
|
93
|
+
(0, performance_util_1.withTimingAsync)('Fetch User Data', () => __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
yield new Promise((resolve) => setTimeout(resolve, 80));
|
|
95
|
+
console.log(' ✓ User data fetched');
|
|
96
|
+
return 'user-data';
|
|
97
|
+
}), { parentNodeId: mainOpId }),
|
|
98
|
+
(0, performance_util_1.withTimingAsync)('Fetch Permissions', () => __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
yield new Promise((resolve) => setTimeout(resolve, 60));
|
|
100
|
+
console.log(' ✓ Permissions fetched');
|
|
101
|
+
return 'permissions-data';
|
|
102
|
+
}), { parentNodeId: mainOpId }),
|
|
103
|
+
(0, performance_util_1.withTimingAsync)('Fetch Preferences', () => __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
yield new Promise((resolve) => setTimeout(resolve, 100));
|
|
105
|
+
console.log(' ✓ Preferences fetched');
|
|
106
|
+
return 'preferences-data';
|
|
107
|
+
}), { parentNodeId: mainOpId }),
|
|
108
|
+
]);
|
|
109
|
+
console.log('All concurrent operations completed:', results);
|
|
110
|
+
yield (0, performance_util_1.withTimingAsync)('Process Results', () => __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
yield new Promise((resolve) => setTimeout(resolve, 30));
|
|
112
|
+
console.log(' ✓ Results processed');
|
|
113
|
+
}));
|
|
114
|
+
}));
|
|
115
|
+
(0, performance_util_1.displayTimingTree)();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function demonstrateMixedNesting() {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
console.log('\n--- Demonstrating Mixed Natural and Explicit Nesting ---\n');
|
|
121
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
122
|
+
console.log('Example 6: Mixed natural and explicit nesting');
|
|
123
|
+
yield (0, performance_util_1.withTimingAsync)('Application Startup', () => __awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
yield (0, performance_util_1.withTimingAsync)('Load Configuration', () => __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
yield new Promise((resolve) => setTimeout(resolve, 50));
|
|
126
|
+
console.log(' ✓ Configuration loaded');
|
|
127
|
+
yield (0, performance_util_1.withTimingAsync)('Validate Config', () => __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
yield new Promise((resolve) => setTimeout(resolve, 20));
|
|
129
|
+
console.log(' ✓ Configuration validated');
|
|
130
|
+
}));
|
|
131
|
+
}));
|
|
132
|
+
console.log('Starting parallel initialization...');
|
|
133
|
+
(0, performance_util_1.startSpan)('Initialization');
|
|
134
|
+
const ininitializeId = (0, performance_util_1.getCurrentParentNodeId)();
|
|
135
|
+
(0, performance_util_1.withTimingSync)('Do something before initialization', () => {
|
|
136
|
+
const start = performance.now();
|
|
137
|
+
while (performance.now() < start + 20) {
|
|
138
|
+
}
|
|
139
|
+
console.log(' ✓ Pre-initialization task completed');
|
|
140
|
+
});
|
|
141
|
+
yield Promise.all([
|
|
142
|
+
(0, performance_util_1.withTimingAsync)('Initialize Database', () => __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
yield new Promise((resolve) => setTimeout(resolve, 120));
|
|
144
|
+
console.log(' ✓ Database initialized');
|
|
145
|
+
}), { parentNodeId: ininitializeId }),
|
|
146
|
+
(0, performance_util_1.withTimingAsync)('Initialize Cache', () => __awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
yield new Promise((resolve) => setTimeout(resolve, 90));
|
|
148
|
+
console.log(' ✓ Cache initialized');
|
|
149
|
+
}), { parentNodeId: ininitializeId }),
|
|
150
|
+
(0, performance_util_1.withTimingAsync)('Initialize Logging', () => __awaiter(this, void 0, void 0, function* () {
|
|
151
|
+
yield new Promise((resolve) => setTimeout(resolve, 40));
|
|
152
|
+
console.log(' ✓ Logging initialized');
|
|
153
|
+
}), { parentNodeId: ininitializeId }),
|
|
154
|
+
]);
|
|
155
|
+
(0, performance_util_1.withTimingSync)('Do something after initialization', () => {
|
|
156
|
+
const start = performance.now();
|
|
157
|
+
while (performance.now() < start + 20) {
|
|
158
|
+
}
|
|
159
|
+
console.log(' ✓ Post-initialization task completed');
|
|
160
|
+
});
|
|
161
|
+
(0, performance_util_1.endSpan)('Initialization');
|
|
162
|
+
yield (0, performance_util_1.withTimingAsync)('Final Setup', () => __awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
yield new Promise((resolve) => setTimeout(resolve, 30));
|
|
164
|
+
console.log(' ✓ Final setup completed');
|
|
165
|
+
}));
|
|
166
|
+
}));
|
|
167
|
+
(0, performance_util_1.displayTimingTree)();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function demonstrateSyncWithParentId() {
|
|
171
|
+
console.log('\n--- Demonstrating Sync Functions with parentNodeId ---\n');
|
|
172
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
173
|
+
console.log('Example 7: Sync functions with explicit parent');
|
|
174
|
+
(0, performance_util_1.withTimingSync)('Data Processing Pipeline', () => {
|
|
175
|
+
const pipelineId = (0, performance_util_1.getCurrentParentNodeId)();
|
|
176
|
+
console.log(`Pipeline ID: ${String(pipelineId)}`);
|
|
177
|
+
(0, performance_util_1.withTimingSync)('Load Input Data', () => {
|
|
178
|
+
const start = performance.now();
|
|
179
|
+
while (performance.now() < start + 50) {
|
|
180
|
+
}
|
|
181
|
+
console.log(' ✓ Input data loaded');
|
|
182
|
+
});
|
|
183
|
+
(0, performance_util_1.withTimingSync)('Process Batch 1', () => {
|
|
184
|
+
const start = performance.now();
|
|
185
|
+
while (performance.now() < start + 80) {
|
|
186
|
+
}
|
|
187
|
+
console.log(' ✓ Batch 1 processed');
|
|
188
|
+
}, { parentNodeId: pipelineId });
|
|
189
|
+
(0, performance_util_1.withTimingSync)('Process Batch 2', () => {
|
|
190
|
+
const start = performance.now();
|
|
191
|
+
while (performance.now() < start + 70) {
|
|
192
|
+
}
|
|
193
|
+
console.log(' ✓ Batch 2 processed');
|
|
194
|
+
}, { parentNodeId: pipelineId });
|
|
195
|
+
(0, performance_util_1.withTimingSync)('Process Batch 3', () => {
|
|
196
|
+
const start = performance.now();
|
|
197
|
+
while (performance.now() < start + 90) {
|
|
198
|
+
}
|
|
199
|
+
console.log(' ✓ Batch 3 processed');
|
|
200
|
+
}, { parentNodeId: pipelineId });
|
|
201
|
+
(0, performance_util_1.withTimingSync)('Save Results', () => {
|
|
202
|
+
const start = performance.now();
|
|
203
|
+
while (performance.now() < start + 40) {
|
|
204
|
+
}
|
|
205
|
+
console.log(' ✓ Results saved');
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
(0, performance_util_1.displayTimingTree)();
|
|
209
|
+
}
|
|
210
|
+
function demonstrateManualSpansWithParentId() {
|
|
211
|
+
console.log('\n--- Demonstrating Manual Spans with parentNodeId ---\n');
|
|
212
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
213
|
+
console.log('Example 8: Manual spans with explicit parent');
|
|
214
|
+
(0, performance_util_1.startSpan)('Service Request');
|
|
215
|
+
const serviceId = (0, performance_util_1.getCurrentParentNodeId)();
|
|
216
|
+
console.log(`Service Request ID: ${String(serviceId)}`);
|
|
217
|
+
(0, performance_util_1.startSpan)('Authenticate User');
|
|
218
|
+
const start1 = performance.now();
|
|
219
|
+
while (performance.now() < start1 + 30) {
|
|
220
|
+
}
|
|
221
|
+
(0, performance_util_1.endSpan)('Authenticate User');
|
|
222
|
+
console.log(' ✓ User authenticated');
|
|
223
|
+
(0, performance_util_1.startSpan)('Validate Input', { parentNodeId: serviceId });
|
|
224
|
+
const start2 = performance.now();
|
|
225
|
+
while (performance.now() < start2 + 20) {
|
|
226
|
+
}
|
|
227
|
+
(0, performance_util_1.endSpan)('Validate Input');
|
|
228
|
+
console.log(' ✓ Input validated');
|
|
229
|
+
(0, performance_util_1.startSpan)('Check Rate Limits', { parentNodeId: serviceId });
|
|
230
|
+
const start3 = performance.now();
|
|
231
|
+
while (performance.now() < start3 + 15) {
|
|
232
|
+
}
|
|
233
|
+
(0, performance_util_1.endSpan)('Check Rate Limits');
|
|
234
|
+
console.log(' ✓ Rate limits checked');
|
|
235
|
+
(0, performance_util_1.startSpan)('Log Request', { parentNodeId: serviceId });
|
|
236
|
+
const start4 = performance.now();
|
|
237
|
+
while (performance.now() < start4 + 10) {
|
|
238
|
+
}
|
|
239
|
+
(0, performance_util_1.endSpan)('Log Request');
|
|
240
|
+
console.log(' ✓ Request logged');
|
|
241
|
+
(0, performance_util_1.startSpan)('Process Request');
|
|
242
|
+
const start5 = performance.now();
|
|
243
|
+
while (performance.now() < start5 + 60) {
|
|
244
|
+
}
|
|
245
|
+
(0, performance_util_1.endSpan)('Process Request');
|
|
246
|
+
console.log(' ✓ Request processed');
|
|
247
|
+
(0, performance_util_1.endSpan)('Service Request');
|
|
248
|
+
(0, performance_util_1.displayTimingTree)();
|
|
249
|
+
}
|
|
250
|
+
function demonstrateNestingComparison() {
|
|
251
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
252
|
+
console.log('\n--- Demonstrating Natural vs Explicit Nesting ---\n');
|
|
253
|
+
console.log('Natural Nesting (call stack based):');
|
|
254
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
255
|
+
yield (0, performance_util_1.withTimingAsync)('Sequential Operations', () => __awaiter(this, void 0, void 0, function* () {
|
|
256
|
+
yield (0, performance_util_1.withTimingAsync)('Operation 1', () => __awaiter(this, void 0, void 0, function* () {
|
|
257
|
+
yield new Promise((resolve) => setTimeout(resolve, 30));
|
|
258
|
+
}));
|
|
259
|
+
yield (0, performance_util_1.withTimingAsync)('Operation 2', () => __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
yield new Promise((resolve) => setTimeout(resolve, 40));
|
|
261
|
+
}));
|
|
262
|
+
yield (0, performance_util_1.withTimingAsync)('Operation 3', () => __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
yield new Promise((resolve) => setTimeout(resolve, 35));
|
|
264
|
+
}));
|
|
265
|
+
}));
|
|
266
|
+
(0, performance_util_1.displayTimingTree)();
|
|
267
|
+
console.log('\nExplicit Parent Assignment (logical grouping):');
|
|
268
|
+
(0, performance_util_1.clearDefaultTimingProfile)();
|
|
269
|
+
yield (0, performance_util_1.withTimingAsync)('Parallel Operations', () => __awaiter(this, void 0, void 0, function* () {
|
|
270
|
+
const parentId = (0, performance_util_1.getCurrentParentNodeId)();
|
|
271
|
+
yield Promise.all([
|
|
272
|
+
(0, performance_util_1.withTimingAsync)('Operation 1', () => __awaiter(this, void 0, void 0, function* () {
|
|
273
|
+
yield new Promise((resolve) => setTimeout(resolve, 30));
|
|
274
|
+
}), { parentNodeId: parentId }),
|
|
275
|
+
(0, performance_util_1.withTimingAsync)('Operation 2', () => __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
yield new Promise((resolve) => setTimeout(resolve, 40));
|
|
277
|
+
}), { parentNodeId: parentId }),
|
|
278
|
+
(0, performance_util_1.withTimingAsync)('Operation 3', () => __awaiter(this, void 0, void 0, function* () {
|
|
279
|
+
yield new Promise((resolve) => setTimeout(resolve, 35));
|
|
280
|
+
}), { parentNodeId: parentId }),
|
|
281
|
+
]);
|
|
282
|
+
}));
|
|
283
|
+
(0, performance_util_1.displayTimingTree)();
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function runAllExamples() {
|
|
287
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
288
|
+
demonstrateStartEndSpan();
|
|
289
|
+
demonstrateWarningBehavior();
|
|
290
|
+
yield demonstrateParentNodeId();
|
|
291
|
+
yield demonstrateMixedNesting();
|
|
292
|
+
demonstrateSyncWithParentId();
|
|
293
|
+
demonstrateManualSpansWithParentId();
|
|
294
|
+
yield demonstrateNestingComparison();
|
|
295
|
+
console.log('\nAll examples completed. ');
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
runAllExamples().catch(console.error);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
type TimingSpans = TimingNode[];
|
|
2
|
+
type TimingStack = TimingNode[];
|
|
3
|
+
export type TimingNode = {
|
|
4
|
+
label: string;
|
|
5
|
+
id: string;
|
|
6
|
+
durationMs: number;
|
|
7
|
+
children: TimingNode[];
|
|
8
|
+
startTime: number;
|
|
9
|
+
};
|
|
10
|
+
type ActiveSpan = {
|
|
11
|
+
node: TimingNode;
|
|
12
|
+
startTime: number;
|
|
13
|
+
wasAddedToStack: boolean;
|
|
14
|
+
};
|
|
15
|
+
type TimingProfile = {
|
|
16
|
+
activeSpans: Map<string, ActiveSpan>;
|
|
17
|
+
spansById: Map<string, TimingNode>;
|
|
18
|
+
timingSpans: TimingSpans;
|
|
19
|
+
timingStack: TimingStack;
|
|
20
|
+
};
|
|
21
|
+
export declare function getDefaultTimingProfile(): TimingProfile;
|
|
22
|
+
export declare function clearDefaultTimingProfile(): void;
|
|
23
|
+
export declare function getCurrentParentNodeId(): string | null;
|
|
24
|
+
export declare function withTimingAsync<T>(label: string, fn: () => Promise<T>, options?: {
|
|
25
|
+
parentNodeId?: string | null;
|
|
26
|
+
}): Promise<T>;
|
|
27
|
+
export declare function withTimingSync<T>(label: string, fn: () => T, options?: {
|
|
28
|
+
parentNodeId?: string | null;
|
|
29
|
+
}): T;
|
|
30
|
+
export declare function displayTimingTree(nodes?: TimingSpans, depth?: number, prefix?: string): string;
|
|
31
|
+
export declare function startSpan(spanName: string, options?: {
|
|
32
|
+
parentNodeId?: string | null;
|
|
33
|
+
}): void;
|
|
34
|
+
export declare function endSpan(spanName: string): void;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getDefaultTimingProfile = getDefaultTimingProfile;
|
|
13
|
+
exports.clearDefaultTimingProfile = clearDefaultTimingProfile;
|
|
14
|
+
exports.getCurrentParentNodeId = getCurrentParentNodeId;
|
|
15
|
+
exports.withTimingAsync = withTimingAsync;
|
|
16
|
+
exports.withTimingSync = withTimingSync;
|
|
17
|
+
exports.displayTimingTree = displayTimingTree;
|
|
18
|
+
exports.startSpan = startSpan;
|
|
19
|
+
exports.endSpan = endSpan;
|
|
20
|
+
const DEFAULT_TIMING_PROFILE = {
|
|
21
|
+
activeSpans: new Map(),
|
|
22
|
+
spansById: new Map(),
|
|
23
|
+
timingSpans: [],
|
|
24
|
+
timingStack: [],
|
|
25
|
+
};
|
|
26
|
+
function getDefaultTimingProfile() {
|
|
27
|
+
return DEFAULT_TIMING_PROFILE;
|
|
28
|
+
}
|
|
29
|
+
function getTimingStack() {
|
|
30
|
+
return DEFAULT_TIMING_PROFILE.timingStack;
|
|
31
|
+
}
|
|
32
|
+
function getTimingSpans() {
|
|
33
|
+
return DEFAULT_TIMING_PROFILE.timingSpans;
|
|
34
|
+
}
|
|
35
|
+
function getNodeById(id) {
|
|
36
|
+
return DEFAULT_TIMING_PROFILE.spansById.get(id);
|
|
37
|
+
}
|
|
38
|
+
function setSpanId(id, node) {
|
|
39
|
+
DEFAULT_TIMING_PROFILE.spansById.set(id, node);
|
|
40
|
+
}
|
|
41
|
+
function clearDefaultTimingProfile() {
|
|
42
|
+
DEFAULT_TIMING_PROFILE.timingSpans = [];
|
|
43
|
+
DEFAULT_TIMING_PROFILE.timingStack = [];
|
|
44
|
+
DEFAULT_TIMING_PROFILE.activeSpans.clear();
|
|
45
|
+
DEFAULT_TIMING_PROFILE.spansById.clear();
|
|
46
|
+
}
|
|
47
|
+
function getParentNode() {
|
|
48
|
+
const stack = getTimingStack();
|
|
49
|
+
return stack.length > 0 ? stack[stack.length - 1] : null;
|
|
50
|
+
}
|
|
51
|
+
function getCurrentParentNodeId() {
|
|
52
|
+
const parentNode = getParentNode();
|
|
53
|
+
return parentNode ? parentNode.id : null;
|
|
54
|
+
}
|
|
55
|
+
function withTimingAsync(label, fn, options) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
const start = performance.now();
|
|
58
|
+
const chosenId = options === null || options === void 0 ? void 0 : options.parentNodeId;
|
|
59
|
+
const uniqueId = generateUUID();
|
|
60
|
+
const timingNode = {
|
|
61
|
+
label,
|
|
62
|
+
durationMs: 0,
|
|
63
|
+
children: [],
|
|
64
|
+
id: uniqueId,
|
|
65
|
+
startTime: start,
|
|
66
|
+
};
|
|
67
|
+
setSpanId(uniqueId, timingNode);
|
|
68
|
+
const parent = chosenId ? getNodeById(chosenId) : getParentNode();
|
|
69
|
+
if (parent) {
|
|
70
|
+
parent.children.push(timingNode);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
getTimingSpans().push(timingNode);
|
|
74
|
+
}
|
|
75
|
+
const isRunningConcurrently = !!chosenId;
|
|
76
|
+
if (!isRunningConcurrently) {
|
|
77
|
+
getTimingStack().push(timingNode);
|
|
78
|
+
}
|
|
79
|
+
return fn().finally(() => {
|
|
80
|
+
const end = performance.now();
|
|
81
|
+
timingNode.durationMs = end - start;
|
|
82
|
+
if (!isRunningConcurrently) {
|
|
83
|
+
getTimingStack().pop();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function withTimingSync(label, fn, options) {
|
|
89
|
+
const start = performance.now();
|
|
90
|
+
const chosenId = options === null || options === void 0 ? void 0 : options.parentNodeId;
|
|
91
|
+
const uniqueId = generateUUID();
|
|
92
|
+
const timingNode = {
|
|
93
|
+
label,
|
|
94
|
+
durationMs: 0,
|
|
95
|
+
children: [],
|
|
96
|
+
id: uniqueId,
|
|
97
|
+
startTime: start,
|
|
98
|
+
};
|
|
99
|
+
setSpanId(uniqueId, timingNode);
|
|
100
|
+
const parent = chosenId ? getNodeById(chosenId) : getParentNode();
|
|
101
|
+
if (parent) {
|
|
102
|
+
parent.children.push(timingNode);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
getTimingSpans().push(timingNode);
|
|
106
|
+
}
|
|
107
|
+
const isRunningConcurrently = !!chosenId;
|
|
108
|
+
if (!isRunningConcurrently) {
|
|
109
|
+
getTimingStack().push(timingNode);
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
return fn();
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
const end = performance.now();
|
|
116
|
+
timingNode.durationMs = end - start;
|
|
117
|
+
if (!isRunningConcurrently) {
|
|
118
|
+
getTimingStack().pop();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function displayTimingTree(nodes = DEFAULT_TIMING_PROFILE.timingSpans, depth = 0, prefix = '') {
|
|
123
|
+
const lines = [];
|
|
124
|
+
const totalWidth = 120;
|
|
125
|
+
const timeWidth = 10;
|
|
126
|
+
const sortedNodes = [...nodes].sort((a, b) => a.startTime - b.startTime);
|
|
127
|
+
const groups = [];
|
|
128
|
+
let currentGroup = [];
|
|
129
|
+
for (let i = 0; i < sortedNodes.length; i++) {
|
|
130
|
+
const node = sortedNodes[i];
|
|
131
|
+
if (currentGroup.length === 0) {
|
|
132
|
+
currentGroup = [node];
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const hasOverlap = currentGroup.some((groupNode) => {
|
|
136
|
+
const nodeEnd = node.startTime + node.durationMs;
|
|
137
|
+
const groupNodeEnd = groupNode.startTime + groupNode.durationMs;
|
|
138
|
+
return node.startTime < groupNodeEnd && nodeEnd > groupNode.startTime;
|
|
139
|
+
});
|
|
140
|
+
if (hasOverlap) {
|
|
141
|
+
currentGroup.push(node);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
groups.push(currentGroup);
|
|
145
|
+
currentGroup = [node];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (currentGroup.length > 0) {
|
|
150
|
+
groups.push(currentGroup);
|
|
151
|
+
}
|
|
152
|
+
groups.forEach((group, groupIndex) => {
|
|
153
|
+
const isLastGroup = groupIndex === groups.length - 1;
|
|
154
|
+
if (group.length === 1) {
|
|
155
|
+
const node = group[0];
|
|
156
|
+
const timeStr = `${node.durationMs.toFixed(2)}ms`;
|
|
157
|
+
const connector = depth === 0 ? '' : isLastGroup ? '└── ' : '├── ';
|
|
158
|
+
const labelWithPrefix = `${prefix}${connector}${node.label}`;
|
|
159
|
+
const availableWidth = totalWidth - timeWidth - labelWithPrefix.length;
|
|
160
|
+
const dots = '.'.repeat(Math.max(2, availableWidth));
|
|
161
|
+
lines.push(`${labelWithPrefix}${dots}${timeStr.padStart(timeWidth)}`);
|
|
162
|
+
if (node.children && node.children.length > 0) {
|
|
163
|
+
const childPrefix = prefix + (depth === 0 ? '' : isLastGroup ? ' ' : '│ ');
|
|
164
|
+
lines.push(displayTimingTree(node.children, depth + 1, childPrefix));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const connector = depth === 0 ? '' : isLastGroup ? '└── ' : '├── ';
|
|
169
|
+
const parallelHeader = `${prefix}${connector}∥ Parallel Operations (${group.length})`;
|
|
170
|
+
lines.push(parallelHeader);
|
|
171
|
+
group.forEach((node, nodeIndex) => {
|
|
172
|
+
const isLastNode = nodeIndex === group.length - 1;
|
|
173
|
+
const timeStr = `${node.durationMs.toFixed(2)}ms`;
|
|
174
|
+
const parallelIndicator = '∥ ';
|
|
175
|
+
const nodeConnector = isLastNode ? '└── ' : '├── ';
|
|
176
|
+
const nodePrefix = prefix + (depth === 0 ? '' : isLastGroup ? ' ' : '│ ');
|
|
177
|
+
const labelWithPrefix = `${nodePrefix}${nodeConnector}${parallelIndicator}${node.label}`;
|
|
178
|
+
const availableWidth = totalWidth - timeWidth - labelWithPrefix.length;
|
|
179
|
+
const dots = '.'.repeat(Math.max(2, availableWidth));
|
|
180
|
+
lines.push(`${labelWithPrefix}${dots}${timeStr.padStart(timeWidth)}`);
|
|
181
|
+
if (node.children && node.children.length > 0) {
|
|
182
|
+
const childPrefix = nodePrefix + (isLastNode ? ' ' : '│ ');
|
|
183
|
+
lines.push(displayTimingTree(node.children, depth + 1, childPrefix));
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const result = lines.join('\n');
|
|
189
|
+
if (depth === 0) {
|
|
190
|
+
console.log('\n--- Performance Timing Tree ---\n');
|
|
191
|
+
console.log(result);
|
|
192
|
+
console.log('\n--- End Timing ---\n');
|
|
193
|
+
}
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
function startSpan(spanName, options) {
|
|
197
|
+
if (DEFAULT_TIMING_PROFILE.activeSpans.has(spanName)) {
|
|
198
|
+
console.warn(`Span "${spanName}" is already active. Please end it before starting a new one with the same name.`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const startTime = performance.now();
|
|
202
|
+
const chosenId = options === null || options === void 0 ? void 0 : options.parentNodeId;
|
|
203
|
+
const uniqueId = generateUUID();
|
|
204
|
+
const timingNode = {
|
|
205
|
+
label: spanName,
|
|
206
|
+
durationMs: 0,
|
|
207
|
+
children: [],
|
|
208
|
+
id: uniqueId,
|
|
209
|
+
startTime: startTime,
|
|
210
|
+
};
|
|
211
|
+
setSpanId(uniqueId, timingNode);
|
|
212
|
+
const parent = chosenId ? getNodeById(chosenId) : getParentNode();
|
|
213
|
+
if (parent) {
|
|
214
|
+
parent.children.push(timingNode);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
getTimingSpans().push(timingNode);
|
|
218
|
+
}
|
|
219
|
+
const isRunningConcurrently = !!chosenId;
|
|
220
|
+
if (!isRunningConcurrently) {
|
|
221
|
+
getTimingStack().push(timingNode);
|
|
222
|
+
}
|
|
223
|
+
DEFAULT_TIMING_PROFILE.activeSpans.set(spanName, {
|
|
224
|
+
node: timingNode,
|
|
225
|
+
startTime: startTime,
|
|
226
|
+
wasAddedToStack: !isRunningConcurrently,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function endSpan(spanName) {
|
|
230
|
+
const activeSpan = DEFAULT_TIMING_PROFILE.activeSpans.get(spanName);
|
|
231
|
+
if (!activeSpan) {
|
|
232
|
+
console.warn(`No active span found with name "${spanName}". Make sure to call startSpan() first.`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const endTime = performance.now();
|
|
236
|
+
activeSpan.node.durationMs = endTime - activeSpan.startTime;
|
|
237
|
+
if (activeSpan.wasAddedToStack) {
|
|
238
|
+
const currentTop = getTimingStack()[getTimingStack().length - 1];
|
|
239
|
+
if (currentTop === activeSpan.node) {
|
|
240
|
+
getTimingStack().pop();
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
const stackIndex = getTimingStack().findIndex((node) => node === activeSpan.node);
|
|
244
|
+
if (stackIndex !== -1) {
|
|
245
|
+
getTimingStack().splice(stackIndex, 1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
DEFAULT_TIMING_PROFILE.activeSpans.delete(spanName);
|
|
250
|
+
}
|
|
251
|
+
function generateUUID() {
|
|
252
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
253
|
+
const r = (Math.random() * 16) | 0;
|
|
254
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
255
|
+
return v.toString(16);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare class PromiseUtil {
|
|
2
|
-
static resolveInChunks(objects: Array<
|
|
3
|
-
static resolveInChunksAndLimit(objects: Array<
|
|
2
|
+
static resolveInChunks<TInput, TOutput>(objects: Array<TInput>, chunksSize: number, asyncFunction: (chunk: TInput[]) => Promise<TOutput[]>): Promise<TOutput[]>;
|
|
3
|
+
static resolveInChunksAndLimit<TInput, TOutput>(objects: Array<TInput>, chunksSize: number, limitSize: number, asyncFunction: (chunk: TInput[]) => Promise<TOutput[]>): Promise<TOutput[]>;
|
|
4
4
|
}
|
|
@@ -14,24 +14,21 @@ const p_limit_1 = require("p-limit");
|
|
|
14
14
|
const lodash_1 = require("lodash");
|
|
15
15
|
class PromiseUtil {
|
|
16
16
|
static resolveInChunks(objects, chunksSize, asyncFunction) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
const chunks = (0, lodash_1.chunk)(objects, chunksSize);
|
|
19
|
+
const promises = chunks.map((chunk) => asyncFunction(chunk));
|
|
20
|
+
const chunkedResults = yield Promise.all(promises);
|
|
21
|
+
return chunkedResults.flat();
|
|
22
|
+
});
|
|
23
23
|
}
|
|
24
24
|
static resolveInChunksAndLimit(objects, chunksSize, limitSize, asyncFunction) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
promises.push(promise);
|
|
33
|
-
}
|
|
34
|
-
return Promise.all(promises).then((chunkedResults) => chunkedResults.flat());
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const limit = (0, p_limit_1.default)(limitSize);
|
|
27
|
+
const chunks = (0, lodash_1.chunk)(objects, chunksSize);
|
|
28
|
+
const promises = chunks.map((chunk) => limit(() => __awaiter(this, void 0, void 0, function* () { return asyncFunction(chunk); })));
|
|
29
|
+
const chunkedResults = yield Promise.all(promises);
|
|
30
|
+
return chunkedResults.flat();
|
|
31
|
+
});
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
34
|
exports.PromiseUtil = PromiseUtil;
|
|
@@ -9,13 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.retry =
|
|
12
|
+
exports.retry = retry;
|
|
13
13
|
const DEFAULT_CONFIG = {
|
|
14
14
|
maxRetries: 3,
|
|
15
15
|
initialDelay: 1000,
|
|
16
16
|
};
|
|
17
|
-
function retry(
|
|
18
|
-
return __awaiter(this,
|
|
17
|
+
function retry(fn_1) {
|
|
18
|
+
return __awaiter(this, arguments, void 0, function* (fn, config = DEFAULT_CONFIG) {
|
|
19
19
|
const { maxRetries, initialDelay, onRetryCallback } = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
|
|
20
20
|
if (maxRetries < 1) {
|
|
21
21
|
throw new Error('maxRetries must be at least 1');
|
|
@@ -39,4 +39,3 @@ function retry(fn, config = DEFAULT_CONFIG) {
|
|
|
39
39
|
throw new Error('Max retries reached');
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
exports.retry = retry;
|
|
@@ -3,6 +3,8 @@ export declare class StringUtil {
|
|
|
3
3
|
static parseVariables(variableString: string, data: any, quoteStrings?: boolean): string;
|
|
4
4
|
static convertToCamelCase(str: any): any;
|
|
5
5
|
static convertToTitleCase(str: any): any;
|
|
6
|
-
static isString(value: any):
|
|
7
|
-
static isArray(value: any):
|
|
6
|
+
static isString(value: any): value is string | String;
|
|
7
|
+
static isArray(value: any): value is any[];
|
|
8
|
+
static decodeEncodedString(encodedString: string): string;
|
|
9
|
+
static getStringSizeInMB(str: string): number;
|
|
8
10
|
}
|
|
@@ -67,5 +67,19 @@ class StringUtil {
|
|
|
67
67
|
static isArray(value) {
|
|
68
68
|
return Array.isArray(value);
|
|
69
69
|
}
|
|
70
|
+
static decodeEncodedString(encodedString) {
|
|
71
|
+
return encodedString.replace(/_COMMA_/g, ',').replace(/%[0-9A-Fa-f]{2}/g, (match) => {
|
|
72
|
+
try {
|
|
73
|
+
return decodeURIComponent(match);
|
|
74
|
+
}
|
|
75
|
+
catch (_a) {
|
|
76
|
+
return match;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
static getStringSizeInMB(str) {
|
|
81
|
+
const bytes = new TextEncoder().encode(str).length;
|
|
82
|
+
return bytes / (1024 * 1024);
|
|
83
|
+
}
|
|
70
84
|
}
|
|
71
85
|
exports.StringUtil = StringUtil;
|
|
@@ -9,12 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.TimerManager = exports.Timer = exports.TimeUnit = void 0;
|
|
13
|
+
exports.delay = delay;
|
|
13
14
|
var TimeUnit;
|
|
14
15
|
(function (TimeUnit) {
|
|
15
16
|
TimeUnit["MILLISECOND"] = "ms";
|
|
16
17
|
TimeUnit["SECOND"] = "s";
|
|
17
|
-
})(TimeUnit
|
|
18
|
+
})(TimeUnit || (exports.TimeUnit = TimeUnit = {}));
|
|
18
19
|
const MILLISECONDS_PER_TIME_UNIT = {
|
|
19
20
|
[TimeUnit.MILLISECOND]: 1,
|
|
20
21
|
[TimeUnit.SECOND]: 1000,
|
|
@@ -116,4 +117,3 @@ function delay(ms) {
|
|
|
116
117
|
});
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
|
-
exports.delay = delay;
|