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.js CHANGED
@@ -9,7 +9,42 @@ 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, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_errorHandler;
12
+ var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_handler;
13
+ /**
14
+ * ## Result Like Symbol
15
+ *
16
+ * Implement a custom result-like by implementing the `ResultLike` interface
17
+ * on a class or object. An object with this implementation can be converted
18
+ * to a `Result` and can be used in most places where a `Result` is required.
19
+ *
20
+ * ```ts
21
+ * import { ResultLikeSymbol } from "retuple/symbol";
22
+ * import { Result, Ok, Err, type ResultLike } from "retuple";
23
+ *
24
+ * class CustomResult<T> implements ResultLike<T, CustomError> {
25
+ * value: T;
26
+ *
27
+ * constructor(value: T) {
28
+ * this.value = value;
29
+ * }
30
+ *
31
+ * [ResultLikeSymbol](): Result<T, CustomError> {
32
+ * return this.value === "test"
33
+ * ? Ok(this.value)
34
+ * : Err(new CustomError("Value was not test"));
35
+ * }
36
+ * }
37
+ *
38
+ * const custom = new CustomResult("test");
39
+ * const result: Result<string, Error> = Result(custom);
40
+ *
41
+ * const chain = Ok()
42
+ * .$map(() => "value")
43
+ * .$andThen((value) => new CustomResult(value))
44
+ * .$or(myresult);
45
+ * ```
46
+ */
47
+ export const ResultLikeSymbol = Symbol("retuple/result");
13
48
  /**
14
49
  * ## Retuple Unwrap Failed
15
50
  *
@@ -44,18 +79,6 @@ export class RetupleExpectFailed extends Error {
44
79
  this.value = value;
45
80
  }
46
81
  }
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
82
  /**
60
83
  * ## Retuple Thrown Value Error
61
84
  *
@@ -63,26 +86,12 @@ export class RetupleFlattenFailed extends Error {
63
86
  * thrown error or rejected value is not an instance of `Error`, and when no
64
87
  * map error function is provided.
65
88
  */
66
- export class RetupleThrownValueError extends Error {
89
+ export class RetupleCaughtValueError extends Error {
67
90
  constructor(value) {
68
91
  super("Caught value was not an instance of Error");
69
92
  this.value = value;
70
93
  }
71
94
  }
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
95
  /**
87
96
  * ## Retuple Invalid Union Error
88
97
  *
@@ -116,26 +125,20 @@ export class RetupleArrayMethodUnavailableError extends Error {
116
125
  * @TODO
117
126
  */
118
127
  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);
128
+ return asResult(resultLike);
127
129
  }
128
130
  Result.Ok = Ok;
129
131
  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;
137
- Result.$retry = retry;
138
- Result.$safeRetry = safeRetry;
132
+ Result.$from = $from;
133
+ Result.$resolve = $resolve;
134
+ Result.$nonNullable = $nonNullable;
135
+ Result.$truthy = $truthy;
136
+ Result.$fromUnion = $fromUnion;
137
+ Result.$safe = $safe;
138
+ Result.$safeAsync = $safeAsync;
139
+ Result.$safePromise = $safePromise;
140
+ Result.$retry = $retry;
141
+ Result.$safeRetry = $safeRetry;
139
142
  Object.freeze(Result);
140
143
  export function Ok(val) {
141
144
  return new ResultOk(val);
@@ -144,35 +147,110 @@ export function Err(err) {
144
147
  return new ResultErr(err);
145
148
  }
146
149
  /**
147
- * @TODO
150
+ * Construct a {@link Result} from a {@link ResultLike}.
151
+ *
152
+ * @example
153
+ *
154
+ * ```ts
155
+ * const value: Result<T, E> | ResultLike<T, E> = someResultFn();
156
+ * const result: Result<T, E> = Result.$from(result);
157
+ * ```
148
158
  */
149
- function resolve(result) {
150
- if (result instanceof ResultAsync) {
159
+ function $from(result) {
160
+ if (result instanceof ResultOk || result instanceof ResultErr) {
151
161
  return result;
152
162
  }
153
- else if (result instanceof ResultOk || result instanceof ResultErr) {
154
- return result.$async();
155
- }
156
- else {
157
- return new ResultAsync(result);
163
+ return asResult(result);
164
+ }
165
+ /**
166
+ * Construct a {@link ResultAsync} from a {@link ResultLikeAwaitable}.
167
+ *
168
+ * @example
169
+ *
170
+ * ```ts
171
+ * const value:
172
+ * | Result<T, E>
173
+ * | ResultLike<T, E>
174
+ * | ResultAsync<T, E>
175
+ * | Promise<Result<T, E>>
176
+ * | Promise<ResultLike<T, E>>
177
+ * | PromiseLike<Result<T, E>>
178
+ * | PromiseLike<ResultLike<T, E>> = someResultFn();
179
+ *
180
+ * const result: ResultAsync<T, E> = Result.$resolve(result);
181
+ * ```
182
+ */
183
+ function $resolve(result) {
184
+ switch (true) {
185
+ case result instanceof ResultAsync:
186
+ return result;
187
+ case result instanceof ResultRetry:
188
+ return new ResultAsync(result);
189
+ case result instanceof ResultOk:
190
+ case result instanceof ResultErr:
191
+ return new ResultAsync(Promise.resolve(result));
192
+ default:
193
+ return new ResultAsync(Promise.resolve(result).then((asResult)));
158
194
  }
159
195
  }
160
- function nonNullable(value, error = mapTrue) {
196
+ function $nonNullable(value, error = mapTrue) {
161
197
  if (value !== null && value !== undefined) {
162
198
  return Ok(value);
163
199
  }
164
200
  return Err(error());
165
201
  }
166
- function truthy(value, error = mapTrue) {
202
+ function $truthy(value, error = mapTrue) {
167
203
  if (value) {
168
204
  return Ok(value);
169
205
  }
170
206
  return Err(error());
171
207
  }
172
208
  /**
173
- * @TODO
209
+ * Construct a {@link Result} from a common discriminated union shape. If the
210
+ * union is 'success' then the result is `Ok`
211
+ *
212
+ * Otherwise, the result is `Err` containing:
213
+ *
214
+ * - the returned value from the error function when provided;
215
+ * - or `true` otherwise.
216
+ *
217
+ * @example
218
+ *
219
+ * ```ts
220
+ * const result: Result<string, Error> = Result.$truthy(
221
+ * username.trim(),
222
+ * () => new Error("Username is empty"),
223
+ * );
224
+ * ```
225
+ *
226
+ * @example
227
+ *
228
+ * ```ts
229
+ * const [err, value] = Result.$truthy("test");
230
+ *
231
+ * assert.equal(err, undefined);
232
+ * assert.equal(value, "test");
233
+ * ```
234
+ *
235
+ * @example
236
+ *
237
+ * ```ts
238
+ * const [err, value] = Result.$truthy("");
239
+ *
240
+ * assert.equal(err, true);
241
+ * assert.equal(value, undefined);
242
+ * ```
243
+ *
244
+ * @example
245
+ *
246
+ * ```ts
247
+ * const [err, value] = Result.$truthy(0, () => "error");
248
+ *
249
+ * assert.equal(err, "error");
250
+ * assert.equal(value, undefined);
251
+ * ```
174
252
  */
175
- function union(union) {
253
+ function $fromUnion(union) {
176
254
  if (union.success === true) {
177
255
  return Ok(union.data);
178
256
  }
@@ -181,7 +259,7 @@ function union(union) {
181
259
  }
182
260
  throw new RetupleInvalidUnionError(union);
183
261
  }
184
- function safe(f, mapError = ensureError) {
262
+ function $safe(f, mapError = ensureError) {
185
263
  try {
186
264
  return Ok(f());
187
265
  }
@@ -189,7 +267,7 @@ function safe(f, mapError = ensureError) {
189
267
  return Err(mapError(err));
190
268
  }
191
269
  }
192
- function safeAsync(f, mapError = ensureError) {
270
+ function $safeAsync(f, mapError = ensureError) {
193
271
  return new ResultAsync((async () => {
194
272
  try {
195
273
  return Ok(await f());
@@ -199,16 +277,29 @@ function safeAsync(f, mapError = ensureError) {
199
277
  }
200
278
  })());
201
279
  }
202
- function safePromise(promise, mapError = ensureError) {
280
+ function $safePromise(promise, mapError = ensureError) {
203
281
  return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
204
282
  }
205
283
  /**
206
- * @TODO
284
+ * Construct a {@link ResultRetry} from a function which returns a
285
+ * {@link Result}. The function will be retried based on provided retry
286
+ * settings and eventually return a `Result`. No attempt is made to catch
287
+ * thrown errors or promise rejections.
288
+ *
289
+ * To retry a potentially unsafe function, use {@link Result.$safeRetry}.
290
+ *
291
+ * @example
292
+ *
293
+ * ```ts
294
+ * // Retry someResultFn up to 3 times until Ok is returned,
295
+ * // with a 1 second delay between each invocation:
296
+ * const result = await Result.$retry(someResultFn).$times(3).$delay(1000);
297
+ * ```
207
298
  */
208
- function retry(f) {
299
+ function $retry(f) {
209
300
  return new ResultRetry(f);
210
301
  }
211
- function safeRetry(f, mapError = ensureError) {
302
+ function $safeRetry(f, mapError = ensureError) {
212
303
  return new ResultRetry(async () => {
213
304
  try {
214
305
  return Ok(await f());
@@ -228,8 +319,7 @@ class RetupleArray extends Array {
228
319
  /**
229
320
  * ## Method not available
230
321
  *
231
- * Built-in array methods not available on `Result` types, convert the result
232
- * to a tuple using `$tuple()` first.
322
+ * Built-in array methods not available on {@link Result} types.
233
323
  *
234
324
  * @deprecated
235
325
  */
@@ -239,8 +329,7 @@ class RetupleArray extends Array {
239
329
  /**
240
330
  * ## Method not available
241
331
  *
242
- * Built-in array methods not available on `Result` types, convert the result
243
- * to a tuple using `$tuple()` first.
332
+ * Built-in array methods not available on {@link Result} types.
244
333
  *
245
334
  * @deprecated
246
335
  */
@@ -250,8 +339,7 @@ class RetupleArray extends Array {
250
339
  /**
251
340
  * ## Method not available
252
341
  *
253
- * Built-in array methods not available on `Result` types, convert the result
254
- * to a tuple using `$tuple()` first.
342
+ * Built-in array methods not available on {@link Result} types.
255
343
  *
256
344
  * @deprecated
257
345
  */
@@ -261,8 +349,7 @@ class RetupleArray extends Array {
261
349
  /**
262
350
  * ## Method not available
263
351
  *
264
- * Built-in array methods not available on `Result` types, convert the result
265
- * to a tuple using `$tuple()` first.
352
+ * Built-in array methods not available on {@link Result} types.
266
353
  *
267
354
  * @deprecated
268
355
  */
@@ -272,8 +359,7 @@ class RetupleArray extends Array {
272
359
  /**
273
360
  * ## Method not available
274
361
  *
275
- * Built-in array methods not available on `Result` types, convert the result
276
- * to a tuple using `$tuple()` first.
362
+ * Built-in array methods not available on {@link Result} types.
277
363
  *
278
364
  * @deprecated
279
365
  */
@@ -283,8 +369,7 @@ class RetupleArray extends Array {
283
369
  /**
284
370
  * ## Method not available
285
371
  *
286
- * Built-in array methods not available on `Result` types, convert the result
287
- * to a tuple using `$tuple()` first.
372
+ * Built-in array methods not available on {@link Result} types.
288
373
  *
289
374
  * @deprecated
290
375
  */
@@ -294,8 +379,7 @@ class RetupleArray extends Array {
294
379
  /**
295
380
  * ## Method not available
296
381
  *
297
- * Built-in array methods not available on `Result` types, convert the result
298
- * to a tuple using `$tuple()` first.
382
+ * Built-in array methods not available on {@link Result} types.
299
383
  *
300
384
  * @deprecated
301
385
  */
@@ -305,8 +389,7 @@ class RetupleArray extends Array {
305
389
  /**
306
390
  * ## Method not available
307
391
  *
308
- * Built-in array methods not available on `Result` types, convert the result
309
- * to a tuple using `$tuple()` first.
392
+ * Built-in array methods not available on {@link Result} types.
310
393
  *
311
394
  * @deprecated
312
395
  */
@@ -316,8 +399,7 @@ class RetupleArray extends Array {
316
399
  /**
317
400
  * ## Method not available
318
401
  *
319
- * Built-in array methods not available on `Result` types, convert the result
320
- * to a tuple using `$tuple()` first.
402
+ * Built-in array methods not available on {@link Result} types.
321
403
  *
322
404
  * @deprecated
323
405
  */
@@ -327,8 +409,7 @@ class RetupleArray extends Array {
327
409
  /**
328
410
  * ## Method not available
329
411
  *
330
- * Built-in array methods not available on `Result` types, convert the result
331
- * to a tuple using `$tuple()` first.
412
+ * Built-in array methods not available on {@link Result} types.
332
413
  *
333
414
  * @deprecated
334
415
  */
@@ -338,8 +419,7 @@ class RetupleArray extends Array {
338
419
  /**
339
420
  * ## Method not available
340
421
  *
341
- * Built-in array methods not available on `Result` types, convert the result
342
- * to a tuple using `$tuple()` first.
422
+ * Built-in array methods not available on {@link Result} types.
343
423
  *
344
424
  * @deprecated
345
425
  */
@@ -349,8 +429,7 @@ class RetupleArray extends Array {
349
429
  /**
350
430
  * ## Method not available
351
431
  *
352
- * Built-in array methods not available on `Result` types, convert the result
353
- * to a tuple using `$tuple()` first.
432
+ * Built-in array methods not available on {@link Result} types.
354
433
  *
355
434
  * @deprecated
356
435
  */
@@ -360,8 +439,7 @@ class RetupleArray extends Array {
360
439
  /**
361
440
  * ## Method not available
362
441
  *
363
- * Built-in array methods not available on `Result` types, convert the result
364
- * to a tuple using `$tuple()` first.
442
+ * Built-in array methods not available on {@link Result} types.
365
443
  *
366
444
  * @deprecated
367
445
  */
@@ -371,8 +449,7 @@ class RetupleArray extends Array {
371
449
  /**
372
450
  * ## Method not available
373
451
  *
374
- * Built-in array methods not available on `Result` types, convert the result
375
- * to a tuple using `$tuple()` first.
452
+ * Built-in array methods not available on {@link Result} types.
376
453
  *
377
454
  * @deprecated
378
455
  */
@@ -382,8 +459,7 @@ class RetupleArray extends Array {
382
459
  /**
383
460
  * ## Method not available
384
461
  *
385
- * Built-in array methods not available on `Result` types, convert the result
386
- * to a tuple using `$tuple()` first.
462
+ * Built-in array methods not available on {@link Result} types.
387
463
  *
388
464
  * @deprecated
389
465
  */
@@ -393,8 +469,7 @@ class RetupleArray extends Array {
393
469
  /**
394
470
  * ## Method not available
395
471
  *
396
- * Built-in array methods not available on `Result` types, convert the result
397
- * to a tuple using `$tuple()` first.
472
+ * Built-in array methods not available on {@link Result} types.
398
473
  *
399
474
  * @deprecated
400
475
  */
@@ -404,8 +479,7 @@ class RetupleArray extends Array {
404
479
  /**
405
480
  * ## Method not available
406
481
  *
407
- * Built-in array methods not available on `Result` types, convert the result
408
- * to a tuple using `$tuple()` first.
482
+ * Built-in array methods not available on {@link Result} types.
409
483
  *
410
484
  * @deprecated
411
485
  */
@@ -415,8 +489,7 @@ class RetupleArray extends Array {
415
489
  /**
416
490
  * ## Method not available
417
491
  *
418
- * Built-in array methods not available on `Result` types, convert the result
419
- * to a tuple using `$tuple()` first.
492
+ * Built-in array methods not available on {@link Result} types.
420
493
  *
421
494
  * @deprecated
422
495
  */
@@ -426,8 +499,7 @@ class RetupleArray extends Array {
426
499
  /**
427
500
  * ## Method not available
428
501
  *
429
- * Built-in array methods not available on `Result` types, convert the result
430
- * to a tuple using `$tuple()` first.
502
+ * Built-in array methods not available on {@link Result} types.
431
503
  *
432
504
  * @deprecated
433
505
  */
@@ -437,8 +509,7 @@ class RetupleArray extends Array {
437
509
  /**
438
510
  * ## Method not available
439
511
  *
440
- * Built-in array methods not available on `Result` types, convert the result
441
- * to a tuple using `$tuple()` first.
512
+ * Built-in array methods not available on {@link Result} types.
442
513
  *
443
514
  * @deprecated
444
515
  */
@@ -448,8 +519,7 @@ class RetupleArray extends Array {
448
519
  /**
449
520
  * ## Method not available
450
521
  *
451
- * Built-in array methods not available on `Result` types, convert the result
452
- * to a tuple using `$tuple()` first.
522
+ * Built-in array methods not available on {@link Result} types.
453
523
  *
454
524
  * @deprecated
455
525
  */
@@ -459,8 +529,7 @@ class RetupleArray extends Array {
459
529
  /**
460
530
  * ## Method not available
461
531
  *
462
- * Built-in array methods not available on `Result` types, convert the result
463
- * to a tuple using `$tuple()` first.
532
+ * Built-in array methods not available on {@link Result} types.
464
533
  *
465
534
  * @deprecated
466
535
  */
@@ -470,8 +539,7 @@ class RetupleArray extends Array {
470
539
  /**
471
540
  * ## Method not available
472
541
  *
473
- * Built-in array methods not available on `Result` types, convert the result
474
- * to a tuple using `$tuple()` first.
542
+ * Built-in array methods not available on {@link Result} types.
475
543
  *
476
544
  * @deprecated
477
545
  */
@@ -481,8 +549,7 @@ class RetupleArray extends Array {
481
549
  /**
482
550
  * ## Method not available
483
551
  *
484
- * Built-in array methods not available on `Result` types, convert the result
485
- * to a tuple using `$tuple()` first.
552
+ * Built-in array methods not available on {@link Result} types.
486
553
  *
487
554
  * @deprecated
488
555
  */
@@ -492,8 +559,7 @@ class RetupleArray extends Array {
492
559
  /**
493
560
  * ## Method not available
494
561
  *
495
- * Built-in array methods not available on `Result` types, convert the result
496
- * to a tuple using `$tuple()` first.
562
+ * Built-in array methods not available on {@link Result} types.
497
563
  *
498
564
  * @deprecated
499
565
  */
@@ -503,8 +569,7 @@ class RetupleArray extends Array {
503
569
  /**
504
570
  * ## Method not available
505
571
  *
506
- * Built-in array methods not available on `Result` types, convert the result
507
- * to a tuple using `$tuple()` first.
572
+ * Built-in array methods not available on {@link Result} types.
508
573
  *
509
574
  * @deprecated
510
575
  */
@@ -514,8 +579,7 @@ class RetupleArray extends Array {
514
579
  /**
515
580
  * ## Method not available
516
581
  *
517
- * Built-in array methods not available on `Result` types, convert the result
518
- * to a tuple using `$tuple()` first.
582
+ * Built-in array methods not available on {@link Result} types.
519
583
  *
520
584
  * @deprecated
521
585
  */
@@ -525,8 +589,7 @@ class RetupleArray extends Array {
525
589
  /**
526
590
  * ## Method not available
527
591
  *
528
- * Built-in array methods not available on `Result` types, convert the result
529
- * to a tuple using `$tuple()` first.
592
+ * Built-in array methods not available on {@link Result} types.
530
593
  *
531
594
  * @deprecated
532
595
  */
@@ -536,8 +599,7 @@ class RetupleArray extends Array {
536
599
  /**
537
600
  * ## Method not available
538
601
  *
539
- * Built-in array methods not available on `Result` types, convert the result
540
- * to a tuple using `$tuple()` first.
602
+ * Built-in array methods not available on {@link Result} types.
541
603
  *
542
604
  * @deprecated
543
605
  */
@@ -547,8 +609,7 @@ class RetupleArray extends Array {
547
609
  /**
548
610
  * ## Method not available
549
611
  *
550
- * Built-in array methods not available on `Result` types, convert the result
551
- * to a tuple using `$tuple()` first.
612
+ * Built-in array methods not available on {@link Result} types.
552
613
  *
553
614
  * @deprecated
554
615
  */
@@ -558,8 +619,7 @@ class RetupleArray extends Array {
558
619
  /**
559
620
  * ## Method not available
560
621
  *
561
- * Built-in array methods not available on `Result` types, convert the result
562
- * to a tuple using `$tuple()` first.
622
+ * Built-in array methods not available on {@link Result} types.
563
623
  *
564
624
  * @deprecated
565
625
  */
@@ -569,8 +629,7 @@ class RetupleArray extends Array {
569
629
  /**
570
630
  * ## Method not available
571
631
  *
572
- * Built-in array methods not available on `Result` types, convert the result
573
- * to a tuple using `$tuple()` first.
632
+ * Built-in array methods not available on {@link Result} types.
574
633
  *
575
634
  * @deprecated
576
635
  */
@@ -580,8 +639,7 @@ class RetupleArray extends Array {
580
639
  /**
581
640
  * ## Method not available
582
641
  *
583
- * Built-in array methods not available on `Result` types, convert the result
584
- * to a tuple using `$tuple()` first.
642
+ * Built-in array methods not available on {@link Result} types.
585
643
  *
586
644
  * @deprecated
587
645
  */
@@ -591,8 +649,7 @@ class RetupleArray extends Array {
591
649
  /**
592
650
  * ## Method not available
593
651
  *
594
- * Built-in array methods not available on `Result` types, convert the result
595
- * to a tuple using `$tuple()` first.
652
+ * Built-in array methods not available on {@link Result} types.
596
653
  *
597
654
  * @deprecated
598
655
  */
@@ -602,8 +659,7 @@ class RetupleArray extends Array {
602
659
  /**
603
660
  * ## Method not available
604
661
  *
605
- * Built-in array methods not available on `Result` types, convert the result
606
- * to a tuple using `$tuple()` first.
662
+ * Built-in array methods not available on {@link Result} types.
607
663
  *
608
664
  * @deprecated
609
665
  */
@@ -613,8 +669,7 @@ class RetupleArray extends Array {
613
669
  /**
614
670
  * ## Method not available
615
671
  *
616
- * Built-in array methods not available on `Result` types, convert the result
617
- * to a tuple using `$tuple()` first.
672
+ * Built-in array methods not available on {@link Result} types.
618
673
  *
619
674
  * @deprecated
620
675
  */
@@ -624,8 +679,7 @@ class RetupleArray extends Array {
624
679
  /**
625
680
  * ## Method not available
626
681
  *
627
- * Built-in array methods not available on `Result` types, convert the result
628
- * to a tuple using `$tuple()` first.
682
+ * Built-in array methods not available on {@link Result} types.
629
683
  *
630
684
  * @deprecated
631
685
  */
@@ -635,8 +689,7 @@ class RetupleArray extends Array {
635
689
  /**
636
690
  * ## Method not available
637
691
  *
638
- * Built-in array methods not available on `Result` types, convert the result
639
- * to a tuple using `$tuple()` first.
692
+ * Built-in array methods not available on {@link Result} types.
640
693
  *
641
694
  * @deprecated
642
695
  */
@@ -655,6 +708,9 @@ class ResultOk extends RetupleArray {
655
708
  this[0] = undefined;
656
709
  this[1] = value;
657
710
  }
711
+ [ResultLikeSymbol]() {
712
+ return this;
713
+ }
658
714
  toJSON() {
659
715
  return this[1];
660
716
  }
@@ -698,10 +754,10 @@ class ResultOk extends RetupleArray {
698
754
  return Ok(f(this[1]));
699
755
  }
700
756
  $andAssertOr(def, condition = isTruthy) {
701
- return condition(this[1]) ? this : def;
757
+ return condition(this[1]) ? this : asResult(def);
702
758
  }
703
759
  $andAssertOrElse(def, condition = isTruthy) {
704
- return condition(this[1]) ? this : def(this[1]);
760
+ return condition(this[1]) ? this : asResult(def(this[1]));
705
761
  }
706
762
  $or() {
707
763
  return this;
@@ -713,13 +769,13 @@ class ResultOk extends RetupleArray {
713
769
  return this;
714
770
  }
715
771
  $and(and) {
716
- return and;
772
+ return asResult(and);
717
773
  }
718
774
  $andThen(f) {
719
- return f(this[1]);
775
+ return asResult(f(this[1]));
720
776
  }
721
777
  $andThrough(f) {
722
- const res = f(this[1]);
778
+ const res = asResult(f(this[1]));
723
779
  return res instanceof ResultErr ? res : this;
724
780
  }
725
781
  $andSafe(f, mapError = ensureError) {
@@ -742,11 +798,7 @@ class ResultOk extends RetupleArray {
742
798
  return this;
743
799
  }
744
800
  $flatten() {
745
- const inner = this[1];
746
- if (inner instanceof ResultOk || inner instanceof ResultErr) {
747
- return inner;
748
- }
749
- throw new RetupleFlattenFailed(this[1]);
801
+ return this[1];
750
802
  }
751
803
  $async() {
752
804
  return new ResultAsync(Promise.resolve(this));
@@ -754,9 +806,6 @@ class ResultOk extends RetupleArray {
754
806
  $promise() {
755
807
  return Promise.resolve(this);
756
808
  }
757
- $tuple() {
758
- return [undefined, this[1]];
759
- }
760
809
  *$iter() {
761
810
  yield* this[1];
762
811
  }
@@ -772,6 +821,9 @@ class ResultErr extends RetupleArray {
772
821
  this[0] = err;
773
822
  this[1] = undefined;
774
823
  }
824
+ [ResultLikeSymbol]() {
825
+ return this;
826
+ }
775
827
  toJSON() {
776
828
  return null;
777
829
  }
@@ -824,10 +876,10 @@ class ResultErr extends RetupleArray {
824
876
  return this;
825
877
  }
826
878
  $or(or) {
827
- return or;
879
+ return asResult(or);
828
880
  }
829
881
  $orElse(f) {
830
- return f(this[0]);
882
+ return asResult(f(this[0]));
831
883
  }
832
884
  $orSafe(f, mapError = ensureError) {
833
885
  try {
@@ -869,9 +921,6 @@ class ResultErr extends RetupleArray {
869
921
  $promise() {
870
922
  return Promise.resolve(this);
871
923
  }
872
- $tuple() {
873
- return [this[0], undefined];
874
- }
875
924
  *$iter() {
876
925
  return;
877
926
  }
@@ -924,37 +973,47 @@ class ResultAsync {
924
973
  return res instanceof ResultOk ? res[1] : f();
925
974
  }
926
975
  /**
927
- * The same as {@link Retuple.$map|$map}, except it returns `ResultAsync`.
976
+ * The same as {@link Retuple.$map|$map}, except it returns
977
+ * {@link ResultAsync}.
928
978
  */
929
979
  $map(f) {
930
980
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
931
- return res instanceof ResultOk ? Ok(f(res[1])) : res;
981
+ return res instanceof ResultOk
982
+ ? new ResultOk(f(res[1]))
983
+ : res;
932
984
  }));
933
985
  }
934
986
  /**
935
987
  * The same as {@link Retuple.$mapErr|$mapErr}, except it returns
936
- * `ResultAsync`.
988
+ * {@link ResultAsync}.
937
989
  */
938
990
  $mapErr(f) {
939
991
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
940
- return res instanceof ResultErr ? Err(f(res[0])) : res;
992
+ return res instanceof ResultErr
993
+ ? new ResultErr(f(res[0]))
994
+ : res;
941
995
  }));
942
996
  }
943
997
  /**
944
- * The same as {@link Retuple.$mapOr|$mapOr}, except it returns `ResultAsync`.
998
+ * The same as {@link Retuple.$mapOr|$mapOr}, except it returns
999
+ * {@link ResultAsync}.
945
1000
  */
946
1001
  $mapOr(def, f) {
947
1002
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
948
- return res instanceof ResultOk ? Ok(f(res[1])) : Ok(def);
1003
+ return res instanceof ResultOk
1004
+ ? new ResultOk(f(res[1]))
1005
+ : new ResultOk(def);
949
1006
  }));
950
1007
  }
951
1008
  /**
952
1009
  * The same as {@link Retuple.$mapOrElse|$mapOrElse}, except it returns
953
- * `ResultAsync`.
1010
+ * {@link ResultAsync}.
954
1011
  */
955
1012
  $mapOrElse(def, f) {
956
1013
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
957
- return res instanceof ResultOk ? Ok(f(res[1])) : Ok(def(res[0]));
1014
+ return res instanceof ResultOk
1015
+ ? new ResultOk(f(res[1]))
1016
+ : new ResultOk(def(res[0]));
958
1017
  }));
959
1018
  }
960
1019
  $andAssertOr(def, condition = isTruthy) {
@@ -962,7 +1021,7 @@ class ResultAsync {
962
1021
  if (res instanceof ResultErr || condition(res[1])) {
963
1022
  return res;
964
1023
  }
965
- return await def;
1024
+ return asResult(await def);
966
1025
  }));
967
1026
  }
968
1027
  $andAssertOrElse(def, condition = isTruthy) {
@@ -970,18 +1029,20 @@ class ResultAsync {
970
1029
  if (res instanceof ResultErr || condition(res[1])) {
971
1030
  return res;
972
1031
  }
973
- return await def(res[1]);
1032
+ return asResult(await def(res[1]));
974
1033
  }));
975
1034
  }
976
1035
  $or(or) {
977
1036
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
978
- return res instanceof ResultErr ? await or : res;
1037
+ return res instanceof ResultErr
1038
+ ? asResult(await or)
1039
+ : res;
979
1040
  }));
980
1041
  }
981
1042
  $orElse(f) {
982
1043
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
983
1044
  return res instanceof ResultErr
984
- ? await f(res[0])
1045
+ ? asResult(await f(res[0]))
985
1046
  : res;
986
1047
  }));
987
1048
  }
@@ -991,10 +1052,10 @@ class ResultAsync {
991
1052
  return res;
992
1053
  }
993
1054
  try {
994
- return Ok(await f(res[0]));
1055
+ return new ResultOk(await f(res[0]));
995
1056
  }
996
1057
  catch (err) {
997
- return Err(mapError(err));
1058
+ return new ResultErr(mapError(err));
998
1059
  }
999
1060
  }));
1000
1061
  }
@@ -1004,27 +1065,31 @@ class ResultAsync {
1004
1065
  return res;
1005
1066
  }
1006
1067
  try {
1007
- return Ok(await promise);
1068
+ return new ResultOk(await promise);
1008
1069
  }
1009
1070
  catch (err) {
1010
- return Err(mapError(err));
1071
+ return new ResultErr(mapError(err));
1011
1072
  }
1012
1073
  }));
1013
1074
  }
1014
1075
  $and(and) {
1015
1076
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1016
- return res instanceof ResultOk ? await and : res;
1077
+ return res instanceof ResultOk
1078
+ ? asResult(await and)
1079
+ : res;
1017
1080
  }));
1018
1081
  }
1019
1082
  $andThen(f) {
1020
1083
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1021
- return res instanceof ResultOk ? await f(res[1]) : res;
1084
+ return res instanceof ResultOk
1085
+ ? asResult(await f(res[1]))
1086
+ : res;
1022
1087
  }));
1023
1088
  }
1024
1089
  $andThrough(f) {
1025
1090
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1026
1091
  if (res instanceof ResultOk) {
1027
- const through = await f(res[1]);
1092
+ const through = asResult(await f(res[1]));
1028
1093
  if (through instanceof ResultErr) {
1029
1094
  return through;
1030
1095
  }
@@ -1062,7 +1127,7 @@ class ResultAsync {
1062
1127
  * The same as {@link Retuple.$peek|$peek}, except it:
1063
1128
  *
1064
1129
  * - awaits the peek function;
1065
- * - returns `ResultAsync`.
1130
+ * - returns {@link ResultAsync}.
1066
1131
  */
1067
1132
  $peek(f) {
1068
1133
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1074,7 +1139,7 @@ class ResultAsync {
1074
1139
  * The same as {@link Retuple.$tap|$tap}, except it:
1075
1140
  *
1076
1141
  * - awaits the tap function;
1077
- * - returns `ResultAsync`.
1142
+ * - returns {@link ResultAsync}.
1078
1143
  */
1079
1144
  $tap(f) {
1080
1145
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1088,7 +1153,7 @@ class ResultAsync {
1088
1153
  * The same as {@link Retuple.$tapErr|$tapErr}, except it:
1089
1154
  *
1090
1155
  * - awaits the tap error function;
1091
- * - returns `ResultAsync`.
1156
+ * - returns {@link ResultAsync}.
1092
1157
  */
1093
1158
  $tapErr(f) {
1094
1159
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1105,13 +1170,7 @@ class ResultAsync {
1105
1170
  return Promise.resolve(this);
1106
1171
  }
1107
1172
  /**
1108
- * The same as {@link Retuple.$tuple|$tuple}, except it returns a `Promise`.
1109
- */
1110
- async $tuple() {
1111
- return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$tuple();
1112
- }
1113
- /**
1114
- * The same as {@link Retuple.$tuple|$iter}, except it returns a `Promise`.
1173
+ * The same as {@link Retuple.$iter|$iter}, except it returns a `Promise`.
1115
1174
  */
1116
1175
  async $iter() {
1117
1176
  return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$iter();
@@ -1119,7 +1178,7 @@ class ResultAsync {
1119
1178
  }
1120
1179
  _ResultAsync_inner = new WeakMap();
1121
1180
  /**
1122
- * @TODO
1181
+ * ## ResultRetry
1123
1182
  */
1124
1183
  class ResultRetry {
1125
1184
  static zero() {
@@ -1142,7 +1201,7 @@ class ResultRetry {
1142
1201
  _ResultRetry_aborted.set(this, false);
1143
1202
  _ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
1144
1203
  _ResultRetry_getDelay.set(this, _a.zero);
1145
- _ResultRetry_errorHandler.set(this, void 0);
1204
+ _ResultRetry_handler.set(this, void 0);
1146
1205
  __classPrivateFieldSet(this, _ResultRetry_f, f, "f");
1147
1206
  __classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
1148
1207
  }
@@ -1150,7 +1209,27 @@ class ResultRetry {
1150
1209
  return __classPrivateFieldGet(this, _ResultRetry_promise, "f").then(onfulfilled, onrejected);
1151
1210
  }
1152
1211
  /**
1153
- * @TODO - Capped 100
1212
+ * Sets the maximum number of times the retry function can be executed,
1213
+ * mutating this `ResultRetry` instance.
1214
+ *
1215
+ * **The default value is 1 - meaning that unless set, no retries will be
1216
+ * attempted.**
1217
+ *
1218
+ * The retry function can be called up to the maximum number of times until
1219
+ * it returns `Ok`. If it never returns `Ok`, the most recent `Err` is
1220
+ * returned.
1221
+ *
1222
+ * This function accepts a positive integer between 1 and 100:
1223
+ *
1224
+ * - Integers outside of this range are clamped to the nearest valid value;
1225
+ * - Any other value (NaN, Infinity, fractions, strings) are treated as 1.
1226
+ *
1227
+ * @example
1228
+ *
1229
+ * ```ts
1230
+ * // Retry someResultFn up to 3 times until Ok is returned:
1231
+ * const result = await Result.$retry(someResultFn).$times(3);
1232
+ * ```
1154
1233
  */
1155
1234
  $times(times) {
1156
1235
  __classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
@@ -1168,34 +1247,84 @@ class ResultRetry {
1168
1247
  return this;
1169
1248
  }
1170
1249
  /**
1171
- * @TODO
1250
+ * Sets a handler to be called when an attempt returns `Err`, mutating this
1251
+ * `ResultRetry` instance. The handler can be used to capture information
1252
+ * about each failure, and to abort early and prevent further retries.
1253
+ *
1254
+ * The handler function is called with `ResultRetryHandleState`, containing:
1255
+ *
1256
+ * - **error** - The error value from the last failed attempt;
1257
+ * - **attempt** - The attempt number;
1258
+ * - **abort** - A function which when called, prevents further retries.
1259
+ *
1260
+ * @example
1261
+ *
1262
+ * ```ts
1263
+ * // Retry someResultFn up to 3 times until Ok is returned, logging each
1264
+ * // attempt and aborting early if the error code is "UNAUTHORIZED".
1265
+ * const result = await Result.$retry(someResultFn)
1266
+ * .$times(3)
1267
+ * .$handle(({ error, attempt, abort }) => {
1268
+ * console.info(`Attempt ${attempt} failed: ${error}`);
1269
+ * if (error === "UNAUTHORIZED") {
1270
+ * abort();
1271
+ * }
1272
+ * });
1273
+ * ```
1172
1274
  */
1173
- $monitor(f) {
1174
- __classPrivateFieldSet(this, _ResultRetry_errorHandler, f, "f");
1275
+ $handle(f) {
1276
+ __classPrivateFieldSet(this, _ResultRetry_handler, f, "f");
1175
1277
  return this;
1176
1278
  }
1177
1279
  /**
1178
- * @TODO
1280
+ * Returns {@link ResultAsync} which resolves to this retried {@link Result}.
1281
+ *
1282
+ * @example
1283
+ *
1284
+ * ```ts
1285
+ * const result: Result<string, SomeError> = await Result
1286
+ * .$retry(someResultFn)
1287
+ * .$times(3)
1288
+ * .$delay(100)
1289
+ * .$async()
1290
+ * .$andThen((message) => `Success: ${message}`)
1291
+ * .$mapErr((code) => new SomeError({ code }));
1292
+ * ```
1179
1293
  */
1180
1294
  $async() {
1181
1295
  return new ResultAsync(this);
1182
1296
  }
1297
+ /**
1298
+ * Returns a `Promise` which resolves to this retried {@link Result}.
1299
+ *
1300
+ * @example
1301
+ *
1302
+ * ```ts
1303
+ * const promise: Promise<Result<string, Error>> = Result
1304
+ * .$retry(someResultFn)
1305
+ * .$times(3)
1306
+ * .$promise();
1307
+ * ```
1308
+ */
1309
+ $promise() {
1310
+ return Promise.resolve(this);
1311
+ }
1183
1312
  async drain() {
1184
1313
  var _b;
1185
1314
  while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1186
- const result = await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this);
1315
+ const result = asResult(await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this));
1187
1316
  __classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
1188
1317
  if (result.$isOk()) {
1189
1318
  return result;
1190
1319
  }
1191
- if (__classPrivateFieldGet(this, _ResultRetry_errorHandler, "f")) {
1192
- await __classPrivateFieldGet(this, _ResultRetry_errorHandler, "f").call(this, {
1320
+ if (__classPrivateFieldGet(this, _ResultRetry_handler, "f")) {
1321
+ await __classPrivateFieldGet(this, _ResultRetry_handler, "f").call(this, {
1193
1322
  error: result[0],
1194
1323
  attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
1195
1324
  abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
1196
1325
  });
1197
1326
  }
1198
- if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") === __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1327
+ if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") >= __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1199
1328
  return result;
1200
1329
  }
1201
1330
  const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
@@ -1203,16 +1332,21 @@ class ResultRetry {
1203
1332
  await _a.delay(delay);
1204
1333
  }
1205
1334
  }
1335
+ /* v8 ignore next */
1336
+ throw new Error("Retuple: Unreachable code executed");
1206
1337
  }
1207
1338
  }
1208
- _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();
1339
+ _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();
1209
1340
  ResultRetry.MAX_TIMEOUT = 3600000;
1210
1341
  ResultRetry.MAX_RETRY = 100;
1342
+ function asResult(resultLike) {
1343
+ return resultLike[ResultLikeSymbol]();
1344
+ }
1211
1345
  function ensureError(err) {
1212
1346
  if (err instanceof Error) {
1213
1347
  return err;
1214
1348
  }
1215
- return new RetupleThrownValueError(err);
1349
+ return new RetupleCaughtValueError(err);
1216
1350
  }
1217
1351
  function mapTrue() {
1218
1352
  return true;