retuple 1.0.0-next.12 → 1.0.0-next.14

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/index.js CHANGED
@@ -9,7 +9,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _ResultAsync_inner;
12
+ var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_handler;
13
+ import { ResultLikeSymbol } from "./symbol.js";
13
14
  /**
14
15
  * ## Retuple Unwrap Failed
15
16
  *
@@ -44,18 +45,6 @@ export class RetupleExpectFailed extends Error {
44
45
  this.value = value;
45
46
  }
46
47
  }
47
- /**
48
- * ## Retuple Expect Failed
49
- *
50
- * An error which occurs when calling `$flatten` on `Ok`, when the value
51
- * contained in the `Ok` is not an `Ok` or `Err`.
52
- */
53
- export class RetupleFlattenFailed extends Error {
54
- constructor(value) {
55
- super("Flatten Result failed, the contained value was not a Result");
56
- this.value = value;
57
- }
58
- }
59
48
  /**
60
49
  * ## Retuple Thrown Value Error
61
50
  *
@@ -63,26 +52,12 @@ export class RetupleFlattenFailed extends Error {
63
52
  * thrown error or rejected value is not an instance of `Error`, and when no
64
53
  * map error function is provided.
65
54
  */
66
- export class RetupleThrownValueError extends Error {
55
+ export class RetupleCaughtValueError extends Error {
67
56
  constructor(value) {
68
57
  super("Caught value was not an instance of Error");
69
58
  this.value = value;
70
59
  }
71
60
  }
72
- /**
73
- * ## Retuple Invalid Result Error
74
- *
75
- * This error is thrown when attempting to construct a `Result` from a tuple,
76
- * when neither index 0 or 1 are null or undefined. In this case, it is
77
- * impossible to determine whether the result should be `Ok` or `Err`.
78
- */
79
- export class RetupleInvalidResultError extends Error {
80
- constructor(value) {
81
- super("Constructing a Result from native tuple failed, at least one of the " +
82
- "values at index 0 or 1 should be null or undefined");
83
- this.value = value;
84
- }
85
- }
86
61
  /**
87
62
  * ## Retuple Invalid Union Error
88
63
  *
@@ -116,24 +91,20 @@ export class RetupleArrayMethodUnavailableError extends Error {
116
91
  * @TODO
117
92
  */
118
93
  export function Result(resultLike) {
119
- const [err, ok] = resultLike;
120
- if (err === null || err === undefined) {
121
- return new ResultOk(ok);
122
- }
123
- if (ok === null || ok === undefined) {
124
- return new ResultErr(err);
125
- }
126
- throw new RetupleInvalidResultError(resultLike);
94
+ return asResult(resultLike);
127
95
  }
128
96
  Result.Ok = Ok;
129
97
  Result.Err = Err;
130
- Result.$resolve = resolve;
131
- Result.$nonNullable = nonNullable;
132
- Result.$truthy = truthy;
133
- Result.$union = union;
134
- Result.$safe = safe;
135
- Result.$safeAsync = safeAsync;
136
- Result.$safePromise = safePromise;
98
+ Result.$from = $from;
99
+ Result.$resolve = $resolve;
100
+ Result.$nonNullable = $nonNullable;
101
+ Result.$truthy = $truthy;
102
+ Result.$fromUnion = $fromUnion;
103
+ Result.$safe = $safe;
104
+ Result.$safeAsync = $safeAsync;
105
+ Result.$safePromise = $safePromise;
106
+ Result.$retry = $retry;
107
+ Result.$safeRetry = $safeRetry;
137
108
  Object.freeze(Result);
138
109
  export function Ok(val) {
139
110
  return new ResultOk(val);
@@ -141,30 +112,111 @@ export function Ok(val) {
141
112
  export function Err(err) {
142
113
  return new ResultErr(err);
143
114
  }
144
- function resolve(result) {
145
- if (result instanceof ResultAsync) {
115
+ /**
116
+ * Construct a {@link Result} from a {@link ResultLike}.
117
+ *
118
+ * @example
119
+ *
120
+ * ```ts
121
+ * const value: Result<T, E> | ResultLike<T, E> = someResultFn();
122
+ * const result: Result<T, E> = Result.$from(result);
123
+ * ```
124
+ */
125
+ function $from(result) {
126
+ if (result instanceof ResultOk || result instanceof ResultErr) {
146
127
  return result;
147
128
  }
148
- else if (result instanceof ResultOk || result instanceof ResultErr) {
149
- return result.$async();
150
- }
151
- else {
152
- return new ResultAsync(result);
129
+ return asResult(result);
130
+ }
131
+ /**
132
+ * Construct a {@link ResultAsync} from a {@link ResultLikeAwaitable}.
133
+ *
134
+ * @example
135
+ *
136
+ * ```ts
137
+ * const value:
138
+ * | Result<T, E>
139
+ * | ResultLike<T, E>
140
+ * | ResultAsync<T, E>
141
+ * | Promise<Result<T, E>>
142
+ * | Promise<ResultLike<T, E>>
143
+ * | PromiseLike<Result<T, E>>
144
+ * | PromiseLike<ResultLike<T, E>> = someResultFn();
145
+ *
146
+ * const result: ResultAsync<T, E> = Result.$resolve(result);
147
+ * ```
148
+ */
149
+ function $resolve(result) {
150
+ switch (true) {
151
+ case result instanceof ResultAsync:
152
+ return result;
153
+ case result instanceof ResultRetry:
154
+ return new ResultAsync(result);
155
+ case result instanceof ResultOk:
156
+ case result instanceof ResultErr:
157
+ return new ResultAsync(Promise.resolve(result));
158
+ default:
159
+ return new ResultAsync(Promise.resolve(result).then((asResult)));
153
160
  }
154
161
  }
155
- function nonNullable(value, error = mapTrue) {
162
+ function $nonNullable(value, error = mapTrue) {
156
163
  if (value !== null && value !== undefined) {
157
164
  return Ok(value);
158
165
  }
159
166
  return Err(error());
160
167
  }
161
- function truthy(value, error = mapTrue) {
168
+ function $truthy(value, error = mapTrue) {
162
169
  if (value) {
163
170
  return Ok(value);
164
171
  }
165
172
  return Err(error());
166
173
  }
167
- function union(union) {
174
+ /**
175
+ * Construct a {@link Result} from a common discriminated union shape. If the
176
+ * union is 'success' then the result is `Ok`
177
+ *
178
+ * Otherwise, the result is `Err` containing:
179
+ *
180
+ * - the returned value from the error function when provided;
181
+ * - or `true` otherwise.
182
+ *
183
+ * @example
184
+ *
185
+ * ```ts
186
+ * const result: Result<string, Error> = Result.$truthy(
187
+ * username.trim(),
188
+ * () => new Error("Username is empty"),
189
+ * );
190
+ * ```
191
+ *
192
+ * @example
193
+ *
194
+ * ```ts
195
+ * const [err, value] = Result.$truthy("test");
196
+ *
197
+ * assert.equal(err, undefined);
198
+ * assert.equal(value, "test");
199
+ * ```
200
+ *
201
+ * @example
202
+ *
203
+ * ```ts
204
+ * const [err, value] = Result.$truthy("");
205
+ *
206
+ * assert.equal(err, true);
207
+ * assert.equal(value, undefined);
208
+ * ```
209
+ *
210
+ * @example
211
+ *
212
+ * ```ts
213
+ * const [err, value] = Result.$truthy(0, () => "error");
214
+ *
215
+ * assert.equal(err, "error");
216
+ * assert.equal(value, undefined);
217
+ * ```
218
+ */
219
+ function $fromUnion(union) {
168
220
  if (union.success === true) {
169
221
  return Ok(union.data);
170
222
  }
@@ -173,7 +225,7 @@ function union(union) {
173
225
  }
174
226
  throw new RetupleInvalidUnionError(union);
175
227
  }
176
- function safe(f, mapError = ensureError) {
228
+ function $safe(f, mapError = ensureError) {
177
229
  try {
178
230
  return Ok(f());
179
231
  }
@@ -181,7 +233,7 @@ function safe(f, mapError = ensureError) {
181
233
  return Err(mapError(err));
182
234
  }
183
235
  }
184
- function safeAsync(f, mapError = ensureError) {
236
+ function $safeAsync(f, mapError = ensureError) {
185
237
  return new ResultAsync((async () => {
186
238
  try {
187
239
  return Ok(await f());
@@ -191,9 +243,38 @@ function safeAsync(f, mapError = ensureError) {
191
243
  }
192
244
  })());
193
245
  }
194
- function safePromise(promise, mapError = ensureError) {
246
+ function $safePromise(promise, mapError = ensureError) {
195
247
  return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
196
248
  }
249
+ /**
250
+ * Construct a {@link ResultRetry} from a function which returns a
251
+ * {@link Result}. The function will be retried based on provided retry
252
+ * settings and eventually return a `Result`. No attempt is made to catch
253
+ * thrown errors or promise rejections.
254
+ *
255
+ * To retry a potentially unsafe function, use {@link Result.$safeRetry}.
256
+ *
257
+ * @example
258
+ *
259
+ * ```ts
260
+ * // Retry someResultFn up to 3 times until Ok is returned,
261
+ * // with a 1 second delay between each invocation:
262
+ * const result = await Result.$retry(someResultFn).$times(3).$delay(1000);
263
+ * ```
264
+ */
265
+ function $retry(f) {
266
+ return new ResultRetry(f);
267
+ }
268
+ function $safeRetry(f, mapError = ensureError) {
269
+ return new ResultRetry(async () => {
270
+ try {
271
+ return Ok(await f());
272
+ }
273
+ catch (err) {
274
+ return Err(mapError(err));
275
+ }
276
+ });
277
+ }
197
278
  /**
198
279
  * ## RetupleArray
199
280
  *
@@ -204,8 +285,7 @@ class RetupleArray extends Array {
204
285
  /**
205
286
  * ## Method not available
206
287
  *
207
- * Built-in array methods not available on `Result` types, convert the result
208
- * to a tuple using `$tuple()` first.
288
+ * Built-in array methods not available on {@link Result} types.
209
289
  *
210
290
  * @deprecated
211
291
  */
@@ -215,8 +295,7 @@ class RetupleArray extends Array {
215
295
  /**
216
296
  * ## Method not available
217
297
  *
218
- * Built-in array methods not available on `Result` types, convert the result
219
- * to a tuple using `$tuple()` first.
298
+ * Built-in array methods not available on {@link Result} types.
220
299
  *
221
300
  * @deprecated
222
301
  */
@@ -226,8 +305,7 @@ class RetupleArray extends Array {
226
305
  /**
227
306
  * ## Method not available
228
307
  *
229
- * Built-in array methods not available on `Result` types, convert the result
230
- * to a tuple using `$tuple()` first.
308
+ * Built-in array methods not available on {@link Result} types.
231
309
  *
232
310
  * @deprecated
233
311
  */
@@ -237,8 +315,7 @@ class RetupleArray extends Array {
237
315
  /**
238
316
  * ## Method not available
239
317
  *
240
- * Built-in array methods not available on `Result` types, convert the result
241
- * to a tuple using `$tuple()` first.
318
+ * Built-in array methods not available on {@link Result} types.
242
319
  *
243
320
  * @deprecated
244
321
  */
@@ -248,8 +325,7 @@ class RetupleArray extends Array {
248
325
  /**
249
326
  * ## Method not available
250
327
  *
251
- * Built-in array methods not available on `Result` types, convert the result
252
- * to a tuple using `$tuple()` first.
328
+ * Built-in array methods not available on {@link Result} types.
253
329
  *
254
330
  * @deprecated
255
331
  */
@@ -259,8 +335,7 @@ class RetupleArray extends Array {
259
335
  /**
260
336
  * ## Method not available
261
337
  *
262
- * Built-in array methods not available on `Result` types, convert the result
263
- * to a tuple using `$tuple()` first.
338
+ * Built-in array methods not available on {@link Result} types.
264
339
  *
265
340
  * @deprecated
266
341
  */
@@ -270,8 +345,7 @@ class RetupleArray extends Array {
270
345
  /**
271
346
  * ## Method not available
272
347
  *
273
- * Built-in array methods not available on `Result` types, convert the result
274
- * to a tuple using `$tuple()` first.
348
+ * Built-in array methods not available on {@link Result} types.
275
349
  *
276
350
  * @deprecated
277
351
  */
@@ -281,8 +355,7 @@ class RetupleArray extends Array {
281
355
  /**
282
356
  * ## Method not available
283
357
  *
284
- * Built-in array methods not available on `Result` types, convert the result
285
- * to a tuple using `$tuple()` first.
358
+ * Built-in array methods not available on {@link Result} types.
286
359
  *
287
360
  * @deprecated
288
361
  */
@@ -292,8 +365,7 @@ class RetupleArray extends Array {
292
365
  /**
293
366
  * ## Method not available
294
367
  *
295
- * Built-in array methods not available on `Result` types, convert the result
296
- * to a tuple using `$tuple()` first.
368
+ * Built-in array methods not available on {@link Result} types.
297
369
  *
298
370
  * @deprecated
299
371
  */
@@ -303,8 +375,7 @@ class RetupleArray extends Array {
303
375
  /**
304
376
  * ## Method not available
305
377
  *
306
- * Built-in array methods not available on `Result` types, convert the result
307
- * to a tuple using `$tuple()` first.
378
+ * Built-in array methods not available on {@link Result} types.
308
379
  *
309
380
  * @deprecated
310
381
  */
@@ -314,8 +385,7 @@ class RetupleArray extends Array {
314
385
  /**
315
386
  * ## Method not available
316
387
  *
317
- * Built-in array methods not available on `Result` types, convert the result
318
- * to a tuple using `$tuple()` first.
388
+ * Built-in array methods not available on {@link Result} types.
319
389
  *
320
390
  * @deprecated
321
391
  */
@@ -325,8 +395,7 @@ class RetupleArray extends Array {
325
395
  /**
326
396
  * ## Method not available
327
397
  *
328
- * Built-in array methods not available on `Result` types, convert the result
329
- * to a tuple using `$tuple()` first.
398
+ * Built-in array methods not available on {@link Result} types.
330
399
  *
331
400
  * @deprecated
332
401
  */
@@ -336,8 +405,7 @@ class RetupleArray extends Array {
336
405
  /**
337
406
  * ## Method not available
338
407
  *
339
- * Built-in array methods not available on `Result` types, convert the result
340
- * to a tuple using `$tuple()` first.
408
+ * Built-in array methods not available on {@link Result} types.
341
409
  *
342
410
  * @deprecated
343
411
  */
@@ -347,8 +415,7 @@ class RetupleArray extends Array {
347
415
  /**
348
416
  * ## Method not available
349
417
  *
350
- * Built-in array methods not available on `Result` types, convert the result
351
- * to a tuple using `$tuple()` first.
418
+ * Built-in array methods not available on {@link Result} types.
352
419
  *
353
420
  * @deprecated
354
421
  */
@@ -358,8 +425,7 @@ class RetupleArray extends Array {
358
425
  /**
359
426
  * ## Method not available
360
427
  *
361
- * Built-in array methods not available on `Result` types, convert the result
362
- * to a tuple using `$tuple()` first.
428
+ * Built-in array methods not available on {@link Result} types.
363
429
  *
364
430
  * @deprecated
365
431
  */
@@ -369,8 +435,7 @@ class RetupleArray extends Array {
369
435
  /**
370
436
  * ## Method not available
371
437
  *
372
- * Built-in array methods not available on `Result` types, convert the result
373
- * to a tuple using `$tuple()` first.
438
+ * Built-in array methods not available on {@link Result} types.
374
439
  *
375
440
  * @deprecated
376
441
  */
@@ -380,8 +445,7 @@ class RetupleArray extends Array {
380
445
  /**
381
446
  * ## Method not available
382
447
  *
383
- * Built-in array methods not available on `Result` types, convert the result
384
- * to a tuple using `$tuple()` first.
448
+ * Built-in array methods not available on {@link Result} types.
385
449
  *
386
450
  * @deprecated
387
451
  */
@@ -391,8 +455,7 @@ class RetupleArray extends Array {
391
455
  /**
392
456
  * ## Method not available
393
457
  *
394
- * Built-in array methods not available on `Result` types, convert the result
395
- * to a tuple using `$tuple()` first.
458
+ * Built-in array methods not available on {@link Result} types.
396
459
  *
397
460
  * @deprecated
398
461
  */
@@ -402,8 +465,7 @@ class RetupleArray extends Array {
402
465
  /**
403
466
  * ## Method not available
404
467
  *
405
- * Built-in array methods not available on `Result` types, convert the result
406
- * to a tuple using `$tuple()` first.
468
+ * Built-in array methods not available on {@link Result} types.
407
469
  *
408
470
  * @deprecated
409
471
  */
@@ -413,8 +475,7 @@ class RetupleArray extends Array {
413
475
  /**
414
476
  * ## Method not available
415
477
  *
416
- * Built-in array methods not available on `Result` types, convert the result
417
- * to a tuple using `$tuple()` first.
478
+ * Built-in array methods not available on {@link Result} types.
418
479
  *
419
480
  * @deprecated
420
481
  */
@@ -424,8 +485,7 @@ class RetupleArray extends Array {
424
485
  /**
425
486
  * ## Method not available
426
487
  *
427
- * Built-in array methods not available on `Result` types, convert the result
428
- * to a tuple using `$tuple()` first.
488
+ * Built-in array methods not available on {@link Result} types.
429
489
  *
430
490
  * @deprecated
431
491
  */
@@ -435,8 +495,7 @@ class RetupleArray extends Array {
435
495
  /**
436
496
  * ## Method not available
437
497
  *
438
- * Built-in array methods not available on `Result` types, convert the result
439
- * to a tuple using `$tuple()` first.
498
+ * Built-in array methods not available on {@link Result} types.
440
499
  *
441
500
  * @deprecated
442
501
  */
@@ -446,8 +505,7 @@ class RetupleArray extends Array {
446
505
  /**
447
506
  * ## Method not available
448
507
  *
449
- * Built-in array methods not available on `Result` types, convert the result
450
- * to a tuple using `$tuple()` first.
508
+ * Built-in array methods not available on {@link Result} types.
451
509
  *
452
510
  * @deprecated
453
511
  */
@@ -457,8 +515,7 @@ class RetupleArray extends Array {
457
515
  /**
458
516
  * ## Method not available
459
517
  *
460
- * Built-in array methods not available on `Result` types, convert the result
461
- * to a tuple using `$tuple()` first.
518
+ * Built-in array methods not available on {@link Result} types.
462
519
  *
463
520
  * @deprecated
464
521
  */
@@ -468,8 +525,7 @@ class RetupleArray extends Array {
468
525
  /**
469
526
  * ## Method not available
470
527
  *
471
- * Built-in array methods not available on `Result` types, convert the result
472
- * to a tuple using `$tuple()` first.
528
+ * Built-in array methods not available on {@link Result} types.
473
529
  *
474
530
  * @deprecated
475
531
  */
@@ -479,8 +535,7 @@ class RetupleArray extends Array {
479
535
  /**
480
536
  * ## Method not available
481
537
  *
482
- * Built-in array methods not available on `Result` types, convert the result
483
- * to a tuple using `$tuple()` first.
538
+ * Built-in array methods not available on {@link Result} types.
484
539
  *
485
540
  * @deprecated
486
541
  */
@@ -490,8 +545,7 @@ class RetupleArray extends Array {
490
545
  /**
491
546
  * ## Method not available
492
547
  *
493
- * Built-in array methods not available on `Result` types, convert the result
494
- * to a tuple using `$tuple()` first.
548
+ * Built-in array methods not available on {@link Result} types.
495
549
  *
496
550
  * @deprecated
497
551
  */
@@ -501,8 +555,7 @@ class RetupleArray extends Array {
501
555
  /**
502
556
  * ## Method not available
503
557
  *
504
- * Built-in array methods not available on `Result` types, convert the result
505
- * to a tuple using `$tuple()` first.
558
+ * Built-in array methods not available on {@link Result} types.
506
559
  *
507
560
  * @deprecated
508
561
  */
@@ -512,8 +565,7 @@ class RetupleArray extends Array {
512
565
  /**
513
566
  * ## Method not available
514
567
  *
515
- * Built-in array methods not available on `Result` types, convert the result
516
- * to a tuple using `$tuple()` first.
568
+ * Built-in array methods not available on {@link Result} types.
517
569
  *
518
570
  * @deprecated
519
571
  */
@@ -523,8 +575,7 @@ class RetupleArray extends Array {
523
575
  /**
524
576
  * ## Method not available
525
577
  *
526
- * Built-in array methods not available on `Result` types, convert the result
527
- * to a tuple using `$tuple()` first.
578
+ * Built-in array methods not available on {@link Result} types.
528
579
  *
529
580
  * @deprecated
530
581
  */
@@ -534,8 +585,7 @@ class RetupleArray extends Array {
534
585
  /**
535
586
  * ## Method not available
536
587
  *
537
- * Built-in array methods not available on `Result` types, convert the result
538
- * to a tuple using `$tuple()` first.
588
+ * Built-in array methods not available on {@link Result} types.
539
589
  *
540
590
  * @deprecated
541
591
  */
@@ -545,8 +595,7 @@ class RetupleArray extends Array {
545
595
  /**
546
596
  * ## Method not available
547
597
  *
548
- * Built-in array methods not available on `Result` types, convert the result
549
- * to a tuple using `$tuple()` first.
598
+ * Built-in array methods not available on {@link Result} types.
550
599
  *
551
600
  * @deprecated
552
601
  */
@@ -556,8 +605,7 @@ class RetupleArray extends Array {
556
605
  /**
557
606
  * ## Method not available
558
607
  *
559
- * Built-in array methods not available on `Result` types, convert the result
560
- * to a tuple using `$tuple()` first.
608
+ * Built-in array methods not available on {@link Result} types.
561
609
  *
562
610
  * @deprecated
563
611
  */
@@ -567,8 +615,7 @@ class RetupleArray extends Array {
567
615
  /**
568
616
  * ## Method not available
569
617
  *
570
- * Built-in array methods not available on `Result` types, convert the result
571
- * to a tuple using `$tuple()` first.
618
+ * Built-in array methods not available on {@link Result} types.
572
619
  *
573
620
  * @deprecated
574
621
  */
@@ -578,8 +625,7 @@ class RetupleArray extends Array {
578
625
  /**
579
626
  * ## Method not available
580
627
  *
581
- * Built-in array methods not available on `Result` types, convert the result
582
- * to a tuple using `$tuple()` first.
628
+ * Built-in array methods not available on {@link Result} types.
583
629
  *
584
630
  * @deprecated
585
631
  */
@@ -589,8 +635,7 @@ class RetupleArray extends Array {
589
635
  /**
590
636
  * ## Method not available
591
637
  *
592
- * Built-in array methods not available on `Result` types, convert the result
593
- * to a tuple using `$tuple()` first.
638
+ * Built-in array methods not available on {@link Result} types.
594
639
  *
595
640
  * @deprecated
596
641
  */
@@ -600,8 +645,7 @@ class RetupleArray extends Array {
600
645
  /**
601
646
  * ## Method not available
602
647
  *
603
- * Built-in array methods not available on `Result` types, convert the result
604
- * to a tuple using `$tuple()` first.
648
+ * Built-in array methods not available on {@link Result} types.
605
649
  *
606
650
  * @deprecated
607
651
  */
@@ -611,8 +655,7 @@ class RetupleArray extends Array {
611
655
  /**
612
656
  * ## Method not available
613
657
  *
614
- * Built-in array methods not available on `Result` types, convert the result
615
- * to a tuple using `$tuple()` first.
658
+ * Built-in array methods not available on {@link Result} types.
616
659
  *
617
660
  * @deprecated
618
661
  */
@@ -631,6 +674,9 @@ class ResultOk extends RetupleArray {
631
674
  this[0] = undefined;
632
675
  this[1] = value;
633
676
  }
677
+ [ResultLikeSymbol]() {
678
+ return this;
679
+ }
634
680
  toJSON() {
635
681
  return this[1];
636
682
  }
@@ -674,10 +720,10 @@ class ResultOk extends RetupleArray {
674
720
  return Ok(f(this[1]));
675
721
  }
676
722
  $andAssertOr(def, condition = isTruthy) {
677
- return condition(this[1]) ? this : def;
723
+ return condition(this[1]) ? this : asResult(def);
678
724
  }
679
725
  $andAssertOrElse(def, condition = isTruthy) {
680
- return condition(this[1]) ? this : def(this[1]);
726
+ return condition(this[1]) ? this : asResult(def(this[1]));
681
727
  }
682
728
  $or() {
683
729
  return this;
@@ -689,13 +735,13 @@ class ResultOk extends RetupleArray {
689
735
  return this;
690
736
  }
691
737
  $and(and) {
692
- return and;
738
+ return asResult(and);
693
739
  }
694
740
  $andThen(f) {
695
- return f(this[1]);
741
+ return asResult(f(this[1]));
696
742
  }
697
743
  $andThrough(f) {
698
- const res = f(this[1]);
744
+ const res = asResult(f(this[1]));
699
745
  return res instanceof ResultErr ? res : this;
700
746
  }
701
747
  $andSafe(f, mapError = ensureError) {
@@ -718,11 +764,7 @@ class ResultOk extends RetupleArray {
718
764
  return this;
719
765
  }
720
766
  $flatten() {
721
- const inner = this[1];
722
- if (inner instanceof ResultOk || inner instanceof ResultErr) {
723
- return inner;
724
- }
725
- throw new RetupleFlattenFailed(this[1]);
767
+ return this[1];
726
768
  }
727
769
  $async() {
728
770
  return new ResultAsync(Promise.resolve(this));
@@ -730,9 +772,6 @@ class ResultOk extends RetupleArray {
730
772
  $promise() {
731
773
  return Promise.resolve(this);
732
774
  }
733
- $tuple() {
734
- return [undefined, this[1]];
735
- }
736
775
  *$iter() {
737
776
  yield* this[1];
738
777
  }
@@ -748,6 +787,9 @@ class ResultErr extends RetupleArray {
748
787
  this[0] = err;
749
788
  this[1] = undefined;
750
789
  }
790
+ [ResultLikeSymbol]() {
791
+ return this;
792
+ }
751
793
  toJSON() {
752
794
  return null;
753
795
  }
@@ -800,10 +842,10 @@ class ResultErr extends RetupleArray {
800
842
  return this;
801
843
  }
802
844
  $or(or) {
803
- return or;
845
+ return asResult(or);
804
846
  }
805
847
  $orElse(f) {
806
- return f(this[0]);
848
+ return asResult(f(this[0]));
807
849
  }
808
850
  $orSafe(f, mapError = ensureError) {
809
851
  try {
@@ -845,9 +887,6 @@ class ResultErr extends RetupleArray {
845
887
  $promise() {
846
888
  return Promise.resolve(this);
847
889
  }
848
- $tuple() {
849
- return [this[0], undefined];
850
- }
851
890
  *$iter() {
852
891
  return;
853
892
  }
@@ -900,37 +939,47 @@ class ResultAsync {
900
939
  return res instanceof ResultOk ? res[1] : f();
901
940
  }
902
941
  /**
903
- * The same as {@link Retuple.$map|$map}, except it returns `ResultAsync`.
942
+ * The same as {@link Retuple.$map|$map}, except it returns
943
+ * {@link ResultAsync}.
904
944
  */
905
945
  $map(f) {
906
946
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
907
- return res instanceof ResultOk ? Ok(f(res[1])) : res;
947
+ return res instanceof ResultOk
948
+ ? new ResultOk(f(res[1]))
949
+ : res;
908
950
  }));
909
951
  }
910
952
  /**
911
953
  * The same as {@link Retuple.$mapErr|$mapErr}, except it returns
912
- * `ResultAsync`.
954
+ * {@link ResultAsync}.
913
955
  */
914
956
  $mapErr(f) {
915
957
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
916
- return res instanceof ResultErr ? Err(f(res[0])) : res;
958
+ return res instanceof ResultErr
959
+ ? new ResultErr(f(res[0]))
960
+ : res;
917
961
  }));
918
962
  }
919
963
  /**
920
- * The same as {@link Retuple.$mapOr|$mapOr}, except it returns `ResultAsync`.
964
+ * The same as {@link Retuple.$mapOr|$mapOr}, except it returns
965
+ * {@link ResultAsync}.
921
966
  */
922
967
  $mapOr(def, f) {
923
968
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
924
- return res instanceof ResultOk ? Ok(f(res[1])) : Ok(def);
969
+ return res instanceof ResultOk
970
+ ? new ResultOk(f(res[1]))
971
+ : new ResultOk(def);
925
972
  }));
926
973
  }
927
974
  /**
928
975
  * The same as {@link Retuple.$mapOrElse|$mapOrElse}, except it returns
929
- * `ResultAsync`.
976
+ * {@link ResultAsync}.
930
977
  */
931
978
  $mapOrElse(def, f) {
932
979
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
933
- return res instanceof ResultOk ? Ok(f(res[1])) : Ok(def(res[0]));
980
+ return res instanceof ResultOk
981
+ ? new ResultOk(f(res[1]))
982
+ : new ResultOk(def(res[0]));
934
983
  }));
935
984
  }
936
985
  $andAssertOr(def, condition = isTruthy) {
@@ -938,7 +987,7 @@ class ResultAsync {
938
987
  if (res instanceof ResultErr || condition(res[1])) {
939
988
  return res;
940
989
  }
941
- return await def;
990
+ return asResult(await def);
942
991
  }));
943
992
  }
944
993
  $andAssertOrElse(def, condition = isTruthy) {
@@ -946,18 +995,20 @@ class ResultAsync {
946
995
  if (res instanceof ResultErr || condition(res[1])) {
947
996
  return res;
948
997
  }
949
- return await def(res[1]);
998
+ return asResult(await def(res[1]));
950
999
  }));
951
1000
  }
952
1001
  $or(or) {
953
1002
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
954
- return res instanceof ResultErr ? await or : res;
1003
+ return res instanceof ResultErr
1004
+ ? asResult(await or)
1005
+ : res;
955
1006
  }));
956
1007
  }
957
1008
  $orElse(f) {
958
1009
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
959
1010
  return res instanceof ResultErr
960
- ? await f(res[0])
1011
+ ? asResult(await f(res[0]))
961
1012
  : res;
962
1013
  }));
963
1014
  }
@@ -967,10 +1018,10 @@ class ResultAsync {
967
1018
  return res;
968
1019
  }
969
1020
  try {
970
- return Ok(await f(res[0]));
1021
+ return new ResultOk(await f(res[0]));
971
1022
  }
972
1023
  catch (err) {
973
- return Err(mapError(err));
1024
+ return new ResultErr(mapError(err));
974
1025
  }
975
1026
  }));
976
1027
  }
@@ -980,27 +1031,31 @@ class ResultAsync {
980
1031
  return res;
981
1032
  }
982
1033
  try {
983
- return Ok(await promise);
1034
+ return new ResultOk(await promise);
984
1035
  }
985
1036
  catch (err) {
986
- return Err(mapError(err));
1037
+ return new ResultErr(mapError(err));
987
1038
  }
988
1039
  }));
989
1040
  }
990
1041
  $and(and) {
991
1042
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
992
- return res instanceof ResultOk ? await and : res;
1043
+ return res instanceof ResultOk
1044
+ ? asResult(await and)
1045
+ : res;
993
1046
  }));
994
1047
  }
995
1048
  $andThen(f) {
996
1049
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
997
- return res instanceof ResultOk ? await f(res[1]) : res;
1050
+ return res instanceof ResultOk
1051
+ ? asResult(await f(res[1]))
1052
+ : res;
998
1053
  }));
999
1054
  }
1000
1055
  $andThrough(f) {
1001
1056
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1002
1057
  if (res instanceof ResultOk) {
1003
- const through = await f(res[1]);
1058
+ const through = asResult(await f(res[1]));
1004
1059
  if (through instanceof ResultErr) {
1005
1060
  return through;
1006
1061
  }
@@ -1038,7 +1093,7 @@ class ResultAsync {
1038
1093
  * The same as {@link Retuple.$peek|$peek}, except it:
1039
1094
  *
1040
1095
  * - awaits the peek function;
1041
- * - returns `ResultAsync`.
1096
+ * - returns {@link ResultAsync}.
1042
1097
  */
1043
1098
  $peek(f) {
1044
1099
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1050,7 +1105,7 @@ class ResultAsync {
1050
1105
  * The same as {@link Retuple.$tap|$tap}, except it:
1051
1106
  *
1052
1107
  * - awaits the tap function;
1053
- * - returns `ResultAsync`.
1108
+ * - returns {@link ResultAsync}.
1054
1109
  */
1055
1110
  $tap(f) {
1056
1111
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1064,7 +1119,7 @@ class ResultAsync {
1064
1119
  * The same as {@link Retuple.$tapErr|$tapErr}, except it:
1065
1120
  *
1066
1121
  * - awaits the tap error function;
1067
- * - returns `ResultAsync`.
1122
+ * - returns {@link ResultAsync}.
1068
1123
  */
1069
1124
  $tapErr(f) {
1070
1125
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1081,24 +1136,183 @@ class ResultAsync {
1081
1136
  return Promise.resolve(this);
1082
1137
  }
1083
1138
  /**
1084
- * The same as {@link Retuple.$tuple|$tuple}, except it returns a `Promise`.
1085
- */
1086
- async $tuple() {
1087
- return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$tuple();
1088
- }
1089
- /**
1090
- * The same as {@link Retuple.$tuple|$iter}, except it returns a `Promise`.
1139
+ * The same as {@link Retuple.$iter|$iter}, except it returns a `Promise`.
1091
1140
  */
1092
1141
  async $iter() {
1093
1142
  return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$iter();
1094
1143
  }
1095
1144
  }
1096
1145
  _ResultAsync_inner = new WeakMap();
1146
+ /**
1147
+ * ## ResultRetry
1148
+ */
1149
+ class ResultRetry {
1150
+ static zero() {
1151
+ return 0;
1152
+ }
1153
+ static delay(ms) {
1154
+ return new Promise((resolve) => setTimeout(resolve, Math.min(ms, _a.MAX_TIMEOUT)));
1155
+ }
1156
+ static integer(value) {
1157
+ if (typeof value === "number" && Number.isInteger(value)) {
1158
+ return Math.max(0, value);
1159
+ }
1160
+ return 0;
1161
+ }
1162
+ constructor(f) {
1163
+ _ResultRetry_f.set(this, void 0);
1164
+ _ResultRetry_promise.set(this, void 0);
1165
+ _ResultRetry_times.set(this, 1);
1166
+ _ResultRetry_attempt.set(this, 0);
1167
+ _ResultRetry_aborted.set(this, false);
1168
+ _ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
1169
+ _ResultRetry_getDelay.set(this, _a.zero);
1170
+ _ResultRetry_handler.set(this, void 0);
1171
+ __classPrivateFieldSet(this, _ResultRetry_f, f, "f");
1172
+ __classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
1173
+ }
1174
+ then(onfulfilled, onrejected) {
1175
+ return __classPrivateFieldGet(this, _ResultRetry_promise, "f").then(onfulfilled, onrejected);
1176
+ }
1177
+ /**
1178
+ * Sets the maximum number of times the retry function can be executed,
1179
+ * mutating this `ResultRetry` instance.
1180
+ *
1181
+ * **The default value is 1 - meaning that unless set, no retries will be
1182
+ * attempted.**
1183
+ *
1184
+ * The retry function can be called up to the maximum number of times until
1185
+ * it returns `Ok`. If it never returns `Ok`, the most recent `Err` is
1186
+ * returned.
1187
+ *
1188
+ * This function accepts a positive integer between 1 and 100:
1189
+ *
1190
+ * - Integers outside of this range are clamped to the nearest valid value;
1191
+ * - Any other value (NaN, Infinity, fractions, strings) are treated as 1.
1192
+ *
1193
+ * @example
1194
+ *
1195
+ * ```ts
1196
+ * // Retry someResultFn up to 3 times until Ok is returned:
1197
+ * const result = await Result.$retry(someResultFn).$times(3);
1198
+ * ```
1199
+ */
1200
+ $times(times) {
1201
+ __classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
1202
+ return this;
1203
+ }
1204
+ $delay(fnOrMs) {
1205
+ if (typeof fnOrMs === "function") {
1206
+ __classPrivateFieldSet(this, _ResultRetry_getDelay, fnOrMs, "f");
1207
+ return this;
1208
+ }
1209
+ const delay = _a.integer(fnOrMs);
1210
+ if (delay > 0) {
1211
+ __classPrivateFieldSet(this, _ResultRetry_getDelay, () => delay, "f");
1212
+ }
1213
+ return this;
1214
+ }
1215
+ /**
1216
+ * Sets a handler to be called when an attempt returns `Err`, mutating this
1217
+ * `ResultRetry` instance. The handler can be used to capture information
1218
+ * about each failure, and to abort early and prevent further retries.
1219
+ *
1220
+ * The handler function is called with `ResultRetryHandleState`, containing:
1221
+ *
1222
+ * - **error** - The error value from the last failed attempt;
1223
+ * - **attempt** - The attempt number;
1224
+ * - **abort** - A function which when called, prevents further retries.
1225
+ *
1226
+ * @example
1227
+ *
1228
+ * ```ts
1229
+ * // Retry someResultFn up to 3 times until Ok is returned, logging each
1230
+ * // attempt and aborting early if the error code is "UNAUTHORIZED".
1231
+ * const result = await Result.$retry(someResultFn)
1232
+ * .$times(3)
1233
+ * .$handle(({ error, attempt, abort }) => {
1234
+ * console.info(`Attempt ${attempt} failed: ${error}`);
1235
+ * if (error === "UNAUTHORIZED") {
1236
+ * abort();
1237
+ * }
1238
+ * });
1239
+ * ```
1240
+ */
1241
+ $handle(f) {
1242
+ __classPrivateFieldSet(this, _ResultRetry_handler, f, "f");
1243
+ return this;
1244
+ }
1245
+ /**
1246
+ * Returns {@link ResultAsync} which resolves to this retried {@link Result}.
1247
+ *
1248
+ * @example
1249
+ *
1250
+ * ```ts
1251
+ * const result: Result<string, SomeError> = await Result
1252
+ * .$retry(someResultFn)
1253
+ * .$times(3)
1254
+ * .$delay(100)
1255
+ * .$async()
1256
+ * .$andThen((message) => `Success: ${message}`)
1257
+ * .$mapErr((code) => new SomeError({ code }));
1258
+ * ```
1259
+ */
1260
+ $async() {
1261
+ return new ResultAsync(this);
1262
+ }
1263
+ /**
1264
+ * Returns a `Promise` which resolves to this retried {@link Result}.
1265
+ *
1266
+ * @example
1267
+ *
1268
+ * ```ts
1269
+ * const promise: Promise<Result<string, Error>> = Result
1270
+ * .$retry(someResultFn)
1271
+ * .$times(3)
1272
+ * .$promise();
1273
+ * ```
1274
+ */
1275
+ $promise() {
1276
+ return Promise.resolve(this);
1277
+ }
1278
+ async drain() {
1279
+ var _b;
1280
+ while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1281
+ const result = asResult(await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this));
1282
+ __classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
1283
+ if (result.$isOk()) {
1284
+ return result;
1285
+ }
1286
+ if (__classPrivateFieldGet(this, _ResultRetry_handler, "f")) {
1287
+ await __classPrivateFieldGet(this, _ResultRetry_handler, "f").call(this, {
1288
+ error: result[0],
1289
+ attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
1290
+ abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
1291
+ });
1292
+ }
1293
+ if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") >= __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1294
+ return result;
1295
+ }
1296
+ const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
1297
+ if (delay > 0) {
1298
+ await _a.delay(delay);
1299
+ }
1300
+ }
1301
+ /* v8 ignore next */
1302
+ throw new Error("Retuple: Unreachable code executed");
1303
+ }
1304
+ }
1305
+ _a = ResultRetry, _ResultRetry_f = new WeakMap(), _ResultRetry_promise = new WeakMap(), _ResultRetry_times = new WeakMap(), _ResultRetry_attempt = new WeakMap(), _ResultRetry_aborted = new WeakMap(), _ResultRetry_abort = new WeakMap(), _ResultRetry_getDelay = new WeakMap(), _ResultRetry_handler = new WeakMap();
1306
+ ResultRetry.MAX_TIMEOUT = 3600000;
1307
+ ResultRetry.MAX_RETRY = 100;
1308
+ function asResult(resultLike) {
1309
+ return resultLike[ResultLikeSymbol]();
1310
+ }
1097
1311
  function ensureError(err) {
1098
1312
  if (err instanceof Error) {
1099
1313
  return err;
1100
1314
  }
1101
- return new RetupleThrownValueError(err);
1315
+ return new RetupleCaughtValueError(err);
1102
1316
  }
1103
1317
  function mapTrue() {
1104
1318
  return true;