@rudderstack/integrations-lib 0.2.32 → 0.2.34
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/build/utils/batch-processing.bench.d.ts +2 -0
- package/build/utils/batch-processing.bench.d.ts.map +1 -0
- package/build/utils/batch-processing.bench.js +96 -0
- package/build/utils/batch-processing.d.ts +197 -0
- package/build/utils/batch-processing.d.ts.map +1 -0
- package/build/utils/batch-processing.js +409 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-processing.bench.d.ts","sourceRoot":"","sources":["../../src/utils/batch-processing.bench.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/* eslint-disable no-console */
|
|
7
|
+
const node_perf_hooks_1 = require("node:perf_hooks");
|
|
8
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
+
const batch_processing_1 = require("./batch-processing");
|
|
10
|
+
async function bench(fn, label, iterations = 5) {
|
|
11
|
+
let total = 0;
|
|
12
|
+
for (let i = 0; i < iterations; i += 1) {
|
|
13
|
+
const start = node_perf_hooks_1.performance.now();
|
|
14
|
+
// eslint-disable-next-line no-await-in-loop
|
|
15
|
+
await fn();
|
|
16
|
+
total += node_perf_hooks_1.performance.now() - start;
|
|
17
|
+
}
|
|
18
|
+
const avg = total / iterations;
|
|
19
|
+
console.log(`${label}: avg ${avg.toFixed(2)} ms over ${iterations} runs`);
|
|
20
|
+
return avg;
|
|
21
|
+
}
|
|
22
|
+
async function section(title, fn) {
|
|
23
|
+
console.log(`\n=== ${title} ===`);
|
|
24
|
+
await fn();
|
|
25
|
+
}
|
|
26
|
+
async function runBenchmarks() {
|
|
27
|
+
const arr = Array.from({ length: 10_000 }, (_, i) => i);
|
|
28
|
+
console.log(`Running benchmarks on array of length ${arr.length}`);
|
|
29
|
+
await section('map', async () => {
|
|
30
|
+
await bench(() => (0, batch_processing_1.mapInBatches)(arr, (x) => x + 1, { batchSize: 20, yieldThreshold: 10 }), 'mapInBatches { batchSize: 20, yieldThreshold: 10 }');
|
|
31
|
+
await bench(() => (0, batch_processing_1.mapInBatches)(arr, (x) => x + 1, {
|
|
32
|
+
batchSize: 20,
|
|
33
|
+
yieldThreshold: 10,
|
|
34
|
+
sequentialProcessing: false,
|
|
35
|
+
}), 'mapInBatches { batchSize: 20, yieldThreshold: 10, sequentialProcessing: false }');
|
|
36
|
+
await bench(() => Promise.resolve(lodash_1.default.map(arr, (x) => x + 1)), 'lodash.map');
|
|
37
|
+
await bench(() => Promise.resolve(arr.map((x) => x + 1)), 'Array.prototype.map');
|
|
38
|
+
});
|
|
39
|
+
await section('filter', async () => {
|
|
40
|
+
await bench(() => (0, batch_processing_1.filterInBatches)(arr, (x) => x % 2 === 0, { batchSize: 20, yieldThreshold: 10 }), 'filterInBatches { batchSize: 20, yieldThreshold: 10 }');
|
|
41
|
+
await bench(() => (0, batch_processing_1.filterInBatches)(arr, (x) => x % 2 === 0, {
|
|
42
|
+
batchSize: 20,
|
|
43
|
+
yieldThreshold: 10,
|
|
44
|
+
sequentialProcessing: false,
|
|
45
|
+
}), 'filterInBatches { batchSize: 20, yieldThreshold: 10, sequentialProcessing: false }');
|
|
46
|
+
await bench(() => Promise.resolve(lodash_1.default.filter(arr, (x) => x % 2 === 0)), 'lodash.filter');
|
|
47
|
+
await bench(() => Promise.resolve(arr.filter((x) => x % 2 === 0)), 'Array.prototype.filter');
|
|
48
|
+
});
|
|
49
|
+
await section('groupBy', async () => {
|
|
50
|
+
await bench(() => (0, batch_processing_1.groupByInBatches)(arr, (x) => (x % 2 === 0 ? 'even' : 'odd'), {
|
|
51
|
+
batchSize: 20,
|
|
52
|
+
yieldThreshold: 10,
|
|
53
|
+
}), 'groupByInBatches { batchSize: 20, yieldThreshold: 10 }');
|
|
54
|
+
await bench(() => (0, batch_processing_1.groupByInBatches)(arr, (x) => (x % 2 === 0 ? 'even' : 'odd'), {
|
|
55
|
+
batchSize: 20,
|
|
56
|
+
yieldThreshold: 10,
|
|
57
|
+
sequentialProcessing: false,
|
|
58
|
+
}), 'groupByInBatches { batchSize: 20, yieldThreshold: 10, sequentialProcessing: false }');
|
|
59
|
+
await bench(() => Promise.resolve(lodash_1.default.groupBy(arr, (x) => (x % 2 === 0 ? 'even' : 'odd'))), 'lodash.groupBy');
|
|
60
|
+
});
|
|
61
|
+
await section('reduce', async () => {
|
|
62
|
+
await bench(() => (0, batch_processing_1.reduceInBatches)(arr, (acc, x) => acc + x, 0, { batchSize: 20, yieldThreshold: 10 }), 'reduceInBatches { batchSize: 20, yieldThreshold: 10 }');
|
|
63
|
+
await bench(() => Promise.resolve(lodash_1.default.reduce(arr, (acc, x) => acc + x, 0)), 'lodash.reduce');
|
|
64
|
+
await bench(() => Promise.resolve(arr.reduce((acc, x) => acc + x, 0)), 'Array.prototype.reduce');
|
|
65
|
+
});
|
|
66
|
+
await section('flatMap', async () => {
|
|
67
|
+
await bench(() => (0, batch_processing_1.flatMapInBatches)(arr, (x) => [x, x], { batchSize: 20, yieldThreshold: 10 }), 'flatMapInBatches { batchSize: 20, yieldThreshold: 10 }');
|
|
68
|
+
await bench(() => (0, batch_processing_1.flatMapInBatches)(arr, (x) => [x, x], {
|
|
69
|
+
batchSize: 20,
|
|
70
|
+
yieldThreshold: 10,
|
|
71
|
+
sequentialProcessing: false,
|
|
72
|
+
}), 'flatMapInBatches { batchSize: 20, yieldThreshold: 10, sequentialProcessing: false }');
|
|
73
|
+
await bench(() => Promise.resolve(lodash_1.default.flatMap(arr, (x) => [x, x])), 'lodash.flatMap');
|
|
74
|
+
await bench(() => Promise.resolve(arr.flatMap
|
|
75
|
+
? arr.flatMap((x) => [x, x])
|
|
76
|
+
: [].concat(...arr.map((x) => [x, x]))), 'Array.prototype.flatMap');
|
|
77
|
+
});
|
|
78
|
+
await section('forEach', async () => {
|
|
79
|
+
await bench(() => (0, batch_processing_1.forEachInBatches)(arr, () => { }, { batchSize: 20, yieldThreshold: 10 }), 'forEachInBatches { batchSize: 20, yieldThreshold: 10 }');
|
|
80
|
+
await bench(() => (0, batch_processing_1.forEachInBatches)(arr, () => { }, {
|
|
81
|
+
batchSize: 20,
|
|
82
|
+
yieldThreshold: 10,
|
|
83
|
+
sequentialProcessing: false,
|
|
84
|
+
}), 'forEachInBatches { batchSize: 20, yieldThreshold: 10, sequentialProcessing: false }');
|
|
85
|
+
await bench(() => Promise.resolve(arr.forEach(() => { })), 'Array.prototype.forEach');
|
|
86
|
+
await bench(() => Promise.resolve(lodash_1.default.forEach(arr, () => { })), 'lodash.forEach');
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// to run benchmarks use: npx ts-node src/utils/batch-processing.bench.ts
|
|
90
|
+
if (require.main === module) {
|
|
91
|
+
runBenchmarks().catch((err) => {
|
|
92
|
+
console.error(err);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF0Y2gtcHJvY2Vzc2luZy5iZW5jaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9iYXRjaC1wcm9jZXNzaW5nLmJlbmNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQStCO0FBQy9CLHFEQUE4QztBQUM5QyxvREFBNEI7QUFDNUIseURBTzRCO0FBRTVCLEtBQUssVUFBVSxLQUFLLENBQ2xCLEVBQW9DLEVBQ3BDLEtBQWEsRUFDYixVQUFVLEdBQUcsQ0FBQztJQUVkLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxHQUFHLDZCQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDaEMsNENBQTRDO1FBQzVDLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFDWCxLQUFLLElBQUksNkJBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUNELE1BQU0sR0FBRyxHQUFHLEtBQUssR0FBRyxVQUFVLENBQUM7SUFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssU0FBUyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxZQUFZLFVBQVUsT0FBTyxDQUFDLENBQUM7SUFDMUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFhLEVBQUUsRUFBdUI7SUFDM0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDbEMsTUFBTSxFQUFFLEVBQUUsQ0FBQztBQUNiLENBQUM7QUFFRCxLQUFLLFVBQVUsYUFBYTtJQUMxQixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFB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QUFFLEdBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsZ0JBQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUN0RixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCx5RUFBeUU7QUFDekUsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRSxDQUFDO0lBQzVCLGFBQWEsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBwZXJmb3JtYW5jZSB9IGZyb20gJ25vZGU6cGVyZl9ob29rcyc7XG5pbXBvcnQgbG9kYXNoIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge1xuICBtYXBJbkJhdGNoZXMsXG4gIGZpbHRlckluQmF0Y2hlcyxcbiAgZ3JvdXBCeUluQmF0Y2hlcyxcbiAgcmVkdWNlSW5CYXRjaGVzLFxuICBmbGF0TWFwSW5CYXRjaGVzLFxuICBmb3JFYWNoSW5CYXRjaGVzLFxufSBmcm9tICcuL2JhdGNoLXByb2Nlc3NpbmcnO1xuXG5hc3luYyBmdW5jdGlvbiBiZW5jaChcbiAgZm46ICgpID0+IFByb21pc2U8dW5rbm93bj4gfCB1bmtub3duLFxuICBsYWJlbDogc3RyaW5nLFxuICBpdGVyYXRpb25zID0gNSxcbik6IFByb21pc2U8bnVtYmVyPiB7XG4gIGxldCB0b3RhbCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlcmF0aW9uczsgaSArPSAxKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgIGF3YWl0IGZuKCk7XG4gICAgdG90YWwgKz0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydDtcbiAgfVxuICBjb25zdCBhdmcgPSB0b3RhbCAvIGl0ZXJhdGlvbnM7XG4gIGNvbnNvbGUubG9nKGAke2xhYmVsfTogYXZnICR7YXZnLnRvRml4ZWQoMil9IG1zIG92ZXIgJHtpdGVyYXRpb25zfSBydW5zYCk7XG4gIHJldHVybiBhdmc7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNlY3Rpb24odGl0bGU6IHN0cmluZywgZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgY29uc29sZS5sb2coYFxcbj09PSAke3RpdGxlfSA9PT1gKTtcbiAgYXdhaXQgZm4oKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuQmVuY2htYXJrcygpIHtcbiAgY29uc3QgYXJyID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogMTBfMDAwIH0sIChfLCBpKSA9PiBpKTtcblxuICBjb25zb2xlLmxvZyhgUnVubmluZyBiZW5jaG1hcmtzIG9uIGFycmF5IG9mIGxlbmd0aCAke2Fyci5sZW5ndGh9YCk7XG5cbiAgYXdhaXQgc2VjdGlvbignbWFwJywgYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IGJlbmNoKFxuICAgICAgKCkgPT4gbWFwSW5CYXRjaGVzKGFyciwgKHgpID0+IHggKyAxLCB7IGJhdGNoU2l6ZTogMjAsIHlpZWxkVGhyZXNob2xkOiAxMCB9KSxcbiAgICAgICdtYXBJbkJhdGNoZXMgeyBiYXRjaFNpemU6IDIwLCB5aWVsZFRocmVzaG9sZDogMTAgfScsXG4gICAgKTtcbiAgICBhd2FpdCBiZW5jaChcbiAgICAgICgpID0+XG4gICAgICAgIG1hcEluQmF0Y2hlcyhhcnIsICh4KSA9PiB4ICsgMSwge1xuICAgICAgICAgIGJhdGNoU2l6ZTogMjAsXG4gICAgICAgICAgeWllbGRUaHJlc2hvbGQ6IDEwLFxuICAgICAgICAgIHNlcXVlbnRpYWxQcm9jZXNzaW5nOiBmYWxzZSxcbiAgICAgICAgfSksXG4gICAgICAnbWFwSW5CYXRjaGVzIHsgYmF0Y2hTaXplOiAyMCwgeWllbGRUaHJlc2hvbGQ6IDEwLCBzZXF1ZW50aWFsUHJvY2Vzc2luZzogZmFsc2UgfScsXG4gICAgKTtcbiAgICBhd2FpdCBiZW5jaCgoKSA9PiBQcm9taXNlLnJlc29sdmUobG9kYXNoLm1hcChhcnIsICh4KSA9PiB4ICsgMSkpLCAnbG9kYXNoLm1hcCcpO1xuICAgIGF3YWl0IGJlbmNoKCgpID0+IFByb21pc2UucmVzb2x2ZShhcnIubWFwKCh4KSA9PiB4ICsgMSkpLCAnQXJyYXkucHJvdG90eXBlLm1hcCcpO1xuICB9KTtcblxuICBhd2FpdCBzZWN0aW9uKCdmaWx0ZXInLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PiBmaWx0ZXJJbkJhdGNoZXMoYXJyLCAoeCkgPT4geCAlIDIgPT09IDAsIHsgYmF0Y2hTaXplOiAyMCwgeWllbGRUaHJlc2hvbGQ6IDEwIH0pLFxuICAgICAgJ2ZpbHRlckluQmF0Y2hlcyB7IGJhdGNoU2l6ZTogMjAsIHlpZWxkVGhyZXNob2xkOiAxMCB9JyxcbiAgICApO1xuICAgIGF3YWl0IGJlbmNoKFxuICAgICAgKCkgPT5cbiAgICAgICAgZmlsdGVySW5CYXRjaGVzKGFyciwgKHgpID0+IHggJSAyID09PSAwLCB7XG4gICAgICAgICAgYmF0Y2hTaXplOiAyMCxcbiAgICAgICAgICB5aWVsZFRocmVzaG9sZDogMTAsXG4gICAgICAgICAgc2VxdWVudGlhbFByb2Nlc3Npbmc6IGZhbHNlLFxuICAgICAgICB9KSxcbiAgICAgICdmaWx0ZXJJbkJhdGNoZXMgeyBiYXRjaFNpemU6IDIwLCB5aWVsZFRocmVzaG9sZDogMTAsIHNlcXVlbnRpYWxQcm9jZXNzaW5nOiBmYWxzZSB9JyxcbiAgICApO1xuICAgIGF3YWl0IGJlbmNoKCgpID0+IFByb21pc2UucmVzb2x2ZShsb2Rhc2guZmlsdGVyKGFyciwgKHgpID0+IHggJSAyID09PSAwKSksICdsb2Rhc2guZmlsdGVyJyk7XG4gICAgYXdhaXQgYmVuY2goKCkgPT4gUHJvbWlzZS5yZXNvbHZlKGFyci5maWx0ZXIoKHgpID0+IHggJSAyID09PSAwKSksICdBcnJheS5wcm90b3R5cGUuZmlsdGVyJyk7XG4gIH0pO1xuXG4gIGF3YWl0IHNlY3Rpb24oJ2dyb3VwQnknLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PlxuICAgICAgICBncm91cEJ5SW5CYXRjaGVzKGFyciwgKHgpID0+ICh4ICUgMiA9PT0gMCA/ICdldmVuJyA6ICdvZGQnKSwge1xuICAgICAgICAgIGJhdGNoU2l6ZTogMjAsXG4gICAgICAgICAgeWllbGRUaHJlc2hvbGQ6IDEwLFxuICAgICAgICB9KSxcbiAgICAgICdncm91cEJ5SW5CYXRjaGVzIHsgYmF0Y2hTaXplOiAyMCwgeWllbGRUaHJlc2hvbGQ6IDEwIH0nLFxuICAgICk7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PlxuICAgICAgICBncm91cEJ5SW5CYXRjaGVzKGFyciwgKHgpID0+ICh4ICUgMiA9PT0gMCA/ICdldmVuJyA6ICdvZGQnKSwge1xuICAgICAgICAgIGJhdGNoU2l6ZTogMjAsXG4gICAgICAgICAgeWllbGRUaHJlc2hvbGQ6IDEwLFxuICAgICAgICAgIHNlcXVlbnRpYWxQcm9jZXNzaW5nOiBmYWxzZSxcbiAgICAgICAgfSksXG4gICAgICAnZ3JvdXBCeUluQmF0Y2hlcyB7IGJhdGNoU2l6ZTogMjAsIHlpZWxkVGhyZXNob2xkOiAxMCwgc2VxdWVudGlhbFByb2Nlc3Npbmc6IGZhbHNlIH0nLFxuICAgICk7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PiBQcm9taXNlLnJlc29sdmUobG9kYXNoLmdyb3VwQnkoYXJyLCAoeCkgPT4gKHggJSAyID09PSAwID8gJ2V2ZW4nIDogJ29kZCcpKSksXG4gICAgICAnbG9kYXNoLmdyb3VwQnknLFxuICAgICk7XG4gIH0pO1xuXG4gIGF3YWl0IHNlY3Rpb24oJ3JlZHVjZScsIGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBiZW5jaChcbiAgICAgICgpID0+IHJlZHVjZUluQmF0Y2hlcyhhcnIsIChhY2MsIHgpID0+IGFjYyArIHgsIDAsIHsgYmF0Y2hTaXplOiAyMCwgeWllbGRUaHJlc2hvbGQ6IDEwIH0pLFxuICAgICAgJ3JlZHVjZUluQmF0Y2hlcyB7IGJhdGNoU2l6ZTogMjAsIHlpZWxkVGhyZXNob2xkOiAxMCB9JyxcbiAgICApO1xuICAgIGF3YWl0IGJlbmNoKCgpID0+IFByb21pc2UucmVzb2x2ZShsb2Rhc2gucmVkdWNlKGFyciwgKGFjYywgeCkgPT4gYWNjICsgeCwgMCkpLCAnbG9kYXNoLnJlZHVjZScpO1xuICAgIGF3YWl0IGJlbmNoKFxuICAgICAgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKGFyci5yZWR1Y2UoKGFjYywgeCkgPT4gYWNjICsgeCwgMCkpLFxuICAgICAgJ0FycmF5LnByb3RvdHlwZS5yZWR1Y2UnLFxuICAgICk7XG4gIH0pO1xuXG4gIGF3YWl0IHNlY3Rpb24oJ2ZsYXRNYXAnLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PiBmbGF0TWFwSW5CYXRjaGVzKGFyciwgKHgpID0+IFt4LCB4XSwgeyBiYXRjaFNpemU6IDIwLCB5aWVsZFRocmVzaG9sZDogMTAgfSksXG4gICAgICAnZmxhdE1hcEluQmF0Y2hlcyB7IGJhdGNoU2l6ZTogMjAsIHlpZWxkVGhyZXNob2xkOiAxMCB9JyxcbiAgICApO1xuICAgIGF3YWl0IGJlbmNoKFxuICAgICAgKCkgPT5cbiAgICAgICAgZmxhdE1hcEluQmF0Y2hlcyhhcnIsICh4KSA9PiBbeCwgeF0sIHtcbiAgICAgICAgICBiYXRjaFNpemU6IDIwLFxuICAgICAgICAgIHlpZWxkVGhyZXNob2xkOiAxMCxcbiAgICAgICAgICBzZXF1ZW50aWFsUHJvY2Vzc2luZzogZmFsc2UsXG4gICAgICAgIH0pLFxuICAgICAgJ2ZsYXRNYXBJbkJhdGNoZXMgeyBiYXRjaFNpemU6IDIwLCB5aWVsZFRocmVzaG9sZDogMTAsIHNlcXVlbnRpYWxQcm9jZXNzaW5nOiBmYWxzZSB9JyxcbiAgICApO1xuICAgIGF3YWl0IGJlbmNoKCgpID0+IFByb21pc2UucmVzb2x2ZShsb2Rhc2guZmxhdE1hcChhcnIsICh4KSA9PiBbeCwgeF0pKSwgJ2xvZGFzaC5mbGF0TWFwJyk7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgICAgYXJyLmZsYXRNYXBcbiAgICAgICAgICAgID8gYXJyLmZsYXRNYXAoKHgpID0+IFt4LCB4XSlcbiAgICAgICAgICAgIDogKFtdIGFzIG51bWJlcltdKS5jb25jYXQoLi4uYXJyLm1hcCgoeCkgPT4gW3gsIHhdKSksXG4gICAgICAgICksXG4gICAgICAnQXJyYXkucHJvdG90eXBlLmZsYXRNYXAnLFxuICAgICk7XG4gIH0pO1xuXG4gIGF3YWl0IHNlY3Rpb24oJ2ZvckVhY2gnLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgYmVuY2goXG4gICAgICAoKSA9PiBmb3JFYWNoSW5CYXRjaGVzKGFyciwgKCkgPT4ge30sIHsgYmF0Y2hTaXplOiAyMCwgeWllbGRUaHJlc2hvbGQ6IDEwIH0pLFxuICAgICAgJ2ZvckVhY2hJbkJhdGNoZXMgeyBiYXRjaFNpemU6IDIwLCB5aWVsZFRocmVzaG9sZDogMTAgfScsXG4gICAgKTtcbiAgICBhd2FpdCBiZW5jaChcbiAgICAgICgpID0+XG4gICAgICAgIGZvckVhY2hJbkJhdGNoZXMoYXJyLCAoKSA9PiB7fSwge1xuICAgICAgICAgIGJhdGNoU2l6ZTogMjAsXG4gICAgICAgICAgeWllbGRUaHJlc2hvbGQ6IDEwLFxuICAgICAgICAgIHNlcXVlbnRpYWxQcm9jZXNzaW5nOiBmYWxzZSxcbiAgICAgICAgfSksXG4gICAgICAnZm9yRWFjaEluQmF0Y2hlcyB7IGJhdGNoU2l6ZTogMjAsIHlpZWxkVGhyZXNob2xkOiAxMCwgc2VxdWVudGlhbFByb2Nlc3Npbmc6IGZhbHNlIH0nLFxuICAgICk7XG4gICAgYXdhaXQgYmVuY2goKCkgPT4gUHJvbWlzZS5yZXNvbHZlKGFyci5mb3JFYWNoKCgpID0+IHt9KSksICdBcnJheS5wcm90b3R5cGUuZm9yRWFjaCcpO1xuICAgIGF3YWl0IGJlbmNoKCgpID0+IFByb21pc2UucmVzb2x2ZShsb2Rhc2guZm9yRWFjaChhcnIsICgpID0+IHt9KSksICdsb2Rhc2guZm9yRWFjaCcpO1xuICB9KTtcbn1cblxuLy8gdG8gcnVuIGJlbmNobWFya3MgdXNlOiBucHggdHMtbm9kZSBzcmMvdXRpbHMvYmF0Y2gtcHJvY2Vzc2luZy5iZW5jaC50c1xuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIHJ1bkJlbmNobWFya3MoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for batch processing operations
|
|
3
|
+
*/
|
|
4
|
+
export interface BatchProcessingOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Number of items to process in each batch (default: 10)
|
|
7
|
+
* Must be a positive integer.
|
|
8
|
+
*/
|
|
9
|
+
batchSize?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Time threshold in milliseconds (default: 10) before yielding control back to the event loop.
|
|
12
|
+
* Set to 0 to yield after every batch. Must be a non-negative integer.
|
|
13
|
+
*/
|
|
14
|
+
yieldThreshold?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to process items sequentially within each batch. When true (default), each item in a batch
|
|
17
|
+
* will be processed one at a time. When false, all items in a batch will be processed concurrently.
|
|
18
|
+
* Consider the implications of concurrency on your processing logic before setting this to false, e.g. race conditions, rate limits, memory pressure, etc.
|
|
19
|
+
*/
|
|
20
|
+
sequentialProcessing?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Configure global defaults for batch processing operations
|
|
24
|
+
*
|
|
25
|
+
* @param config - Configuration options for batch processing
|
|
26
|
+
* @returns The current configuration after applying changes
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Set both defaults
|
|
31
|
+
* configureBatchProcessingDefaults({ batchSize: 20, yieldThreshold: 5 });
|
|
32
|
+
*
|
|
33
|
+
* // Set only batch size
|
|
34
|
+
* configureBatchProcessingDefaults({ batchSize: 50 });
|
|
35
|
+
*
|
|
36
|
+
* // Enable concurrent processing within batches
|
|
37
|
+
* configureBatchProcessingDefaults({ sequentialProcessing: false });
|
|
38
|
+
*
|
|
39
|
+
* // Get current configuration
|
|
40
|
+
* const currentConfig = configureBatchProcessingDefaults();
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function configureBatchProcessingDefaults(config?: BatchProcessingOptions): BatchProcessingOptions;
|
|
44
|
+
/**
|
|
45
|
+
* Maps over an array in batches to avoid blocking the event loop.
|
|
46
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
47
|
+
* when the processing time exceeds the threshold.
|
|
48
|
+
*
|
|
49
|
+
* @template T - The type of items in the input array
|
|
50
|
+
* @template R - The type of items in the result array
|
|
51
|
+
* @param items - The array to map over
|
|
52
|
+
* @param mapFn - The mapping function to apply to each item. Receives the item and its index.
|
|
53
|
+
* @param options - Batch processing options
|
|
54
|
+
* @returns A promise that resolves to the mapped array
|
|
55
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // Synchronous mapping with default options (sequential processing)
|
|
60
|
+
* const doubled = await mapInBatches([1, 2, 3, 4], (x) => x * 2);
|
|
61
|
+
*
|
|
62
|
+
* // With concurrent processing within batches
|
|
63
|
+
* const doubled = await mapInBatches([1, 2, 3, 4], (x) => x * 2, { sequentialProcessing: false });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function mapInBatches<T, R>(items: T[], mapFn: (item: T, index: number) => R | Promise<R>, options?: BatchProcessingOptions): Promise<R[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Filters an array in batches to avoid blocking the event loop.
|
|
69
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
70
|
+
* when the processing time exceeds the threshold.
|
|
71
|
+
*
|
|
72
|
+
* @template T - The type of items in the array
|
|
73
|
+
* @param items - The array to filter
|
|
74
|
+
* @param predicate - The predicate function to test each item. Receives the item and its index.
|
|
75
|
+
* @param options - Batch processing options
|
|
76
|
+
* @returns A promise that resolves to the filtered array
|
|
77
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Synchronous filtering with default options
|
|
82
|
+
* const evens = await filterInBatches([1, 2, 3, 4, 5], (x) => x % 2 === 0);
|
|
83
|
+
* // Result: [2, 4]
|
|
84
|
+
*
|
|
85
|
+
* // With custom batch size
|
|
86
|
+
* const evens = await filterInBatches([1, 2, 3, 4, 5], (x) => x % 2 === 0, { batchSize: 2 });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function filterInBatches<T>(items: T[], predicate: (item: T, index: number) => boolean | Promise<boolean>, options?: BatchProcessingOptions): Promise<T[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Groups an array by a key function in batches to avoid blocking the event loop.
|
|
92
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
93
|
+
* when the processing time exceeds the threshold.
|
|
94
|
+
*
|
|
95
|
+
* @template T - The type of items in the array
|
|
96
|
+
* @template K - The type of the grouping key (must extend PropertyKey)
|
|
97
|
+
* @param items - The array to group
|
|
98
|
+
* @param keyFn - The function to extract the grouping key from each item. Receives the item and its index.
|
|
99
|
+
* @param options - Batch processing options
|
|
100
|
+
* @returns A promise that resolves to an object with grouped items
|
|
101
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* // Group by property with default options
|
|
106
|
+
* const byType = await groupByInBatches(
|
|
107
|
+
* [{type: 'A', value: 1}, {type: 'B', value: 2}, {type: 'A', value: 3}],
|
|
108
|
+
* (item) => item.type
|
|
109
|
+
* );
|
|
110
|
+
* // Result: {A: [{type: 'A', value: 1}, {type: 'A', value: 3}], B: [{type: 'B', value: 2}]}
|
|
111
|
+
*
|
|
112
|
+
* // With custom batch size
|
|
113
|
+
* const byType = await groupByInBatches(
|
|
114
|
+
* [{type: 'A', value: 1}, {type: 'B', value: 2}, {type: 'A', value: 3}],
|
|
115
|
+
* (item) => item.type,
|
|
116
|
+
* { batchSize: 2 }
|
|
117
|
+
* );
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function groupByInBatches<T, K extends PropertyKey>(items: T[], keyFn: (item: T, index: number) => K | Promise<K>, options?: BatchProcessingOptions): Promise<Record<K, T[]>>;
|
|
121
|
+
/**
|
|
122
|
+
* Reduces an array in batches to avoid blocking the event loop.
|
|
123
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
124
|
+
* when the processing time exceeds the threshold. Sequential processing is always used for the reducer function,
|
|
125
|
+
* irrespective of the `sequentialProcessing` option.
|
|
126
|
+
*
|
|
127
|
+
* @template T - The type of items in the array
|
|
128
|
+
* @template R - The type of the accumulator/result
|
|
129
|
+
* @param items - The array to reduce
|
|
130
|
+
* @param reducer - The reducer function. Receives the accumulator, current item, and index.
|
|
131
|
+
* @param initialValue - The initial value for the accumulator
|
|
132
|
+
* @param options - Batch processing options
|
|
133
|
+
* @returns A promise that resolves to the reduced value
|
|
134
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* // Sum numbers with default options
|
|
139
|
+
* const sum = await reduceInBatches([1, 2, 3, 4], (acc, x) => acc + x, 0);
|
|
140
|
+
* // Result: 10
|
|
141
|
+
*
|
|
142
|
+
* // With custom batch size
|
|
143
|
+
* const sum = await reduceInBatches([1, 2, 3, 4], (acc, x) => acc + x, 0, { batchSize: 2 });
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare function reduceInBatches<T, R>(items: T[], reducer: (acc: R, item: T, index: number) => R | Promise<R>, initialValue: R, options?: BatchProcessingOptions): Promise<R>;
|
|
147
|
+
/**
|
|
148
|
+
* FlatMaps an array in batches to avoid blocking the event loop.
|
|
149
|
+
* Processes items in chunks, flattens the results, and yields control back to the event loop between batches
|
|
150
|
+
* when the processing time exceeds the threshold.
|
|
151
|
+
*
|
|
152
|
+
* @template T - The type of items in the input array
|
|
153
|
+
* @template R - The type of items in the flattened result array
|
|
154
|
+
* @param items - The array to flatMap over
|
|
155
|
+
* @param mapFn - The mapping function that returns an array for each item. Receives the item and its index.
|
|
156
|
+
* @param options - Batch processing options
|
|
157
|
+
* @returns A promise that resolves to the flattened mapped array
|
|
158
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* // Duplicate each item with default options
|
|
163
|
+
* const duplicated = await flatMapInBatches([1, 2, 3], (x) => [x, x]);
|
|
164
|
+
* // Result: [1, 1, 2, 2, 3, 3]
|
|
165
|
+
*
|
|
166
|
+
* // With custom batch size
|
|
167
|
+
* const duplicated = await flatMapInBatches([1, 2, 3], (x) => [x, x], { batchSize: 2 });
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export declare function flatMapInBatches<T, R>(items: T[], mapFn: (item: T, index: number) => R[] | Promise<R[]>, options?: BatchProcessingOptions): Promise<R[]>;
|
|
171
|
+
/**
|
|
172
|
+
* forEach over an array in batches to avoid blocking the event loop.
|
|
173
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
174
|
+
* when the processing time exceeds the threshold.
|
|
175
|
+
*
|
|
176
|
+
* @template T - The type of items in the input array
|
|
177
|
+
* @param items - The array to iterate over
|
|
178
|
+
* @param fn - The function to apply to each item. Receives the item and its index. Can be async.
|
|
179
|
+
* @param options - Batch processing options
|
|
180
|
+
* @returns A promise that resolves when all items have been processed
|
|
181
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* // Process items in batches with default options
|
|
186
|
+
* await forEachInBatches([1, 2, 3, 4], async (x) => {
|
|
187
|
+
* await doSomething(x);
|
|
188
|
+
* });
|
|
189
|
+
*
|
|
190
|
+
* // With custom batch size
|
|
191
|
+
* await forEachInBatches([1, 2, 3, 4], async (x) => {
|
|
192
|
+
* await doSomething(x);
|
|
193
|
+
* }, { batchSize: 2 });
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
export declare function forEachInBatches<T>(items: T[], fn: (item: T, index: number) => void | Promise<void>, options?: BatchProcessingOptions): Promise<void>;
|
|
197
|
+
//# sourceMappingURL=batch-processing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-processing.d.ts","sourceRoot":"","sources":["../../src/utils/batch-processing.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAOD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gCAAgC,CAC9C,MAAM,CAAC,EAAE,sBAAsB,GAC9B,sBAAsB,CA0BxB;AAoFD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAC/B,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACjD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,CAqBd;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,CAAC,EAAE,EACV,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EACjE,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,CAuBd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,EACvD,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACjD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CA0BzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,KAAK,EAAE,CAAC,EAAE,EACV,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC3D,YAAY,EAAE,CAAC,EACf,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EACnC,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EACrD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,CAuBd;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,KAAK,EAAE,CAAC,EAAE,EACV,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACpD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureBatchProcessingDefaults = configureBatchProcessingDefaults;
|
|
4
|
+
exports.mapInBatches = mapInBatches;
|
|
5
|
+
exports.filterInBatches = filterInBatches;
|
|
6
|
+
exports.groupByInBatches = groupByInBatches;
|
|
7
|
+
exports.reduceInBatches = reduceInBatches;
|
|
8
|
+
exports.flatMapInBatches = flatMapInBatches;
|
|
9
|
+
exports.forEachInBatches = forEachInBatches;
|
|
10
|
+
// Default configuration values (internal)
|
|
11
|
+
let defaultBatchSize = 10;
|
|
12
|
+
let defaultYieldThreshold = 10;
|
|
13
|
+
let defaultSequentialProcessing = true;
|
|
14
|
+
/**
|
|
15
|
+
* Configure global defaults for batch processing operations
|
|
16
|
+
*
|
|
17
|
+
* @param config - Configuration options for batch processing
|
|
18
|
+
* @returns The current configuration after applying changes
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Set both defaults
|
|
23
|
+
* configureBatchProcessingDefaults({ batchSize: 20, yieldThreshold: 5 });
|
|
24
|
+
*
|
|
25
|
+
* // Set only batch size
|
|
26
|
+
* configureBatchProcessingDefaults({ batchSize: 50 });
|
|
27
|
+
*
|
|
28
|
+
* // Enable concurrent processing within batches
|
|
29
|
+
* configureBatchProcessingDefaults({ sequentialProcessing: false });
|
|
30
|
+
*
|
|
31
|
+
* // Get current configuration
|
|
32
|
+
* const currentConfig = configureBatchProcessingDefaults();
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function configureBatchProcessingDefaults(config) {
|
|
36
|
+
if (config) {
|
|
37
|
+
if (config.batchSize !== undefined) {
|
|
38
|
+
if (!Number.isInteger(config.batchSize) || config.batchSize <= 0) {
|
|
39
|
+
throw new Error('batchSize must be a positive integer');
|
|
40
|
+
}
|
|
41
|
+
defaultBatchSize = config.batchSize;
|
|
42
|
+
}
|
|
43
|
+
if (config.yieldThreshold !== undefined) {
|
|
44
|
+
if (!Number.isInteger(config.yieldThreshold) || config.yieldThreshold < 0) {
|
|
45
|
+
throw new Error('yieldThreshold must be a non-negative integer');
|
|
46
|
+
}
|
|
47
|
+
defaultYieldThreshold = config.yieldThreshold;
|
|
48
|
+
}
|
|
49
|
+
if (config.sequentialProcessing !== undefined) {
|
|
50
|
+
defaultSequentialProcessing = Boolean(config.sequentialProcessing);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
batchSize: defaultBatchSize,
|
|
55
|
+
yieldThreshold: defaultYieldThreshold,
|
|
56
|
+
sequentialProcessing: defaultSequentialProcessing,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Utility function to defer execution to the next tick of the event loop.
|
|
61
|
+
* This prevents blocking the event loop during heavy batch operations by
|
|
62
|
+
* yielding control back to the event loop using setImmediate.
|
|
63
|
+
*
|
|
64
|
+
* @param startTime - The timestamp when the current batch processing started
|
|
65
|
+
* @param yieldThreshold - Time threshold in milliseconds before yielding control
|
|
66
|
+
* @returns A promise that resolves to a boolean indicating whether a yield occurred
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
function defer(startTime, yieldThreshold) {
|
|
70
|
+
const elapsed = Date.now() - startTime;
|
|
71
|
+
// Only yield if we've exceeded the threshold
|
|
72
|
+
if (elapsed >= yieldThreshold) {
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
setImmediate(() => resolve(true));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Otherwise continue immediately
|
|
78
|
+
return Promise.resolve(false);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Helper to get batch processing options with defaults applied
|
|
82
|
+
* @param options - User provided options
|
|
83
|
+
* @returns Options with defaults applied
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
function getOptions(options) {
|
|
87
|
+
const batchSize = options?.batchSize ?? defaultBatchSize;
|
|
88
|
+
const yieldThreshold = options?.yieldThreshold ?? defaultYieldThreshold;
|
|
89
|
+
const sequentialProcessing = options?.sequentialProcessing ?? defaultSequentialProcessing;
|
|
90
|
+
if (!Number.isInteger(batchSize) || batchSize <= 0) {
|
|
91
|
+
throw new Error('batchSize must be a positive integer');
|
|
92
|
+
}
|
|
93
|
+
if (!Number.isInteger(yieldThreshold) || yieldThreshold < 0) {
|
|
94
|
+
throw new Error('yieldThreshold must be a non-negative integer');
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
batchSize,
|
|
98
|
+
yieldThreshold,
|
|
99
|
+
sequentialProcessing,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Helper to process an array in batches, yielding as needed.
|
|
104
|
+
* @param items - The array to process
|
|
105
|
+
* @param options - Batch processing options
|
|
106
|
+
* @param batchHandler - Function to handle each batch: (batch, batchStartIndex) => Promise<any>
|
|
107
|
+
* @returns Promise<void>
|
|
108
|
+
*/
|
|
109
|
+
async function processInBatches(items, options, batchHandler) {
|
|
110
|
+
let i = 0;
|
|
111
|
+
let startTime = Date.now();
|
|
112
|
+
const { batchSize } = options;
|
|
113
|
+
const n = items.length;
|
|
114
|
+
// Allocate a single batch array and reuses it for all batches
|
|
115
|
+
const batch = Array(batchSize);
|
|
116
|
+
while (i < n) {
|
|
117
|
+
const len = Math.min(batchSize, n - i);
|
|
118
|
+
for (let j = 0; j < len; j += 1) {
|
|
119
|
+
batch[j] = items[i + j];
|
|
120
|
+
}
|
|
121
|
+
batch.length = len;
|
|
122
|
+
// eslint-disable-next-line no-await-in-loop
|
|
123
|
+
await batchHandler(batch, i);
|
|
124
|
+
i += batchSize;
|
|
125
|
+
// eslint-disable-next-line no-await-in-loop
|
|
126
|
+
const didYield = await defer(startTime, options.yieldThreshold);
|
|
127
|
+
if (didYield)
|
|
128
|
+
startTime = Date.now();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Maps over an array in batches to avoid blocking the event loop.
|
|
133
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
134
|
+
* when the processing time exceeds the threshold.
|
|
135
|
+
*
|
|
136
|
+
* @template T - The type of items in the input array
|
|
137
|
+
* @template R - The type of items in the result array
|
|
138
|
+
* @param items - The array to map over
|
|
139
|
+
* @param mapFn - The mapping function to apply to each item. Receives the item and its index.
|
|
140
|
+
* @param options - Batch processing options
|
|
141
|
+
* @returns A promise that resolves to the mapped array
|
|
142
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* // Synchronous mapping with default options (sequential processing)
|
|
147
|
+
* const doubled = await mapInBatches([1, 2, 3, 4], (x) => x * 2);
|
|
148
|
+
*
|
|
149
|
+
* // With concurrent processing within batches
|
|
150
|
+
* const doubled = await mapInBatches([1, 2, 3, 4], (x) => x * 2, { sequentialProcessing: false });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
function mapInBatches(items, mapFn, options) {
|
|
154
|
+
const opts = getOptions(options);
|
|
155
|
+
return (async () => {
|
|
156
|
+
const result = [];
|
|
157
|
+
await processInBatches(items, opts, async (batch, batchStart) => {
|
|
158
|
+
if (opts.sequentialProcessing) {
|
|
159
|
+
// Process items sequentially
|
|
160
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
161
|
+
// eslint-disable-next-line no-await-in-loop -- sequential processing is required
|
|
162
|
+
const mapped = await mapFn(batch[j], batchStart + j);
|
|
163
|
+
result.push(mapped);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// Process items concurrently
|
|
168
|
+
const mapped = await Promise.all(batch.map((item, j) => mapFn(item, batchStart + j)));
|
|
169
|
+
result.push(...mapped);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return result;
|
|
173
|
+
})();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Filters an array in batches to avoid blocking the event loop.
|
|
177
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
178
|
+
* when the processing time exceeds the threshold.
|
|
179
|
+
*
|
|
180
|
+
* @template T - The type of items in the array
|
|
181
|
+
* @param items - The array to filter
|
|
182
|
+
* @param predicate - The predicate function to test each item. Receives the item and its index.
|
|
183
|
+
* @param options - Batch processing options
|
|
184
|
+
* @returns A promise that resolves to the filtered array
|
|
185
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* // Synchronous filtering with default options
|
|
190
|
+
* const evens = await filterInBatches([1, 2, 3, 4, 5], (x) => x % 2 === 0);
|
|
191
|
+
* // Result: [2, 4]
|
|
192
|
+
*
|
|
193
|
+
* // With custom batch size
|
|
194
|
+
* const evens = await filterInBatches([1, 2, 3, 4, 5], (x) => x % 2 === 0, { batchSize: 2 });
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
function filterInBatches(items, predicate, options) {
|
|
198
|
+
const opts = getOptions(options);
|
|
199
|
+
return (async () => {
|
|
200
|
+
const result = [];
|
|
201
|
+
await processInBatches(items, opts, async (batch, batchStart) => {
|
|
202
|
+
if (opts.sequentialProcessing) {
|
|
203
|
+
// Process items sequentially
|
|
204
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
205
|
+
// eslint-disable-next-line no-await-in-loop -- sequential processing is required
|
|
206
|
+
const passes = await predicate(batch[j], batchStart + j);
|
|
207
|
+
if (passes)
|
|
208
|
+
result.push(batch[j]);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// Process items concurrently
|
|
213
|
+
const flags = await Promise.all(batch.map((item, j) => predicate(item, batchStart + j)));
|
|
214
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
215
|
+
if (flags[j])
|
|
216
|
+
result.push(batch[j]);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
return result;
|
|
221
|
+
})();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Groups an array by a key function in batches to avoid blocking the event loop.
|
|
225
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
226
|
+
* when the processing time exceeds the threshold.
|
|
227
|
+
*
|
|
228
|
+
* @template T - The type of items in the array
|
|
229
|
+
* @template K - The type of the grouping key (must extend PropertyKey)
|
|
230
|
+
* @param items - The array to group
|
|
231
|
+
* @param keyFn - The function to extract the grouping key from each item. Receives the item and its index.
|
|
232
|
+
* @param options - Batch processing options
|
|
233
|
+
* @returns A promise that resolves to an object with grouped items
|
|
234
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* // Group by property with default options
|
|
239
|
+
* const byType = await groupByInBatches(
|
|
240
|
+
* [{type: 'A', value: 1}, {type: 'B', value: 2}, {type: 'A', value: 3}],
|
|
241
|
+
* (item) => item.type
|
|
242
|
+
* );
|
|
243
|
+
* // Result: {A: [{type: 'A', value: 1}, {type: 'A', value: 3}], B: [{type: 'B', value: 2}]}
|
|
244
|
+
*
|
|
245
|
+
* // With custom batch size
|
|
246
|
+
* const byType = await groupByInBatches(
|
|
247
|
+
* [{type: 'A', value: 1}, {type: 'B', value: 2}, {type: 'A', value: 3}],
|
|
248
|
+
* (item) => item.type,
|
|
249
|
+
* { batchSize: 2 }
|
|
250
|
+
* );
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
function groupByInBatches(items, keyFn, options) {
|
|
254
|
+
const opts = getOptions(options);
|
|
255
|
+
return (async () => {
|
|
256
|
+
const result = {};
|
|
257
|
+
await processInBatches(items, opts, async (batch, batchStart) => {
|
|
258
|
+
if (opts.sequentialProcessing) {
|
|
259
|
+
// Process items sequentially
|
|
260
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
261
|
+
// eslint-disable-next-line no-await-in-loop -- sequential processing is required
|
|
262
|
+
const key = await keyFn(batch[j], batchStart + j);
|
|
263
|
+
if (!result[key])
|
|
264
|
+
result[key] = [];
|
|
265
|
+
result[key].push(batch[j]);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
// Process items concurrently
|
|
270
|
+
const keys = await Promise.all(batch.map((item, j) => keyFn(item, batchStart + j)));
|
|
271
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
272
|
+
const key = keys[j];
|
|
273
|
+
if (!result[key])
|
|
274
|
+
result[key] = [];
|
|
275
|
+
result[key].push(batch[j]);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
return result;
|
|
280
|
+
})();
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Reduces an array in batches to avoid blocking the event loop.
|
|
284
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
285
|
+
* when the processing time exceeds the threshold. Sequential processing is always used for the reducer function,
|
|
286
|
+
* irrespective of the `sequentialProcessing` option.
|
|
287
|
+
*
|
|
288
|
+
* @template T - The type of items in the array
|
|
289
|
+
* @template R - The type of the accumulator/result
|
|
290
|
+
* @param items - The array to reduce
|
|
291
|
+
* @param reducer - The reducer function. Receives the accumulator, current item, and index.
|
|
292
|
+
* @param initialValue - The initial value for the accumulator
|
|
293
|
+
* @param options - Batch processing options
|
|
294
|
+
* @returns A promise that resolves to the reduced value
|
|
295
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* // Sum numbers with default options
|
|
300
|
+
* const sum = await reduceInBatches([1, 2, 3, 4], (acc, x) => acc + x, 0);
|
|
301
|
+
* // Result: 10
|
|
302
|
+
*
|
|
303
|
+
* // With custom batch size
|
|
304
|
+
* const sum = await reduceInBatches([1, 2, 3, 4], (acc, x) => acc + x, 0, { batchSize: 2 });
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
function reduceInBatches(items, reducer, initialValue, options) {
|
|
308
|
+
const opts = getOptions(options);
|
|
309
|
+
return (async () => {
|
|
310
|
+
let acc = initialValue;
|
|
311
|
+
await processInBatches(items, opts, async (batch, batchStart) => {
|
|
312
|
+
// Always sequential, regardless of sequentialProcessing option
|
|
313
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
314
|
+
// eslint-disable-next-line no-await-in-loop -- sequential processing is required
|
|
315
|
+
acc = await reducer(acc, batch[j], batchStart + j);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
return acc;
|
|
319
|
+
})();
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* FlatMaps an array in batches to avoid blocking the event loop.
|
|
323
|
+
* Processes items in chunks, flattens the results, and yields control back to the event loop between batches
|
|
324
|
+
* when the processing time exceeds the threshold.
|
|
325
|
+
*
|
|
326
|
+
* @template T - The type of items in the input array
|
|
327
|
+
* @template R - The type of items in the flattened result array
|
|
328
|
+
* @param items - The array to flatMap over
|
|
329
|
+
* @param mapFn - The mapping function that returns an array for each item. Receives the item and its index.
|
|
330
|
+
* @param options - Batch processing options
|
|
331
|
+
* @returns A promise that resolves to the flattened mapped array
|
|
332
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```typescript
|
|
336
|
+
* // Duplicate each item with default options
|
|
337
|
+
* const duplicated = await flatMapInBatches([1, 2, 3], (x) => [x, x]);
|
|
338
|
+
* // Result: [1, 1, 2, 2, 3, 3]
|
|
339
|
+
*
|
|
340
|
+
* // With custom batch size
|
|
341
|
+
* const duplicated = await flatMapInBatches([1, 2, 3], (x) => [x, x], { batchSize: 2 });
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
function flatMapInBatches(items, mapFn, options) {
|
|
345
|
+
const opts = getOptions(options);
|
|
346
|
+
return (async () => {
|
|
347
|
+
const result = [];
|
|
348
|
+
await processInBatches(items, opts, async (batch, batchStart) => {
|
|
349
|
+
if (opts.sequentialProcessing) {
|
|
350
|
+
// Process items sequentially
|
|
351
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
352
|
+
// eslint-disable-next-line no-await-in-loop -- sequential processing is required
|
|
353
|
+
const mapped = await mapFn(batch[j], batchStart + j);
|
|
354
|
+
result.push(...mapped);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
// Process items concurrently
|
|
359
|
+
const mapped = await Promise.all(batch.map((item, j) => mapFn(item, batchStart + j)));
|
|
360
|
+
mapped.forEach((arr) => {
|
|
361
|
+
result.push(...arr);
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
return result;
|
|
366
|
+
})();
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* forEach over an array in batches to avoid blocking the event loop.
|
|
370
|
+
* Processes items in chunks and yields control back to the event loop between batches
|
|
371
|
+
* when the processing time exceeds the threshold.
|
|
372
|
+
*
|
|
373
|
+
* @template T - The type of items in the input array
|
|
374
|
+
* @param items - The array to iterate over
|
|
375
|
+
* @param fn - The function to apply to each item. Receives the item and its index. Can be async.
|
|
376
|
+
* @param options - Batch processing options
|
|
377
|
+
* @returns A promise that resolves when all items have been processed
|
|
378
|
+
* @throws {Error} When batchSize is not a positive integer
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```typescript
|
|
382
|
+
* // Process items in batches with default options
|
|
383
|
+
* await forEachInBatches([1, 2, 3, 4], async (x) => {
|
|
384
|
+
* await doSomething(x);
|
|
385
|
+
* });
|
|
386
|
+
*
|
|
387
|
+
* // With custom batch size
|
|
388
|
+
* await forEachInBatches([1, 2, 3, 4], async (x) => {
|
|
389
|
+
* await doSomething(x);
|
|
390
|
+
* }, { batchSize: 2 });
|
|
391
|
+
* ```
|
|
392
|
+
*/
|
|
393
|
+
function forEachInBatches(items, fn, options) {
|
|
394
|
+
const opts = getOptions(options);
|
|
395
|
+
return processInBatches(items, opts, async (batch, batchStart) => {
|
|
396
|
+
if (opts.sequentialProcessing) {
|
|
397
|
+
// Process items sequentially
|
|
398
|
+
for (let j = 0; j < batch.length; j += 1) {
|
|
399
|
+
// eslint-disable-next-line no-await-in-loop -- sequential processing is required
|
|
400
|
+
await fn(batch[j], batchStart + j);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
// Process items concurrently
|
|
405
|
+
await Promise.all(batch.map((item, j) => fn(item, batchStart + j)));
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF0Y2gtcHJvY2Vzc2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9iYXRjaC1wcm9jZXNzaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBa0RBLDRFQTRCQztBQTBHRCxvQ0F5QkM7QUF3QkQsMENBMkJDO0FBZ0NELDRDQThCQztBQTJCRCwwQ0FtQkM7QUF5QkQsNENBMkJDO0FBMkJELDRDQW1CQztBQTFiRCwwQ0FBMEM7QUFDMUMsSUFBSSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFDMUIsSUFBSSxxQkFBcUIsR0FBRyxFQUFFLENBQUM7QUFDL0IsSUFBSSwyQkFBMkIsR0FBRyxJQUFJLENBQUM7QUFFdkM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsU0FBZ0IsZ0NBQWdDLENBQzlDLE1BQStCO0lBRS9CLElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxJQUFJLE1BQU0sQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxTQUFTLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2pFLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztZQUMxRCxDQUFDO1lBQ0QsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxNQUFNLENBQUMsY0FBYyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMxRSxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUM7WUFDbkUsQ0FBQztZQUNELHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUM7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Tiw2QkFBNkI7WUFDN0IsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT3B0aW9ucyBmb3IgYmF0Y2ggcHJvY2Vzc2luZyBvcGVyYXRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmF0Y2hQcm9jZXNzaW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaXRlbXMgdG8gcHJvY2VzcyBpbiBlYWNoIGJhdGNoIChkZWZhdWx0OiAxMClcbiAgICogTXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIuXG4gICAqL1xuICBiYXRjaFNpemU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRpbWUgdGhyZXNob2xkIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMTApIGJlZm9yZSB5aWVsZGluZyBjb250cm9sIGJhY2sgdG8gdGhlIGV2ZW50IGxvb3AuXG4gICAqIFNldCB0byAwIHRvIHlpZWxkIGFmdGVyIGV2ZXJ5IGJhdGNoLiBNdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIuXG4gICAqL1xuICB5aWVsZFRocmVzaG9sZD86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBwcm9jZXNzIGl0ZW1zIHNlcXVlbnRpYWxseSB3aXRoaW4gZWFjaCBiYXRjaC4gV2hlbiB0cnVlIChkZWZhdWx0KSwgZWFjaCBpdGVtIGluIGEgYmF0Y2hcbiAgICogd2lsbCBiZSBwcm9jZXNzZWQgb25lIGF0IGEgdGltZS4gV2hlbiBmYWxzZSwgYWxsIGl0ZW1zIGluIGEgYmF0Y2ggd2lsbCBiZSBwcm9jZXNzZWQgY29uY3VycmVudGx5LlxuICAgKiBDb25zaWRlciB0aGUgaW1wbGljYXRpb25zIG9mIGNvbmN1cnJlbmN5IG9uIHlvdXIgcHJvY2Vzc2luZyBsb2dpYyBiZWZvcmUgc2V0dGluZyB0aGlzIHRvIGZhbHNlLCBlLmcuIHJhY2UgY29uZGl0aW9ucywgcmF0ZSBsaW1pdHMsIG1lbW9yeSBwcmVzc3VyZSwgZXRjLlxuICAgKi9cbiAgc2VxdWVudGlhbFByb2Nlc3Npbmc/OiBib29sZWFuO1xufVxuXG4vLyBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gdmFsdWVzIChpbnRlcm5hbClcbmxldCBkZWZhdWx0QmF0Y2hTaXplID0gMTA7XG5sZXQgZGVmYXVsdFlpZWxkVGhyZXNob2xkID0gMTA7XG5sZXQgZGVmYXVsdFNlcXVlbnRpYWxQcm9jZXNzaW5nID0gdHJ1ZTtcblxuLyoqXG4gKiBDb25maWd1cmUgZ2xvYmFsIGRlZmF1bHRzIGZvciBiYXRjaCBwcm9jZXNzaW5nIG9wZXJhdGlvbnNcbiAqXG4gKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBiYXRjaCBwcm9jZXNzaW5nXG4gKiBAcmV0dXJucyBUaGUgY3VycmVudCBjb25maWd1cmF0aW9uIGFmdGVyIGFwcGx5aW5nIGNoYW5nZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gU2V0IGJvdGggZGVmYXVsdHNcbiAqIGNvbmZpZ3VyZUJhdGNoUHJvY2Vzc2luZ0RlZmF1bHRzKHsgYmF0Y2hTaXplOiAyMCwgeWllbGRUaHJlc2hvbGQ6IDUgfSk7XG4gKlxuICogLy8gU2V0IG9ubHkgYmF0Y2ggc2l6ZVxuICogY29uZmlndXJlQmF0Y2hQcm9jZXNzaW5nRGVmYXVsdHMoeyBiYXRjaFNpemU6IDUwIH0pO1xuICpcbiAqIC8vIEVuYWJsZSBjb25jdXJyZW50IHByb2Nlc3Npbmcgd2l0aGluIGJhdGNoZXNcbiAqIGNvbmZpZ3VyZUJhdGNoUHJvY2Vzc2luZ0RlZmF1bHRzKHsgc2VxdWVudGlhbFByb2Nlc3Npbmc6IGZhbHNlIH0pO1xuICpcbiAqIC8vIEdldCBjdXJyZW50IGNvbmZpZ3VyYXRpb25cbiAqIGNvbnN0IGN1cnJlbnRDb25maWcgPSBjb25maWd1cmVCYXRjaFByb2Nlc3NpbmdEZWZhdWx0cygpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25maWd1cmVCYXRjaFByb2Nlc3NpbmdEZWZhdWx0cyhcbiAgY29uZmlnPzogQmF0Y2hQcm9jZXNzaW5nT3B0aW9ucyxcbik6IEJhdGNoUHJvY2Vzc2luZ09wdGlvbnMge1xuICBpZiAoY29uZmlnKSB7XG4gICAgaWYgKGNvbmZpZy5iYXRjaFNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGNvbmZpZy5iYXRjaFNpemUpIHx8IGNvbmZpZy5iYXRjaFNpemUgPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhdGNoU2l6ZSBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlcicpO1xuICAgICAgfVxuICAgICAgZGVmYXVsdEJhdGNoU2l6ZSA9IGNvbmZpZy5iYXRjaFNpemU7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy55aWVsZFRocmVzaG9sZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoY29uZmlnLnlpZWxkVGhyZXNob2xkKSB8fCBjb25maWcueWllbGRUaHJlc2hvbGQgPCAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigneWllbGRUaHJlc2hvbGQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyJyk7XG4gICAgICB9XG4gICAgICBkZWZhdWx0WWllbGRUaHJlc2hvbGQgPSBjb25maWcueWllbGRUaHJlc2hvbGQ7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5zZXF1ZW50aWFsUHJvY2Vzc2luZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZWZhdWx0U2VxdWVudGlhbFByb2Nlc3NpbmcgPSBCb29sZWFuKGNvbmZpZy5zZXF1ZW50aWFsUHJvY2Vzc2luZyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBiYXRjaFNpemU6IGRlZmF1bHRCYXRjaFNpemUsXG4gICAgeWllbGRUaHJlc2hvbGQ6IGRlZmF1bHRZaWVsZFRocmVzaG9sZCxcbiAgICBzZXF1ZW50aWFsUHJvY2Vzc2luZzogZGVmYXVsdFNlcXVlbnRpYWxQcm9jZXNzaW5nLFxuICB9O1xufVxuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gZGVmZXIgZXhlY3V0aW9uIHRvIHRoZSBuZXh0IHRpY2sgb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBUaGlzIHByZXZlbnRzIGJsb2NraW5nIHRoZSBldmVudCBsb29wIGR1cmluZyBoZWF2eSBiYXRjaCBvcGVyYXRpb25zIGJ5XG4gKiB5aWVsZGluZyBjb250cm9sIGJhY2sgdG8gdGhlIGV2ZW50IGxvb3AgdXNpbmcgc2V0SW1tZWRpYXRlLlxuICpcbiAqIEBwYXJhbSBzdGFydFRpbWUgLSBUaGUgdGltZXN0YW1wIHdoZW4gdGhlIGN1cnJlbnQgYmF0Y2ggcHJvY2Vzc2luZyBzdGFydGVkXG4gKiBAcGFyYW0geWllbGRUaHJlc2hvbGQgLSBUaW1lIHRocmVzaG9sZCBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIHlpZWxkaW5nIGNvbnRyb2xcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgYSB5aWVsZCBvY2N1cnJlZFxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGRlZmVyKHN0YXJ0VGltZTogbnVtYmVyLCB5aWVsZFRocmVzaG9sZDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IGVsYXBzZWQgPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xuXG4gIC8vIE9ubHkgeWllbGQgaWYgd2UndmUgZXhjZWVkZWQgdGhlIHRocmVzaG9sZFxuICBpZiAoZWxhcHNlZCA+PSB5aWVsZFRocmVzaG9sZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHJlc29sdmUodHJ1ZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlIGNvbnRpbnVlIGltbWVkaWF0ZWx5XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBnZXQgYmF0Y2ggcHJvY2Vzc2luZyBvcHRpb25zIHdpdGggZGVmYXVsdHMgYXBwbGllZFxuICogQHBhcmFtIG9wdGlvbnMgLSBVc2VyIHByb3ZpZGVkIG9wdGlvbnNcbiAqIEByZXR1cm5zIE9wdGlvbnMgd2l0aCBkZWZhdWx0cyBhcHBsaWVkXG4gKiBAaW50ZXJuYWxcbiAqL1xuZnVuY3Rpb24gZ2V0T3B0aW9ucyhvcHRpb25zPzogQmF0Y2hQcm9jZXNzaW5nT3B0aW9ucyk6IFJlcXVpcmVkPEJhdGNoUHJvY2Vzc2luZ09wdGlvbnM+IHtcbiAgY29uc3QgYmF0Y2hTaXplID0gb3B0aW9ucz8uYmF0Y2hTaXplID8/IGRlZmF1bHRCYXRjaFNpemU7XG4gIGNvbnN0IHlpZWxkVGhyZXNob2xkID0gb3B0aW9ucz8ueWllbGRUaHJlc2hvbGQgPz8gZGVmYXVsdFlpZWxkVGhyZXNob2xkO1xuICBjb25zdCBzZXF1ZW50aWFsUHJvY2Vzc2luZyA9IG9wdGlvbnM/LnNlcXVlbnRpYWxQcm9jZXNzaW5nID8/IGRlZmF1bHRTZXF1ZW50aWFsUHJvY2Vzc2luZztcblxuICBpZiAoIU51bWJlci5pc0ludGVnZXIoYmF0Y2hTaXplKSB8fCBiYXRjaFNpemUgPD0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignYmF0Y2hTaXplIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyJyk7XG4gIH1cbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHlpZWxkVGhyZXNob2xkKSB8fCB5aWVsZFRocmVzaG9sZCA8IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3lpZWxkVGhyZXNob2xkIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlcicpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBiYXRjaFNpemUsXG4gICAgeWllbGRUaHJlc2hvbGQsXG4gICAgc2VxdWVudGlhbFByb2Nlc3NpbmcsXG4gIH07XG59XG5cbi8qKlxuICogSGVscGVyIHRvIHByb2Nlc3MgYW4gYXJyYXkgaW4gYmF0Y2hlcywgeWllbGRpbmcgYXMgbmVlZGVkLlxuICogQHBhcmFtIGl0ZW1zIC0gVGhlIGFycmF5IHRvIHByb2Nlc3NcbiAqIEBwYXJhbSBvcHRpb25zIC0gQmF0Y2ggcHJvY2Vzc2luZyBvcHRpb25zXG4gKiBAcGFyYW0gYmF0Y2hIYW5kbGVyIC0gRnVuY3Rpb24gdG8gaGFuZGxlIGVhY2ggYmF0Y2g6IChiYXRjaCwgYmF0Y2hTdGFydEluZGV4KSA9PiBQcm9taXNlPGFueT5cbiAqIEByZXR1cm5zIFByb21pc2U8dm9pZD5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc0luQmF0Y2hlczxUPihcbiAgaXRlbXM6IFRbXSxcbiAgb3B0aW9uczogUmVxdWlyZWQ8QmF0Y2hQcm9jZXNzaW5nT3B0aW9ucz4sXG4gIGJhdGNoSGFuZGxlcjogKGJhdGNoOiBUW10sIGJhdGNoU3RhcnQ6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPixcbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgaSA9IDA7XG4gIGxldCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICBjb25zdCB7IGJhdGNoU2l6ZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgbiA9IGl0ZW1zLmxlbmd0aDtcbiAgLy8gQWxsb2NhdGUgYSBzaW5nbGUgYmF0Y2ggYXJyYXkgYW5kIHJldXNlcyBpdCBmb3IgYWxsIGJhdGNoZXNcbiAgY29uc3QgYmF0Y2g6IFRbXSA9IEFycmF5KGJhdGNoU2l6ZSk7XG4gIHdoaWxlIChpIDwgbikge1xuICAgIGNvbnN0IGxlbiA9IE1hdGgubWluKGJhdGNoU2l6ZSwgbiAtIGkpO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuOyBqICs9IDEpIHtcbiAgICAgIGJhdGNoW2pdID0gaXRlbXNbaSArIGpdO1xuICAgIH1cbiAgICBiYXRjaC5sZW5ndGggPSBsZW47XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3BcbiAgICBhd2FpdCBiYXRjaEhhbmRsZXIoYmF0Y2gsIGkpO1xuICAgIGkgKz0gYmF0Y2hTaXplO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgY29uc3QgZGlkWWllbGQgPSBhd2FpdCBkZWZlcihzdGFydFRpbWUsIG9wdGlvbnMueWllbGRUaHJlc2hvbGQpO1xuICAgIGlmIChkaWRZaWVsZCkgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgfVxufVxuXG4vKipcbiAqIE1hcHMgb3ZlciBhbiBhcnJheSBpbiBiYXRjaGVzIHRvIGF2b2lkIGJsb2NraW5nIHRoZSBldmVudCBsb29wLlxuICogUHJvY2Vzc2VzIGl0ZW1zIGluIGNodW5rcyBhbmQgeWllbGRzIGNvbnRyb2wgYmFjayB0byB0aGUgZXZlbnQgbG9vcCBiZXR3ZWVuIGJhdGNoZXNcbiAqIHdoZW4gdGhlIHByb2Nlc3NpbmcgdGltZSBleGNlZWRzIHRoZSB0aHJlc2hvbGQuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiBpdGVtcyBpbiB0aGUgaW5wdXQgYXJyYXlcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHR5cGUgb2YgaXRlbXMgaW4gdGhlIHJlc3VsdCBhcnJheVxuICogQHBhcmFtIGl0ZW1zIC0gVGhlIGFycmF5IHRvIG1hcCBvdmVyXG4gKiBAcGFyYW0gbWFwRm4gLSBUaGUgbWFwcGluZyBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGl0ZW0uIFJlY2VpdmVzIHRoZSBpdGVtIGFuZCBpdHMgaW5kZXguXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEJhdGNoIHByb2Nlc3Npbmcgb3B0aW9uc1xuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIG1hcHBlZCBhcnJheVxuICogQHRocm93cyB7RXJyb3J9IFdoZW4gYmF0Y2hTaXplIGlzIG5vdCBhIHBvc2l0aXZlIGludGVnZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gU3luY2hyb25vdXMgbWFwcGluZyB3aXRoIGRlZmF1bHQgb3B0aW9ucyAoc2VxdWVudGlhbCBwcm9jZXNzaW5nKVxuICogY29uc3QgZG91YmxlZCA9IGF3YWl0IG1hcEluQmF0Y2hlcyhbMSwgMiwgMywgNF0sICh4KSA9PiB4ICogMik7XG4gKlxuICogLy8gV2l0aCBjb25jdXJyZW50IHByb2Nlc3Npbmcgd2l0aGluIGJhdGNoZXNcbiAqIGNvbnN0IGRvdWJsZWQgPSBhd2FpdCBtYXBJbkJhdGNoZXMoWzEsIDIsIDMsIDRdLCAoeCkgPT4geCAqIDIsIHsgc2VxdWVudGlhbFByb2Nlc3Npbmc6IGZhbHNlIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBJbkJhdGNoZXM8VCwgUj4oXG4gIGl0ZW1zOiBUW10sXG4gIG1hcEZuOiAoaXRlbTogVCwgaW5kZXg6IG51bWJlcikgPT4gUiB8IFByb21pc2U8Uj4sXG4gIG9wdGlvbnM/OiBCYXRjaFByb2Nlc3NpbmdPcHRpb25zLFxuKTogUHJvbWlzZTxSW10+IHtcbiAgY29uc3Qgb3B0cyA9IGdldE9wdGlvbnMob3B0aW9ucyk7XG5cbiAgcmV0dXJuIChhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0OiBSW10gPSBbXTtcbiAgICBhd2FpdCBwcm9jZXNzSW5CYXRjaGVzKGl0ZW1zLCBvcHRzLCBhc3luYyAoYmF0Y2gsIGJhdGNoU3RhcnQpID0+IHtcbiAgICAgIGlmIChvcHRzLnNlcXVlbnRpYWxQcm9jZXNzaW5nKSB7XG4gICAgICAgIC8vIFByb2Nlc3MgaXRlbXMgc2VxdWVudGlhbGx5XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYmF0Y2gubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcCAtLSBzZXF1ZW50aWFsIHByb2Nlc3NpbmcgaXMgcmVxdWlyZWRcbiAgICAgICAgICBjb25zdCBtYXBwZWQgPSBhd2FpdCBtYXBGbihiYXRjaFtqXSwgYmF0Y2hTdGFydCArIGopO1xuICAgICAgICAgIHJlc3VsdC5wdXNoKG1hcHBlZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFByb2Nlc3MgaXRlbXMgY29uY3VycmVudGx5XG4gICAgICAgIGNvbnN0IG1hcHBlZCA9IGF3YWl0IFByb21pc2UuYWxsKGJhdGNoLm1hcCgoaXRlbSwgaikgPT4gbWFwRm4oaXRlbSwgYmF0Y2hTdGFydCArIGopKSk7XG4gICAgICAgIHJlc3VsdC5wdXNoKC4uLm1hcHBlZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSkoKTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIGFuIGFycmF5IGluIGJhdGNoZXMgdG8gYXZvaWQgYmxvY2tpbmcgdGhlIGV2ZW50IGxvb3AuXG4gKiBQcm9jZXNzZXMgaXRlbXMgaW4gY2h1bmtzIGFuZCB5aWVsZHMgY29udHJvbCBiYWNrIHRvIHRoZSBldmVudCBsb29wIGJldHdlZW4gYmF0Y2hlc1xuICogd2hlbiB0aGUgcHJvY2Vzc2luZyB0aW1lIGV4Y2VlZHMgdGhlIHRocmVzaG9sZC5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGl0ZW1zIGluIHRoZSBhcnJheVxuICogQHBhcmFtIGl0ZW1zIC0gVGhlIGFycmF5IHRvIGZpbHRlclxuICogQHBhcmFtIHByZWRpY2F0ZSAtIFRoZSBwcmVkaWNhdGUgZnVuY3Rpb24gdG8gdGVzdCBlYWNoIGl0ZW0uIFJlY2VpdmVzIHRoZSBpdGVtIGFuZCBpdHMgaW5kZXguXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEJhdGNoIHByb2Nlc3Npbmcgb3B0aW9uc1xuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGZpbHRlcmVkIGFycmF5XG4gKiBAdGhyb3dzIHtFcnJvcn0gV2hlbiBiYXRjaFNpemUgaXMgbm90IGEgcG9zaXRpdmUgaW50ZWdlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBTeW5jaHJvbm91cyBmaWx0ZXJpbmcgd2l0aCBkZWZhdWx0IG9wdGlvbnNcbiAqIGNvbnN0IGV2ZW5zID0gYXdhaXQgZmlsdGVySW5CYXRjaGVzKFsxLCAyLCAzLCA0LCA1XSwgKHgpID0+IHggJSAyID09PSAwKTtcbiAqIC8vIFJlc3VsdDogWzIsIDRdXG4gKlxuICogLy8gV2l0aCBjdXN0b20gYmF0Y2ggc2l6ZVxuICogY29uc3QgZXZlbnMgPSBhd2FpdCBmaWx0ZXJJbkJhdGNoZXMoWzEsIDIsIDMsIDQsIDVdLCAoeCkgPT4geCAlIDIgPT09IDAsIHsgYmF0Y2hTaXplOiAyIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJJbkJhdGNoZXM8VD4oXG4gIGl0ZW1zOiBUW10sXG4gIHByZWRpY2F0ZTogKGl0ZW06IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+LFxuICBvcHRpb25zPzogQmF0Y2hQcm9jZXNzaW5nT3B0aW9ucyxcbik6IFByb21pc2U8VFtdPiB7XG4gIGNvbnN0IG9wdHMgPSBnZXRPcHRpb25zKG9wdGlvbnMpO1xuXG4gIHJldHVybiAoYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdDogVFtdID0gW107XG4gICAgYXdhaXQgcHJvY2Vzc0luQmF0Y2hlcyhpdGVtcywgb3B0cywgYXN5bmMgKGJhdGNoLCBiYXRjaFN0YXJ0KSA9PiB7XG4gICAgICBpZiAob3B0cy5zZXF1ZW50aWFsUHJvY2Vzc2luZykge1xuICAgICAgICAvLyBQcm9jZXNzIGl0ZW1zIHNlcXVlbnRpYWxseVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGJhdGNoLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3AgLS0gc2VxdWVudGlhbCBwcm9jZXNzaW5nIGlzIHJlcXVpcmVkXG4gICAgICAgICAgY29uc3QgcGFzc2VzID0gYXdhaXQgcHJlZGljYXRlKGJhdGNoW2pdLCBiYXRjaFN0YXJ0ICsgaik7XG4gICAgICAgICAgaWYgKHBhc3NlcykgcmVzdWx0LnB1c2goYmF0Y2hbal0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQcm9jZXNzIGl0ZW1zIGNvbmN1cnJlbnRseVxuICAgICAgICBjb25zdCBmbGFncyA9IGF3YWl0IFByb21pc2UuYWxsKGJhdGNoLm1hcCgoaXRlbSwgaikgPT4gcHJlZGljYXRlKGl0ZW0sIGJhdGNoU3RhcnQgKyBqKSkpO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGJhdGNoLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgaWYgKGZsYWdzW2pdKSByZXN1bHQucHVzaChiYXRjaFtqXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9KSgpO1xufVxuXG4vKipcbiAqIEdyb3VwcyBhbiBhcnJheSBieSBhIGtleSBmdW5jdGlvbiBpbiBiYXRjaGVzIHRvIGF2b2lkIGJsb2NraW5nIHRoZSBldmVudCBsb29wLlxuICogUHJvY2Vzc2VzIGl0ZW1zIGluIGNodW5rcyBhbmQgeWllbGRzIGNvbnRyb2wgYmFjayB0byB0aGUgZXZlbnQgbG9vcCBiZXR3ZWVuIGJhdGNoZXNcbiAqIHdoZW4gdGhlIHByb2Nlc3NpbmcgdGltZSBleGNlZWRzIHRoZSB0aHJlc2hvbGQuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiBpdGVtcyBpbiB0aGUgYXJyYXlcbiAqIEB0ZW1wbGF0ZSBLIC0gVGhlIHR5cGUgb2YgdGhlIGdyb3VwaW5nIGtleSAobXVzdCBleHRlbmQgUHJvcGVydHlLZXkpXG4gKiBAcGFyYW0gaXRlbXMgLSBUaGUgYXJyYXkgdG8gZ3JvdXBcbiAqIEBwYXJhbSBrZXlGbiAtIFRoZSBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSBncm91cGluZyBrZXkgZnJvbSBlYWNoIGl0ZW0uIFJlY2VpdmVzIHRoZSBpdGVtIGFuZCBpdHMgaW5kZXguXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEJhdGNoIHByb2Nlc3Npbmcgb3B0aW9uc1xuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gb2JqZWN0IHdpdGggZ3JvdXBlZCBpdGVtc1xuICogQHRocm93cyB7RXJyb3J9IFdoZW4gYmF0Y2hTaXplIGlzIG5vdCBhIHBvc2l0aXZlIGludGVnZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gR3JvdXAgYnkgcHJvcGVydHkgd2l0aCBkZWZhdWx0IG9wdGlvbnNcbiAqIGNvbnN0IGJ5VHlwZSA9IGF3YWl0IGdyb3VwQnlJbkJhdGNoZXMoXG4gKiAgIFt7dHlwZTogJ0EnLCB2YWx1ZTogMX0sIHt0eXBlOiAnQicsIHZhbHVlOiAyfSwge3R5cGU6ICdBJywgdmFsdWU6IDN9XSxcbiAqICAgKGl0ZW0pID0+IGl0ZW0udHlwZVxuICogKTtcbiAqIC8vIFJlc3VsdDoge0E6IFt7dHlwZTogJ0EnLCB2YWx1ZTogMX0sIHt0eXBlOiAnQScsIHZhbHVlOiAzfV0sIEI6IFt7dHlwZTogJ0InLCB2YWx1ZTogMn1dfVxuICpcbiAqIC8vIFdpdGggY3VzdG9tIGJhdGNoIHNpemVcbiAqIGNvbnN0IGJ5VHlwZSA9IGF3YWl0IGdyb3VwQnlJbkJhdGNoZXMoXG4gKiAgIFt7dHlwZTogJ0EnLCB2YWx1ZTogMX0sIHt0eXBlOiAnQicsIHZhbHVlOiAyfSwge3R5cGU6ICdBJywgdmFsdWU6IDN9XSxcbiAqICAgKGl0ZW0pID0+IGl0ZW0udHlwZSxcbiAqICAgeyBiYXRjaFNpemU6IDIgfVxuICogKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBCeUluQmF0Y2hlczxULCBLIGV4dGVuZHMgUHJvcGVydHlLZXk+KFxuICBpdGVtczogVFtdLFxuICBrZXlGbjogKGl0ZW06IFQsIGluZGV4OiBudW1iZXIpID0+IEsgfCBQcm9taXNlPEs+LFxuICBvcHRpb25zPzogQmF0Y2hQcm9jZXNzaW5nT3B0aW9ucyxcbik6IFByb21pc2U8UmVjb3JkPEssIFRbXT4+IHtcbiAgY29uc3Qgb3B0cyA9IGdldE9wdGlvbnMob3B0aW9ucyk7XG5cbiAgcmV0dXJuIChhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8SywgVFtdPiA9IHt9IGFzIFJlY29yZDxLLCBUW10+O1xuICAgIGF3YWl0IHByb2Nlc3NJbkJhdGNoZXMoaXRlbXMsIG9wdHMsIGFzeW5jIChiYXRjaCwgYmF0Y2hTdGFydCkgPT4ge1xuICAgICAgaWYgKG9wdHMuc2VxdWVudGlhbFByb2Nlc3NpbmcpIHtcbiAgICAgICAgLy8gUHJvY2VzcyBpdGVtcyBzZXF1ZW50aWFsbHlcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBiYXRjaC5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wIC0tIHNlcXVlbnRpYWwgcHJvY2Vzc2luZyBpcyByZXF1aXJlZFxuICAgICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IGtleUZuKGJhdGNoW2pdLCBiYXRjaFN0YXJ0ICsgaik7XG4gICAgICAgICAgaWYgKCFyZXN1bHRba2V5XSkgcmVzdWx0W2tleV0gPSBbXTtcbiAgICAgICAgICByZXN1bHRba2V5XS5wdXNoKGJhdGNoW2pdKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUHJvY2VzcyBpdGVtcyBjb25jdXJyZW50bHlcbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IFByb21pc2UuYWxsKGJhdGNoLm1hcCgoaXRlbSwgaikgPT4ga2V5Rm4oaXRlbSwgYmF0Y2hTdGFydCArIGopKSk7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYmF0Y2gubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2pdO1xuICAgICAgICAgIGlmICghcmVzdWx0W2tleV0pIHJlc3VsdFtrZXldID0gW107XG4gICAgICAgICAgcmVzdWx0W2tleV0ucHVzaChiYXRjaFtqXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9KSgpO1xufVxuXG4vKipcbiAqIFJlZHVjZXMgYW4gYXJyYXkgaW4gYmF0Y2hlcyB0byBhdm9pZCBibG9ja2luZyB0aGUgZXZlbnQgbG9vcC5cbiAqIFByb2Nlc3NlcyBpdGVtcyBpbiBjaHVua3MgYW5kIHlpZWxkcyBjb250cm9sIGJhY2sgdG8gdGhlIGV2ZW50IGxvb3AgYmV0d2VlbiBiYXRjaGVzXG4gKiB3aGVuIHRoZSBwcm9jZXNzaW5nIHRpbWUgZXhjZWVkcyB0aGUgdGhyZXNob2xkLiBTZXF1ZW50aWFsIHByb2Nlc3NpbmcgaXMgYWx3YXlzIHVzZWQgZm9yIHRoZSByZWR1Y2VyIGZ1bmN0aW9uLFxuICogaXJyZXNwZWN0aXZlIG9mIHRoZSBgc2VxdWVudGlhbFByb2Nlc3NpbmdgIG9wdGlvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGl0ZW1zIGluIHRoZSBhcnJheVxuICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgYWNjdW11bGF0b3IvcmVzdWx0XG4gKiBAcGFyYW0gaXRlbXMgLSBUaGUgYXJyYXkgdG8gcmVkdWNlXG4gKiBAcGFyYW0gcmVkdWNlciAtIFRoZSByZWR1Y2VyIGZ1bmN0aW9uLiBSZWNlaXZlcyB0aGUgYWNjdW11bGF0b3IsIGN1cnJlbnQgaXRlbSwgYW5kIGluZGV4LlxuICogQHBhcmFtIGluaXRpYWxWYWx1ZSAtIFRoZSBpbml0aWFsIHZhbHVlIGZvciB0aGUgYWNjdW11bGF0b3JcbiAqIEBwYXJhbSBvcHRpb25zIC0gQmF0Y2ggcHJvY2Vzc2luZyBvcHRpb25zXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcmVkdWNlZCB2YWx1ZVxuICogQHRocm93cyB7RXJyb3J9IFdoZW4gYmF0Y2hTaXplIGlzIG5vdCBhIHBvc2l0aXZlIGludGVnZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gU3VtIG51bWJlcnMgd2l0aCBkZWZhdWx0IG9wdGlvbnNcbiAqIGNvbnN0IHN1bSA9IGF3YWl0IHJlZHVjZUluQmF0Y2hlcyhbMSwgMiwgMywgNF0sIChhY2MsIHgpID0+IGFjYyArIHgsIDApO1xuICogLy8gUmVzdWx0OiAxMFxuICpcbiAqIC8vIFdpdGggY3VzdG9tIGJhdGNoIHNpemVcbiAqIGNvbnN0IHN1bSA9IGF3YWl0IHJlZHVjZUluQmF0Y2hlcyhbMSwgMiwgMywgNF0sIChhY2MsIHgpID0+IGFjYyArIHgsIDAsIHsgYmF0Y2hTaXplOiAyIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWR1Y2VJbkJhdGNoZXM8VCwgUj4oXG4gIGl0ZW1zOiBUW10sXG4gIHJlZHVjZXI6IChhY2M6IFIsIGl0ZW06IFQsIGluZGV4OiBudW1iZXIpID0+IFIgfCBQcm9taXNlPFI+LFxuICBpbml0aWFsVmFsdWU6IFIsXG4gIG9wdGlvbnM/OiBCYXRjaFByb2Nlc3NpbmdPcHRpb25zLFxuKTogUHJvbWlzZTxSPiB7XG4gIGNvbnN0IG9wdHMgPSBnZXRPcHRpb25zKG9wdGlvbnMpO1xuXG4gIHJldHVybiAoYXN5bmMgKCkgPT4ge1xuICAgIGxldCBhY2MgPSBpbml0aWFsVmFsdWU7XG4gICAgYXdhaXQgcHJvY2Vzc0luQmF0Y2hlcyhpdGVtcywgb3B0cywgYXN5bmMgKGJhdGNoLCBiYXRjaFN0YXJ0KSA9PiB7XG4gICAgICAvLyBBbHdheXMgc2VxdWVudGlhbCwgcmVnYXJkbGVzcyBvZiBzZXF1ZW50aWFsUHJvY2Vzc2luZyBvcHRpb25cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYmF0Y2gubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3AgLS0gc2VxdWVudGlhbCBwcm9jZXNzaW5nIGlzIHJlcXVpcmVkXG4gICAgICAgIGFjYyA9IGF3YWl0IHJlZHVjZXIoYWNjLCBiYXRjaFtqXSwgYmF0Y2hTdGFydCArIGopO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBhY2M7XG4gIH0pKCk7XG59XG5cbi8qKlxuICogRmxhdE1hcHMgYW4gYXJyYXkgaW4gYmF0Y2hlcyB0byBhdm9pZCBibG9ja2luZyB0aGUgZXZlbnQgbG9vcC5cbiAqIFByb2Nlc3NlcyBpdGVtcyBpbiBjaHVua3MsIGZsYXR0ZW5zIHRoZSByZXN1bHRzLCBhbmQgeWllbGRzIGNvbnRyb2wgYmFjayB0byB0aGUgZXZlbnQgbG9vcCBiZXR3ZWVuIGJhdGNoZXNcbiAqIHdoZW4gdGhlIHByb2Nlc3NpbmcgdGltZSBleGNlZWRzIHRoZSB0aHJlc2hvbGQuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiBpdGVtcyBpbiB0aGUgaW5wdXQgYXJyYXlcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHR5cGUgb2YgaXRlbXMgaW4gdGhlIGZsYXR0ZW5lZCByZXN1bHQgYXJyYXlcbiAqIEBwYXJhbSBpdGVtcyAtIFRoZSBhcnJheSB0byBmbGF0TWFwIG92ZXJcbiAqIEBwYXJhbSBtYXBGbiAtIFRoZSBtYXBwaW5nIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhbiBhcnJheSBmb3IgZWFjaCBpdGVtLiBSZWNlaXZlcyB0aGUgaXRlbSBhbmQgaXRzIGluZGV4LlxuICogQHBhcmFtIG9wdGlvbnMgLSBCYXRjaCBwcm9jZXNzaW5nIG9wdGlvbnNcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBmbGF0dGVuZWQgbWFwcGVkIGFycmF5XG4gKiBAdGhyb3dzIHtFcnJvcn0gV2hlbiBiYXRjaFNpemUgaXMgbm90IGEgcG9zaXRpdmUgaW50ZWdlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBEdXBsaWNhdGUgZWFjaCBpdGVtIHdpdGggZGVmYXVsdCBvcHRpb25zXG4gKiBjb25zdCBkdXBsaWNhdGVkID0gYXdhaXQgZmxhdE1hcEluQmF0Y2hlcyhbMSwgMiwgM10sICh4KSA9PiBbeCwgeF0pO1xuICogLy8gUmVzdWx0OiBbMSwgMSwgMiwgMiwgMywgM11cbiAqXG4gKiAvLyBXaXRoIGN1c3RvbSBiYXRjaCBzaXplXG4gKiBjb25zdCBkdXBsaWNhdGVkID0gYXdhaXQgZmxhdE1hcEluQmF0Y2hlcyhbMSwgMiwgM10sICh4KSA9PiBbeCwgeF0sIHsgYmF0Y2hTaXplOiAyIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0TWFwSW5CYXRjaGVzPFQsIFI+KFxuICBpdGVtczogVFtdLFxuICBtYXBGbjogKGl0ZW06IFQsIGluZGV4OiBudW1iZXIpID0+IFJbXSB8IFByb21pc2U8UltdPixcbiAgb3B0aW9ucz86IEJhdGNoUHJvY2Vzc2luZ09wdGlvbnMsXG4pOiBQcm9taXNlPFJbXT4ge1xuICBjb25zdCBvcHRzID0gZ2V0T3B0aW9ucyhvcHRpb25zKTtcblxuICByZXR1cm4gKGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQ6IFJbXSA9IFtdO1xuICAgIGF3YWl0IHByb2Nlc3NJbkJhdGNoZXMoaXRlbXMsIG9wdHMsIGFzeW5jIChiYXRjaCwgYmF0Y2hTdGFydCkgPT4ge1xuICAgICAgaWYgKG9wdHMuc2VxdWVudGlhbFByb2Nlc3NpbmcpIHtcbiAgICAgICAgLy8gUHJvY2VzcyBpdGVtcyBzZXF1ZW50aWFsbHlcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBiYXRjaC5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wIC0tIHNlcXVlbnRpYWwgcHJvY2Vzc2luZyBpcyByZXF1aXJlZFxuICAgICAgICAgIGNvbnN0IG1hcHBlZCA9IGF3YWl0IG1hcEZuKGJhdGNoW2pdLCBiYXRjaFN0YXJ0ICsgaik7XG4gICAgICAgICAgcmVzdWx0LnB1c2goLi4ubWFwcGVkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUHJvY2VzcyBpdGVtcyBjb25jdXJyZW50bHlcbiAgICAgICAgY29uc3QgbWFwcGVkID0gYXdhaXQgUHJvbWlzZS5hbGwoYmF0Y2gubWFwKChpdGVtLCBqKSA9PiBtYXBGbihpdGVtLCBiYXRjaFN0YXJ0ICsgaikpKTtcbiAgICAgICAgbWFwcGVkLmZvckVhY2goKGFycikgPT4ge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKC4uLmFycik7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0pKCk7XG59XG5cbi8qKlxuICogZm9yRWFjaCBvdmVyIGFuIGFycmF5IGluIGJhdGNoZXMgdG8gYXZvaWQgYmxvY2tpbmcgdGhlIGV2ZW50IGxvb3AuXG4gKiBQcm9jZXNzZXMgaXRlbXMgaW4gY2h1bmtzIGFuZCB5aWVsZHMgY29udHJvbCBiYWNrIHRvIHRoZSBldmVudCBsb29wIGJldHdlZW4gYmF0Y2hlc1xuICogd2hlbiB0aGUgcHJvY2Vzc2luZyB0aW1lIGV4Y2VlZHMgdGhlIHRocmVzaG9sZC5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIGl0ZW1zIGluIHRoZSBpbnB1dCBhcnJheVxuICogQHBhcmFtIGl0ZW1zIC0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtIGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbS4gUmVjZWl2ZXMgdGhlIGl0ZW0gYW5kIGl0cyBpbmRleC4gQ2FuIGJlIGFzeW5jLlxuICogQHBhcmFtIG9wdGlvbnMgLSBCYXRjaCBwcm9jZXNzaW5nIG9wdGlvbnNcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIGl0ZW1zIGhhdmUgYmVlbiBwcm9jZXNzZWRcbiAqIEB0aHJvd3Mge0Vycm9yfSBXaGVuIGJhdGNoU2l6ZSBpcyBub3QgYSBwb3NpdGl2ZSBpbnRlZ2VyXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIFByb2Nlc3MgaXRlbXMgaW4gYmF0Y2hlcyB3aXRoIGRlZmF1bHQgb3B0aW9uc1xuICogYXdhaXQgZm9yRWFjaEluQmF0Y2hlcyhbMSwgMiwgMywgNF0sIGFzeW5jICh4KSA9PiB7XG4gKiAgIGF3YWl0IGRvU29tZXRoaW5nKHgpO1xuICogfSk7XG4gKlxuICogLy8gV2l0aCBjdXN0b20gYmF0Y2ggc2l6ZVxuICogYXdhaXQgZm9yRWFjaEluQmF0Y2hlcyhbMSwgMiwgMywgNF0sIGFzeW5jICh4KSA9PiB7XG4gKiAgIGF3YWl0IGRvU29tZXRoaW5nKHgpO1xuICogfSwgeyBiYXRjaFNpemU6IDIgfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvckVhY2hJbkJhdGNoZXM8VD4oXG4gIGl0ZW1zOiBUW10sXG4gIGZuOiAoaXRlbTogVCwgaW5kZXg6IG51bWJlcikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD4sXG4gIG9wdGlvbnM/OiBCYXRjaFByb2Nlc3NpbmdPcHRpb25zLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IG9wdHMgPSBnZXRPcHRpb25zKG9wdGlvbnMpO1xuXG4gIHJldHVybiBwcm9jZXNzSW5CYXRjaGVzKGl0ZW1zLCBvcHRzLCBhc3luYyAoYmF0Y2gsIGJhdGNoU3RhcnQpID0+IHtcbiAgICBpZiAob3B0cy5zZXF1ZW50aWFsUHJvY2Vzc2luZykge1xuICAgICAgLy8gUHJvY2VzcyBpdGVtcyBzZXF1ZW50aWFsbHlcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYmF0Y2gubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3AgLS0gc2VxdWVudGlhbCBwcm9jZXNzaW5nIGlzIHJlcXVpcmVkXG4gICAgICAgIGF3YWl0IGZuKGJhdGNoW2pdLCBiYXRjaFN0YXJ0ICsgaik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFByb2Nlc3MgaXRlbXMgY29uY3VycmVudGx5XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChiYXRjaC5tYXAoKGl0ZW0sIGopID0+IGZuKGl0ZW0sIGJhdGNoU3RhcnQgKyBqKSkpO1xuICAgIH1cbiAgfSk7XG59XG4iXX0=
|
package/build/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC"}
|
package/build/utils/index.js
CHANGED
|
@@ -14,9 +14,10 @@ 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("./batch-processing"), exports);
|
|
17
18
|
__exportStar(require("./json-schema-generator"), exports);
|
|
18
19
|
__exportStar(require("./misc"), exports);
|
|
19
20
|
__exportStar(require("./request"), exports);
|
|
20
21
|
__exportStar(require("./tests"), exports);
|
|
21
22
|
__exportStar(require("./zod"), exports);
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFEQUFtQztBQUNuQywwREFBd0M7QUFDeEMseUNBQXVCO0FBQ3ZCLDRDQUEwQjtBQUMxQiwwQ0FBd0I7QUFDeEIsd0NBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9iYXRjaC1wcm9jZXNzaW5nJztcbmV4cG9ydCAqIGZyb20gJy4vanNvbi1zY2hlbWEtZ2VuZXJhdG9yJztcbmV4cG9ydCAqIGZyb20gJy4vbWlzYyc7XG5leHBvcnQgKiBmcm9tICcuL3JlcXVlc3QnO1xuZXhwb3J0ICogZnJvbSAnLi90ZXN0cyc7XG5leHBvcnQgKiBmcm9tICcuL3pvZCc7XG4iXX0=
|