retuple 1.0.0-next.13 → 1.0.0-next.15

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.cjs CHANGED
@@ -10,12 +10,47 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_errorHandler;
13
+ var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_handler;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.RetupleArrayMethodUnavailableError = exports.RetupleInvalidUnionError = exports.RetupleInvalidResultError = exports.RetupleThrownValueError = exports.RetupleFlattenFailed = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
15
+ exports.RetupleArrayMethodUnavailableError = exports.RetupleInvalidUnionError = exports.RetupleCaughtValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = exports.ResultLikeSymbol = void 0;
16
16
  exports.Result = Result;
17
17
  exports.Ok = Ok;
18
18
  exports.Err = Err;
19
+ /**
20
+ * ## Result Like Symbol
21
+ *
22
+ * Implement a custom result-like by implementing the `ResultLike` interface
23
+ * on a class or object. An object with this implementation can be converted
24
+ * to a `Result` and can be used in most places where a `Result` is required.
25
+ *
26
+ * ```ts
27
+ * import { ResultLikeSymbol } from "retuple/symbol";
28
+ * import { Result, Ok, Err, type ResultLike } from "retuple";
29
+ *
30
+ * class CustomResult<T> implements ResultLike<T, CustomError> {
31
+ * value: T;
32
+ *
33
+ * constructor(value: T) {
34
+ * this.value = value;
35
+ * }
36
+ *
37
+ * [ResultLikeSymbol](): Result<T, CustomError> {
38
+ * return this.value === "test"
39
+ * ? Ok(this.value)
40
+ * : Err(new CustomError("Value was not test"));
41
+ * }
42
+ * }
43
+ *
44
+ * const custom = new CustomResult("test");
45
+ * const result: Result<string, Error> = Result(custom);
46
+ *
47
+ * const chain = Ok()
48
+ * .$map(() => "value")
49
+ * .$andThen((value) => new CustomResult(value))
50
+ * .$or(myresult);
51
+ * ```
52
+ */
53
+ exports.ResultLikeSymbol = Symbol("retuple/result");
19
54
  /**
20
55
  * ## Retuple Unwrap Failed
21
56
  *
@@ -53,19 +88,6 @@ class RetupleExpectFailed extends Error {
53
88
  }
54
89
  }
55
90
  exports.RetupleExpectFailed = RetupleExpectFailed;
56
- /**
57
- * ## Retuple Expect Failed
58
- *
59
- * An error which occurs when calling `$flatten` on `Ok`, when the value
60
- * contained in the `Ok` is not an `Ok` or `Err`.
61
- */
62
- class RetupleFlattenFailed extends Error {
63
- constructor(value) {
64
- super("Flatten Result failed, the contained value was not a Result");
65
- this.value = value;
66
- }
67
- }
68
- exports.RetupleFlattenFailed = RetupleFlattenFailed;
69
91
  /**
70
92
  * ## Retuple Thrown Value Error
71
93
  *
@@ -73,28 +95,13 @@ exports.RetupleFlattenFailed = RetupleFlattenFailed;
73
95
  * thrown error or rejected value is not an instance of `Error`, and when no
74
96
  * map error function is provided.
75
97
  */
76
- class RetupleThrownValueError extends Error {
98
+ class RetupleCaughtValueError extends Error {
77
99
  constructor(value) {
78
100
  super("Caught value was not an instance of Error");
79
101
  this.value = value;
80
102
  }
81
103
  }
82
- exports.RetupleThrownValueError = RetupleThrownValueError;
83
- /**
84
- * ## Retuple Invalid Result Error
85
- *
86
- * This error is thrown when attempting to construct a `Result` from a tuple,
87
- * when neither index 0 or 1 are null or undefined. In this case, it is
88
- * impossible to determine whether the result should be `Ok` or `Err`.
89
- */
90
- class RetupleInvalidResultError extends Error {
91
- constructor(value) {
92
- super("Constructing a Result from native tuple failed, at least one of the " +
93
- "values at index 0 or 1 should be null or undefined");
94
- this.value = value;
95
- }
96
- }
97
- exports.RetupleInvalidResultError = RetupleInvalidResultError;
104
+ exports.RetupleCaughtValueError = RetupleCaughtValueError;
98
105
  /**
99
106
  * ## Retuple Invalid Union Error
100
107
  *
@@ -130,26 +137,20 @@ exports.RetupleArrayMethodUnavailableError = RetupleArrayMethodUnavailableError;
130
137
  * @TODO
131
138
  */
132
139
  function Result(resultLike) {
133
- const [err, ok] = resultLike;
134
- if (err === null || err === undefined) {
135
- return new ResultOk(ok);
136
- }
137
- if (ok === null || ok === undefined) {
138
- return new ResultErr(err);
139
- }
140
- throw new RetupleInvalidResultError(resultLike);
140
+ return asResult(resultLike);
141
141
  }
142
142
  Result.Ok = Ok;
143
143
  Result.Err = Err;
144
- Result.$resolve = resolve;
145
- Result.$nonNullable = nonNullable;
146
- Result.$truthy = truthy;
147
- Result.$union = union;
148
- Result.$safe = safe;
149
- Result.$safeAsync = safeAsync;
150
- Result.$safePromise = safePromise;
151
- Result.$retry = retry;
152
- Result.$safeRetry = safeRetry;
144
+ Result.$from = $from;
145
+ Result.$resolve = $resolve;
146
+ Result.$nonNullable = $nonNullable;
147
+ Result.$truthy = $truthy;
148
+ Result.$fromUnion = $fromUnion;
149
+ Result.$safe = $safe;
150
+ Result.$safeAsync = $safeAsync;
151
+ Result.$safePromise = $safePromise;
152
+ Result.$retry = $retry;
153
+ Result.$safeRetry = $safeRetry;
153
154
  Object.freeze(Result);
154
155
  function Ok(val) {
155
156
  return new ResultOk(val);
@@ -158,35 +159,110 @@ function Err(err) {
158
159
  return new ResultErr(err);
159
160
  }
160
161
  /**
161
- * @TODO
162
+ * Construct a {@link Result} from a {@link ResultLike}.
163
+ *
164
+ * @example
165
+ *
166
+ * ```ts
167
+ * const value: Result<T, E> | ResultLike<T, E> = someResultFn();
168
+ * const result: Result<T, E> = Result.$from(result);
169
+ * ```
162
170
  */
163
- function resolve(result) {
164
- if (result instanceof ResultAsync) {
171
+ function $from(result) {
172
+ if (result instanceof ResultOk || result instanceof ResultErr) {
165
173
  return result;
166
174
  }
167
- else if (result instanceof ResultOk || result instanceof ResultErr) {
168
- return result.$async();
169
- }
170
- else {
171
- return new ResultAsync(result);
175
+ return asResult(result);
176
+ }
177
+ /**
178
+ * Construct a {@link ResultAsync} from a {@link ResultLikeAwaitable}.
179
+ *
180
+ * @example
181
+ *
182
+ * ```ts
183
+ * const value:
184
+ * | Result<T, E>
185
+ * | ResultLike<T, E>
186
+ * | ResultAsync<T, E>
187
+ * | Promise<Result<T, E>>
188
+ * | Promise<ResultLike<T, E>>
189
+ * | PromiseLike<Result<T, E>>
190
+ * | PromiseLike<ResultLike<T, E>> = someResultFn();
191
+ *
192
+ * const result: ResultAsync<T, E> = Result.$resolve(result);
193
+ * ```
194
+ */
195
+ function $resolve(result) {
196
+ switch (true) {
197
+ case result instanceof ResultAsync:
198
+ return result;
199
+ case result instanceof ResultRetry:
200
+ return new ResultAsync(result);
201
+ case result instanceof ResultOk:
202
+ case result instanceof ResultErr:
203
+ return new ResultAsync(Promise.resolve(result));
204
+ default:
205
+ return new ResultAsync(Promise.resolve(result).then((asResult)));
172
206
  }
173
207
  }
174
- function nonNullable(value, error = mapTrue) {
208
+ function $nonNullable(value, error = mapTrue) {
175
209
  if (value !== null && value !== undefined) {
176
210
  return Ok(value);
177
211
  }
178
212
  return Err(error());
179
213
  }
180
- function truthy(value, error = mapTrue) {
214
+ function $truthy(value, error = mapTrue) {
181
215
  if (value) {
182
216
  return Ok(value);
183
217
  }
184
218
  return Err(error());
185
219
  }
186
220
  /**
187
- * @TODO
221
+ * Construct a {@link Result} from a common discriminated union shape. If the
222
+ * union is 'success' then the result is `Ok`
223
+ *
224
+ * Otherwise, the result is `Err` containing:
225
+ *
226
+ * - the returned value from the error function when provided;
227
+ * - or `true` otherwise.
228
+ *
229
+ * @example
230
+ *
231
+ * ```ts
232
+ * const result: Result<string, Error> = Result.$truthy(
233
+ * username.trim(),
234
+ * () => new Error("Username is empty"),
235
+ * );
236
+ * ```
237
+ *
238
+ * @example
239
+ *
240
+ * ```ts
241
+ * const [err, value] = Result.$truthy("test");
242
+ *
243
+ * assert.equal(err, undefined);
244
+ * assert.equal(value, "test");
245
+ * ```
246
+ *
247
+ * @example
248
+ *
249
+ * ```ts
250
+ * const [err, value] = Result.$truthy("");
251
+ *
252
+ * assert.equal(err, true);
253
+ * assert.equal(value, undefined);
254
+ * ```
255
+ *
256
+ * @example
257
+ *
258
+ * ```ts
259
+ * const [err, value] = Result.$truthy(0, () => "error");
260
+ *
261
+ * assert.equal(err, "error");
262
+ * assert.equal(value, undefined);
263
+ * ```
188
264
  */
189
- function union(union) {
265
+ function $fromUnion(union) {
190
266
  if (union.success === true) {
191
267
  return Ok(union.data);
192
268
  }
@@ -195,7 +271,7 @@ function union(union) {
195
271
  }
196
272
  throw new RetupleInvalidUnionError(union);
197
273
  }
198
- function safe(f, mapError = ensureError) {
274
+ function $safe(f, mapError = ensureError) {
199
275
  try {
200
276
  return Ok(f());
201
277
  }
@@ -203,7 +279,7 @@ function safe(f, mapError = ensureError) {
203
279
  return Err(mapError(err));
204
280
  }
205
281
  }
206
- function safeAsync(f, mapError = ensureError) {
282
+ function $safeAsync(f, mapError = ensureError) {
207
283
  return new ResultAsync((async () => {
208
284
  try {
209
285
  return Ok(await f());
@@ -213,16 +289,29 @@ function safeAsync(f, mapError = ensureError) {
213
289
  }
214
290
  })());
215
291
  }
216
- function safePromise(promise, mapError = ensureError) {
292
+ function $safePromise(promise, mapError = ensureError) {
217
293
  return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
218
294
  }
219
295
  /**
220
- * @TODO
296
+ * Construct a {@link ResultRetry} from a function which returns a
297
+ * {@link Result}. The function will be retried based on provided retry
298
+ * settings and eventually return a `Result`. No attempt is made to catch
299
+ * thrown errors or promise rejections.
300
+ *
301
+ * To retry a potentially unsafe function, use {@link Result.$safeRetry}.
302
+ *
303
+ * @example
304
+ *
305
+ * ```ts
306
+ * // Retry someResultFn up to 3 times until Ok is returned,
307
+ * // with a 1 second delay between each invocation:
308
+ * const result = await Result.$retry(someResultFn).$times(3).$delay(1000);
309
+ * ```
221
310
  */
222
- function retry(f) {
311
+ function $retry(f) {
223
312
  return new ResultRetry(f);
224
313
  }
225
- function safeRetry(f, mapError = ensureError) {
314
+ function $safeRetry(f, mapError = ensureError) {
226
315
  return new ResultRetry(async () => {
227
316
  try {
228
317
  return Ok(await f());
@@ -242,8 +331,7 @@ class RetupleArray extends Array {
242
331
  /**
243
332
  * ## Method not available
244
333
  *
245
- * Built-in array methods not available on `Result` types, convert the result
246
- * to a tuple using `$tuple()` first.
334
+ * Built-in array methods not available on {@link Result} types.
247
335
  *
248
336
  * @deprecated
249
337
  */
@@ -253,8 +341,7 @@ class RetupleArray extends Array {
253
341
  /**
254
342
  * ## Method not available
255
343
  *
256
- * Built-in array methods not available on `Result` types, convert the result
257
- * to a tuple using `$tuple()` first.
344
+ * Built-in array methods not available on {@link Result} types.
258
345
  *
259
346
  * @deprecated
260
347
  */
@@ -264,8 +351,7 @@ class RetupleArray extends Array {
264
351
  /**
265
352
  * ## Method not available
266
353
  *
267
- * Built-in array methods not available on `Result` types, convert the result
268
- * to a tuple using `$tuple()` first.
354
+ * Built-in array methods not available on {@link Result} types.
269
355
  *
270
356
  * @deprecated
271
357
  */
@@ -275,8 +361,7 @@ class RetupleArray extends Array {
275
361
  /**
276
362
  * ## Method not available
277
363
  *
278
- * Built-in array methods not available on `Result` types, convert the result
279
- * to a tuple using `$tuple()` first.
364
+ * Built-in array methods not available on {@link Result} types.
280
365
  *
281
366
  * @deprecated
282
367
  */
@@ -286,8 +371,7 @@ class RetupleArray extends Array {
286
371
  /**
287
372
  * ## Method not available
288
373
  *
289
- * Built-in array methods not available on `Result` types, convert the result
290
- * to a tuple using `$tuple()` first.
374
+ * Built-in array methods not available on {@link Result} types.
291
375
  *
292
376
  * @deprecated
293
377
  */
@@ -297,8 +381,7 @@ class RetupleArray extends Array {
297
381
  /**
298
382
  * ## Method not available
299
383
  *
300
- * Built-in array methods not available on `Result` types, convert the result
301
- * to a tuple using `$tuple()` first.
384
+ * Built-in array methods not available on {@link Result} types.
302
385
  *
303
386
  * @deprecated
304
387
  */
@@ -308,8 +391,7 @@ class RetupleArray extends Array {
308
391
  /**
309
392
  * ## Method not available
310
393
  *
311
- * Built-in array methods not available on `Result` types, convert the result
312
- * to a tuple using `$tuple()` first.
394
+ * Built-in array methods not available on {@link Result} types.
313
395
  *
314
396
  * @deprecated
315
397
  */
@@ -319,8 +401,7 @@ class RetupleArray extends Array {
319
401
  /**
320
402
  * ## Method not available
321
403
  *
322
- * Built-in array methods not available on `Result` types, convert the result
323
- * to a tuple using `$tuple()` first.
404
+ * Built-in array methods not available on {@link Result} types.
324
405
  *
325
406
  * @deprecated
326
407
  */
@@ -330,8 +411,7 @@ class RetupleArray extends Array {
330
411
  /**
331
412
  * ## Method not available
332
413
  *
333
- * Built-in array methods not available on `Result` types, convert the result
334
- * to a tuple using `$tuple()` first.
414
+ * Built-in array methods not available on {@link Result} types.
335
415
  *
336
416
  * @deprecated
337
417
  */
@@ -341,8 +421,7 @@ class RetupleArray extends Array {
341
421
  /**
342
422
  * ## Method not available
343
423
  *
344
- * Built-in array methods not available on `Result` types, convert the result
345
- * to a tuple using `$tuple()` first.
424
+ * Built-in array methods not available on {@link Result} types.
346
425
  *
347
426
  * @deprecated
348
427
  */
@@ -352,8 +431,7 @@ class RetupleArray extends Array {
352
431
  /**
353
432
  * ## Method not available
354
433
  *
355
- * Built-in array methods not available on `Result` types, convert the result
356
- * to a tuple using `$tuple()` first.
434
+ * Built-in array methods not available on {@link Result} types.
357
435
  *
358
436
  * @deprecated
359
437
  */
@@ -363,8 +441,7 @@ class RetupleArray extends Array {
363
441
  /**
364
442
  * ## Method not available
365
443
  *
366
- * Built-in array methods not available on `Result` types, convert the result
367
- * to a tuple using `$tuple()` first.
444
+ * Built-in array methods not available on {@link Result} types.
368
445
  *
369
446
  * @deprecated
370
447
  */
@@ -374,8 +451,7 @@ class RetupleArray extends Array {
374
451
  /**
375
452
  * ## Method not available
376
453
  *
377
- * Built-in array methods not available on `Result` types, convert the result
378
- * to a tuple using `$tuple()` first.
454
+ * Built-in array methods not available on {@link Result} types.
379
455
  *
380
456
  * @deprecated
381
457
  */
@@ -385,8 +461,7 @@ class RetupleArray extends Array {
385
461
  /**
386
462
  * ## Method not available
387
463
  *
388
- * Built-in array methods not available on `Result` types, convert the result
389
- * to a tuple using `$tuple()` first.
464
+ * Built-in array methods not available on {@link Result} types.
390
465
  *
391
466
  * @deprecated
392
467
  */
@@ -396,8 +471,7 @@ class RetupleArray extends Array {
396
471
  /**
397
472
  * ## Method not available
398
473
  *
399
- * Built-in array methods not available on `Result` types, convert the result
400
- * to a tuple using `$tuple()` first.
474
+ * Built-in array methods not available on {@link Result} types.
401
475
  *
402
476
  * @deprecated
403
477
  */
@@ -407,8 +481,7 @@ class RetupleArray extends Array {
407
481
  /**
408
482
  * ## Method not available
409
483
  *
410
- * Built-in array methods not available on `Result` types, convert the result
411
- * to a tuple using `$tuple()` first.
484
+ * Built-in array methods not available on {@link Result} types.
412
485
  *
413
486
  * @deprecated
414
487
  */
@@ -418,8 +491,7 @@ class RetupleArray extends Array {
418
491
  /**
419
492
  * ## Method not available
420
493
  *
421
- * Built-in array methods not available on `Result` types, convert the result
422
- * to a tuple using `$tuple()` first.
494
+ * Built-in array methods not available on {@link Result} types.
423
495
  *
424
496
  * @deprecated
425
497
  */
@@ -429,8 +501,7 @@ class RetupleArray extends Array {
429
501
  /**
430
502
  * ## Method not available
431
503
  *
432
- * Built-in array methods not available on `Result` types, convert the result
433
- * to a tuple using `$tuple()` first.
504
+ * Built-in array methods not available on {@link Result} types.
434
505
  *
435
506
  * @deprecated
436
507
  */
@@ -440,8 +511,7 @@ class RetupleArray extends Array {
440
511
  /**
441
512
  * ## Method not available
442
513
  *
443
- * Built-in array methods not available on `Result` types, convert the result
444
- * to a tuple using `$tuple()` first.
514
+ * Built-in array methods not available on {@link Result} types.
445
515
  *
446
516
  * @deprecated
447
517
  */
@@ -451,8 +521,7 @@ class RetupleArray extends Array {
451
521
  /**
452
522
  * ## Method not available
453
523
  *
454
- * Built-in array methods not available on `Result` types, convert the result
455
- * to a tuple using `$tuple()` first.
524
+ * Built-in array methods not available on {@link Result} types.
456
525
  *
457
526
  * @deprecated
458
527
  */
@@ -462,8 +531,7 @@ class RetupleArray extends Array {
462
531
  /**
463
532
  * ## Method not available
464
533
  *
465
- * Built-in array methods not available on `Result` types, convert the result
466
- * to a tuple using `$tuple()` first.
534
+ * Built-in array methods not available on {@link Result} types.
467
535
  *
468
536
  * @deprecated
469
537
  */
@@ -473,8 +541,7 @@ class RetupleArray extends Array {
473
541
  /**
474
542
  * ## Method not available
475
543
  *
476
- * Built-in array methods not available on `Result` types, convert the result
477
- * to a tuple using `$tuple()` first.
544
+ * Built-in array methods not available on {@link Result} types.
478
545
  *
479
546
  * @deprecated
480
547
  */
@@ -484,8 +551,7 @@ class RetupleArray extends Array {
484
551
  /**
485
552
  * ## Method not available
486
553
  *
487
- * Built-in array methods not available on `Result` types, convert the result
488
- * to a tuple using `$tuple()` first.
554
+ * Built-in array methods not available on {@link Result} types.
489
555
  *
490
556
  * @deprecated
491
557
  */
@@ -495,8 +561,7 @@ class RetupleArray extends Array {
495
561
  /**
496
562
  * ## Method not available
497
563
  *
498
- * Built-in array methods not available on `Result` types, convert the result
499
- * to a tuple using `$tuple()` first.
564
+ * Built-in array methods not available on {@link Result} types.
500
565
  *
501
566
  * @deprecated
502
567
  */
@@ -506,8 +571,7 @@ class RetupleArray extends Array {
506
571
  /**
507
572
  * ## Method not available
508
573
  *
509
- * Built-in array methods not available on `Result` types, convert the result
510
- * to a tuple using `$tuple()` first.
574
+ * Built-in array methods not available on {@link Result} types.
511
575
  *
512
576
  * @deprecated
513
577
  */
@@ -517,8 +581,7 @@ class RetupleArray extends Array {
517
581
  /**
518
582
  * ## Method not available
519
583
  *
520
- * Built-in array methods not available on `Result` types, convert the result
521
- * to a tuple using `$tuple()` first.
584
+ * Built-in array methods not available on {@link Result} types.
522
585
  *
523
586
  * @deprecated
524
587
  */
@@ -528,8 +591,7 @@ class RetupleArray extends Array {
528
591
  /**
529
592
  * ## Method not available
530
593
  *
531
- * Built-in array methods not available on `Result` types, convert the result
532
- * to a tuple using `$tuple()` first.
594
+ * Built-in array methods not available on {@link Result} types.
533
595
  *
534
596
  * @deprecated
535
597
  */
@@ -539,8 +601,7 @@ class RetupleArray extends Array {
539
601
  /**
540
602
  * ## Method not available
541
603
  *
542
- * Built-in array methods not available on `Result` types, convert the result
543
- * to a tuple using `$tuple()` first.
604
+ * Built-in array methods not available on {@link Result} types.
544
605
  *
545
606
  * @deprecated
546
607
  */
@@ -550,8 +611,7 @@ class RetupleArray extends Array {
550
611
  /**
551
612
  * ## Method not available
552
613
  *
553
- * Built-in array methods not available on `Result` types, convert the result
554
- * to a tuple using `$tuple()` first.
614
+ * Built-in array methods not available on {@link Result} types.
555
615
  *
556
616
  * @deprecated
557
617
  */
@@ -561,8 +621,7 @@ class RetupleArray extends Array {
561
621
  /**
562
622
  * ## Method not available
563
623
  *
564
- * Built-in array methods not available on `Result` types, convert the result
565
- * to a tuple using `$tuple()` first.
624
+ * Built-in array methods not available on {@link Result} types.
566
625
  *
567
626
  * @deprecated
568
627
  */
@@ -572,8 +631,7 @@ class RetupleArray extends Array {
572
631
  /**
573
632
  * ## Method not available
574
633
  *
575
- * Built-in array methods not available on `Result` types, convert the result
576
- * to a tuple using `$tuple()` first.
634
+ * Built-in array methods not available on {@link Result} types.
577
635
  *
578
636
  * @deprecated
579
637
  */
@@ -583,8 +641,7 @@ class RetupleArray extends Array {
583
641
  /**
584
642
  * ## Method not available
585
643
  *
586
- * Built-in array methods not available on `Result` types, convert the result
587
- * to a tuple using `$tuple()` first.
644
+ * Built-in array methods not available on {@link Result} types.
588
645
  *
589
646
  * @deprecated
590
647
  */
@@ -594,8 +651,7 @@ class RetupleArray extends Array {
594
651
  /**
595
652
  * ## Method not available
596
653
  *
597
- * Built-in array methods not available on `Result` types, convert the result
598
- * to a tuple using `$tuple()` first.
654
+ * Built-in array methods not available on {@link Result} types.
599
655
  *
600
656
  * @deprecated
601
657
  */
@@ -605,8 +661,7 @@ class RetupleArray extends Array {
605
661
  /**
606
662
  * ## Method not available
607
663
  *
608
- * Built-in array methods not available on `Result` types, convert the result
609
- * to a tuple using `$tuple()` first.
664
+ * Built-in array methods not available on {@link Result} types.
610
665
  *
611
666
  * @deprecated
612
667
  */
@@ -616,8 +671,7 @@ class RetupleArray extends Array {
616
671
  /**
617
672
  * ## Method not available
618
673
  *
619
- * Built-in array methods not available on `Result` types, convert the result
620
- * to a tuple using `$tuple()` first.
674
+ * Built-in array methods not available on {@link Result} types.
621
675
  *
622
676
  * @deprecated
623
677
  */
@@ -627,8 +681,7 @@ class RetupleArray extends Array {
627
681
  /**
628
682
  * ## Method not available
629
683
  *
630
- * Built-in array methods not available on `Result` types, convert the result
631
- * to a tuple using `$tuple()` first.
684
+ * Built-in array methods not available on {@link Result} types.
632
685
  *
633
686
  * @deprecated
634
687
  */
@@ -638,8 +691,7 @@ class RetupleArray extends Array {
638
691
  /**
639
692
  * ## Method not available
640
693
  *
641
- * Built-in array methods not available on `Result` types, convert the result
642
- * to a tuple using `$tuple()` first.
694
+ * Built-in array methods not available on {@link Result} types.
643
695
  *
644
696
  * @deprecated
645
697
  */
@@ -649,8 +701,7 @@ class RetupleArray extends Array {
649
701
  /**
650
702
  * ## Method not available
651
703
  *
652
- * Built-in array methods not available on `Result` types, convert the result
653
- * to a tuple using `$tuple()` first.
704
+ * Built-in array methods not available on {@link Result} types.
654
705
  *
655
706
  * @deprecated
656
707
  */
@@ -669,6 +720,9 @@ class ResultOk extends RetupleArray {
669
720
  this[0] = undefined;
670
721
  this[1] = value;
671
722
  }
723
+ [exports.ResultLikeSymbol]() {
724
+ return this;
725
+ }
672
726
  toJSON() {
673
727
  return this[1];
674
728
  }
@@ -712,10 +766,10 @@ class ResultOk extends RetupleArray {
712
766
  return Ok(f(this[1]));
713
767
  }
714
768
  $andAssertOr(def, condition = isTruthy) {
715
- return condition(this[1]) ? this : def;
769
+ return condition(this[1]) ? this : asResult(def);
716
770
  }
717
771
  $andAssertOrElse(def, condition = isTruthy) {
718
- return condition(this[1]) ? this : def(this[1]);
772
+ return condition(this[1]) ? this : asResult(def(this[1]));
719
773
  }
720
774
  $or() {
721
775
  return this;
@@ -727,13 +781,13 @@ class ResultOk extends RetupleArray {
727
781
  return this;
728
782
  }
729
783
  $and(and) {
730
- return and;
784
+ return asResult(and);
731
785
  }
732
786
  $andThen(f) {
733
- return f(this[1]);
787
+ return asResult(f(this[1]));
734
788
  }
735
789
  $andThrough(f) {
736
- const res = f(this[1]);
790
+ const res = asResult(f(this[1]));
737
791
  return res instanceof ResultErr ? res : this;
738
792
  }
739
793
  $andSafe(f, mapError = ensureError) {
@@ -756,11 +810,7 @@ class ResultOk extends RetupleArray {
756
810
  return this;
757
811
  }
758
812
  $flatten() {
759
- const inner = this[1];
760
- if (inner instanceof ResultOk || inner instanceof ResultErr) {
761
- return inner;
762
- }
763
- throw new RetupleFlattenFailed(this[1]);
813
+ return this[1];
764
814
  }
765
815
  $async() {
766
816
  return new ResultAsync(Promise.resolve(this));
@@ -768,9 +818,6 @@ class ResultOk extends RetupleArray {
768
818
  $promise() {
769
819
  return Promise.resolve(this);
770
820
  }
771
- $tuple() {
772
- return [undefined, this[1]];
773
- }
774
821
  *$iter() {
775
822
  yield* this[1];
776
823
  }
@@ -786,6 +833,9 @@ class ResultErr extends RetupleArray {
786
833
  this[0] = err;
787
834
  this[1] = undefined;
788
835
  }
836
+ [exports.ResultLikeSymbol]() {
837
+ return this;
838
+ }
789
839
  toJSON() {
790
840
  return null;
791
841
  }
@@ -838,10 +888,10 @@ class ResultErr extends RetupleArray {
838
888
  return this;
839
889
  }
840
890
  $or(or) {
841
- return or;
891
+ return asResult(or);
842
892
  }
843
893
  $orElse(f) {
844
- return f(this[0]);
894
+ return asResult(f(this[0]));
845
895
  }
846
896
  $orSafe(f, mapError = ensureError) {
847
897
  try {
@@ -883,9 +933,6 @@ class ResultErr extends RetupleArray {
883
933
  $promise() {
884
934
  return Promise.resolve(this);
885
935
  }
886
- $tuple() {
887
- return [this[0], undefined];
888
- }
889
936
  *$iter() {
890
937
  return;
891
938
  }
@@ -938,37 +985,47 @@ class ResultAsync {
938
985
  return res instanceof ResultOk ? res[1] : f();
939
986
  }
940
987
  /**
941
- * The same as {@link Retuple.$map|$map}, except it returns `ResultAsync`.
988
+ * The same as {@link Retuple.$map|$map}, except it returns
989
+ * {@link ResultAsync}.
942
990
  */
943
991
  $map(f) {
944
992
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
945
- return res instanceof ResultOk ? Ok(f(res[1])) : res;
993
+ return res instanceof ResultOk
994
+ ? new ResultOk(f(res[1]))
995
+ : res;
946
996
  }));
947
997
  }
948
998
  /**
949
999
  * The same as {@link Retuple.$mapErr|$mapErr}, except it returns
950
- * `ResultAsync`.
1000
+ * {@link ResultAsync}.
951
1001
  */
952
1002
  $mapErr(f) {
953
1003
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
954
- return res instanceof ResultErr ? Err(f(res[0])) : res;
1004
+ return res instanceof ResultErr
1005
+ ? new ResultErr(f(res[0]))
1006
+ : res;
955
1007
  }));
956
1008
  }
957
1009
  /**
958
- * The same as {@link Retuple.$mapOr|$mapOr}, except it returns `ResultAsync`.
1010
+ * The same as {@link Retuple.$mapOr|$mapOr}, except it returns
1011
+ * {@link ResultAsync}.
959
1012
  */
960
1013
  $mapOr(def, f) {
961
1014
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
962
- return res instanceof ResultOk ? Ok(f(res[1])) : Ok(def);
1015
+ return res instanceof ResultOk
1016
+ ? new ResultOk(f(res[1]))
1017
+ : new ResultOk(def);
963
1018
  }));
964
1019
  }
965
1020
  /**
966
1021
  * The same as {@link Retuple.$mapOrElse|$mapOrElse}, except it returns
967
- * `ResultAsync`.
1022
+ * {@link ResultAsync}.
968
1023
  */
969
1024
  $mapOrElse(def, f) {
970
1025
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
971
- return res instanceof ResultOk ? Ok(f(res[1])) : Ok(def(res[0]));
1026
+ return res instanceof ResultOk
1027
+ ? new ResultOk(f(res[1]))
1028
+ : new ResultOk(def(res[0]));
972
1029
  }));
973
1030
  }
974
1031
  $andAssertOr(def, condition = isTruthy) {
@@ -976,7 +1033,7 @@ class ResultAsync {
976
1033
  if (res instanceof ResultErr || condition(res[1])) {
977
1034
  return res;
978
1035
  }
979
- return await def;
1036
+ return asResult(await def);
980
1037
  }));
981
1038
  }
982
1039
  $andAssertOrElse(def, condition = isTruthy) {
@@ -984,18 +1041,20 @@ class ResultAsync {
984
1041
  if (res instanceof ResultErr || condition(res[1])) {
985
1042
  return res;
986
1043
  }
987
- return await def(res[1]);
1044
+ return asResult(await def(res[1]));
988
1045
  }));
989
1046
  }
990
1047
  $or(or) {
991
1048
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
992
- return res instanceof ResultErr ? await or : res;
1049
+ return res instanceof ResultErr
1050
+ ? asResult(await or)
1051
+ : res;
993
1052
  }));
994
1053
  }
995
1054
  $orElse(f) {
996
1055
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
997
1056
  return res instanceof ResultErr
998
- ? await f(res[0])
1057
+ ? asResult(await f(res[0]))
999
1058
  : res;
1000
1059
  }));
1001
1060
  }
@@ -1005,10 +1064,10 @@ class ResultAsync {
1005
1064
  return res;
1006
1065
  }
1007
1066
  try {
1008
- return Ok(await f(res[0]));
1067
+ return new ResultOk(await f(res[0]));
1009
1068
  }
1010
1069
  catch (err) {
1011
- return Err(mapError(err));
1070
+ return new ResultErr(mapError(err));
1012
1071
  }
1013
1072
  }));
1014
1073
  }
@@ -1018,27 +1077,31 @@ class ResultAsync {
1018
1077
  return res;
1019
1078
  }
1020
1079
  try {
1021
- return Ok(await promise);
1080
+ return new ResultOk(await promise);
1022
1081
  }
1023
1082
  catch (err) {
1024
- return Err(mapError(err));
1083
+ return new ResultErr(mapError(err));
1025
1084
  }
1026
1085
  }));
1027
1086
  }
1028
1087
  $and(and) {
1029
1088
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1030
- return res instanceof ResultOk ? await and : res;
1089
+ return res instanceof ResultOk
1090
+ ? asResult(await and)
1091
+ : res;
1031
1092
  }));
1032
1093
  }
1033
1094
  $andThen(f) {
1034
1095
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1035
- return res instanceof ResultOk ? await f(res[1]) : res;
1096
+ return res instanceof ResultOk
1097
+ ? asResult(await f(res[1]))
1098
+ : res;
1036
1099
  }));
1037
1100
  }
1038
1101
  $andThrough(f) {
1039
1102
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1040
1103
  if (res instanceof ResultOk) {
1041
- const through = await f(res[1]);
1104
+ const through = asResult(await f(res[1]));
1042
1105
  if (through instanceof ResultErr) {
1043
1106
  return through;
1044
1107
  }
@@ -1076,7 +1139,7 @@ class ResultAsync {
1076
1139
  * The same as {@link Retuple.$peek|$peek}, except it:
1077
1140
  *
1078
1141
  * - awaits the peek function;
1079
- * - returns `ResultAsync`.
1142
+ * - returns {@link ResultAsync}.
1080
1143
  */
1081
1144
  $peek(f) {
1082
1145
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1088,7 +1151,7 @@ class ResultAsync {
1088
1151
  * The same as {@link Retuple.$tap|$tap}, except it:
1089
1152
  *
1090
1153
  * - awaits the tap function;
1091
- * - returns `ResultAsync`.
1154
+ * - returns {@link ResultAsync}.
1092
1155
  */
1093
1156
  $tap(f) {
1094
1157
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1102,7 +1165,7 @@ class ResultAsync {
1102
1165
  * The same as {@link Retuple.$tapErr|$tapErr}, except it:
1103
1166
  *
1104
1167
  * - awaits the tap error function;
1105
- * - returns `ResultAsync`.
1168
+ * - returns {@link ResultAsync}.
1106
1169
  */
1107
1170
  $tapErr(f) {
1108
1171
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1119,13 +1182,7 @@ class ResultAsync {
1119
1182
  return Promise.resolve(this);
1120
1183
  }
1121
1184
  /**
1122
- * The same as {@link Retuple.$tuple|$tuple}, except it returns a `Promise`.
1123
- */
1124
- async $tuple() {
1125
- return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$tuple();
1126
- }
1127
- /**
1128
- * The same as {@link Retuple.$tuple|$iter}, except it returns a `Promise`.
1185
+ * The same as {@link Retuple.$iter|$iter}, except it returns a `Promise`.
1129
1186
  */
1130
1187
  async $iter() {
1131
1188
  return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$iter();
@@ -1133,7 +1190,7 @@ class ResultAsync {
1133
1190
  }
1134
1191
  _ResultAsync_inner = new WeakMap();
1135
1192
  /**
1136
- * @TODO
1193
+ * ## ResultRetry
1137
1194
  */
1138
1195
  class ResultRetry {
1139
1196
  static zero() {
@@ -1156,7 +1213,7 @@ class ResultRetry {
1156
1213
  _ResultRetry_aborted.set(this, false);
1157
1214
  _ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
1158
1215
  _ResultRetry_getDelay.set(this, _a.zero);
1159
- _ResultRetry_errorHandler.set(this, void 0);
1216
+ _ResultRetry_handler.set(this, void 0);
1160
1217
  __classPrivateFieldSet(this, _ResultRetry_f, f, "f");
1161
1218
  __classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
1162
1219
  }
@@ -1164,7 +1221,27 @@ class ResultRetry {
1164
1221
  return __classPrivateFieldGet(this, _ResultRetry_promise, "f").then(onfulfilled, onrejected);
1165
1222
  }
1166
1223
  /**
1167
- * @TODO - Capped 100
1224
+ * Sets the maximum number of times the retry function can be executed,
1225
+ * mutating this `ResultRetry` instance.
1226
+ *
1227
+ * **The default value is 1 - meaning that unless set, no retries will be
1228
+ * attempted.**
1229
+ *
1230
+ * The retry function can be called up to the maximum number of times until
1231
+ * it returns `Ok`. If it never returns `Ok`, the most recent `Err` is
1232
+ * returned.
1233
+ *
1234
+ * This function accepts a positive integer between 1 and 100:
1235
+ *
1236
+ * - Integers outside of this range are clamped to the nearest valid value;
1237
+ * - Any other value (NaN, Infinity, fractions, strings) are treated as 1.
1238
+ *
1239
+ * @example
1240
+ *
1241
+ * ```ts
1242
+ * // Retry someResultFn up to 3 times until Ok is returned:
1243
+ * const result = await Result.$retry(someResultFn).$times(3);
1244
+ * ```
1168
1245
  */
1169
1246
  $times(times) {
1170
1247
  __classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
@@ -1182,34 +1259,84 @@ class ResultRetry {
1182
1259
  return this;
1183
1260
  }
1184
1261
  /**
1185
- * @TODO
1262
+ * Sets a handler to be called when an attempt returns `Err`, mutating this
1263
+ * `ResultRetry` instance. The handler can be used to capture information
1264
+ * about each failure, and to abort early and prevent further retries.
1265
+ *
1266
+ * The handler function is called with `ResultRetryHandleState`, containing:
1267
+ *
1268
+ * - **error** - The error value from the last failed attempt;
1269
+ * - **attempt** - The attempt number;
1270
+ * - **abort** - A function which when called, prevents further retries.
1271
+ *
1272
+ * @example
1273
+ *
1274
+ * ```ts
1275
+ * // Retry someResultFn up to 3 times until Ok is returned, logging each
1276
+ * // attempt and aborting early if the error code is "UNAUTHORIZED".
1277
+ * const result = await Result.$retry(someResultFn)
1278
+ * .$times(3)
1279
+ * .$handle(({ error, attempt, abort }) => {
1280
+ * console.info(`Attempt ${attempt} failed: ${error}`);
1281
+ * if (error === "UNAUTHORIZED") {
1282
+ * abort();
1283
+ * }
1284
+ * });
1285
+ * ```
1186
1286
  */
1187
- $monitor(f) {
1188
- __classPrivateFieldSet(this, _ResultRetry_errorHandler, f, "f");
1287
+ $handle(f) {
1288
+ __classPrivateFieldSet(this, _ResultRetry_handler, f, "f");
1189
1289
  return this;
1190
1290
  }
1191
1291
  /**
1192
- * @TODO
1292
+ * Returns {@link ResultAsync} which resolves to this retried {@link Result}.
1293
+ *
1294
+ * @example
1295
+ *
1296
+ * ```ts
1297
+ * const result: Result<string, SomeError> = await Result
1298
+ * .$retry(someResultFn)
1299
+ * .$times(3)
1300
+ * .$delay(100)
1301
+ * .$async()
1302
+ * .$andThen((message) => `Success: ${message}`)
1303
+ * .$mapErr((code) => new SomeError({ code }));
1304
+ * ```
1193
1305
  */
1194
1306
  $async() {
1195
1307
  return new ResultAsync(this);
1196
1308
  }
1309
+ /**
1310
+ * Returns a `Promise` which resolves to this retried {@link Result}.
1311
+ *
1312
+ * @example
1313
+ *
1314
+ * ```ts
1315
+ * const promise: Promise<Result<string, Error>> = Result
1316
+ * .$retry(someResultFn)
1317
+ * .$times(3)
1318
+ * .$promise();
1319
+ * ```
1320
+ */
1321
+ $promise() {
1322
+ return Promise.resolve(this);
1323
+ }
1197
1324
  async drain() {
1198
1325
  var _b;
1199
1326
  while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1200
- const result = await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this);
1327
+ const result = asResult(await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this));
1201
1328
  __classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
1202
1329
  if (result.$isOk()) {
1203
1330
  return result;
1204
1331
  }
1205
- if (__classPrivateFieldGet(this, _ResultRetry_errorHandler, "f")) {
1206
- await __classPrivateFieldGet(this, _ResultRetry_errorHandler, "f").call(this, {
1332
+ if (__classPrivateFieldGet(this, _ResultRetry_handler, "f")) {
1333
+ await __classPrivateFieldGet(this, _ResultRetry_handler, "f").call(this, {
1207
1334
  error: result[0],
1208
1335
  attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
1209
1336
  abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
1210
1337
  });
1211
1338
  }
1212
- if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") === __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1339
+ if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") >= __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1213
1340
  return result;
1214
1341
  }
1215
1342
  const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
@@ -1217,16 +1344,21 @@ class ResultRetry {
1217
1344
  await _a.delay(delay);
1218
1345
  }
1219
1346
  }
1347
+ /* v8 ignore next */
1348
+ throw new Error("Retuple: Unreachable code executed");
1220
1349
  }
1221
1350
  }
1222
- _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_errorHandler = new WeakMap();
1351
+ _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();
1223
1352
  ResultRetry.MAX_TIMEOUT = 3600000;
1224
1353
  ResultRetry.MAX_RETRY = 100;
1354
+ function asResult(resultLike) {
1355
+ return resultLike[exports.ResultLikeSymbol]();
1356
+ }
1225
1357
  function ensureError(err) {
1226
1358
  if (err instanceof Error) {
1227
1359
  return err;
1228
1360
  }
1229
- return new RetupleThrownValueError(err);
1361
+ return new RetupleCaughtValueError(err);
1230
1362
  }
1231
1363
  function mapTrue() {
1232
1364
  return true;