retuple 1.0.0-next.13 → 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, _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
+ 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,26 +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;
137
- Result.$retry = retry;
138
- Result.$safeRetry = safeRetry;
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;
139
108
  Object.freeze(Result);
140
109
  export function Ok(val) {
141
110
  return new ResultOk(val);
@@ -144,35 +113,110 @@ export function Err(err) {
144
113
  return new ResultErr(err);
145
114
  }
146
115
  /**
147
- * @TODO
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
+ * ```
148
124
  */
149
- function resolve(result) {
150
- if (result instanceof ResultAsync) {
125
+ function $from(result) {
126
+ if (result instanceof ResultOk || result instanceof ResultErr) {
151
127
  return result;
152
128
  }
153
- else if (result instanceof ResultOk || result instanceof ResultErr) {
154
- return result.$async();
155
- }
156
- else {
157
- 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)));
158
160
  }
159
161
  }
160
- function nonNullable(value, error = mapTrue) {
162
+ function $nonNullable(value, error = mapTrue) {
161
163
  if (value !== null && value !== undefined) {
162
164
  return Ok(value);
163
165
  }
164
166
  return Err(error());
165
167
  }
166
- function truthy(value, error = mapTrue) {
168
+ function $truthy(value, error = mapTrue) {
167
169
  if (value) {
168
170
  return Ok(value);
169
171
  }
170
172
  return Err(error());
171
173
  }
172
174
  /**
173
- * @TODO
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
+ * ```
174
218
  */
175
- function union(union) {
219
+ function $fromUnion(union) {
176
220
  if (union.success === true) {
177
221
  return Ok(union.data);
178
222
  }
@@ -181,7 +225,7 @@ function union(union) {
181
225
  }
182
226
  throw new RetupleInvalidUnionError(union);
183
227
  }
184
- function safe(f, mapError = ensureError) {
228
+ function $safe(f, mapError = ensureError) {
185
229
  try {
186
230
  return Ok(f());
187
231
  }
@@ -189,7 +233,7 @@ function safe(f, mapError = ensureError) {
189
233
  return Err(mapError(err));
190
234
  }
191
235
  }
192
- function safeAsync(f, mapError = ensureError) {
236
+ function $safeAsync(f, mapError = ensureError) {
193
237
  return new ResultAsync((async () => {
194
238
  try {
195
239
  return Ok(await f());
@@ -199,16 +243,29 @@ function safeAsync(f, mapError = ensureError) {
199
243
  }
200
244
  })());
201
245
  }
202
- function safePromise(promise, mapError = ensureError) {
246
+ function $safePromise(promise, mapError = ensureError) {
203
247
  return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
204
248
  }
205
249
  /**
206
- * @TODO
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
+ * ```
207
264
  */
208
- function retry(f) {
265
+ function $retry(f) {
209
266
  return new ResultRetry(f);
210
267
  }
211
- function safeRetry(f, mapError = ensureError) {
268
+ function $safeRetry(f, mapError = ensureError) {
212
269
  return new ResultRetry(async () => {
213
270
  try {
214
271
  return Ok(await f());
@@ -228,8 +285,7 @@ class RetupleArray extends Array {
228
285
  /**
229
286
  * ## Method not available
230
287
  *
231
- * Built-in array methods not available on `Result` types, convert the result
232
- * to a tuple using `$tuple()` first.
288
+ * Built-in array methods not available on {@link Result} types.
233
289
  *
234
290
  * @deprecated
235
291
  */
@@ -239,8 +295,7 @@ class RetupleArray extends Array {
239
295
  /**
240
296
  * ## Method not available
241
297
  *
242
- * Built-in array methods not available on `Result` types, convert the result
243
- * to a tuple using `$tuple()` first.
298
+ * Built-in array methods not available on {@link Result} types.
244
299
  *
245
300
  * @deprecated
246
301
  */
@@ -250,8 +305,7 @@ class RetupleArray extends Array {
250
305
  /**
251
306
  * ## Method not available
252
307
  *
253
- * Built-in array methods not available on `Result` types, convert the result
254
- * to a tuple using `$tuple()` first.
308
+ * Built-in array methods not available on {@link Result} types.
255
309
  *
256
310
  * @deprecated
257
311
  */
@@ -261,8 +315,7 @@ class RetupleArray extends Array {
261
315
  /**
262
316
  * ## Method not available
263
317
  *
264
- * Built-in array methods not available on `Result` types, convert the result
265
- * to a tuple using `$tuple()` first.
318
+ * Built-in array methods not available on {@link Result} types.
266
319
  *
267
320
  * @deprecated
268
321
  */
@@ -272,8 +325,7 @@ class RetupleArray extends Array {
272
325
  /**
273
326
  * ## Method not available
274
327
  *
275
- * Built-in array methods not available on `Result` types, convert the result
276
- * to a tuple using `$tuple()` first.
328
+ * Built-in array methods not available on {@link Result} types.
277
329
  *
278
330
  * @deprecated
279
331
  */
@@ -283,8 +335,7 @@ class RetupleArray extends Array {
283
335
  /**
284
336
  * ## Method not available
285
337
  *
286
- * Built-in array methods not available on `Result` types, convert the result
287
- * to a tuple using `$tuple()` first.
338
+ * Built-in array methods not available on {@link Result} types.
288
339
  *
289
340
  * @deprecated
290
341
  */
@@ -294,8 +345,7 @@ class RetupleArray extends Array {
294
345
  /**
295
346
  * ## Method not available
296
347
  *
297
- * Built-in array methods not available on `Result` types, convert the result
298
- * to a tuple using `$tuple()` first.
348
+ * Built-in array methods not available on {@link Result} types.
299
349
  *
300
350
  * @deprecated
301
351
  */
@@ -305,8 +355,7 @@ class RetupleArray extends Array {
305
355
  /**
306
356
  * ## Method not available
307
357
  *
308
- * Built-in array methods not available on `Result` types, convert the result
309
- * to a tuple using `$tuple()` first.
358
+ * Built-in array methods not available on {@link Result} types.
310
359
  *
311
360
  * @deprecated
312
361
  */
@@ -316,8 +365,7 @@ class RetupleArray extends Array {
316
365
  /**
317
366
  * ## Method not available
318
367
  *
319
- * Built-in array methods not available on `Result` types, convert the result
320
- * to a tuple using `$tuple()` first.
368
+ * Built-in array methods not available on {@link Result} types.
321
369
  *
322
370
  * @deprecated
323
371
  */
@@ -327,8 +375,7 @@ class RetupleArray extends Array {
327
375
  /**
328
376
  * ## Method not available
329
377
  *
330
- * Built-in array methods not available on `Result` types, convert the result
331
- * to a tuple using `$tuple()` first.
378
+ * Built-in array methods not available on {@link Result} types.
332
379
  *
333
380
  * @deprecated
334
381
  */
@@ -338,8 +385,7 @@ class RetupleArray extends Array {
338
385
  /**
339
386
  * ## Method not available
340
387
  *
341
- * Built-in array methods not available on `Result` types, convert the result
342
- * to a tuple using `$tuple()` first.
388
+ * Built-in array methods not available on {@link Result} types.
343
389
  *
344
390
  * @deprecated
345
391
  */
@@ -349,8 +395,7 @@ class RetupleArray extends Array {
349
395
  /**
350
396
  * ## Method not available
351
397
  *
352
- * Built-in array methods not available on `Result` types, convert the result
353
- * to a tuple using `$tuple()` first.
398
+ * Built-in array methods not available on {@link Result} types.
354
399
  *
355
400
  * @deprecated
356
401
  */
@@ -360,8 +405,7 @@ class RetupleArray extends Array {
360
405
  /**
361
406
  * ## Method not available
362
407
  *
363
- * Built-in array methods not available on `Result` types, convert the result
364
- * to a tuple using `$tuple()` first.
408
+ * Built-in array methods not available on {@link Result} types.
365
409
  *
366
410
  * @deprecated
367
411
  */
@@ -371,8 +415,7 @@ class RetupleArray extends Array {
371
415
  /**
372
416
  * ## Method not available
373
417
  *
374
- * Built-in array methods not available on `Result` types, convert the result
375
- * to a tuple using `$tuple()` first.
418
+ * Built-in array methods not available on {@link Result} types.
376
419
  *
377
420
  * @deprecated
378
421
  */
@@ -382,8 +425,7 @@ class RetupleArray extends Array {
382
425
  /**
383
426
  * ## Method not available
384
427
  *
385
- * Built-in array methods not available on `Result` types, convert the result
386
- * to a tuple using `$tuple()` first.
428
+ * Built-in array methods not available on {@link Result} types.
387
429
  *
388
430
  * @deprecated
389
431
  */
@@ -393,8 +435,7 @@ class RetupleArray extends Array {
393
435
  /**
394
436
  * ## Method not available
395
437
  *
396
- * Built-in array methods not available on `Result` types, convert the result
397
- * to a tuple using `$tuple()` first.
438
+ * Built-in array methods not available on {@link Result} types.
398
439
  *
399
440
  * @deprecated
400
441
  */
@@ -404,8 +445,7 @@ class RetupleArray extends Array {
404
445
  /**
405
446
  * ## Method not available
406
447
  *
407
- * Built-in array methods not available on `Result` types, convert the result
408
- * to a tuple using `$tuple()` first.
448
+ * Built-in array methods not available on {@link Result} types.
409
449
  *
410
450
  * @deprecated
411
451
  */
@@ -415,8 +455,7 @@ class RetupleArray extends Array {
415
455
  /**
416
456
  * ## Method not available
417
457
  *
418
- * Built-in array methods not available on `Result` types, convert the result
419
- * to a tuple using `$tuple()` first.
458
+ * Built-in array methods not available on {@link Result} types.
420
459
  *
421
460
  * @deprecated
422
461
  */
@@ -426,8 +465,7 @@ class RetupleArray extends Array {
426
465
  /**
427
466
  * ## Method not available
428
467
  *
429
- * Built-in array methods not available on `Result` types, convert the result
430
- * to a tuple using `$tuple()` first.
468
+ * Built-in array methods not available on {@link Result} types.
431
469
  *
432
470
  * @deprecated
433
471
  */
@@ -437,8 +475,7 @@ class RetupleArray extends Array {
437
475
  /**
438
476
  * ## Method not available
439
477
  *
440
- * Built-in array methods not available on `Result` types, convert the result
441
- * to a tuple using `$tuple()` first.
478
+ * Built-in array methods not available on {@link Result} types.
442
479
  *
443
480
  * @deprecated
444
481
  */
@@ -448,8 +485,7 @@ class RetupleArray extends Array {
448
485
  /**
449
486
  * ## Method not available
450
487
  *
451
- * Built-in array methods not available on `Result` types, convert the result
452
- * to a tuple using `$tuple()` first.
488
+ * Built-in array methods not available on {@link Result} types.
453
489
  *
454
490
  * @deprecated
455
491
  */
@@ -459,8 +495,7 @@ class RetupleArray extends Array {
459
495
  /**
460
496
  * ## Method not available
461
497
  *
462
- * Built-in array methods not available on `Result` types, convert the result
463
- * to a tuple using `$tuple()` first.
498
+ * Built-in array methods not available on {@link Result} types.
464
499
  *
465
500
  * @deprecated
466
501
  */
@@ -470,8 +505,7 @@ class RetupleArray extends Array {
470
505
  /**
471
506
  * ## Method not available
472
507
  *
473
- * Built-in array methods not available on `Result` types, convert the result
474
- * to a tuple using `$tuple()` first.
508
+ * Built-in array methods not available on {@link Result} types.
475
509
  *
476
510
  * @deprecated
477
511
  */
@@ -481,8 +515,7 @@ class RetupleArray extends Array {
481
515
  /**
482
516
  * ## Method not available
483
517
  *
484
- * Built-in array methods not available on `Result` types, convert the result
485
- * to a tuple using `$tuple()` first.
518
+ * Built-in array methods not available on {@link Result} types.
486
519
  *
487
520
  * @deprecated
488
521
  */
@@ -492,8 +525,7 @@ class RetupleArray extends Array {
492
525
  /**
493
526
  * ## Method not available
494
527
  *
495
- * Built-in array methods not available on `Result` types, convert the result
496
- * to a tuple using `$tuple()` first.
528
+ * Built-in array methods not available on {@link Result} types.
497
529
  *
498
530
  * @deprecated
499
531
  */
@@ -503,8 +535,7 @@ class RetupleArray extends Array {
503
535
  /**
504
536
  * ## Method not available
505
537
  *
506
- * Built-in array methods not available on `Result` types, convert the result
507
- * to a tuple using `$tuple()` first.
538
+ * Built-in array methods not available on {@link Result} types.
508
539
  *
509
540
  * @deprecated
510
541
  */
@@ -514,8 +545,7 @@ class RetupleArray extends Array {
514
545
  /**
515
546
  * ## Method not available
516
547
  *
517
- * Built-in array methods not available on `Result` types, convert the result
518
- * to a tuple using `$tuple()` first.
548
+ * Built-in array methods not available on {@link Result} types.
519
549
  *
520
550
  * @deprecated
521
551
  */
@@ -525,8 +555,7 @@ class RetupleArray extends Array {
525
555
  /**
526
556
  * ## Method not available
527
557
  *
528
- * Built-in array methods not available on `Result` types, convert the result
529
- * to a tuple using `$tuple()` first.
558
+ * Built-in array methods not available on {@link Result} types.
530
559
  *
531
560
  * @deprecated
532
561
  */
@@ -536,8 +565,7 @@ class RetupleArray extends Array {
536
565
  /**
537
566
  * ## Method not available
538
567
  *
539
- * Built-in array methods not available on `Result` types, convert the result
540
- * to a tuple using `$tuple()` first.
568
+ * Built-in array methods not available on {@link Result} types.
541
569
  *
542
570
  * @deprecated
543
571
  */
@@ -547,8 +575,7 @@ class RetupleArray extends Array {
547
575
  /**
548
576
  * ## Method not available
549
577
  *
550
- * Built-in array methods not available on `Result` types, convert the result
551
- * to a tuple using `$tuple()` first.
578
+ * Built-in array methods not available on {@link Result} types.
552
579
  *
553
580
  * @deprecated
554
581
  */
@@ -558,8 +585,7 @@ class RetupleArray extends Array {
558
585
  /**
559
586
  * ## Method not available
560
587
  *
561
- * Built-in array methods not available on `Result` types, convert the result
562
- * to a tuple using `$tuple()` first.
588
+ * Built-in array methods not available on {@link Result} types.
563
589
  *
564
590
  * @deprecated
565
591
  */
@@ -569,8 +595,7 @@ class RetupleArray extends Array {
569
595
  /**
570
596
  * ## Method not available
571
597
  *
572
- * Built-in array methods not available on `Result` types, convert the result
573
- * to a tuple using `$tuple()` first.
598
+ * Built-in array methods not available on {@link Result} types.
574
599
  *
575
600
  * @deprecated
576
601
  */
@@ -580,8 +605,7 @@ class RetupleArray extends Array {
580
605
  /**
581
606
  * ## Method not available
582
607
  *
583
- * Built-in array methods not available on `Result` types, convert the result
584
- * to a tuple using `$tuple()` first.
608
+ * Built-in array methods not available on {@link Result} types.
585
609
  *
586
610
  * @deprecated
587
611
  */
@@ -591,8 +615,7 @@ class RetupleArray extends Array {
591
615
  /**
592
616
  * ## Method not available
593
617
  *
594
- * Built-in array methods not available on `Result` types, convert the result
595
- * to a tuple using `$tuple()` first.
618
+ * Built-in array methods not available on {@link Result} types.
596
619
  *
597
620
  * @deprecated
598
621
  */
@@ -602,8 +625,7 @@ class RetupleArray extends Array {
602
625
  /**
603
626
  * ## Method not available
604
627
  *
605
- * Built-in array methods not available on `Result` types, convert the result
606
- * to a tuple using `$tuple()` first.
628
+ * Built-in array methods not available on {@link Result} types.
607
629
  *
608
630
  * @deprecated
609
631
  */
@@ -613,8 +635,7 @@ class RetupleArray extends Array {
613
635
  /**
614
636
  * ## Method not available
615
637
  *
616
- * Built-in array methods not available on `Result` types, convert the result
617
- * to a tuple using `$tuple()` first.
638
+ * Built-in array methods not available on {@link Result} types.
618
639
  *
619
640
  * @deprecated
620
641
  */
@@ -624,8 +645,7 @@ class RetupleArray extends Array {
624
645
  /**
625
646
  * ## Method not available
626
647
  *
627
- * Built-in array methods not available on `Result` types, convert the result
628
- * to a tuple using `$tuple()` first.
648
+ * Built-in array methods not available on {@link Result} types.
629
649
  *
630
650
  * @deprecated
631
651
  */
@@ -635,8 +655,7 @@ class RetupleArray extends Array {
635
655
  /**
636
656
  * ## Method not available
637
657
  *
638
- * Built-in array methods not available on `Result` types, convert the result
639
- * to a tuple using `$tuple()` first.
658
+ * Built-in array methods not available on {@link Result} types.
640
659
  *
641
660
  * @deprecated
642
661
  */
@@ -655,6 +674,9 @@ class ResultOk extends RetupleArray {
655
674
  this[0] = undefined;
656
675
  this[1] = value;
657
676
  }
677
+ [ResultLikeSymbol]() {
678
+ return this;
679
+ }
658
680
  toJSON() {
659
681
  return this[1];
660
682
  }
@@ -698,10 +720,10 @@ class ResultOk extends RetupleArray {
698
720
  return Ok(f(this[1]));
699
721
  }
700
722
  $andAssertOr(def, condition = isTruthy) {
701
- return condition(this[1]) ? this : def;
723
+ return condition(this[1]) ? this : asResult(def);
702
724
  }
703
725
  $andAssertOrElse(def, condition = isTruthy) {
704
- return condition(this[1]) ? this : def(this[1]);
726
+ return condition(this[1]) ? this : asResult(def(this[1]));
705
727
  }
706
728
  $or() {
707
729
  return this;
@@ -713,13 +735,13 @@ class ResultOk extends RetupleArray {
713
735
  return this;
714
736
  }
715
737
  $and(and) {
716
- return and;
738
+ return asResult(and);
717
739
  }
718
740
  $andThen(f) {
719
- return f(this[1]);
741
+ return asResult(f(this[1]));
720
742
  }
721
743
  $andThrough(f) {
722
- const res = f(this[1]);
744
+ const res = asResult(f(this[1]));
723
745
  return res instanceof ResultErr ? res : this;
724
746
  }
725
747
  $andSafe(f, mapError = ensureError) {
@@ -742,11 +764,7 @@ class ResultOk extends RetupleArray {
742
764
  return this;
743
765
  }
744
766
  $flatten() {
745
- const inner = this[1];
746
- if (inner instanceof ResultOk || inner instanceof ResultErr) {
747
- return inner;
748
- }
749
- throw new RetupleFlattenFailed(this[1]);
767
+ return this[1];
750
768
  }
751
769
  $async() {
752
770
  return new ResultAsync(Promise.resolve(this));
@@ -754,9 +772,6 @@ class ResultOk extends RetupleArray {
754
772
  $promise() {
755
773
  return Promise.resolve(this);
756
774
  }
757
- $tuple() {
758
- return [undefined, this[1]];
759
- }
760
775
  *$iter() {
761
776
  yield* this[1];
762
777
  }
@@ -772,6 +787,9 @@ class ResultErr extends RetupleArray {
772
787
  this[0] = err;
773
788
  this[1] = undefined;
774
789
  }
790
+ [ResultLikeSymbol]() {
791
+ return this;
792
+ }
775
793
  toJSON() {
776
794
  return null;
777
795
  }
@@ -824,10 +842,10 @@ class ResultErr extends RetupleArray {
824
842
  return this;
825
843
  }
826
844
  $or(or) {
827
- return or;
845
+ return asResult(or);
828
846
  }
829
847
  $orElse(f) {
830
- return f(this[0]);
848
+ return asResult(f(this[0]));
831
849
  }
832
850
  $orSafe(f, mapError = ensureError) {
833
851
  try {
@@ -869,9 +887,6 @@ class ResultErr extends RetupleArray {
869
887
  $promise() {
870
888
  return Promise.resolve(this);
871
889
  }
872
- $tuple() {
873
- return [this[0], undefined];
874
- }
875
890
  *$iter() {
876
891
  return;
877
892
  }
@@ -924,37 +939,47 @@ class ResultAsync {
924
939
  return res instanceof ResultOk ? res[1] : f();
925
940
  }
926
941
  /**
927
- * 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}.
928
944
  */
929
945
  $map(f) {
930
946
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
931
- return res instanceof ResultOk ? Ok(f(res[1])) : res;
947
+ return res instanceof ResultOk
948
+ ? new ResultOk(f(res[1]))
949
+ : res;
932
950
  }));
933
951
  }
934
952
  /**
935
953
  * The same as {@link Retuple.$mapErr|$mapErr}, except it returns
936
- * `ResultAsync`.
954
+ * {@link ResultAsync}.
937
955
  */
938
956
  $mapErr(f) {
939
957
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
940
- return res instanceof ResultErr ? Err(f(res[0])) : res;
958
+ return res instanceof ResultErr
959
+ ? new ResultErr(f(res[0]))
960
+ : res;
941
961
  }));
942
962
  }
943
963
  /**
944
- * 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}.
945
966
  */
946
967
  $mapOr(def, f) {
947
968
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
948
- 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);
949
972
  }));
950
973
  }
951
974
  /**
952
975
  * The same as {@link Retuple.$mapOrElse|$mapOrElse}, except it returns
953
- * `ResultAsync`.
976
+ * {@link ResultAsync}.
954
977
  */
955
978
  $mapOrElse(def, f) {
956
979
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
957
- 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]));
958
983
  }));
959
984
  }
960
985
  $andAssertOr(def, condition = isTruthy) {
@@ -962,7 +987,7 @@ class ResultAsync {
962
987
  if (res instanceof ResultErr || condition(res[1])) {
963
988
  return res;
964
989
  }
965
- return await def;
990
+ return asResult(await def);
966
991
  }));
967
992
  }
968
993
  $andAssertOrElse(def, condition = isTruthy) {
@@ -970,18 +995,20 @@ class ResultAsync {
970
995
  if (res instanceof ResultErr || condition(res[1])) {
971
996
  return res;
972
997
  }
973
- return await def(res[1]);
998
+ return asResult(await def(res[1]));
974
999
  }));
975
1000
  }
976
1001
  $or(or) {
977
1002
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
978
- return res instanceof ResultErr ? await or : res;
1003
+ return res instanceof ResultErr
1004
+ ? asResult(await or)
1005
+ : res;
979
1006
  }));
980
1007
  }
981
1008
  $orElse(f) {
982
1009
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
983
1010
  return res instanceof ResultErr
984
- ? await f(res[0])
1011
+ ? asResult(await f(res[0]))
985
1012
  : res;
986
1013
  }));
987
1014
  }
@@ -991,10 +1018,10 @@ class ResultAsync {
991
1018
  return res;
992
1019
  }
993
1020
  try {
994
- return Ok(await f(res[0]));
1021
+ return new ResultOk(await f(res[0]));
995
1022
  }
996
1023
  catch (err) {
997
- return Err(mapError(err));
1024
+ return new ResultErr(mapError(err));
998
1025
  }
999
1026
  }));
1000
1027
  }
@@ -1004,27 +1031,31 @@ class ResultAsync {
1004
1031
  return res;
1005
1032
  }
1006
1033
  try {
1007
- return Ok(await promise);
1034
+ return new ResultOk(await promise);
1008
1035
  }
1009
1036
  catch (err) {
1010
- return Err(mapError(err));
1037
+ return new ResultErr(mapError(err));
1011
1038
  }
1012
1039
  }));
1013
1040
  }
1014
1041
  $and(and) {
1015
1042
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1016
- return res instanceof ResultOk ? await and : res;
1043
+ return res instanceof ResultOk
1044
+ ? asResult(await and)
1045
+ : res;
1017
1046
  }));
1018
1047
  }
1019
1048
  $andThen(f) {
1020
1049
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1021
- return res instanceof ResultOk ? await f(res[1]) : res;
1050
+ return res instanceof ResultOk
1051
+ ? asResult(await f(res[1]))
1052
+ : res;
1022
1053
  }));
1023
1054
  }
1024
1055
  $andThrough(f) {
1025
1056
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
1026
1057
  if (res instanceof ResultOk) {
1027
- const through = await f(res[1]);
1058
+ const through = asResult(await f(res[1]));
1028
1059
  if (through instanceof ResultErr) {
1029
1060
  return through;
1030
1061
  }
@@ -1062,7 +1093,7 @@ class ResultAsync {
1062
1093
  * The same as {@link Retuple.$peek|$peek}, except it:
1063
1094
  *
1064
1095
  * - awaits the peek function;
1065
- * - returns `ResultAsync`.
1096
+ * - returns {@link ResultAsync}.
1066
1097
  */
1067
1098
  $peek(f) {
1068
1099
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1074,7 +1105,7 @@ class ResultAsync {
1074
1105
  * The same as {@link Retuple.$tap|$tap}, except it:
1075
1106
  *
1076
1107
  * - awaits the tap function;
1077
- * - returns `ResultAsync`.
1108
+ * - returns {@link ResultAsync}.
1078
1109
  */
1079
1110
  $tap(f) {
1080
1111
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1088,7 +1119,7 @@ class ResultAsync {
1088
1119
  * The same as {@link Retuple.$tapErr|$tapErr}, except it:
1089
1120
  *
1090
1121
  * - awaits the tap error function;
1091
- * - returns `ResultAsync`.
1122
+ * - returns {@link ResultAsync}.
1092
1123
  */
1093
1124
  $tapErr(f) {
1094
1125
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
@@ -1105,13 +1136,7 @@ class ResultAsync {
1105
1136
  return Promise.resolve(this);
1106
1137
  }
1107
1138
  /**
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`.
1139
+ * The same as {@link Retuple.$iter|$iter}, except it returns a `Promise`.
1115
1140
  */
1116
1141
  async $iter() {
1117
1142
  return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$iter();
@@ -1119,7 +1144,7 @@ class ResultAsync {
1119
1144
  }
1120
1145
  _ResultAsync_inner = new WeakMap();
1121
1146
  /**
1122
- * @TODO
1147
+ * ## ResultRetry
1123
1148
  */
1124
1149
  class ResultRetry {
1125
1150
  static zero() {
@@ -1142,7 +1167,7 @@ class ResultRetry {
1142
1167
  _ResultRetry_aborted.set(this, false);
1143
1168
  _ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
1144
1169
  _ResultRetry_getDelay.set(this, _a.zero);
1145
- _ResultRetry_errorHandler.set(this, void 0);
1170
+ _ResultRetry_handler.set(this, void 0);
1146
1171
  __classPrivateFieldSet(this, _ResultRetry_f, f, "f");
1147
1172
  __classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
1148
1173
  }
@@ -1150,7 +1175,27 @@ class ResultRetry {
1150
1175
  return __classPrivateFieldGet(this, _ResultRetry_promise, "f").then(onfulfilled, onrejected);
1151
1176
  }
1152
1177
  /**
1153
- * @TODO - Capped 100
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
+ * ```
1154
1199
  */
1155
1200
  $times(times) {
1156
1201
  __classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
@@ -1168,34 +1213,84 @@ class ResultRetry {
1168
1213
  return this;
1169
1214
  }
1170
1215
  /**
1171
- * @TODO
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
+ * ```
1172
1240
  */
1173
- $monitor(f) {
1174
- __classPrivateFieldSet(this, _ResultRetry_errorHandler, f, "f");
1241
+ $handle(f) {
1242
+ __classPrivateFieldSet(this, _ResultRetry_handler, f, "f");
1175
1243
  return this;
1176
1244
  }
1177
1245
  /**
1178
- * @TODO
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
+ * ```
1179
1259
  */
1180
1260
  $async() {
1181
1261
  return new ResultAsync(this);
1182
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
+ }
1183
1278
  async drain() {
1184
1279
  var _b;
1185
1280
  while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1186
- const result = await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this);
1281
+ const result = asResult(await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this));
1187
1282
  __classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
1188
1283
  if (result.$isOk()) {
1189
1284
  return result;
1190
1285
  }
1191
- if (__classPrivateFieldGet(this, _ResultRetry_errorHandler, "f")) {
1192
- await __classPrivateFieldGet(this, _ResultRetry_errorHandler, "f").call(this, {
1286
+ if (__classPrivateFieldGet(this, _ResultRetry_handler, "f")) {
1287
+ await __classPrivateFieldGet(this, _ResultRetry_handler, "f").call(this, {
1193
1288
  error: result[0],
1194
1289
  attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
1195
1290
  abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
1196
1291
  });
1197
1292
  }
1198
- if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") === __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1293
+ if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") >= __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
1199
1294
  return result;
1200
1295
  }
1201
1296
  const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
@@ -1203,16 +1298,21 @@ class ResultRetry {
1203
1298
  await _a.delay(delay);
1204
1299
  }
1205
1300
  }
1301
+ /* v8 ignore next */
1302
+ throw new Error("Retuple: Unreachable code executed");
1206
1303
  }
1207
1304
  }
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();
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();
1209
1306
  ResultRetry.MAX_TIMEOUT = 3600000;
1210
1307
  ResultRetry.MAX_RETRY = 100;
1308
+ function asResult(resultLike) {
1309
+ return resultLike[ResultLikeSymbol]();
1310
+ }
1211
1311
  function ensureError(err) {
1212
1312
  if (err instanceof Error) {
1213
1313
  return err;
1214
1314
  }
1215
- return new RetupleThrownValueError(err);
1315
+ return new RetupleCaughtValueError(err);
1216
1316
  }
1217
1317
  function mapTrue() {
1218
1318
  return true;