@nlozgachev/pipelined 0.31.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Task-CnF22Q2o.d.ts → Task-5na0QzS4.d.mts} +281 -66
- package/dist/{Task-BDcKwFAj.d.mts → Task-DeiWgoeJ.d.ts} +281 -66
- package/dist/{chunk-VIC54JR4.mjs → chunk-FZX4MTRI.mjs} +135 -21
- package/dist/{chunk-SDGDJ7CU.mjs → chunk-GSTKY7MF.mjs} +158 -35
- package/dist/chunk-IPP4XFYH.mjs +0 -0
- package/dist/chunk-VWVPHDZO.mjs +29 -0
- package/dist/{chunk-FWYOEWJ2.mjs → chunk-W53ZYTLX.mjs} +98 -4
- package/dist/core.d.mts +249 -9
- package/dist/core.d.ts +249 -9
- package/dist/core.js +366 -104
- package/dist/core.mjs +11 -2
- package/dist/index.d.mts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +465 -114
- package/dist/index.mjs +17 -6
- package/dist/types.d.mts +104 -2
- package/dist/types.d.ts +104 -2
- package/dist/types.js +20 -0
- package/dist/types.mjs +6 -3
- package/dist/utils.d.mts +124 -2
- package/dist/utils.d.ts +124 -2
- package/dist/utils.js +266 -28
- package/dist/utils.mjs +3 -2
- package/package.json +1 -1
- package/dist/NonEmptyList-BlGFjor5.d.mts +0 -30
- package/dist/NonEmptyList-BlGFjor5.d.ts +0 -30
- package/dist/chunk-BYWKZLHM.mjs +0 -10
package/dist/utils.js
CHANGED
|
@@ -68,6 +68,15 @@ var Result;
|
|
|
68
68
|
return data;
|
|
69
69
|
};
|
|
70
70
|
Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.error)(onFalse(a));
|
|
71
|
+
Result2.fromNullable = (onNull) => (value) => value === null || value === void 0 ? (0, Result2.error)(onNull()) : (0, Result2.ok)(value);
|
|
72
|
+
Result2.fromMaybe = (onNone) => (maybe) => Maybe.isNone(maybe) ? (0, Result2.error)(onNone()) : (0, Result2.ok)(maybe.value);
|
|
73
|
+
Result2.fromThrowable = (f, onError) => (...args) => {
|
|
74
|
+
try {
|
|
75
|
+
return (0, Result2.ok)(f(...args));
|
|
76
|
+
} catch (e) {
|
|
77
|
+
return (0, Result2.error)(onError(e));
|
|
78
|
+
}
|
|
79
|
+
};
|
|
71
80
|
Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
|
|
72
81
|
Result2.recoverUnless = (isBlocked, fallback) => (data) => (0, Result2.isError)(data) && !isBlocked(data.error) ? fallback() : data;
|
|
73
82
|
Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
|
|
@@ -102,8 +111,34 @@ var Maybe;
|
|
|
102
111
|
Maybe2.ap = (arg) => (data) => (0, Maybe2.isSome)(data) && (0, Maybe2.isSome)(arg) ? (0, Maybe2.some)(data.value(arg.value)) : (0, Maybe2.none)();
|
|
103
112
|
})(Maybe || (Maybe = {}));
|
|
104
113
|
|
|
114
|
+
// src/Types/Brand.ts
|
|
115
|
+
var Brand;
|
|
116
|
+
((Brand2) => {
|
|
117
|
+
Brand2.wrap = () => (value) => value;
|
|
118
|
+
Brand2.unwrap = (branded) => branded;
|
|
119
|
+
})(Brand || (Brand = {}));
|
|
120
|
+
|
|
121
|
+
// src/Types/Duration.ts
|
|
122
|
+
var Duration;
|
|
123
|
+
((Duration2) => {
|
|
124
|
+
const wrap = Brand.wrap();
|
|
125
|
+
Duration2.milliseconds = (ms) => wrap(ms);
|
|
126
|
+
Duration2.seconds = (s) => wrap(s * 1e3);
|
|
127
|
+
Duration2.minutes = (m) => wrap(m * 60 * 1e3);
|
|
128
|
+
Duration2.hours = (h) => wrap(h * 60 * 60 * 1e3);
|
|
129
|
+
Duration2.days = (d) => wrap(d * 24 * 60 * 60 * 1e3);
|
|
130
|
+
Duration2.toMilliseconds = (d) => Brand.unwrap(d);
|
|
131
|
+
Duration2.toSeconds = (d) => Brand.unwrap(d) / 1e3;
|
|
132
|
+
Duration2.toMinutes = (d) => Brand.unwrap(d) / (60 * 1e3);
|
|
133
|
+
Duration2.toHours = (d) => Brand.unwrap(d) / (60 * 60 * 1e3);
|
|
134
|
+
Duration2.toDays = (d) => Brand.unwrap(d) / (24 * 60 * 60 * 1e3);
|
|
135
|
+
Duration2.add = (other) => (self) => wrap(Brand.unwrap(self) + Brand.unwrap(other));
|
|
136
|
+
Duration2.subtract = (other) => (self) => wrap(Brand.unwrap(self) - Brand.unwrap(other));
|
|
137
|
+
})(Duration || (Duration = {}));
|
|
138
|
+
|
|
105
139
|
// src/Core/Task.ts
|
|
106
140
|
var toPromise = (task, signal) => Deferred.toPromise(task(signal));
|
|
141
|
+
var getMs = (ms) => typeof ms === "number" ? ms : Duration.toMilliseconds(ms);
|
|
107
142
|
var Task;
|
|
108
143
|
((Task2) => {
|
|
109
144
|
Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
|
|
@@ -127,60 +162,169 @@ var Task;
|
|
|
127
162
|
(signal) => Promise.all(tasks.map((t) => toPromise(t, signal)))
|
|
128
163
|
);
|
|
129
164
|
Task2.delay = (ms) => (data) => (0, Task2.from)(
|
|
130
|
-
(signal) => new Promise(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
165
|
+
(signal) => new Promise((resolve2) => {
|
|
166
|
+
let timerId = void 0;
|
|
167
|
+
const onAbort = () => {
|
|
168
|
+
if (timerId !== void 0) {
|
|
169
|
+
clearTimeout(timerId);
|
|
170
|
+
}
|
|
171
|
+
resolve2(toPromise(data, signal));
|
|
172
|
+
};
|
|
173
|
+
if (signal) {
|
|
174
|
+
if (signal.aborted) {
|
|
175
|
+
return resolve2(toPromise(data, signal));
|
|
176
|
+
}
|
|
177
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
178
|
+
}
|
|
179
|
+
timerId = setTimeout(() => {
|
|
180
|
+
signal?.removeEventListener("abort", onAbort);
|
|
181
|
+
resolve2(toPromise(data, signal));
|
|
182
|
+
}, getMs(ms));
|
|
183
|
+
})
|
|
136
184
|
);
|
|
137
185
|
Task2.repeat = (options) => (task) => (0, Task2.from)((signal) => {
|
|
138
186
|
const { times, delay: ms } = options;
|
|
139
187
|
if (times <= 0) return Promise.resolve([]);
|
|
140
188
|
const results = [];
|
|
141
|
-
const wait = () =>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
189
|
+
const wait = () => {
|
|
190
|
+
if (signal?.aborted) return Promise.resolve();
|
|
191
|
+
return new Promise((r) => {
|
|
192
|
+
let timerId = void 0;
|
|
193
|
+
const onAbort = () => {
|
|
194
|
+
if (timerId !== void 0) {
|
|
195
|
+
clearTimeout(timerId);
|
|
196
|
+
}
|
|
197
|
+
r();
|
|
198
|
+
};
|
|
199
|
+
if (signal) {
|
|
200
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
201
|
+
}
|
|
202
|
+
timerId = setTimeout(() => {
|
|
203
|
+
signal?.removeEventListener("abort", onAbort);
|
|
204
|
+
r();
|
|
205
|
+
}, getMs(ms || 0));
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
const run2 = (left) => {
|
|
209
|
+
if (signal?.aborted) {
|
|
210
|
+
return Promise.resolve(results);
|
|
211
|
+
}
|
|
212
|
+
return toPromise(task, signal).then((a) => {
|
|
213
|
+
results.push(a);
|
|
214
|
+
if (left <= 1 || signal?.aborted) return results;
|
|
215
|
+
return wait().then(() => run2(left - 1));
|
|
216
|
+
});
|
|
217
|
+
};
|
|
147
218
|
return run2(times);
|
|
148
219
|
});
|
|
149
220
|
Task2.repeatUntil = (options) => (task) => (0, Task2.from)((signal) => {
|
|
150
221
|
const { when: predicate, delay: ms, maxAttempts } = options;
|
|
151
|
-
const wait = () =>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
222
|
+
const wait = () => {
|
|
223
|
+
if (signal?.aborted) return Promise.resolve();
|
|
224
|
+
return new Promise((r) => {
|
|
225
|
+
let timerId = void 0;
|
|
226
|
+
const onAbort = () => {
|
|
227
|
+
if (timerId !== void 0) {
|
|
228
|
+
clearTimeout(timerId);
|
|
229
|
+
}
|
|
230
|
+
r();
|
|
231
|
+
};
|
|
232
|
+
if (signal) {
|
|
233
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
234
|
+
}
|
|
235
|
+
timerId = setTimeout(() => {
|
|
236
|
+
signal?.removeEventListener("abort", onAbort);
|
|
237
|
+
r();
|
|
238
|
+
}, getMs(ms || 0));
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
const run2 = (attempt, lastValue) => {
|
|
242
|
+
if (signal?.aborted && lastValue !== void 0) {
|
|
243
|
+
return Promise.resolve(lastValue);
|
|
244
|
+
}
|
|
245
|
+
return toPromise(task, signal).then((a) => {
|
|
246
|
+
if (predicate(a)) return a;
|
|
247
|
+
if (maxAttempts !== void 0 && attempt >= maxAttempts) return a;
|
|
248
|
+
if (signal?.aborted) return a;
|
|
249
|
+
return wait().then(() => run2(attempt + 1, a));
|
|
250
|
+
});
|
|
251
|
+
};
|
|
157
252
|
return run2(1);
|
|
158
253
|
});
|
|
159
|
-
Task2.race = (tasks) =>
|
|
254
|
+
Task2.race = (tasks) => {
|
|
255
|
+
if (tasks.length === 0) {
|
|
256
|
+
return () => Deferred.fromPromise(new Promise(() => {
|
|
257
|
+
}));
|
|
258
|
+
}
|
|
259
|
+
return (0, Task2.from)((outerSignal) => {
|
|
260
|
+
const controllers = tasks.map(() => new AbortController());
|
|
261
|
+
const onOuterAbort = () => {
|
|
262
|
+
for (const ctrl of controllers) ctrl.abort();
|
|
263
|
+
};
|
|
264
|
+
if (outerSignal) {
|
|
265
|
+
if (outerSignal.aborted) {
|
|
266
|
+
onOuterAbort();
|
|
267
|
+
} else {
|
|
268
|
+
outerSignal.addEventListener("abort", onOuterAbort, { once: true });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const promises = tasks.map((task, idx) => {
|
|
272
|
+
const ctrl = controllers[idx];
|
|
273
|
+
return toPromise(task, ctrl.signal).then((result) => {
|
|
274
|
+
for (let i = 0; i < controllers.length; i++) {
|
|
275
|
+
if (i !== idx) {
|
|
276
|
+
controllers[i].abort();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
outerSignal?.removeEventListener("abort", onOuterAbort);
|
|
280
|
+
return result;
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
return Promise.race(promises);
|
|
284
|
+
});
|
|
285
|
+
};
|
|
286
|
+
Task2.sequence = (tasks) => (0, Task2.from)((signal) => Promise.all(tasks.map((t) => toPromise(t, signal))));
|
|
160
287
|
Task2.sequential = (tasks) => (0, Task2.from)(async (signal) => {
|
|
161
288
|
const results = [];
|
|
162
289
|
for (const task of tasks) {
|
|
290
|
+
if (signal?.aborted) {
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
163
293
|
results.push(await toPromise(task, signal));
|
|
164
294
|
}
|
|
165
295
|
return results;
|
|
166
296
|
});
|
|
167
297
|
Task2.timeout = (ms, onTimeout) => (task) => (0, Task2.from)((outerSignal) => {
|
|
168
298
|
const controller = new AbortController();
|
|
169
|
-
const onOuterAbort = () => controller.abort();
|
|
170
|
-
outerSignal?.addEventListener("abort", onOuterAbort, { once: true });
|
|
171
299
|
let timerId;
|
|
300
|
+
const cleanUp = () => {
|
|
301
|
+
if (timerId !== void 0) {
|
|
302
|
+
clearTimeout(timerId);
|
|
303
|
+
}
|
|
304
|
+
outerSignal?.removeEventListener("abort", onOuterAbort);
|
|
305
|
+
};
|
|
306
|
+
const onOuterAbort = () => {
|
|
307
|
+
cleanUp();
|
|
308
|
+
controller.abort();
|
|
309
|
+
};
|
|
310
|
+
if (outerSignal) {
|
|
311
|
+
if (outerSignal.aborted) {
|
|
312
|
+
controller.abort();
|
|
313
|
+
} else {
|
|
314
|
+
outerSignal.addEventListener("abort", onOuterAbort, { once: true });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
172
317
|
return Promise.race([
|
|
173
318
|
toPromise(task, controller.signal).then((a) => {
|
|
174
|
-
|
|
175
|
-
outerSignal?.removeEventListener("abort", onOuterAbort);
|
|
319
|
+
cleanUp();
|
|
176
320
|
return Result.ok(a);
|
|
177
321
|
}),
|
|
178
322
|
new Promise((resolve2) => {
|
|
179
323
|
timerId = setTimeout(() => {
|
|
180
324
|
controller.abort();
|
|
181
|
-
|
|
325
|
+
cleanUp();
|
|
182
326
|
resolve2(Result.error(onTimeout()));
|
|
183
|
-
}, ms);
|
|
327
|
+
}, getMs(ms));
|
|
184
328
|
})
|
|
185
329
|
]);
|
|
186
330
|
});
|
|
@@ -265,6 +409,40 @@ var Arr;
|
|
|
265
409
|
}
|
|
266
410
|
return [pass, fail];
|
|
267
411
|
};
|
|
412
|
+
Arr2.compact = (data) => {
|
|
413
|
+
const result = [];
|
|
414
|
+
for (const item of data) {
|
|
415
|
+
if (item.kind === "Some") {
|
|
416
|
+
result.push(item.value);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return result;
|
|
420
|
+
};
|
|
421
|
+
Arr2.separate = (data) => {
|
|
422
|
+
const errors = [];
|
|
423
|
+
const successes = [];
|
|
424
|
+
for (const item of data) {
|
|
425
|
+
if (item.kind === "Ok") {
|
|
426
|
+
successes.push(item.value);
|
|
427
|
+
} else {
|
|
428
|
+
errors.push(item.error);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return [errors, successes];
|
|
432
|
+
};
|
|
433
|
+
Arr2.partitionMap = (f) => (data) => {
|
|
434
|
+
const errors = [];
|
|
435
|
+
const successes = [];
|
|
436
|
+
for (const item of data) {
|
|
437
|
+
const mapped = f(item);
|
|
438
|
+
if (mapped.kind === "Ok") {
|
|
439
|
+
successes.push(mapped.value);
|
|
440
|
+
} else {
|
|
441
|
+
errors.push(mapped.error);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return [errors, successes];
|
|
445
|
+
};
|
|
268
446
|
Arr2.groupBy = (f) => (data) => {
|
|
269
447
|
const result = {};
|
|
270
448
|
for (const a of data) {
|
|
@@ -289,11 +467,25 @@ var Arr;
|
|
|
289
467
|
}
|
|
290
468
|
return result;
|
|
291
469
|
};
|
|
470
|
+
Arr2.uniqWith = (eq) => (data) => {
|
|
471
|
+
const result = [];
|
|
472
|
+
for (const a of data) {
|
|
473
|
+
if (!result.some((x) => eq(x, a))) {
|
|
474
|
+
result.push(a);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return result;
|
|
478
|
+
};
|
|
292
479
|
Arr2.sortBy = (compare) => (data) => {
|
|
293
480
|
const arr = data;
|
|
294
481
|
if (typeof arr.toSorted === "function") return arr.toSorted(compare);
|
|
295
482
|
return [...data].sort(compare);
|
|
296
483
|
};
|
|
484
|
+
Arr2.sortWith = (ord) => (data) => {
|
|
485
|
+
const arr = data;
|
|
486
|
+
if (typeof arr.toSorted === "function") return arr.toSorted(ord);
|
|
487
|
+
return [...data].sort(ord);
|
|
488
|
+
};
|
|
297
489
|
Arr2.zip = (other) => (data) => {
|
|
298
490
|
const len = Math.min(data.length, other.length);
|
|
299
491
|
const result = new Array(len);
|
|
@@ -326,7 +518,23 @@ var Arr;
|
|
|
326
518
|
}
|
|
327
519
|
return result;
|
|
328
520
|
};
|
|
329
|
-
Arr2.flatten = (data) =>
|
|
521
|
+
Arr2.flatten = (data) => {
|
|
522
|
+
let totalLen = 0;
|
|
523
|
+
const outerLen = data.length;
|
|
524
|
+
for (let i = 0; i < outerLen; i++) {
|
|
525
|
+
totalLen += data[i].length;
|
|
526
|
+
}
|
|
527
|
+
const result = new Array(totalLen);
|
|
528
|
+
let idx = 0;
|
|
529
|
+
for (let i = 0; i < outerLen; i++) {
|
|
530
|
+
const chunk = data[i];
|
|
531
|
+
const innerLen = chunk.length;
|
|
532
|
+
for (let j = 0; j < innerLen; j++) {
|
|
533
|
+
result[idx++] = chunk[j];
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return result;
|
|
537
|
+
};
|
|
330
538
|
Arr2.flatMap = (f) => (data) => {
|
|
331
539
|
const n = data.length;
|
|
332
540
|
const result = [];
|
|
@@ -565,8 +773,8 @@ var Num;
|
|
|
565
773
|
}
|
|
566
774
|
return result;
|
|
567
775
|
};
|
|
568
|
-
Num2.clamp = (
|
|
569
|
-
Num2.between = (
|
|
776
|
+
Num2.clamp = (min2, max2) => (n) => Math.min(Math.max(n, min2), max2);
|
|
777
|
+
Num2.between = (min2, max2) => (n) => n >= min2 && n <= max2;
|
|
570
778
|
Num2.parse = (s) => {
|
|
571
779
|
if (s.trim() === "") return Maybe.none();
|
|
572
780
|
const n = Number(s);
|
|
@@ -582,6 +790,28 @@ var Num;
|
|
|
582
790
|
Num2.floor = (n) => Math.floor(n);
|
|
583
791
|
Num2.ceil = (n) => Math.ceil(n);
|
|
584
792
|
Num2.remainder = (divisor) => (n) => divisor === 0 ? Maybe.none() : Maybe.some(n % divisor);
|
|
793
|
+
Num2.sum = (ns) => {
|
|
794
|
+
let result = 0;
|
|
795
|
+
for (let i = 0; i < ns.length; i++) result += ns[i];
|
|
796
|
+
return result;
|
|
797
|
+
};
|
|
798
|
+
Num2.mean = (ns) => ns.length === 0 ? Maybe.none() : Maybe.some((0, Num2.sum)(ns) / ns.length);
|
|
799
|
+
Num2.min = (ns) => {
|
|
800
|
+
if (ns.length === 0) return Maybe.none();
|
|
801
|
+
let [result] = ns;
|
|
802
|
+
for (let i = 1; i < ns.length; i++) {
|
|
803
|
+
if (ns[i] < result) result = ns[i];
|
|
804
|
+
}
|
|
805
|
+
return Maybe.some(result);
|
|
806
|
+
};
|
|
807
|
+
Num2.max = (ns) => {
|
|
808
|
+
if (ns.length === 0) return Maybe.none();
|
|
809
|
+
let [result] = ns;
|
|
810
|
+
for (let i = 1; i < ns.length; i++) {
|
|
811
|
+
if (ns[i] > result) result = ns[i];
|
|
812
|
+
}
|
|
813
|
+
return Maybe.some(result);
|
|
814
|
+
};
|
|
585
815
|
})(Num || (Num = {}));
|
|
586
816
|
|
|
587
817
|
// src/Utils/Rec.ts
|
|
@@ -705,6 +935,7 @@ var Str;
|
|
|
705
935
|
Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
|
|
706
936
|
Str2.toUpperCase = (s) => s.toUpperCase();
|
|
707
937
|
Str2.toLowerCase = (s) => s.toLowerCase();
|
|
938
|
+
Str2.capitalize = (s) => s.length === 0 ? "" : s.charAt(0).toUpperCase() + s.slice(1);
|
|
708
939
|
Str2.lines = (s) => s.split(/\r?\n|\r/);
|
|
709
940
|
Str2.words = (s) => s.trim().split(/\s+/).filter(Boolean);
|
|
710
941
|
Str2.isEmpty = (s) => s.length === 0;
|
|
@@ -743,6 +974,13 @@ var Str;
|
|
|
743
974
|
return isNaN(n) ? Maybe.none() : Maybe.some(n);
|
|
744
975
|
}
|
|
745
976
|
};
|
|
977
|
+
Str2.parseJson = (s) => {
|
|
978
|
+
try {
|
|
979
|
+
return Result.ok(JSON.parse(s));
|
|
980
|
+
} catch (e) {
|
|
981
|
+
return Result.error(e);
|
|
982
|
+
}
|
|
983
|
+
};
|
|
746
984
|
})(Str || (Str = {}));
|
|
747
985
|
|
|
748
986
|
// src/Utils/Uniq.ts
|
package/dist/utils.mjs
CHANGED
|
@@ -5,9 +5,10 @@ import {
|
|
|
5
5
|
Rec,
|
|
6
6
|
Str,
|
|
7
7
|
Uniq
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-W53ZYTLX.mjs";
|
|
9
|
+
import "./chunk-GSTKY7MF.mjs";
|
|
10
10
|
import "./chunk-DBIC62UV.mjs";
|
|
11
|
+
import "./chunk-VWVPHDZO.mjs";
|
|
11
12
|
export {
|
|
12
13
|
Arr,
|
|
13
14
|
Dict,
|
package/package.json
CHANGED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A list that is guaranteed to have at least one element.
|
|
3
|
-
* Useful for ensuring functions receive non-empty input and for
|
|
4
|
-
* accumulating errors in Validation.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const errors: NonEmptyList<string> = ["First error", "Second error"];
|
|
9
|
-
*
|
|
10
|
-
* // TypeScript ensures at least one element:
|
|
11
|
-
* const invalid: NonEmptyList<string> = []; // Error!
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
|
-
type NonEmptyList<A> = readonly [A, ...A[]];
|
|
15
|
-
/**
|
|
16
|
-
* Type guard that checks if an array is non-empty.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* const items: string[] = getItems();
|
|
21
|
-
*
|
|
22
|
-
* if (isNonEmptyList(items)) {
|
|
23
|
-
* // TypeScript knows items has at least one element
|
|
24
|
-
* const first = items[0]; // string, not string | undefined
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
declare const isNonEmptyList: <A>(list: readonly A[]) => list is NonEmptyList<A>;
|
|
29
|
-
|
|
30
|
-
export { type NonEmptyList as N, isNonEmptyList as i };
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A list that is guaranteed to have at least one element.
|
|
3
|
-
* Useful for ensuring functions receive non-empty input and for
|
|
4
|
-
* accumulating errors in Validation.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const errors: NonEmptyList<string> = ["First error", "Second error"];
|
|
9
|
-
*
|
|
10
|
-
* // TypeScript ensures at least one element:
|
|
11
|
-
* const invalid: NonEmptyList<string> = []; // Error!
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
|
-
type NonEmptyList<A> = readonly [A, ...A[]];
|
|
15
|
-
/**
|
|
16
|
-
* Type guard that checks if an array is non-empty.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* const items: string[] = getItems();
|
|
21
|
-
*
|
|
22
|
-
* if (isNonEmptyList(items)) {
|
|
23
|
-
* // TypeScript knows items has at least one element
|
|
24
|
-
* const first = items[0]; // string, not string | undefined
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
declare const isNonEmptyList: <A>(list: readonly A[]) => list is NonEmptyList<A>;
|
|
29
|
-
|
|
30
|
-
export { type NonEmptyList as N, isNonEmptyList as i };
|