@nlozgachev/pipelined 0.31.0 → 0.32.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.
@@ -3,7 +3,79 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-SDGDJ7CU.mjs";
6
+ } from "./chunk-TK5ZCGP2.mjs";
7
+
8
+ // src/Core/Combinable.ts
9
+ var Combinable;
10
+ ((Combinable2) => {
11
+ Combinable2.string = {
12
+ empty: "",
13
+ combine: (b) => (a) => a + b
14
+ };
15
+ Combinable2.sum = {
16
+ empty: 0,
17
+ combine: (b) => (a) => a + b
18
+ };
19
+ Combinable2.product = {
20
+ empty: 1,
21
+ combine: (b) => (a) => a * b
22
+ };
23
+ Combinable2.all = {
24
+ empty: true,
25
+ combine: (b) => (a) => a && b
26
+ };
27
+ Combinable2.any = {
28
+ empty: false,
29
+ combine: (b) => (a) => a || b
30
+ };
31
+ Combinable2.array = () => ({
32
+ empty: [],
33
+ combine: (b) => (a) => [...a, ...b]
34
+ });
35
+ Combinable2.maybe = (inner) => ({
36
+ empty: Maybe.none(),
37
+ combine: (b) => (a) => Maybe.isNone(a) ? b : Maybe.isNone(b) ? a : Maybe.some(inner.combine(b.value)(a.value))
38
+ });
39
+ Combinable2.fold = (c) => (data) => data.reduce((acc, x) => c.combine(x)(acc), c.empty);
40
+ })(Combinable || (Combinable = {}));
41
+
42
+ // src/Core/Equality.ts
43
+ var Equality;
44
+ ((Equality2) => {
45
+ Equality2.string = (a, b) => a === b;
46
+ Equality2.number = (a, b) => a === b;
47
+ Equality2.boolean = (a, b) => a === b;
48
+ Equality2.date = (a, b) => a.getTime() === b.getTime();
49
+ Equality2.array = (eq) => (a, b) => a.length === b.length && a.every((x, i) => eq(x, b[i]));
50
+ Equality2.by = (f) => (eq) => (a, b) => eq(f(a), f(b));
51
+ Equality2.and = (eq2) => (eq1) => (a, b) => eq1(a, b) && eq2(a, b);
52
+ })(Equality || (Equality = {}));
53
+
54
+ // src/Core/Lazy.ts
55
+ var Lazy;
56
+ ((Lazy2) => {
57
+ Lazy2.from = (f) => {
58
+ let done = false;
59
+ let cache;
60
+ return {
61
+ get: () => {
62
+ if (!done) {
63
+ cache = f();
64
+ done = true;
65
+ }
66
+ return cache;
67
+ }
68
+ };
69
+ };
70
+ Lazy2.evaluate = (lazy) => lazy.get();
71
+ Lazy2.map = (f) => (lazy) => Lazy2.from(() => f(lazy.get()));
72
+ Lazy2.chain = (f) => (lazy) => Lazy2.from(() => f(lazy.get()).get());
73
+ Lazy2.tap = (f) => (lazy) => Lazy2.from(() => {
74
+ const v = lazy.get();
75
+ f(v);
76
+ return v;
77
+ });
78
+ })(Lazy || (Lazy = {}));
7
79
 
8
80
  // src/Core/Lens.ts
9
81
  var Lens;
@@ -1056,6 +1128,20 @@ var Optional;
1056
1128
  );
1057
1129
  })(Optional || (Optional = {}));
1058
1130
 
1131
+ // src/Core/Ordering.ts
1132
+ var Ordering;
1133
+ ((Ordering2) => {
1134
+ Ordering2.string = (a, b) => a < b ? -1 : a > b ? 1 : 0;
1135
+ Ordering2.number = (a, b) => a - b;
1136
+ Ordering2.date = (a, b) => a.getTime() - b.getTime();
1137
+ Ordering2.reverse = (ord) => (a, b) => ord(b, a);
1138
+ Ordering2.thenBy = (ord2) => (ord1) => (a, b) => {
1139
+ const r = ord1(a, b);
1140
+ return r !== 0 ? r : ord2(a, b);
1141
+ };
1142
+ Ordering2.by = (f) => (ord) => (a, b) => ord(f(a), f(b));
1143
+ })(Ordering || (Ordering = {}));
1144
+
1059
1145
  // src/Core/Predicate.ts
1060
1146
  var Predicate;
1061
1147
  ((Predicate2) => {
@@ -1178,28 +1264,33 @@ var Resource;
1178
1264
  release
1179
1265
  });
1180
1266
  Resource2.use = (f) => (resource) => Task.from(
1181
- () => Deferred.toPromise(resource.acquire()).then(async (acquired) => {
1267
+ (signal) => Deferred.toPromise(resource.acquire(signal)).then(async (acquired) => {
1182
1268
  if (Result.isError(acquired)) return acquired;
1183
1269
  const a = acquired.value;
1184
- const usageResult = await Deferred.toPromise(f(a)());
1185
- await Deferred.toPromise(resource.release(a)());
1186
- return usageResult;
1270
+ try {
1271
+ const usageResult = await Deferred.toPromise(f(a)(signal));
1272
+ return usageResult;
1273
+ } finally {
1274
+ await Deferred.toPromise(resource.release(a)(signal));
1275
+ }
1187
1276
  })
1188
1277
  );
1189
1278
  Resource2.combine = (resourceA, resourceB) => ({
1190
1279
  acquire: Task.from(
1191
- () => Deferred.toPromise(resourceA.acquire()).then(async (acquiredA) => {
1280
+ (signal) => Deferred.toPromise(resourceA.acquire(signal)).then(async (acquiredA) => {
1192
1281
  if (Result.isError(acquiredA)) return acquiredA;
1193
1282
  const a = acquiredA.value;
1194
- const acquiredB = await Deferred.toPromise(resourceB.acquire());
1283
+ const acquiredB = await Deferred.toPromise(resourceB.acquire(signal));
1195
1284
  if (Result.isError(acquiredB)) {
1196
- await Deferred.toPromise(resourceA.release(a)());
1285
+ await Deferred.toPromise(resourceA.release(a)(signal));
1197
1286
  return acquiredB;
1198
1287
  }
1199
1288
  return Result.ok([a, acquiredB.value]);
1200
1289
  })
1201
1290
  ),
1202
- release: ([a, b]) => Task.from(() => Deferred.toPromise(resourceB.release(b)()).then(() => Deferred.toPromise(resourceA.release(a)())))
1291
+ release: ([a, b]) => Task.from(
1292
+ (signal) => Deferred.toPromise(resourceB.release(b)(signal)).then(() => Deferred.toPromise(resourceA.release(a)(signal)))
1293
+ )
1203
1294
  });
1204
1295
  })(Resource || (Resource = {}));
1205
1296
 
@@ -1242,14 +1333,14 @@ var TaskMaybe;
1242
1333
  TaskMaybe2.fromMaybe = (option) => Task.resolve(option);
1243
1334
  TaskMaybe2.fromTask = (task) => Task.map(Maybe.some)(task);
1244
1335
  TaskMaybe2.tryCatch = (f) => Task.from(
1245
- () => f().then(Maybe.some).catch(() => Maybe.none())
1336
+ (signal) => f(signal).then(Maybe.some).catch(() => Maybe.none())
1246
1337
  );
1247
1338
  TaskMaybe2.map = (f) => (data) => Task.map(Maybe.map(f))(data);
1248
1339
  TaskMaybe2.chain = (f) => (data) => Task.chain((option) => Maybe.isSome(option) ? f(option.value) : Task.resolve(Maybe.none()))(data);
1249
1340
  TaskMaybe2.ap = (arg) => (data) => Task.from(
1250
- () => Promise.all([
1251
- Deferred.toPromise(data()),
1252
- Deferred.toPromise(arg())
1341
+ (signal) => Promise.all([
1342
+ Deferred.toPromise(data(signal)),
1343
+ Deferred.toPromise(arg(signal))
1253
1344
  ]).then(([of_, oa]) => Maybe.ap(oa)(of_))
1254
1345
  );
1255
1346
  TaskMaybe2.fold = (onNone, onSome) => (data) => Task.map(Maybe.fold(onNone, onSome))(data);
@@ -1283,6 +1374,12 @@ var TaskResult;
1283
1374
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1284
1375
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1285
1376
  TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1377
+ TaskResult2.ap = (arg) => (data) => Task.from(
1378
+ (signal) => Promise.all([
1379
+ Deferred.toPromise(data(signal)),
1380
+ Deferred.toPromise(arg(signal))
1381
+ ]).then(([of_, oa]) => Result.ap(oa)(of_))
1382
+ );
1286
1383
  TaskResult2.run = (signal) => (task) => Deferred.toPromise(task(signal));
1287
1384
  })(TaskResult || (TaskResult = {}));
1288
1385
 
@@ -1356,13 +1453,13 @@ var TaskValidation;
1356
1453
  TaskValidation2.invalidAll = (errors) => Task.resolve(Validation.invalidAll(errors));
1357
1454
  TaskValidation2.fromValidation = (validation) => Task.resolve(validation);
1358
1455
  TaskValidation2.tryCatch = (f, onError) => Task.from(
1359
- () => f().then(Validation.valid).catch((e) => Validation.invalid(onError(e)))
1456
+ (signal) => f(signal).then(Validation.valid).catch((e) => Validation.invalid(onError(e)))
1360
1457
  );
1361
1458
  TaskValidation2.map = (f) => (data) => Task.map(Validation.map(f))(data);
1362
1459
  TaskValidation2.ap = (arg) => (data) => Task.from(
1363
- () => Promise.all([
1364
- Deferred.toPromise(data()),
1365
- Deferred.toPromise(arg())
1460
+ (signal) => Promise.all([
1461
+ Deferred.toPromise(data(signal)),
1462
+ Deferred.toPromise(arg(signal))
1366
1463
  ]).then(([vf, va]) => Validation.ap(va)(vf))
1367
1464
  );
1368
1465
  TaskValidation2.fold = (onInvalid, onValid) => (data) => Task.map(Validation.fold(onInvalid, onValid))(data);
@@ -1373,13 +1470,13 @@ var TaskValidation;
1373
1470
  (validation) => Validation.isValid(validation) ? Task.resolve(validation) : fallback(validation.errors)
1374
1471
  )(data);
1375
1472
  TaskValidation2.product = (first, second) => Task.from(
1376
- () => Promise.all([
1377
- Deferred.toPromise(first()),
1378
- Deferred.toPromise(second())
1473
+ (signal) => Promise.all([
1474
+ Deferred.toPromise(first(signal)),
1475
+ Deferred.toPromise(second(signal))
1379
1476
  ]).then(([va, vb]) => Validation.product(va, vb))
1380
1477
  );
1381
1478
  TaskValidation2.productAll = (data) => Task.from(
1382
- () => Promise.all(data.map((t) => Deferred.toPromise(t()))).then((results) => Validation.productAll(results))
1479
+ (signal) => Promise.all(data.map((t) => Deferred.toPromise(t(signal)))).then((results) => Validation.productAll(results))
1383
1480
  );
1384
1481
  })(TaskValidation || (TaskValidation = {}));
1385
1482
 
@@ -1466,10 +1563,14 @@ var Tuple;
1466
1563
  })(Tuple || (Tuple = {}));
1467
1564
 
1468
1565
  export {
1566
+ Combinable,
1567
+ Equality,
1568
+ Lazy,
1469
1569
  Lens,
1470
1570
  Logged,
1471
1571
  Op,
1472
1572
  Optional,
1573
+ Ordering,
1473
1574
  Predicate,
1474
1575
  Reader,
1475
1576
  Refinement,
@@ -1,13 +1,3 @@
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 = {}));
10
-
11
1
  // src/Core/Maybe.ts
12
2
  var _none = { kind: "None" };
13
3
  var Maybe;
@@ -71,6 +61,16 @@ var Result;
71
61
  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
62
  })(Result || (Result = {}));
73
63
 
64
+ // src/Core/Deferred.ts
65
+ var Deferred;
66
+ ((Deferred2) => {
67
+ Deferred2.fromPromise = (p) => (
68
+ // eslint-disable-next-line unicorn/no-thenable -- Deferred is intentionally thenable; it is the mechanism that makes Task awaitable
69
+ { then: ((f) => p.then(f)) }
70
+ );
71
+ Deferred2.toPromise = (d) => new Promise((resolve) => d.then(resolve));
72
+ })(Deferred || (Deferred = {}));
73
+
74
74
  // src/Core/Task.ts
75
75
  var toPromise = (task, signal) => Deferred.toPromise(task(signal));
76
76
  var Task;
@@ -96,58 +96,135 @@ var Task;
96
96
  (signal) => Promise.all(tasks.map((t) => toPromise(t, signal)))
97
97
  );
98
98
  Task2.delay = (ms) => (data) => (0, Task2.from)(
99
- (signal) => new Promise(
100
- (resolve2) => setTimeout(
101
- () => toPromise(data, signal).then(resolve2),
102
- ms
103
- )
104
- )
99
+ (signal) => new Promise((resolve2) => {
100
+ let timerId = void 0;
101
+ const onAbort = () => {
102
+ if (timerId !== void 0) {
103
+ clearTimeout(timerId);
104
+ }
105
+ resolve2(toPromise(data, signal));
106
+ };
107
+ if (signal) {
108
+ if (signal.aborted) {
109
+ return resolve2(toPromise(data, signal));
110
+ }
111
+ signal.addEventListener("abort", onAbort, { once: true });
112
+ }
113
+ timerId = setTimeout(() => {
114
+ signal?.removeEventListener("abort", onAbort);
115
+ resolve2(toPromise(data, signal));
116
+ }, ms);
117
+ })
105
118
  );
106
119
  Task2.repeat = (options) => (task) => (0, Task2.from)((signal) => {
107
120
  const { times, delay: ms } = options;
108
121
  if (times <= 0) return Promise.resolve([]);
109
122
  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
- });
123
+ const wait = () => {
124
+ if (signal?.aborted) return Promise.resolve();
125
+ return new Promise((r) => {
126
+ let timerId = void 0;
127
+ const onAbort = () => {
128
+ if (timerId !== void 0) {
129
+ clearTimeout(timerId);
130
+ }
131
+ r();
132
+ };
133
+ if (signal) {
134
+ signal.addEventListener("abort", onAbort, { once: true });
135
+ }
136
+ timerId = setTimeout(() => {
137
+ signal?.removeEventListener("abort", onAbort);
138
+ r();
139
+ }, ms || 0);
140
+ });
141
+ };
142
+ const run2 = (left) => {
143
+ if (signal?.aborted) {
144
+ return Promise.resolve(results);
145
+ }
146
+ return toPromise(task, signal).then((a) => {
147
+ results.push(a);
148
+ if (left <= 1 || signal?.aborted) return results;
149
+ return wait().then(() => run2(left - 1));
150
+ });
151
+ };
116
152
  return run2(times);
117
153
  });
118
154
  Task2.repeatUntil = (options) => (task) => (0, Task2.from)((signal) => {
119
155
  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
- });
156
+ const wait = () => {
157
+ if (signal?.aborted) return Promise.resolve();
158
+ return new Promise((r) => {
159
+ let timerId = void 0;
160
+ const onAbort = () => {
161
+ if (timerId !== void 0) {
162
+ clearTimeout(timerId);
163
+ }
164
+ r();
165
+ };
166
+ if (signal) {
167
+ signal.addEventListener("abort", onAbort, { once: true });
168
+ }
169
+ timerId = setTimeout(() => {
170
+ signal?.removeEventListener("abort", onAbort);
171
+ r();
172
+ }, ms || 0);
173
+ });
174
+ };
175
+ const run2 = (attempt, lastValue) => {
176
+ if (signal?.aborted && lastValue !== void 0) {
177
+ return Promise.resolve(lastValue);
178
+ }
179
+ return toPromise(task, signal).then((a) => {
180
+ if (predicate(a)) return a;
181
+ if (maxAttempts !== void 0 && attempt >= maxAttempts) return a;
182
+ if (signal?.aborted) return a;
183
+ return wait().then(() => run2(attempt + 1, a));
184
+ });
185
+ };
126
186
  return run2(1);
127
187
  });
128
188
  Task2.race = (tasks) => (0, Task2.from)((signal) => Promise.race(tasks.map((t) => toPromise(t, signal))));
129
189
  Task2.sequential = (tasks) => (0, Task2.from)(async (signal) => {
130
190
  const results = [];
131
191
  for (const task of tasks) {
192
+ if (signal?.aborted) {
193
+ break;
194
+ }
132
195
  results.push(await toPromise(task, signal));
133
196
  }
134
197
  return results;
135
198
  });
136
199
  Task2.timeout = (ms, onTimeout) => (task) => (0, Task2.from)((outerSignal) => {
137
200
  const controller = new AbortController();
138
- const onOuterAbort = () => controller.abort();
139
- outerSignal?.addEventListener("abort", onOuterAbort, { once: true });
140
201
  let timerId;
202
+ const cleanUp = () => {
203
+ if (timerId !== void 0) {
204
+ clearTimeout(timerId);
205
+ }
206
+ outerSignal?.removeEventListener("abort", onOuterAbort);
207
+ };
208
+ const onOuterAbort = () => {
209
+ cleanUp();
210
+ controller.abort();
211
+ };
212
+ if (outerSignal) {
213
+ if (outerSignal.aborted) {
214
+ controller.abort();
215
+ } else {
216
+ outerSignal.addEventListener("abort", onOuterAbort, { once: true });
217
+ }
218
+ }
141
219
  return Promise.race([
142
220
  toPromise(task, controller.signal).then((a) => {
143
- clearTimeout(timerId);
144
- outerSignal?.removeEventListener("abort", onOuterAbort);
221
+ cleanUp();
145
222
  return Result.ok(a);
146
223
  }),
147
224
  new Promise((resolve2) => {
148
225
  timerId = setTimeout(() => {
149
226
  controller.abort();
150
- outerSignal?.removeEventListener("abort", onOuterAbort);
227
+ cleanUp();
151
228
  resolve2(Result.error(onTimeout()));
152
229
  }, ms);
153
230
  })
@@ -175,8 +252,8 @@ var Task;
175
252
  })(Task || (Task = {}));
176
253
 
177
254
  export {
178
- Deferred,
179
255
  Result,
180
256
  Maybe,
257
+ Deferred,
181
258
  Task
182
259
  };
package/dist/core.d.mts CHANGED
@@ -1,7 +1,171 @@
1
- import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-BDcKwFAj.mjs';
2
- export { E as Error, N as None, O as Ok, S as Some } from './Task-BDcKwFAj.mjs';
1
+ import { M as Maybe, W as WithValue, c as WithLog, D as Deferred, R as Result, d as WithKind, e as WithError, f as RetryOptions, g as TimeoutOptions, h as WithTimeout, i as WithMinInterval, j as WithCooldown, k as WithConcurrency, l as WithSize, m as WithMs, n as WithN, T as Task, o as WithErrors, p as WithFirst, q as WithSecond } from './Task-CJZfcOkO.mjs';
2
+ export { E as Equality, a as Error, N as None, O as Ok, b as Ordering, S as Some } from './Task-CJZfcOkO.mjs';
3
3
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
4
4
 
5
+ /**
6
+ * A type that can combine two values of type `A` into one, with a neutral starting value.
7
+ * `empty` is the identity: `combine(empty)(a) === a` and `combine(a)(empty) === a`.
8
+ * `combine(b)(a)` appends `b` onto `a` — `a` is the accumulated value, `b` is the new element.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * pipe(["hello", ", ", "world"], Combinable.fold(Combinable.string)); // "hello, world"
13
+ * pipe([1, 2, 3, 4, 5], Combinable.fold(Combinable.sum)); // 15
14
+ * ```
15
+ */
16
+ type Combinable<A> = {
17
+ readonly empty: A;
18
+ readonly combine: (b: A) => (a: A) => A;
19
+ };
20
+ declare namespace Combinable {
21
+ /**
22
+ * Combines strings by concatenation. Empty string is the neutral element.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * pipe(["a", "b", "c"], Combinable.fold(Combinable.string)); // "abc"
27
+ * ```
28
+ */
29
+ const string: Combinable<string>;
30
+ /**
31
+ * Combines numbers by addition. `0` is the neutral element.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * pipe([1, 2, 3], Combinable.fold(Combinable.sum)); // 6
36
+ * ```
37
+ */
38
+ const sum: Combinable<number>;
39
+ /**
40
+ * Combines numbers by multiplication. `1` is the neutral element.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * pipe([2, 3, 4], Combinable.fold(Combinable.product)); // 24
45
+ * ```
46
+ */
47
+ const product: Combinable<number>;
48
+ /**
49
+ * Combines booleans with logical AND. `true` is the neutral element.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * pipe([true, true, false], Combinable.fold(Combinable.all)); // false
54
+ * ```
55
+ */
56
+ const all: Combinable<boolean>;
57
+ /**
58
+ * Combines booleans with logical OR. `false` is the neutral element.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * pipe([false, false, true], Combinable.fold(Combinable.any)); // true
63
+ * ```
64
+ */
65
+ const any: Combinable<boolean>;
66
+ /**
67
+ * Combines arrays by concatenation. Empty array is the neutral element.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * pipe([[1, 2], [3], [4, 5]], Combinable.fold(Combinable.array<number>())); // [1, 2, 3, 4, 5]
72
+ * ```
73
+ */
74
+ const array: <A>() => Combinable<readonly A[]>;
75
+ /**
76
+ * Lifts a `Combinable<A>` to `Combinable<Maybe<A>>`. `None` is the neutral element —
77
+ * combining with `None` on either side returns the other value unchanged.
78
+ * Two `Some` values combine their inner values using the inner `Combinable`.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const c = Combinable.maybe(Combinable.sum);
83
+ * c.combine(Maybe.some(3))(Maybe.some(2)); // Some(5)
84
+ * c.combine(Maybe.none())(Maybe.some(5)); // Some(5)
85
+ * ```
86
+ */
87
+ const maybe: <A>(inner: Combinable<A>) => Combinable<Maybe<A>>;
88
+ /**
89
+ * Folds an array into a single value using the `Combinable`'s `empty` as the starting point.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * pipe([1, 2, 3, 4, 5], Combinable.fold(Combinable.sum)); // 15
94
+ * pipe([], Combinable.fold(Combinable.sum)); // 0
95
+ * ```
96
+ */
97
+ const fold: <A>(c: Combinable<A>) => (data: readonly A[]) => A;
98
+ }
99
+
100
+ /**
101
+ * A synchronous memoized computation. The factory function runs exactly once —
102
+ * on the first call to `Lazy.evaluate` — and the result is cached for all subsequent calls.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * const config = Lazy.from(() => parseConfig(rawInput));
107
+ *
108
+ * pipe(
109
+ * config,
110
+ * Lazy.map(cfg => cfg.port),
111
+ * Lazy.evaluate,
112
+ * ); // parseConfig ran once; cfg.port returned
113
+ * ```
114
+ */
115
+ type Lazy<A> = {
116
+ readonly get: () => A;
117
+ };
118
+ declare namespace Lazy {
119
+ /**
120
+ * Wraps a thunk in a `Lazy`. The thunk runs exactly once, on first `evaluate`.
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * const expensive = Lazy.from(() => computeExpensiveValue(input));
125
+ * ```
126
+ */
127
+ const from: <A>(f: () => A) => Lazy<A>;
128
+ /**
129
+ * Forces evaluation and returns the cached result. Safe to call multiple times.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * const value = Lazy.evaluate(Lazy.from(() => 42)); // 42
134
+ * ```
135
+ */
136
+ const evaluate: <A>(lazy: Lazy<A>) => A;
137
+ /**
138
+ * Transforms the result of a `Lazy` without triggering evaluation.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * pipe(Lazy.from(() => loadConfig()), Lazy.map(cfg => cfg.port));
143
+ * ```
144
+ */
145
+ const map: <A, B>(f: (a: A) => B) => (lazy: Lazy<A>) => Lazy<B>;
146
+ /**
147
+ * Chains a `Lazy`-returning transformation without triggering evaluation.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * pipe(
152
+ * Lazy.from(() => loadConfig()),
153
+ * Lazy.chain(cfg => Lazy.from(() => openConnection(cfg.dbUrl))),
154
+ * );
155
+ * ```
156
+ */
157
+ const chain: <A, B>(f: (a: A) => Lazy<B>) => (lazy: Lazy<A>) => Lazy<B>;
158
+ /**
159
+ * Runs a side effect on the value without changing it. Fires once, on first `evaluate`.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * pipe(Lazy.from(() => compute()), Lazy.tap(v => console.log("computed:", v)));
164
+ * ```
165
+ */
166
+ const tap: <A>(f: (a: A) => void) => (lazy: Lazy<A>) => Lazy<A>;
167
+ }
168
+
5
169
  /** Keys of T for which undefined is assignable (i.e. optional fields). */
6
170
  type OptionalKeys<T> = {
7
171
  [K in keyof T]-?: undefined extends T[K] ? K : never;
@@ -1888,6 +2052,11 @@ declare namespace TaskResult {
1888
2052
  * ```
1889
2053
  */
1890
2054
  const tapError: <E, A>(f: (e: E) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
2055
+ /**
2056
+ * Applies a function wrapped in a TaskResult to a value wrapped in a TaskResult.
2057
+ * Both Tasks run in parallel.
2058
+ */
2059
+ const ap: <E, A>(arg: TaskResult<E, A>) => <B>(data: TaskResult<E, (a: A) => B>) => TaskResult<E, B>;
1891
2060
  /**
1892
2061
  * Executes a `TaskResult` with an optional signal, returning `Promise<Result<E, A>>`.
1893
2062
  * Use as a terminal step in a `pipe` chain.
@@ -2230,15 +2399,16 @@ declare namespace TaskMaybe {
2230
2399
  /**
2231
2400
  * Creates a TaskMaybe from a Promise-returning function.
2232
2401
  * Returns Some if the promise resolves, None if it rejects.
2402
+ * The factory optionally receives an `AbortSignal` forwarded from the call site.
2233
2403
  *
2234
2404
  * @example
2235
2405
  * ```ts
2236
- * const fetchUser = TaskMaybe.tryCatch(() =>
2237
- * fetch("/user/1").then(r => r.json())
2406
+ * const fetchUser = TaskMaybe.tryCatch((signal) =>
2407
+ * fetch("/user/1", { signal }).then(r => r.json())
2238
2408
  * );
2239
2409
  * ```
2240
2410
  */
2241
- const tryCatch: <A>(f: () => Promise<A>) => TaskMaybe<A>;
2411
+ const tryCatch: <A>(f: (signal?: AbortSignal) => Promise<A>) => TaskMaybe<A>;
2242
2412
  /**
2243
2413
  * Transforms the value inside a TaskMaybe.
2244
2414
  */
@@ -2627,17 +2797,18 @@ declare namespace TaskValidation {
2627
2797
  /**
2628
2798
  * Creates a TaskValidation from a Promise-returning function.
2629
2799
  * Catches any errors and transforms them using the onError function.
2800
+ * The factory optionally receives an `AbortSignal` forwarded from the call site.
2630
2801
  *
2631
2802
  * @example
2632
2803
  * ```ts
2633
2804
  * const fetchUser = (id: string): TaskValidation<string, User> =>
2634
2805
  * TaskValidation.tryCatch(
2635
- * () => fetch(`/users/${id}`).then(r => r.json()),
2806
+ * (signal) => fetch(`/users/${id}`, { signal }).then(r => r.json()),
2636
2807
  * e => `Failed to fetch user: ${e}`
2637
2808
  * );
2638
2809
  * ```
2639
2810
  */
2640
- const tryCatch: <E, A>(f: () => Promise<A>, onError: (e: unknown) => E) => TaskValidation<E, A>;
2811
+ const tryCatch: <E, A>(f: (signal?: AbortSignal) => Promise<A>, onError: (e: unknown) => E) => TaskValidation<E, A>;
2641
2812
  /**
2642
2813
  * Transforms the success value inside a TaskValidation.
2643
2814
  */
@@ -3079,4 +3250,4 @@ declare namespace Tuple {
3079
3250
  const tap: <A, B>(f: (a: A, b: B) => void) => (tuple: Tuple<A, B>) => Tuple<A, B>;
3080
3251
  }
3081
3252
 
3082
- export { Deferred, type Failure, type Invalid, Lens, type Loading, Logged, Maybe, type NotAsked, Op, Optional, Predicate, Reader, Refinement, RemoteData, Resource, Result, State, type Success, Task, TaskMaybe, TaskResult, TaskValidation, These, type TheseBoth, type TheseFirst, type TheseSecond, Tuple, type Valid, Validation };
3253
+ export { Combinable, Deferred, type Failure, type Invalid, Lazy, Lens, type Loading, Logged, Maybe, type NotAsked, Op, Optional, Predicate, Reader, Refinement, RemoteData, Resource, Result, State, type Success, Task, TaskMaybe, TaskResult, TaskValidation, These, type TheseBoth, type TheseFirst, type TheseSecond, Tuple, type Valid, Validation };