@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.
@@ -1,12 +1,6 @@
1
- // src/Core/Deferred.ts
2
- var Deferred;
3
- ((Deferred2) => {
4
- Deferred2.fromPromise = (p) => (
5
- // eslint-disable-next-line unicorn/no-thenable -- Deferred is intentionally thenable; it is the mechanism that makes Task awaitable
6
- { then: ((f) => p.then(f)) }
7
- );
8
- Deferred2.toPromise = (d) => new Promise((resolve) => d.then(resolve));
9
- })(Deferred || (Deferred = {}));
1
+ import {
2
+ Duration
3
+ } from "./chunk-VWVPHDZO.mjs";
10
4
 
11
5
  // src/Core/Maybe.ts
12
6
  var _none = { kind: "None" };
@@ -65,14 +59,34 @@ var Result;
65
59
  return data;
66
60
  };
67
61
  Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.error)(onFalse(a));
62
+ Result2.fromNullable = (onNull) => (value) => value === null || value === void 0 ? (0, Result2.error)(onNull()) : (0, Result2.ok)(value);
63
+ Result2.fromMaybe = (onNone) => (maybe) => Maybe.isNone(maybe) ? (0, Result2.error)(onNone()) : (0, Result2.ok)(maybe.value);
64
+ Result2.fromThrowable = (f, onError) => (...args) => {
65
+ try {
66
+ return (0, Result2.ok)(f(...args));
67
+ } catch (e) {
68
+ return (0, Result2.error)(onError(e));
69
+ }
70
+ };
68
71
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
69
72
  Result2.recoverUnless = (isBlocked, fallback) => (data) => (0, Result2.isError)(data) && !isBlocked(data.error) ? fallback() : data;
70
73
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
71
74
  Result2.ap = (arg) => (data) => (0, Result2.isOk)(data) && (0, Result2.isOk)(arg) ? (0, Result2.ok)(data.value(arg.value)) : (0, Result2.isError)(data) ? data : arg;
72
75
  })(Result || (Result = {}));
73
76
 
77
+ // src/Core/Deferred.ts
78
+ var Deferred;
79
+ ((Deferred2) => {
80
+ Deferred2.fromPromise = (p) => (
81
+ // eslint-disable-next-line unicorn/no-thenable -- Deferred is intentionally thenable; it is the mechanism that makes Task awaitable
82
+ { then: ((f) => p.then(f)) }
83
+ );
84
+ Deferred2.toPromise = (d) => new Promise((resolve) => d.then(resolve));
85
+ })(Deferred || (Deferred = {}));
86
+
74
87
  // src/Core/Task.ts
75
88
  var toPromise = (task, signal) => Deferred.toPromise(task(signal));
89
+ var getMs = (ms) => typeof ms === "number" ? ms : Duration.toMilliseconds(ms);
76
90
  var Task;
77
91
  ((Task2) => {
78
92
  Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
@@ -96,60 +110,169 @@ var Task;
96
110
  (signal) => Promise.all(tasks.map((t) => toPromise(t, signal)))
97
111
  );
98
112
  Task2.delay = (ms) => (data) => (0, Task2.from)(
99
- (signal) => new Promise(
100
- (resolve2) => setTimeout(
101
- () => toPromise(data, signal).then(resolve2),
102
- ms
103
- )
104
- )
113
+ (signal) => new Promise((resolve2) => {
114
+ let timerId = void 0;
115
+ const onAbort = () => {
116
+ if (timerId !== void 0) {
117
+ clearTimeout(timerId);
118
+ }
119
+ resolve2(toPromise(data, signal));
120
+ };
121
+ if (signal) {
122
+ if (signal.aborted) {
123
+ return resolve2(toPromise(data, signal));
124
+ }
125
+ signal.addEventListener("abort", onAbort, { once: true });
126
+ }
127
+ timerId = setTimeout(() => {
128
+ signal?.removeEventListener("abort", onAbort);
129
+ resolve2(toPromise(data, signal));
130
+ }, getMs(ms));
131
+ })
105
132
  );
106
133
  Task2.repeat = (options) => (task) => (0, Task2.from)((signal) => {
107
134
  const { times, delay: ms } = options;
108
135
  if (times <= 0) return Promise.resolve([]);
109
136
  const results = [];
110
- const wait = () => ms !== void 0 && ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve();
111
- const run2 = (left) => toPromise(task, signal).then((a) => {
112
- results.push(a);
113
- if (left <= 1) return results;
114
- return wait().then(() => run2(left - 1));
115
- });
137
+ const wait = () => {
138
+ if (signal?.aborted) return Promise.resolve();
139
+ return new Promise((r) => {
140
+ let timerId = void 0;
141
+ const onAbort = () => {
142
+ if (timerId !== void 0) {
143
+ clearTimeout(timerId);
144
+ }
145
+ r();
146
+ };
147
+ if (signal) {
148
+ signal.addEventListener("abort", onAbort, { once: true });
149
+ }
150
+ timerId = setTimeout(() => {
151
+ signal?.removeEventListener("abort", onAbort);
152
+ r();
153
+ }, getMs(ms || 0));
154
+ });
155
+ };
156
+ const run2 = (left) => {
157
+ if (signal?.aborted) {
158
+ return Promise.resolve(results);
159
+ }
160
+ return toPromise(task, signal).then((a) => {
161
+ results.push(a);
162
+ if (left <= 1 || signal?.aborted) return results;
163
+ return wait().then(() => run2(left - 1));
164
+ });
165
+ };
116
166
  return run2(times);
117
167
  });
118
168
  Task2.repeatUntil = (options) => (task) => (0, Task2.from)((signal) => {
119
169
  const { when: predicate, delay: ms, maxAttempts } = options;
120
- const wait = () => ms !== void 0 && ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve();
121
- const run2 = (attempt) => toPromise(task, signal).then((a) => {
122
- if (predicate(a)) return a;
123
- if (maxAttempts !== void 0 && attempt >= maxAttempts) return a;
124
- return wait().then(() => run2(attempt + 1));
125
- });
170
+ const wait = () => {
171
+ if (signal?.aborted) return Promise.resolve();
172
+ return new Promise((r) => {
173
+ let timerId = void 0;
174
+ const onAbort = () => {
175
+ if (timerId !== void 0) {
176
+ clearTimeout(timerId);
177
+ }
178
+ r();
179
+ };
180
+ if (signal) {
181
+ signal.addEventListener("abort", onAbort, { once: true });
182
+ }
183
+ timerId = setTimeout(() => {
184
+ signal?.removeEventListener("abort", onAbort);
185
+ r();
186
+ }, getMs(ms || 0));
187
+ });
188
+ };
189
+ const run2 = (attempt, lastValue) => {
190
+ if (signal?.aborted && lastValue !== void 0) {
191
+ return Promise.resolve(lastValue);
192
+ }
193
+ return toPromise(task, signal).then((a) => {
194
+ if (predicate(a)) return a;
195
+ if (maxAttempts !== void 0 && attempt >= maxAttempts) return a;
196
+ if (signal?.aborted) return a;
197
+ return wait().then(() => run2(attempt + 1, a));
198
+ });
199
+ };
126
200
  return run2(1);
127
201
  });
128
- Task2.race = (tasks) => (0, Task2.from)((signal) => Promise.race(tasks.map((t) => toPromise(t, signal))));
202
+ Task2.race = (tasks) => {
203
+ if (tasks.length === 0) {
204
+ return () => Deferred.fromPromise(new Promise(() => {
205
+ }));
206
+ }
207
+ return (0, Task2.from)((outerSignal) => {
208
+ const controllers = tasks.map(() => new AbortController());
209
+ const onOuterAbort = () => {
210
+ for (const ctrl of controllers) ctrl.abort();
211
+ };
212
+ if (outerSignal) {
213
+ if (outerSignal.aborted) {
214
+ onOuterAbort();
215
+ } else {
216
+ outerSignal.addEventListener("abort", onOuterAbort, { once: true });
217
+ }
218
+ }
219
+ const promises = tasks.map((task, idx) => {
220
+ const ctrl = controllers[idx];
221
+ return toPromise(task, ctrl.signal).then((result) => {
222
+ for (let i = 0; i < controllers.length; i++) {
223
+ if (i !== idx) {
224
+ controllers[i].abort();
225
+ }
226
+ }
227
+ outerSignal?.removeEventListener("abort", onOuterAbort);
228
+ return result;
229
+ });
230
+ });
231
+ return Promise.race(promises);
232
+ });
233
+ };
234
+ Task2.sequence = (tasks) => (0, Task2.from)((signal) => Promise.all(tasks.map((t) => toPromise(t, signal))));
129
235
  Task2.sequential = (tasks) => (0, Task2.from)(async (signal) => {
130
236
  const results = [];
131
237
  for (const task of tasks) {
238
+ if (signal?.aborted) {
239
+ break;
240
+ }
132
241
  results.push(await toPromise(task, signal));
133
242
  }
134
243
  return results;
135
244
  });
136
245
  Task2.timeout = (ms, onTimeout) => (task) => (0, Task2.from)((outerSignal) => {
137
246
  const controller = new AbortController();
138
- const onOuterAbort = () => controller.abort();
139
- outerSignal?.addEventListener("abort", onOuterAbort, { once: true });
140
247
  let timerId;
248
+ const cleanUp = () => {
249
+ if (timerId !== void 0) {
250
+ clearTimeout(timerId);
251
+ }
252
+ outerSignal?.removeEventListener("abort", onOuterAbort);
253
+ };
254
+ const onOuterAbort = () => {
255
+ cleanUp();
256
+ controller.abort();
257
+ };
258
+ if (outerSignal) {
259
+ if (outerSignal.aborted) {
260
+ controller.abort();
261
+ } else {
262
+ outerSignal.addEventListener("abort", onOuterAbort, { once: true });
263
+ }
264
+ }
141
265
  return Promise.race([
142
266
  toPromise(task, controller.signal).then((a) => {
143
- clearTimeout(timerId);
144
- outerSignal?.removeEventListener("abort", onOuterAbort);
267
+ cleanUp();
145
268
  return Result.ok(a);
146
269
  }),
147
270
  new Promise((resolve2) => {
148
271
  timerId = setTimeout(() => {
149
272
  controller.abort();
150
- outerSignal?.removeEventListener("abort", onOuterAbort);
273
+ cleanUp();
151
274
  resolve2(Result.error(onTimeout()));
152
- }, ms);
275
+ }, getMs(ms));
153
276
  })
154
277
  ]);
155
278
  });
@@ -175,8 +298,8 @@ var Task;
175
298
  })(Task || (Task = {}));
176
299
 
177
300
  export {
178
- Deferred,
179
301
  Result,
180
302
  Maybe,
303
+ Deferred,
181
304
  Task
182
305
  };
File without changes
@@ -0,0 +1,29 @@
1
+ // src/Types/Brand.ts
2
+ var Brand;
3
+ ((Brand2) => {
4
+ Brand2.wrap = () => (value) => value;
5
+ Brand2.unwrap = (branded) => branded;
6
+ })(Brand || (Brand = {}));
7
+
8
+ // src/Types/Duration.ts
9
+ var Duration;
10
+ ((Duration2) => {
11
+ const wrap = Brand.wrap();
12
+ Duration2.milliseconds = (ms) => wrap(ms);
13
+ Duration2.seconds = (s) => wrap(s * 1e3);
14
+ Duration2.minutes = (m) => wrap(m * 60 * 1e3);
15
+ Duration2.hours = (h) => wrap(h * 60 * 60 * 1e3);
16
+ Duration2.days = (d) => wrap(d * 24 * 60 * 60 * 1e3);
17
+ Duration2.toMilliseconds = (d) => Brand.unwrap(d);
18
+ Duration2.toSeconds = (d) => Brand.unwrap(d) / 1e3;
19
+ Duration2.toMinutes = (d) => Brand.unwrap(d) / (60 * 1e3);
20
+ Duration2.toHours = (d) => Brand.unwrap(d) / (60 * 60 * 1e3);
21
+ Duration2.toDays = (d) => Brand.unwrap(d) / (24 * 60 * 60 * 1e3);
22
+ Duration2.add = (other) => (self) => wrap(Brand.unwrap(self) + Brand.unwrap(other));
23
+ Duration2.subtract = (other) => (self) => wrap(Brand.unwrap(self) - Brand.unwrap(other));
24
+ })(Duration || (Duration = {}));
25
+
26
+ export {
27
+ Brand,
28
+ Duration
29
+ };
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-SDGDJ7CU.mjs";
6
+ } from "./chunk-GSTKY7MF.mjs";
7
7
  import {
8
8
  isNonEmptyList
9
9
  } from "./chunk-DBIC62UV.mjs";
@@ -65,6 +65,40 @@ var Arr;
65
65
  }
66
66
  return [pass, fail];
67
67
  };
68
+ Arr2.compact = (data) => {
69
+ const result = [];
70
+ for (const item of data) {
71
+ if (item.kind === "Some") {
72
+ result.push(item.value);
73
+ }
74
+ }
75
+ return result;
76
+ };
77
+ Arr2.separate = (data) => {
78
+ const errors = [];
79
+ const successes = [];
80
+ for (const item of data) {
81
+ if (item.kind === "Ok") {
82
+ successes.push(item.value);
83
+ } else {
84
+ errors.push(item.error);
85
+ }
86
+ }
87
+ return [errors, successes];
88
+ };
89
+ Arr2.partitionMap = (f) => (data) => {
90
+ const errors = [];
91
+ const successes = [];
92
+ for (const item of data) {
93
+ const mapped = f(item);
94
+ if (mapped.kind === "Ok") {
95
+ successes.push(mapped.value);
96
+ } else {
97
+ errors.push(mapped.error);
98
+ }
99
+ }
100
+ return [errors, successes];
101
+ };
68
102
  Arr2.groupBy = (f) => (data) => {
69
103
  const result = {};
70
104
  for (const a of data) {
@@ -89,11 +123,25 @@ var Arr;
89
123
  }
90
124
  return result;
91
125
  };
126
+ Arr2.uniqWith = (eq) => (data) => {
127
+ const result = [];
128
+ for (const a of data) {
129
+ if (!result.some((x) => eq(x, a))) {
130
+ result.push(a);
131
+ }
132
+ }
133
+ return result;
134
+ };
92
135
  Arr2.sortBy = (compare) => (data) => {
93
136
  const arr = data;
94
137
  if (typeof arr.toSorted === "function") return arr.toSorted(compare);
95
138
  return [...data].sort(compare);
96
139
  };
140
+ Arr2.sortWith = (ord) => (data) => {
141
+ const arr = data;
142
+ if (typeof arr.toSorted === "function") return arr.toSorted(ord);
143
+ return [...data].sort(ord);
144
+ };
97
145
  Arr2.zip = (other) => (data) => {
98
146
  const len = Math.min(data.length, other.length);
99
147
  const result = new Array(len);
@@ -126,7 +174,23 @@ var Arr;
126
174
  }
127
175
  return result;
128
176
  };
129
- Arr2.flatten = (data) => [].concat(...data);
177
+ Arr2.flatten = (data) => {
178
+ let totalLen = 0;
179
+ const outerLen = data.length;
180
+ for (let i = 0; i < outerLen; i++) {
181
+ totalLen += data[i].length;
182
+ }
183
+ const result = new Array(totalLen);
184
+ let idx = 0;
185
+ for (let i = 0; i < outerLen; i++) {
186
+ const chunk = data[i];
187
+ const innerLen = chunk.length;
188
+ for (let j = 0; j < innerLen; j++) {
189
+ result[idx++] = chunk[j];
190
+ }
191
+ }
192
+ return result;
193
+ };
130
194
  Arr2.flatMap = (f) => (data) => {
131
195
  const n = data.length;
132
196
  const result = [];
@@ -365,8 +429,8 @@ var Num;
365
429
  }
366
430
  return result;
367
431
  };
368
- Num2.clamp = (min, max) => (n) => Math.min(Math.max(n, min), max);
369
- Num2.between = (min, max) => (n) => n >= min && n <= max;
432
+ Num2.clamp = (min2, max2) => (n) => Math.min(Math.max(n, min2), max2);
433
+ Num2.between = (min2, max2) => (n) => n >= min2 && n <= max2;
370
434
  Num2.parse = (s) => {
371
435
  if (s.trim() === "") return Maybe.none();
372
436
  const n = Number(s);
@@ -382,6 +446,28 @@ var Num;
382
446
  Num2.floor = (n) => Math.floor(n);
383
447
  Num2.ceil = (n) => Math.ceil(n);
384
448
  Num2.remainder = (divisor) => (n) => divisor === 0 ? Maybe.none() : Maybe.some(n % divisor);
449
+ Num2.sum = (ns) => {
450
+ let result = 0;
451
+ for (let i = 0; i < ns.length; i++) result += ns[i];
452
+ return result;
453
+ };
454
+ Num2.mean = (ns) => ns.length === 0 ? Maybe.none() : Maybe.some((0, Num2.sum)(ns) / ns.length);
455
+ Num2.min = (ns) => {
456
+ if (ns.length === 0) return Maybe.none();
457
+ let [result] = ns;
458
+ for (let i = 1; i < ns.length; i++) {
459
+ if (ns[i] < result) result = ns[i];
460
+ }
461
+ return Maybe.some(result);
462
+ };
463
+ Num2.max = (ns) => {
464
+ if (ns.length === 0) return Maybe.none();
465
+ let [result] = ns;
466
+ for (let i = 1; i < ns.length; i++) {
467
+ if (ns[i] > result) result = ns[i];
468
+ }
469
+ return Maybe.some(result);
470
+ };
385
471
  })(Num || (Num = {}));
386
472
 
387
473
  // src/Utils/Rec.ts
@@ -505,6 +591,7 @@ var Str;
505
591
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
506
592
  Str2.toUpperCase = (s) => s.toUpperCase();
507
593
  Str2.toLowerCase = (s) => s.toLowerCase();
594
+ Str2.capitalize = (s) => s.length === 0 ? "" : s.charAt(0).toUpperCase() + s.slice(1);
508
595
  Str2.lines = (s) => s.split(/\r?\n|\r/);
509
596
  Str2.words = (s) => s.trim().split(/\s+/).filter(Boolean);
510
597
  Str2.isEmpty = (s) => s.length === 0;
@@ -543,6 +630,13 @@ var Str;
543
630
  return isNaN(n) ? Maybe.none() : Maybe.some(n);
544
631
  }
545
632
  };
633
+ Str2.parseJson = (s) => {
634
+ try {
635
+ return Result.ok(JSON.parse(s));
636
+ } catch (e) {
637
+ return Result.error(e);
638
+ }
639
+ };
546
640
  })(Str || (Str = {}));
547
641
 
548
642
  // src/Utils/Uniq.ts