@ls-stack/utils 3.22.0 → 3.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/concurrentCalls/-internal-.md +28 -26
- package/docs/concurrentCalls/README.md +2 -2
- package/docs/testUtils.md +27 -3
- package/docs/yamlStringify.md +53 -15
- package/lib/chunk-JAPKLFIK.js +353 -0
- package/lib/concurrentCalls.cjs +18 -34
- package/lib/concurrentCalls.d.cts +3 -3
- package/lib/concurrentCalls.d.ts +3 -3
- package/lib/concurrentCalls.js +22 -36
- package/lib/testUtils.cjs +538 -0
- package/lib/testUtils.d.cts +16 -1
- package/lib/testUtils.d.ts +16 -1
- package/lib/testUtils.js +172 -1
- package/lib/yamlStringify.cjs +83 -30
- package/lib/yamlStringify.d.cts +5 -3
- package/lib/yamlStringify.d.ts +5 -3
- package/lib/yamlStringify.js +4 -291
- package/package.json +1 -1
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bytesToHumanReadable
|
|
3
|
+
} from "./chunk-IATIXMCE.js";
|
|
4
|
+
import {
|
|
5
|
+
truncateString
|
|
6
|
+
} from "./chunk-4REIIZQY.js";
|
|
7
|
+
import {
|
|
8
|
+
isObject,
|
|
9
|
+
isPlainObject
|
|
10
|
+
} from "./chunk-JF2MDHOJ.js";
|
|
11
|
+
|
|
12
|
+
// src/yamlStringify.ts
|
|
13
|
+
function yamlStringify(obj, {
|
|
14
|
+
maxLineLength = 100,
|
|
15
|
+
showUndefined,
|
|
16
|
+
maxDepth = 50,
|
|
17
|
+
collapseObjects = false,
|
|
18
|
+
addRootObjSpaces = "beforeAndAfter"
|
|
19
|
+
} = {}) {
|
|
20
|
+
if (isObject(obj) || Array.isArray(obj) || typeof obj === "function") {
|
|
21
|
+
return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces)}
|
|
22
|
+
`;
|
|
23
|
+
}
|
|
24
|
+
return JSON.stringify(obj) || "undefined";
|
|
25
|
+
}
|
|
26
|
+
function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces) {
|
|
27
|
+
let result = "";
|
|
28
|
+
const childIndent = `${indent} `;
|
|
29
|
+
if (isPlainObject(value)) {
|
|
30
|
+
if (Object.keys(value).length === 0) {
|
|
31
|
+
return "{}";
|
|
32
|
+
}
|
|
33
|
+
if (collapseObjects && depth > 0) {
|
|
34
|
+
const entries = Object.entries(value).filter(
|
|
35
|
+
([, val]) => val !== void 0 || showUndefined
|
|
36
|
+
);
|
|
37
|
+
const isSimpleObject = entries.every(
|
|
38
|
+
([, val]) => {
|
|
39
|
+
if (typeof val === "string") {
|
|
40
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
41
|
+
}
|
|
42
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
if (isSimpleObject && entries.length > 0) {
|
|
46
|
+
let line = "{ ";
|
|
47
|
+
line += entries.map(([key, val]) => {
|
|
48
|
+
let valueStr;
|
|
49
|
+
if (typeof val === "string") {
|
|
50
|
+
if (val.includes("'") && !val.includes('"')) {
|
|
51
|
+
valueStr = `"${val}"`;
|
|
52
|
+
} else if (val.includes('"') && !val.includes("'")) {
|
|
53
|
+
valueStr = `'${val}'`;
|
|
54
|
+
} else if (val.includes("'") && val.includes('"')) {
|
|
55
|
+
valueStr = `"${val.replace(/"/g, '\\"')}"`;
|
|
56
|
+
} else {
|
|
57
|
+
valueStr = `'${val}'`;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
valueStr = String(val);
|
|
61
|
+
}
|
|
62
|
+
return `${key}: ${valueStr}`;
|
|
63
|
+
}).join(", ");
|
|
64
|
+
line += " }";
|
|
65
|
+
if (line.length <= maxLineLength) {
|
|
66
|
+
return line;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let prevValue;
|
|
71
|
+
let afterSpaceWasAdded = false;
|
|
72
|
+
for (let [key, objVal] of Object.entries(value)) {
|
|
73
|
+
if (objVal === void 0 && !showUndefined) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (depth > maxDepth) {
|
|
77
|
+
objVal = `{max depth reached}`;
|
|
78
|
+
}
|
|
79
|
+
const normalizedValue2 = normalizeValue(objVal);
|
|
80
|
+
if (normalizedValue2 !== null) {
|
|
81
|
+
objVal = normalizedValue2[1];
|
|
82
|
+
key = `${key}{${normalizedValue2[0]}}`;
|
|
83
|
+
}
|
|
84
|
+
const valueString = stringifyValue(
|
|
85
|
+
objVal,
|
|
86
|
+
childIndent,
|
|
87
|
+
maxLineLength,
|
|
88
|
+
showUndefined,
|
|
89
|
+
maxDepth,
|
|
90
|
+
depth + 1,
|
|
91
|
+
collapseObjects,
|
|
92
|
+
addObjSpaces
|
|
93
|
+
);
|
|
94
|
+
const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 && Object.entries(objVal).filter(([, val]) => val !== void 0 || showUndefined).every(([, val]) => {
|
|
95
|
+
if (typeof val === "string") {
|
|
96
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
97
|
+
}
|
|
98
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
99
|
+
}));
|
|
100
|
+
const prevWasCollapsed = prevValue && isObject(prevValue) && (Object.keys(prevValue).length === 0 || collapseObjects && depth + 1 > 0 && Object.entries(prevValue).filter(([, val]) => val !== void 0 || showUndefined).every(([, val]) => {
|
|
101
|
+
if (typeof val === "string") {
|
|
102
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
103
|
+
}
|
|
104
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
105
|
+
}));
|
|
106
|
+
if (!afterSpaceWasAdded && indent === "" && isObject(objVal) && !willBeCollapsed && prevValue && !prevWasCollapsed && (addObjSpaces === "before" || addObjSpaces === "beforeAndAfter")) {
|
|
107
|
+
result += "\n";
|
|
108
|
+
}
|
|
109
|
+
if (Array.isArray(objVal)) {
|
|
110
|
+
const arrayIsSingleLine = valueString.split("\n").length === 1;
|
|
111
|
+
if (arrayIsSingleLine && !valueString.trim().startsWith("-")) {
|
|
112
|
+
result += `${indent}${key}: `;
|
|
113
|
+
} else {
|
|
114
|
+
result += `${indent}${key}:
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
} else if (isObject(objVal)) {
|
|
118
|
+
const isCollapsedObject = valueString.startsWith("{") && !valueString.includes("\n");
|
|
119
|
+
if (Object.keys(objVal).length === 0 || isCollapsedObject) {
|
|
120
|
+
result += `${indent}${key}: `;
|
|
121
|
+
} else {
|
|
122
|
+
result += `${indent}${key}:
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
result += `${indent}${key}: `;
|
|
127
|
+
}
|
|
128
|
+
result += valueString;
|
|
129
|
+
result += "\n";
|
|
130
|
+
if (indent === "") {
|
|
131
|
+
const isCollapsedObject = valueString.startsWith("{") && !valueString.includes("\n") && valueString.length > 2;
|
|
132
|
+
if (isObject(objVal) && !isCollapsedObject) {
|
|
133
|
+
if (addObjSpaces === "after" || addObjSpaces === "beforeAndAfter") {
|
|
134
|
+
result += "\n";
|
|
135
|
+
afterSpaceWasAdded = true;
|
|
136
|
+
} else {
|
|
137
|
+
afterSpaceWasAdded = false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
prevValue = objVal;
|
|
142
|
+
}
|
|
143
|
+
return result.trimEnd();
|
|
144
|
+
}
|
|
145
|
+
if (Array.isArray(value)) {
|
|
146
|
+
let arrayWasAdded = false;
|
|
147
|
+
if (value.length === 0 || value.every(
|
|
148
|
+
(item) => typeof item === "string" || typeof item === "number" || typeof item === "boolean" || item === null || item === void 0
|
|
149
|
+
)) {
|
|
150
|
+
let line = "";
|
|
151
|
+
line += `[`;
|
|
152
|
+
line += value.map((item) => {
|
|
153
|
+
let valueToUse = item;
|
|
154
|
+
if (depth > maxDepth) {
|
|
155
|
+
valueToUse = `{max depth reached}`;
|
|
156
|
+
}
|
|
157
|
+
if (typeof valueToUse === "string" && valueToUse.includes("\n")) {
|
|
158
|
+
valueToUse = valueToUse.replace(/\n/g, "\\n");
|
|
159
|
+
}
|
|
160
|
+
return stringifyValue(
|
|
161
|
+
valueToUse,
|
|
162
|
+
"",
|
|
163
|
+
maxLineLength,
|
|
164
|
+
showUndefined,
|
|
165
|
+
maxDepth,
|
|
166
|
+
depth + 1,
|
|
167
|
+
collapseObjects,
|
|
168
|
+
addObjSpaces
|
|
169
|
+
);
|
|
170
|
+
}).join(", ");
|
|
171
|
+
line += "]";
|
|
172
|
+
if (line.length <= maxLineLength) {
|
|
173
|
+
result += line;
|
|
174
|
+
arrayWasAdded = true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (!arrayWasAdded) {
|
|
178
|
+
for (let item of value) {
|
|
179
|
+
if (depth > maxDepth) {
|
|
180
|
+
item = `{max depth reached}`;
|
|
181
|
+
}
|
|
182
|
+
result += `${indent}- `;
|
|
183
|
+
if (Array.isArray(item) || isObject(item)) {
|
|
184
|
+
let arrayString = stringifyValue(
|
|
185
|
+
item,
|
|
186
|
+
childIndent,
|
|
187
|
+
maxLineLength,
|
|
188
|
+
showUndefined,
|
|
189
|
+
maxDepth,
|
|
190
|
+
depth + 1,
|
|
191
|
+
collapseObjects,
|
|
192
|
+
addObjSpaces
|
|
193
|
+
);
|
|
194
|
+
arrayString = arrayString.trimStart();
|
|
195
|
+
result += arrayString;
|
|
196
|
+
} else {
|
|
197
|
+
result += stringifyValue(
|
|
198
|
+
item,
|
|
199
|
+
childIndent,
|
|
200
|
+
maxLineLength,
|
|
201
|
+
showUndefined,
|
|
202
|
+
maxDepth,
|
|
203
|
+
depth + 1,
|
|
204
|
+
collapseObjects,
|
|
205
|
+
addObjSpaces
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
result += "\n";
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return result.trimEnd();
|
|
212
|
+
}
|
|
213
|
+
if (typeof value === "string") {
|
|
214
|
+
if (value.includes("\n")) {
|
|
215
|
+
const lines = value.split("\n");
|
|
216
|
+
for (const [i, line] of lines.entries()) {
|
|
217
|
+
if (i === 0) {
|
|
218
|
+
if (value.endsWith("\n")) {
|
|
219
|
+
result += `|`;
|
|
220
|
+
} else {
|
|
221
|
+
result += `|-`;
|
|
222
|
+
}
|
|
223
|
+
result += `
|
|
224
|
+
${indent}${line}
|
|
225
|
+
`;
|
|
226
|
+
} else {
|
|
227
|
+
result += `${indent}${line}
|
|
228
|
+
`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
if (value.includes("'") && !value.includes('"')) {
|
|
233
|
+
result += `"${value}"`;
|
|
234
|
+
} else if (value.includes('"') && !value.includes("'")) {
|
|
235
|
+
result += `'${value}'`;
|
|
236
|
+
} else if (value.includes("'") && value.includes('"')) {
|
|
237
|
+
result += `"${value.replace(/"/g, '\\"')}"`;
|
|
238
|
+
} else {
|
|
239
|
+
result += `'${value}'`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return result.trimEnd();
|
|
243
|
+
}
|
|
244
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) {
|
|
245
|
+
return String(value).trimEnd();
|
|
246
|
+
}
|
|
247
|
+
const normalizedValue = normalizeValue(value);
|
|
248
|
+
if (normalizedValue !== null) {
|
|
249
|
+
return stringifyValue(
|
|
250
|
+
{
|
|
251
|
+
[`${normalizedValue[0]}#`]: normalizedValue[1]
|
|
252
|
+
},
|
|
253
|
+
indent,
|
|
254
|
+
maxLineLength,
|
|
255
|
+
showUndefined,
|
|
256
|
+
maxDepth,
|
|
257
|
+
depth + 1,
|
|
258
|
+
collapseObjects,
|
|
259
|
+
addObjSpaces
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return JSON.stringify(value);
|
|
263
|
+
}
|
|
264
|
+
function normalizeValue(value) {
|
|
265
|
+
if (value === null || isPlainObject(value) || Array.isArray(value)) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
if (value instanceof Map) {
|
|
269
|
+
const mapEntries = Array.from(value.entries());
|
|
270
|
+
let mapValue;
|
|
271
|
+
if (mapEntries.every(([key]) => typeof key === "string")) {
|
|
272
|
+
const mapObjValue = {};
|
|
273
|
+
for (const [key, val] of mapEntries) {
|
|
274
|
+
mapObjValue[key] = val;
|
|
275
|
+
}
|
|
276
|
+
mapValue = mapObjValue;
|
|
277
|
+
} else {
|
|
278
|
+
mapValue = mapEntries.map(([key, val]) => ({
|
|
279
|
+
key,
|
|
280
|
+
value: val
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
return ["Map", mapValue];
|
|
284
|
+
}
|
|
285
|
+
if (value instanceof Set) {
|
|
286
|
+
const setValue = Array.from(value);
|
|
287
|
+
return ["Set", setValue];
|
|
288
|
+
}
|
|
289
|
+
if (value instanceof Date) {
|
|
290
|
+
return ["Date", value.toISOString()];
|
|
291
|
+
}
|
|
292
|
+
if (value instanceof RegExp) {
|
|
293
|
+
return ["RegExp", value.toString()];
|
|
294
|
+
}
|
|
295
|
+
if (value instanceof Error) {
|
|
296
|
+
return [
|
|
297
|
+
"Error",
|
|
298
|
+
{
|
|
299
|
+
message: value.message,
|
|
300
|
+
name: value.name,
|
|
301
|
+
stack: value.stack
|
|
302
|
+
}
|
|
303
|
+
];
|
|
304
|
+
}
|
|
305
|
+
if (value instanceof File) {
|
|
306
|
+
return [
|
|
307
|
+
"File",
|
|
308
|
+
{
|
|
309
|
+
name: value.name,
|
|
310
|
+
type: value.type,
|
|
311
|
+
lastModified: new Date(value.lastModified).toISOString(),
|
|
312
|
+
size: bytesToHumanReadable(value.size)
|
|
313
|
+
}
|
|
314
|
+
];
|
|
315
|
+
}
|
|
316
|
+
if (typeof value === "object") {
|
|
317
|
+
if ("toJSON" in value && typeof value.toJSON === "function") {
|
|
318
|
+
return [value.constructor.name, value.toJSON()];
|
|
319
|
+
}
|
|
320
|
+
if ("toString" in value && typeof value.toString === "function") {
|
|
321
|
+
const stringValue = value.toString();
|
|
322
|
+
if (stringValue.toString() !== "[object Object]") {
|
|
323
|
+
return [value.constructor.name, stringValue];
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const objectValue = { ...value };
|
|
327
|
+
const displayValue = {};
|
|
328
|
+
let addedKeys = 0;
|
|
329
|
+
for (const [key, item] of Object.entries(objectValue)) {
|
|
330
|
+
if (addedKeys > 4) {
|
|
331
|
+
displayValue["...and more properties"] = Object.keys(objectValue).length - 4;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
if (typeof item === "string" || typeof item === "number" || typeof item === "boolean" || item === null || item === void 0) {
|
|
335
|
+
displayValue[key] = item;
|
|
336
|
+
addedKeys++;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return [String(value.constructor.name), displayValue];
|
|
340
|
+
}
|
|
341
|
+
if (typeof value === "function") {
|
|
342
|
+
const functionString = value.toString();
|
|
343
|
+
return [
|
|
344
|
+
`Function`,
|
|
345
|
+
functionString.includes("\n") ? truncateString(functionString.split("\n").join(""), 40) : functionString
|
|
346
|
+
];
|
|
347
|
+
}
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export {
|
|
352
|
+
yamlStringify
|
|
353
|
+
};
|
package/lib/concurrentCalls.cjs
CHANGED
|
@@ -44,7 +44,6 @@ function invariant(condition, error = "Invariant violation") {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
var isFunction2 = isFunction;
|
|
47
|
-
var isPromise2 = isPromise;
|
|
48
47
|
|
|
49
48
|
// src/arrayUtils.ts
|
|
50
49
|
function truncateArray(array, maxLength, appendIfTruncated) {
|
|
@@ -80,23 +79,17 @@ var ConcurrentCalls = class {
|
|
|
80
79
|
}
|
|
81
80
|
resultifyAdd(...calls) {
|
|
82
81
|
const processedCalls = calls.map((call) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} catch (err) {
|
|
93
|
-
return import_t_result.Result.err((0, import_t_result.unknownToError)(err));
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
82
|
+
return async () => {
|
|
83
|
+
try {
|
|
84
|
+
const valueOrPromise = call();
|
|
85
|
+
const value = isPromise(valueOrPromise) ? await valueOrPromise : valueOrPromise;
|
|
86
|
+
return import_t_result.Result.ok(value);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
return import_t_result.Result.err((0, import_t_result.unknownToError)(err));
|
|
89
|
+
}
|
|
90
|
+
};
|
|
97
91
|
});
|
|
98
|
-
|
|
99
|
-
return this.add(...correctlyTypedProcessedCalls);
|
|
92
|
+
return this.add(...processedCalls);
|
|
100
93
|
}
|
|
101
94
|
async runAll({ delayStart } = {}) {
|
|
102
95
|
invariant(!this.#alreadyRun, "Already run");
|
|
@@ -105,15 +98,10 @@ var ConcurrentCalls = class {
|
|
|
105
98
|
const asyncResults = await Promise.all(
|
|
106
99
|
this.#pendingCalls.map(async (fn, i) => {
|
|
107
100
|
try {
|
|
108
|
-
const isP = isPromise2(fn);
|
|
109
101
|
if (delayStart) {
|
|
110
|
-
invariant(
|
|
111
|
-
!isP,
|
|
112
|
-
"Delay start is not supported direct promise calls"
|
|
113
|
-
);
|
|
114
102
|
await sleep(delayStart(i));
|
|
115
103
|
}
|
|
116
|
-
const result = await
|
|
104
|
+
const result = await fn();
|
|
117
105
|
if (!result.ok) throw result.error;
|
|
118
106
|
return result.value;
|
|
119
107
|
} catch (exception) {
|
|
@@ -135,15 +123,10 @@ var ConcurrentCalls = class {
|
|
|
135
123
|
const settledResults = await Promise.allSettled(
|
|
136
124
|
this.#pendingCalls.map(async (callOrPromise, i) => {
|
|
137
125
|
try {
|
|
138
|
-
const isP = isPromise2(callOrPromise);
|
|
139
126
|
if (delayStart) {
|
|
140
|
-
invariant(
|
|
141
|
-
!isP,
|
|
142
|
-
"Delay start is not supported for direct promise calls"
|
|
143
|
-
);
|
|
144
127
|
await sleep(delayStart(i));
|
|
145
128
|
}
|
|
146
|
-
const result = await
|
|
129
|
+
const result = await callOrPromise();
|
|
147
130
|
if (!result.ok) {
|
|
148
131
|
throw result.error;
|
|
149
132
|
}
|
|
@@ -190,9 +173,10 @@ var ConcurrentCallsWithMetadata = class {
|
|
|
190
173
|
}
|
|
191
174
|
resultifyAdd(...items) {
|
|
192
175
|
const processedItems = items.map(({ fn, metadata }) => {
|
|
193
|
-
const cb =
|
|
194
|
-
const
|
|
195
|
-
|
|
176
|
+
const cb = () => (0, import_t_result.resultify)(async () => {
|
|
177
|
+
const valueOrPromise = fn();
|
|
178
|
+
const value = isPromise(valueOrPromise) ? await valueOrPromise : valueOrPromise;
|
|
179
|
+
return value;
|
|
196
180
|
});
|
|
197
181
|
return {
|
|
198
182
|
fn: cb,
|
|
@@ -214,7 +198,7 @@ var ConcurrentCallsWithMetadata = class {
|
|
|
214
198
|
if (delayStart) {
|
|
215
199
|
await sleep(delayStart(i));
|
|
216
200
|
}
|
|
217
|
-
const result = await
|
|
201
|
+
const result = await call.fn();
|
|
218
202
|
if (!result.ok) {
|
|
219
203
|
throw { metadata: call.metadata, error: result.error };
|
|
220
204
|
}
|
|
@@ -261,7 +245,7 @@ var ConcurrentCallsWithMetadata = class {
|
|
|
261
245
|
if (delayStart) {
|
|
262
246
|
await sleep(delayStart(i));
|
|
263
247
|
}
|
|
264
|
-
const result = await
|
|
248
|
+
const result = await call.fn();
|
|
265
249
|
if (!result.ok) {
|
|
266
250
|
throw result.error;
|
|
267
251
|
}
|
|
@@ -12,7 +12,7 @@ type FailedCall<M, E extends Error = Error> = {
|
|
|
12
12
|
metadata: M;
|
|
13
13
|
error: E;
|
|
14
14
|
};
|
|
15
|
-
type Action<R, E extends Error> = (
|
|
15
|
+
type Action<R, E extends Error> = () => Promise<Result<R, E>>;
|
|
16
16
|
type SettledResultWithMetadata<R, M, E extends Error = Error> = {
|
|
17
17
|
ok: true;
|
|
18
18
|
value: R;
|
|
@@ -26,7 +26,7 @@ type SettledResultWithMetadata<R, M, E extends Error = Error> = {
|
|
|
26
26
|
declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
|
|
27
27
|
#private;
|
|
28
28
|
add(...calls: Action<R, E>[]): this;
|
|
29
|
-
resultifyAdd(...calls: (
|
|
29
|
+
resultifyAdd(...calls: ((() => R) | (() => Promise<R>))[]): this;
|
|
30
30
|
runAll({ delayStart }?: RunProps): Promise<Result<R[], E>>;
|
|
31
31
|
runAllSettled({ delayStart }?: RunProps): Promise<{
|
|
32
32
|
allFailed: boolean;
|
|
@@ -50,7 +50,7 @@ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown,
|
|
|
50
50
|
metadata: M;
|
|
51
51
|
}[]): this;
|
|
52
52
|
resultifyAdd(...items: {
|
|
53
|
-
fn: (() => R) | (() => Promise<R>)
|
|
53
|
+
fn: (() => R) | (() => Promise<R>);
|
|
54
54
|
metadata: M;
|
|
55
55
|
}[]): this;
|
|
56
56
|
runAll({ delayStart }?: RunProps): Promise<Result<SucceededCall<R, M>[], FailedCall<M, E>>>;
|
package/lib/concurrentCalls.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ type FailedCall<M, E extends Error = Error> = {
|
|
|
12
12
|
metadata: M;
|
|
13
13
|
error: E;
|
|
14
14
|
};
|
|
15
|
-
type Action<R, E extends Error> = (
|
|
15
|
+
type Action<R, E extends Error> = () => Promise<Result<R, E>>;
|
|
16
16
|
type SettledResultWithMetadata<R, M, E extends Error = Error> = {
|
|
17
17
|
ok: true;
|
|
18
18
|
value: R;
|
|
@@ -26,7 +26,7 @@ type SettledResultWithMetadata<R, M, E extends Error = Error> = {
|
|
|
26
26
|
declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
|
|
27
27
|
#private;
|
|
28
28
|
add(...calls: Action<R, E>[]): this;
|
|
29
|
-
resultifyAdd(...calls: (
|
|
29
|
+
resultifyAdd(...calls: ((() => R) | (() => Promise<R>))[]): this;
|
|
30
30
|
runAll({ delayStart }?: RunProps): Promise<Result<R[], E>>;
|
|
31
31
|
runAllSettled({ delayStart }?: RunProps): Promise<{
|
|
32
32
|
allFailed: boolean;
|
|
@@ -50,7 +50,7 @@ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown,
|
|
|
50
50
|
metadata: M;
|
|
51
51
|
}[]): this;
|
|
52
52
|
resultifyAdd(...items: {
|
|
53
|
-
fn: (() => R) | (() => Promise<R>)
|
|
53
|
+
fn: (() => R) | (() => Promise<R>);
|
|
54
54
|
metadata: M;
|
|
55
55
|
}[]): this;
|
|
56
56
|
runAll({ delayStart }?: RunProps): Promise<Result<SucceededCall<R, M>[], FailedCall<M, E>>>;
|
package/lib/concurrentCalls.js
CHANGED
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
truncateArray
|
|
9
9
|
} from "./chunk-SRVMMYSW.js";
|
|
10
10
|
import {
|
|
11
|
-
invariant
|
|
12
|
-
isPromise
|
|
11
|
+
invariant
|
|
13
12
|
} from "./chunk-C2SVCIWE.js";
|
|
14
|
-
import
|
|
13
|
+
import {
|
|
14
|
+
isPromise
|
|
15
|
+
} from "./chunk-JF2MDHOJ.js";
|
|
15
16
|
|
|
16
17
|
// src/concurrentCalls.ts
|
|
17
18
|
import { Result, resultify, unknownToError } from "t-result";
|
|
@@ -24,23 +25,17 @@ var ConcurrentCalls = class {
|
|
|
24
25
|
}
|
|
25
26
|
resultifyAdd(...calls) {
|
|
26
27
|
const processedCalls = calls.map((call) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} catch (err) {
|
|
37
|
-
return Result.err(unknownToError(err));
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}
|
|
28
|
+
return async () => {
|
|
29
|
+
try {
|
|
30
|
+
const valueOrPromise = call();
|
|
31
|
+
const value = isPromise(valueOrPromise) ? await valueOrPromise : valueOrPromise;
|
|
32
|
+
return Result.ok(value);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
return Result.err(unknownToError(err));
|
|
35
|
+
}
|
|
36
|
+
};
|
|
41
37
|
});
|
|
42
|
-
|
|
43
|
-
return this.add(...correctlyTypedProcessedCalls);
|
|
38
|
+
return this.add(...processedCalls);
|
|
44
39
|
}
|
|
45
40
|
async runAll({ delayStart } = {}) {
|
|
46
41
|
invariant(!this.#alreadyRun, "Already run");
|
|
@@ -49,15 +44,10 @@ var ConcurrentCalls = class {
|
|
|
49
44
|
const asyncResults = await Promise.all(
|
|
50
45
|
this.#pendingCalls.map(async (fn, i) => {
|
|
51
46
|
try {
|
|
52
|
-
const isP = isPromise(fn);
|
|
53
47
|
if (delayStart) {
|
|
54
|
-
invariant(
|
|
55
|
-
!isP,
|
|
56
|
-
"Delay start is not supported direct promise calls"
|
|
57
|
-
);
|
|
58
48
|
await sleep(delayStart(i));
|
|
59
49
|
}
|
|
60
|
-
const result = await
|
|
50
|
+
const result = await fn();
|
|
61
51
|
if (!result.ok) throw result.error;
|
|
62
52
|
return result.value;
|
|
63
53
|
} catch (exception) {
|
|
@@ -79,15 +69,10 @@ var ConcurrentCalls = class {
|
|
|
79
69
|
const settledResults = await Promise.allSettled(
|
|
80
70
|
this.#pendingCalls.map(async (callOrPromise, i) => {
|
|
81
71
|
try {
|
|
82
|
-
const isP = isPromise(callOrPromise);
|
|
83
72
|
if (delayStart) {
|
|
84
|
-
invariant(
|
|
85
|
-
!isP,
|
|
86
|
-
"Delay start is not supported for direct promise calls"
|
|
87
|
-
);
|
|
88
73
|
await sleep(delayStart(i));
|
|
89
74
|
}
|
|
90
|
-
const result = await
|
|
75
|
+
const result = await callOrPromise();
|
|
91
76
|
if (!result.ok) {
|
|
92
77
|
throw result.error;
|
|
93
78
|
}
|
|
@@ -134,9 +119,10 @@ var ConcurrentCallsWithMetadata = class {
|
|
|
134
119
|
}
|
|
135
120
|
resultifyAdd(...items) {
|
|
136
121
|
const processedItems = items.map(({ fn, metadata }) => {
|
|
137
|
-
const cb =
|
|
138
|
-
const
|
|
139
|
-
|
|
122
|
+
const cb = () => resultify(async () => {
|
|
123
|
+
const valueOrPromise = fn();
|
|
124
|
+
const value = isPromise(valueOrPromise) ? await valueOrPromise : valueOrPromise;
|
|
125
|
+
return value;
|
|
140
126
|
});
|
|
141
127
|
return {
|
|
142
128
|
fn: cb,
|
|
@@ -158,7 +144,7 @@ var ConcurrentCallsWithMetadata = class {
|
|
|
158
144
|
if (delayStart) {
|
|
159
145
|
await sleep(delayStart(i));
|
|
160
146
|
}
|
|
161
|
-
const result = await
|
|
147
|
+
const result = await call.fn();
|
|
162
148
|
if (!result.ok) {
|
|
163
149
|
throw { metadata: call.metadata, error: result.error };
|
|
164
150
|
}
|
|
@@ -205,7 +191,7 @@ var ConcurrentCallsWithMetadata = class {
|
|
|
205
191
|
if (delayStart) {
|
|
206
192
|
await sleep(delayStart(i));
|
|
207
193
|
}
|
|
208
|
-
const result = await
|
|
194
|
+
const result = await call.fn();
|
|
209
195
|
if (!result.ok) {
|
|
210
196
|
throw result.error;
|
|
211
197
|
}
|