@mikeyt23/node-cli-utils 2.0.10 → 2.0.12
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/LICENSE +6 -6
- package/README.md +1 -0
- package/dist/cjs/certUtils.js +22 -22
- package/dist/cjs/dbMigrationUtils.js +21 -21
- package/dist/cjs/generalUtils.d.ts +37 -1
- package/dist/cjs/generalUtils.d.ts.map +1 -1
- package/dist/cjs/generalUtils.js +52 -2
- package/dist/cjs/generalUtilsInternal.d.ts.map +1 -1
- package/dist/cjs/generalUtilsInternal.js +5 -2
- package/dist/cjs/package.json +5 -5
- package/dist/cjs/parallel.d.ts +118 -0
- package/dist/cjs/parallel.d.ts.map +1 -0
- package/dist/cjs/parallel.js +228 -0
- package/dist/esm/certUtils.js +22 -22
- package/dist/esm/dbMigrationUtils.js +21 -21
- package/dist/esm/generalUtils.d.ts +37 -1
- package/dist/esm/generalUtils.d.ts.map +1 -1
- package/dist/esm/generalUtils.js +49 -1
- package/dist/esm/generalUtilsInternal.d.ts.map +1 -1
- package/dist/esm/generalUtilsInternal.js +5 -2
- package/dist/esm/parallel.d.ts +118 -0
- package/dist/esm/parallel.d.ts.map +1 -0
- package/dist/esm/parallel.js +222 -0
- package/package.json +11 -1
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { Emoji, log, trace } from './generalUtils.js';
|
|
2
|
+
import { cyan } from './colors.js';
|
|
3
|
+
/**
|
|
4
|
+
* A type guard useful for filtering results of `Promise.allSettled`.
|
|
5
|
+
* @example
|
|
6
|
+
* ```
|
|
7
|
+
* const settledPromises = await Promise.allSettled(promises)
|
|
8
|
+
* settledPromises.filter(isSettledRejected).map(r => r.reason)
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export const isSettledRejected = (input) => input.status === 'rejected';
|
|
12
|
+
/**
|
|
13
|
+
* A type guard useful for filtering results of `Promise.allSettled`.
|
|
14
|
+
* @example
|
|
15
|
+
* ```
|
|
16
|
+
* const settledPromises = await Promise.allSettled(promises)
|
|
17
|
+
* settledPromises.filter(isSettledFulfilled).map(r => r.value)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const isSettledFulfilled = (input) => input.status === 'fulfilled';
|
|
21
|
+
/**
|
|
22
|
+
* The result of {@link runParallel}.
|
|
23
|
+
*/
|
|
24
|
+
export class ParallelResult {
|
|
25
|
+
allItemResults;
|
|
26
|
+
onlyFirstN;
|
|
27
|
+
constructor(allItemResults, onlyFirstN) {
|
|
28
|
+
this.allItemResults = allItemResults;
|
|
29
|
+
this.onlyFirstN = onlyFirstN;
|
|
30
|
+
}
|
|
31
|
+
get successfulItemResults() {
|
|
32
|
+
return this.allItemResults.filter(r => r.success);
|
|
33
|
+
}
|
|
34
|
+
get allInputItems() {
|
|
35
|
+
return this.allItemResults.map(r => r.inputItem);
|
|
36
|
+
}
|
|
37
|
+
get allOutputResults() {
|
|
38
|
+
return this.allItemResults.filter(r => r.outputResult !== undefined).map(r => r.outputResult);
|
|
39
|
+
}
|
|
40
|
+
/** Does not include skipped items. */
|
|
41
|
+
get failedItemResults() {
|
|
42
|
+
return this.allItemResults.filter(r => !r.success && !r.skipped);
|
|
43
|
+
}
|
|
44
|
+
get skippedItemResults() {
|
|
45
|
+
return this.allItemResults.filter(r => r.skipped);
|
|
46
|
+
}
|
|
47
|
+
get rejectedItemResults() {
|
|
48
|
+
return this.allItemResults.filter(r => r.rejectedReason);
|
|
49
|
+
}
|
|
50
|
+
get numSuccessful() {
|
|
51
|
+
return this.successfulItemResults.length;
|
|
52
|
+
}
|
|
53
|
+
/** Note that this does not include promise rejections (see {@link numRejected}) or skipped items (see {@link numSkipped}). */
|
|
54
|
+
get numFailed() {
|
|
55
|
+
return this.failedItemResults.length;
|
|
56
|
+
}
|
|
57
|
+
/** Note that this does not include successful promises with failure results - see {@link numFailed}. */
|
|
58
|
+
get numRejected() {
|
|
59
|
+
return this.rejectedItemResults.length;
|
|
60
|
+
}
|
|
61
|
+
get numSkipped() {
|
|
62
|
+
return this.skippedItemResults.length;
|
|
63
|
+
}
|
|
64
|
+
get numTotalItems() {
|
|
65
|
+
return this.allItemResults.length;
|
|
66
|
+
}
|
|
67
|
+
/** Does not consider skipped items - only promise rejections and evaluated failures. */
|
|
68
|
+
get noFailures() {
|
|
69
|
+
return this.numFailed === 0 && this.numRejected === 0;
|
|
70
|
+
}
|
|
71
|
+
logFinishedMessage() {
|
|
72
|
+
const divider = '---';
|
|
73
|
+
const onlyFirstNMessage = this.onlyFirstN !== undefined ? ` (onlyFirstN set to ${this.onlyFirstN})` : '';
|
|
74
|
+
log(`${this.noFailures ? Emoji.GreenCheck : Emoji.Warning} ${cyan('runParallel')} completed - ${this.numTotalItems - this.numSkipped} items processed${onlyFirstNMessage}`);
|
|
75
|
+
if (this.numSkipped > 0) {
|
|
76
|
+
log(`${Emoji.Info} skipped ${this.numSkipped}`);
|
|
77
|
+
}
|
|
78
|
+
if (this.numRejected > 0) {
|
|
79
|
+
log(`${Emoji.Stop} Warning: some calls were rejected instead of returning a result`);
|
|
80
|
+
log(divider);
|
|
81
|
+
for (const rejected of this.rejectedItemResults) {
|
|
82
|
+
log('item: ', rejected.inputItem);
|
|
83
|
+
log('reason: ', rejected.rejectedReason);
|
|
84
|
+
log(divider);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (this.numFailed > 0) {
|
|
88
|
+
log(`${Emoji.Warning} Number of failed results: ${this.numFailed}`);
|
|
89
|
+
log(divider);
|
|
90
|
+
for (const failed of this.failedItemResults) {
|
|
91
|
+
log('item: ', failed.inputItem);
|
|
92
|
+
log('output: ', failed.outputResult);
|
|
93
|
+
log(divider);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Run an operation against an array of items.
|
|
100
|
+
* @template OutputType The output type of each call to `operationFunc`.
|
|
101
|
+
* @template InputType The input type for each item in the `itemsToOperateOn` array.
|
|
102
|
+
* @param itemsToOperateOn The array of items of type `InputType` to operate on.
|
|
103
|
+
* @param executorFunc The async function to call on each item in `itemsToOperateOn` - should return type `OutputType`.
|
|
104
|
+
* @param isResultSuccessFunc The boolean returning function to evaluate whether each item of type `OutputType` returned should be considered successful.
|
|
105
|
+
* @param skipCheckFunc An optional boolean async function to determine whether each item of type `InputType` should be operated on.
|
|
106
|
+
* @param onlyFirstN Optional. Stop after this number of items processed.
|
|
107
|
+
* @returns A {@link ParallelResult}
|
|
108
|
+
*/
|
|
109
|
+
export async function runParallel(itemsToOperateOn, executorFunc, isResultSuccessFunc, options) {
|
|
110
|
+
const defaultOptions = { maxConcurrent: 10 };
|
|
111
|
+
const mergedOptions = { ...defaultOptions, ...options };
|
|
112
|
+
const parallel = new ParallelExecutor(mergedOptions.maxConcurrent);
|
|
113
|
+
const skippedItemResults = [];
|
|
114
|
+
let i = 0;
|
|
115
|
+
for (const item of itemsToOperateOn) {
|
|
116
|
+
if (mergedOptions.onlyFirstN !== undefined && i >= mergedOptions.onlyFirstN) {
|
|
117
|
+
trace(`stopping because 'onlyFirstN' param was passed with the value ${mergedOptions.onlyFirstN}`);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
i++;
|
|
121
|
+
if (mergedOptions.shouldSkipFunc !== undefined && await mergedOptions.shouldSkipFunc(item)) {
|
|
122
|
+
trace(`skipped item: `, item);
|
|
123
|
+
skippedItemResults.push({ inputItem: item, skipped: true, success: false });
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
parallel.queueTask(item, executorFunc);
|
|
127
|
+
}
|
|
128
|
+
const promiseResults = await parallel.processQueue();
|
|
129
|
+
const itemResults = promiseResults.filter(isSettledFulfilled).map(r => r.value);
|
|
130
|
+
const promiseRejections = promiseResults.filter(isSettledRejected).map(r => r.reason);
|
|
131
|
+
if (promiseRejections.length > 0) {
|
|
132
|
+
log('---');
|
|
133
|
+
log(`${Emoji.Exclamation} Warning: control flow functions that should normally not fail had promise rejections`);
|
|
134
|
+
for (const reject of promiseRejections) {
|
|
135
|
+
log(reject);
|
|
136
|
+
log('---');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
for (const itemResult of itemResults) {
|
|
140
|
+
itemResult.success = itemResult.rejectedReason === undefined
|
|
141
|
+
&& itemResult.outputResult !== undefined
|
|
142
|
+
&& isResultSuccessFunc(itemResult.outputResult);
|
|
143
|
+
}
|
|
144
|
+
const parallelResult = new ParallelResult([...itemResults, ...skippedItemResults]);
|
|
145
|
+
return parallelResult;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* This class simulates a semaphore, running as many of the tasks simultaneously as possible while staying under the limit of the value passed for `maxConcurrent`.
|
|
149
|
+
*
|
|
150
|
+
* Note that NodeJS is single-threaded, so this is more about prevention of overwhelming I/O systems and external services than it is about true parallel execution.
|
|
151
|
+
*/
|
|
152
|
+
export class ParallelExecutor {
|
|
153
|
+
maxConcurrent = 0;
|
|
154
|
+
numExecuting = 0;
|
|
155
|
+
queue = [];
|
|
156
|
+
operationPromises = [];
|
|
157
|
+
taskCompletePromises = [];
|
|
158
|
+
constructor(maxConcurrent) {
|
|
159
|
+
if (maxConcurrent <= 0) {
|
|
160
|
+
throw new Error('Invalid value passed for maxConcurrent - must be greater than 0');
|
|
161
|
+
}
|
|
162
|
+
this.maxConcurrent = maxConcurrent;
|
|
163
|
+
}
|
|
164
|
+
queueTask(item, operationFunc) {
|
|
165
|
+
let completionResolver;
|
|
166
|
+
const completionPromise = new Promise((resolve) => {
|
|
167
|
+
completionResolver = resolve;
|
|
168
|
+
});
|
|
169
|
+
this.taskCompletePromises.push(completionPromise);
|
|
170
|
+
const operationWrapper = async () => {
|
|
171
|
+
return new Promise(resolve => {
|
|
172
|
+
operationFunc(item)
|
|
173
|
+
.then(output => {
|
|
174
|
+
resolve({
|
|
175
|
+
inputItem: item,
|
|
176
|
+
skipped: false,
|
|
177
|
+
success: true,
|
|
178
|
+
rejectedReason: undefined,
|
|
179
|
+
outputResult: output
|
|
180
|
+
});
|
|
181
|
+
})
|
|
182
|
+
.catch(err => {
|
|
183
|
+
resolve({
|
|
184
|
+
inputItem: item,
|
|
185
|
+
skipped: false,
|
|
186
|
+
success: false,
|
|
187
|
+
rejectedReason: err,
|
|
188
|
+
outputResult: undefined
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
const parallelTask = () => {
|
|
194
|
+
trace(`Task called - queue.length: ${this.queue.length} - numExecuting: ${this.numExecuting}`);
|
|
195
|
+
this.numExecuting++;
|
|
196
|
+
const promise = operationWrapper();
|
|
197
|
+
this.operationPromises.push(promise);
|
|
198
|
+
promise.finally(() => {
|
|
199
|
+
this.release(completionResolver);
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
this.queue.push(parallelTask);
|
|
203
|
+
}
|
|
204
|
+
async processQueue() {
|
|
205
|
+
while (this.queue.length > 0 && this.numExecuting < this.maxConcurrent) {
|
|
206
|
+
const next = this.queue.shift();
|
|
207
|
+
if (next)
|
|
208
|
+
next();
|
|
209
|
+
}
|
|
210
|
+
await Promise.allSettled(this.taskCompletePromises);
|
|
211
|
+
return await Promise.allSettled(this.operationPromises);
|
|
212
|
+
}
|
|
213
|
+
release(completionResolver) {
|
|
214
|
+
trace(`Task released - queue.length: ${this.queue.length} - numExecuting: ${this.numExecuting}`);
|
|
215
|
+
this.numExecuting--;
|
|
216
|
+
completionResolver();
|
|
217
|
+
const next = this.queue.shift();
|
|
218
|
+
if (next)
|
|
219
|
+
next();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYWxsZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyYWxsZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDckQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUVsQzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxLQUFvQyxFQUFrQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxVQUFVLENBQUE7QUFDdEk7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUksS0FBOEIsRUFBc0MsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssV0FBVyxDQUFBO0FBcUJ6STs7R0FFRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBQ2hCLGNBQWMsQ0FBNkM7SUFDM0QsVUFBVSxDQUFTO0lBRTVCLFlBQVksY0FBMkQsRUFBRSxVQUFtQjtRQUMxRixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQTtRQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtJQUM5QixDQUFDO0lBRUQsSUFBSSxxQkFBcUI7UUFDdkIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUNuRCxDQUFDO0lBQ0QsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBQ0QsSUFBSSxnQkFBZ0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxD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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikeyt23/node-cli-utils",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.12",
|
|
4
4
|
"description": "Some node cli utility functions",
|
|
5
5
|
"author": "Mike Thompson",
|
|
6
6
|
"license": "MIT",
|
|
@@ -95,6 +95,16 @@
|
|
|
95
95
|
"default": "./dist/cjs/hostFileUtils.js"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
|
+
"./parallel": {
|
|
99
|
+
"import": {
|
|
100
|
+
"types": "./dist/esm/parallel.d.ts",
|
|
101
|
+
"default": "./dist/esm/parallel.js"
|
|
102
|
+
},
|
|
103
|
+
"require": {
|
|
104
|
+
"types": "./dist/cjs/parallel.d.ts",
|
|
105
|
+
"default": "./dist/cjs/parallel.js"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
98
108
|
"./testUtils": {
|
|
99
109
|
"import": {
|
|
100
110
|
"types": "./dist/esm/testUtils.d.ts",
|