retuple 1.0.0-next.2 → 1.0.0-next.20
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/README.md +14 -1
- package/dist/index.cjs +551 -112
- package/dist/index.d.cts +1350 -295
- package/dist/index.d.ts +1350 -295
- package/dist/index.js +546 -106
- package/package.json +13 -10
package/dist/index.js
CHANGED
|
@@ -9,61 +9,221 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _ResultAsync_inner;
|
|
12
|
+
var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_handler;
|
|
13
|
+
import { ResultLikeSymbol, } from "retuple-symbols";
|
|
14
|
+
/**
|
|
15
|
+
* ## Retuple Unwrap Failed
|
|
16
|
+
*
|
|
17
|
+
* An error which occurs when calling `$unwrap` on `Err`.
|
|
18
|
+
*/
|
|
13
19
|
export class RetupleUnwrapFailed extends Error {
|
|
14
20
|
constructor(value, msg = "Unwrap failed") {
|
|
15
21
|
super(msg, value instanceof Error ? { cause: value } : undefined);
|
|
16
22
|
this.value = value;
|
|
17
23
|
}
|
|
18
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* ## Retuple Unwrap Err Failed
|
|
27
|
+
*
|
|
28
|
+
* An error which occurs when calling `$unwrapErr` on `Ok`.
|
|
29
|
+
*/
|
|
19
30
|
export class RetupleUnwrapErrFailed extends Error {
|
|
20
31
|
constructor(value, msg = "Unwrap error failed") {
|
|
21
32
|
super(msg);
|
|
22
33
|
this.value = value;
|
|
23
34
|
}
|
|
24
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* ## Retuple Expect Failed
|
|
38
|
+
*
|
|
39
|
+
* An error which occurs when calling `$expect` on `Err`, when the value
|
|
40
|
+
* contained in the `Err` is not an instance of `Error`.
|
|
41
|
+
*/
|
|
25
42
|
export class RetupleExpectFailed extends Error {
|
|
26
43
|
constructor(value) {
|
|
27
44
|
super("Expect failed");
|
|
28
45
|
this.value = value;
|
|
29
46
|
}
|
|
30
47
|
}
|
|
31
|
-
|
|
48
|
+
/**
|
|
49
|
+
* ## Retuple Thrown Value Error
|
|
50
|
+
*
|
|
51
|
+
* An error constructed when a safe function call throws or rejects, when the
|
|
52
|
+
* thrown error or rejected value is not an instance of `Error`, and when no
|
|
53
|
+
* map error function is provided.
|
|
54
|
+
*/
|
|
55
|
+
export class RetupleCaughtValueError extends Error {
|
|
32
56
|
constructor(value) {
|
|
33
57
|
super("Caught value was not an instance of Error");
|
|
34
58
|
this.value = value;
|
|
35
59
|
}
|
|
36
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* ## Retuple Invalid Union Error
|
|
63
|
+
*
|
|
64
|
+
* This error is thrown when attempting to construct a `Result` from a
|
|
65
|
+
* discriminated union, when the 'success' property is not boolean. In this
|
|
66
|
+
* case, it is impossible to determine whether the result should be `Ok` or
|
|
67
|
+
* `Err`.
|
|
68
|
+
*/
|
|
69
|
+
export class RetupleInvalidUnionError extends Error {
|
|
70
|
+
constructor(value) {
|
|
71
|
+
super("Constructing a Result from discriminated union failed, the success " +
|
|
72
|
+
"property must be boolean");
|
|
73
|
+
this.value = value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* ## Retuple Array Method Unavailable Error
|
|
78
|
+
*
|
|
79
|
+
* This error is thrown when calling a built-in array method from a `Result`.
|
|
80
|
+
*/
|
|
81
|
+
export class RetupleArrayMethodUnavailableError extends Error {
|
|
82
|
+
constructor(value, method) {
|
|
83
|
+
super(`Built in array method '${method}' should not be called directly from ` +
|
|
84
|
+
"a Result, convert the Result to a tuple first");
|
|
85
|
+
this.value = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
37
88
|
/**
|
|
38
89
|
* ## Result
|
|
39
90
|
*
|
|
40
91
|
* @TODO
|
|
41
92
|
*/
|
|
42
|
-
export
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
93
|
+
export function Result(resultLike) {
|
|
94
|
+
return asResult(resultLike);
|
|
95
|
+
}
|
|
96
|
+
Result.Ok = Ok;
|
|
97
|
+
Result.Err = Err;
|
|
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;
|
|
108
|
+
Object.freeze(Result);
|
|
51
109
|
export function Ok(val) {
|
|
52
110
|
return new ResultOk(val);
|
|
53
111
|
}
|
|
54
112
|
export function Err(err) {
|
|
55
113
|
return new ResultErr(err);
|
|
56
114
|
}
|
|
57
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Construct a {@link Result} from a {@link ResultLike}.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
*
|
|
120
|
+
* ```ts
|
|
121
|
+
* const value: Result<T, E> | ResultLike<T, E> = someResultFn();
|
|
122
|
+
* const result: Result<T, E> = Result.$from(result);
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
function $from(result) {
|
|
126
|
+
if (result instanceof ResultOk || result instanceof ResultErr) {
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
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 ResultOk:
|
|
154
|
+
case result instanceof ResultErr:
|
|
155
|
+
return new ResultAsync(Promise.resolve(result));
|
|
156
|
+
default:
|
|
157
|
+
return new ResultAsync(Promise.resolve(result).then((asResult)));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function $nonNullable(value, error = mapTrue) {
|
|
161
|
+
if (value !== null && value !== undefined) {
|
|
162
|
+
return Ok(value);
|
|
163
|
+
}
|
|
164
|
+
return Err(error());
|
|
165
|
+
}
|
|
166
|
+
function $truthy(value, error = mapTrue) {
|
|
58
167
|
if (value) {
|
|
59
|
-
return
|
|
168
|
+
return Ok(value);
|
|
60
169
|
}
|
|
61
|
-
|
|
62
|
-
|
|
170
|
+
return Err(error());
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Construct a {@link Result} from a common discriminated union shape. If the
|
|
174
|
+
* union is 'success' then the result is `Ok`
|
|
175
|
+
*
|
|
176
|
+
* Otherwise, the result is `Err` containing:
|
|
177
|
+
*
|
|
178
|
+
* - the returned value from the error function when provided;
|
|
179
|
+
* - or `true` otherwise.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
*
|
|
183
|
+
* ```ts
|
|
184
|
+
* const result: Result<string, Error> = Result.$truthy(
|
|
185
|
+
* username.trim(),
|
|
186
|
+
* () => new Error("Username is empty"),
|
|
187
|
+
* );
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
*
|
|
192
|
+
* ```ts
|
|
193
|
+
* const [err, value] = Result.$truthy("test");
|
|
194
|
+
*
|
|
195
|
+
* assert.equal(err, undefined);
|
|
196
|
+
* assert.equal(value, "test");
|
|
197
|
+
* ```
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
*
|
|
201
|
+
* ```ts
|
|
202
|
+
* const [err, value] = Result.$truthy("");
|
|
203
|
+
*
|
|
204
|
+
* assert.equal(err, true);
|
|
205
|
+
* assert.equal(value, undefined);
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
*
|
|
210
|
+
* ```ts
|
|
211
|
+
* const [err, value] = Result.$truthy(0, () => "error");
|
|
212
|
+
*
|
|
213
|
+
* assert.equal(err, "error");
|
|
214
|
+
* assert.equal(value, undefined);
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
function $fromUnion(union) {
|
|
218
|
+
if (union.success === true) {
|
|
219
|
+
return Ok(union.data);
|
|
220
|
+
}
|
|
221
|
+
if (union.success === false) {
|
|
222
|
+
return Err(union.error);
|
|
63
223
|
}
|
|
64
|
-
|
|
224
|
+
throw new RetupleInvalidUnionError(union);
|
|
65
225
|
}
|
|
66
|
-
|
|
226
|
+
function $safe(f, mapError = ensureError) {
|
|
67
227
|
try {
|
|
68
228
|
return Ok(f());
|
|
69
229
|
}
|
|
@@ -71,7 +231,7 @@ export function safe(f, mapError = ensureError) {
|
|
|
71
231
|
return Err(mapError(err));
|
|
72
232
|
}
|
|
73
233
|
}
|
|
74
|
-
|
|
234
|
+
function $safeAsync(f, mapError = ensureError) {
|
|
75
235
|
return new ResultAsync((async () => {
|
|
76
236
|
try {
|
|
77
237
|
return Ok(await f());
|
|
@@ -81,13 +241,42 @@ export function safeAsync(f, mapError = ensureError) {
|
|
|
81
241
|
}
|
|
82
242
|
})());
|
|
83
243
|
}
|
|
84
|
-
|
|
244
|
+
function $safePromise(promise, mapError = ensureError) {
|
|
85
245
|
return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
|
|
86
246
|
}
|
|
87
247
|
/**
|
|
88
|
-
*
|
|
248
|
+
* Construct a {@link ResultRetry} from a function which returns a
|
|
249
|
+
* {@link Result}. The function will be retried based on provided retry
|
|
250
|
+
* settings and eventually return a `Result`. No attempt is made to catch
|
|
251
|
+
* thrown errors or promise rejections.
|
|
89
252
|
*
|
|
90
|
-
* @
|
|
253
|
+
* To retry a potentially unsafe function, use {@link Result.$safeRetry}.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
*
|
|
257
|
+
* ```ts
|
|
258
|
+
* // Retry someResultFn up to 3 times until Ok is returned,
|
|
259
|
+
* // with a 1 second delay between each invocation:
|
|
260
|
+
* const result = await Result.$retry(someResultFn).$times(3).$delay(1000);
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
function $retry(f) {
|
|
264
|
+
return new ResultRetry(f);
|
|
265
|
+
}
|
|
266
|
+
function $safeRetry(f, mapError = ensureError) {
|
|
267
|
+
return new ResultRetry(async () => {
|
|
268
|
+
try {
|
|
269
|
+
return Ok(await f());
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
return Err(mapError(err));
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* ## ResultOk
|
|
278
|
+
*
|
|
279
|
+
* This is the `Ok` variant of a `Result`, used internally and not exported.
|
|
91
280
|
*/
|
|
92
281
|
class ResultOk extends Array {
|
|
93
282
|
constructor(value) {
|
|
@@ -95,14 +284,17 @@ class ResultOk extends Array {
|
|
|
95
284
|
this[0] = undefined;
|
|
96
285
|
this[1] = value;
|
|
97
286
|
}
|
|
98
|
-
|
|
287
|
+
[ResultLikeSymbol]() {
|
|
288
|
+
return { ok: true, value: this[1] };
|
|
289
|
+
}
|
|
290
|
+
toJSON() {
|
|
99
291
|
return this[1];
|
|
100
292
|
}
|
|
101
293
|
$isOk() {
|
|
102
294
|
return true;
|
|
103
295
|
}
|
|
104
296
|
$isOkAnd(f) {
|
|
105
|
-
return f(this[1]);
|
|
297
|
+
return !!f(this[1]);
|
|
106
298
|
}
|
|
107
299
|
$isErr() {
|
|
108
300
|
return false;
|
|
@@ -126,44 +318,77 @@ class ResultOk extends Array {
|
|
|
126
318
|
return this[1];
|
|
127
319
|
}
|
|
128
320
|
$map(f) {
|
|
129
|
-
return
|
|
321
|
+
return Ok(f(this[1]));
|
|
130
322
|
}
|
|
131
323
|
$mapErr() {
|
|
132
324
|
return this;
|
|
133
325
|
}
|
|
134
326
|
$mapOr(_def, f) {
|
|
135
|
-
return
|
|
327
|
+
return Ok(f(this[1]));
|
|
136
328
|
}
|
|
137
329
|
$mapOrElse(_def, f) {
|
|
138
|
-
return
|
|
330
|
+
return Ok(f(this[1]));
|
|
331
|
+
}
|
|
332
|
+
$andAssertOr(def, condition = isTruthy) {
|
|
333
|
+
return condition(this[1]) ? this : asResult(def);
|
|
334
|
+
}
|
|
335
|
+
$andAssertOrElse(def, condition = isTruthy) {
|
|
336
|
+
return condition(this[1]) ? this : asResult(def(this[1]));
|
|
139
337
|
}
|
|
140
338
|
$or() {
|
|
141
339
|
return this;
|
|
142
340
|
}
|
|
341
|
+
$orAsync() {
|
|
342
|
+
return this.$async();
|
|
343
|
+
}
|
|
143
344
|
$orElse() {
|
|
144
345
|
return this;
|
|
145
346
|
}
|
|
347
|
+
$orElseAsync() {
|
|
348
|
+
return this.$async();
|
|
349
|
+
}
|
|
146
350
|
$orSafe() {
|
|
147
351
|
return this;
|
|
148
352
|
}
|
|
353
|
+
$orSafeAsync() {
|
|
354
|
+
return this.$async();
|
|
355
|
+
}
|
|
356
|
+
$orSafePromise() {
|
|
357
|
+
return this.$async();
|
|
358
|
+
}
|
|
149
359
|
$and(and) {
|
|
150
|
-
return and;
|
|
360
|
+
return asResult(and);
|
|
361
|
+
}
|
|
362
|
+
$andAsync(and) {
|
|
363
|
+
return this.$async().$and(and);
|
|
151
364
|
}
|
|
152
365
|
$andThen(f) {
|
|
153
|
-
return f(this[1]);
|
|
366
|
+
return asResult(f(this[1]));
|
|
367
|
+
}
|
|
368
|
+
$andThenAsync(f) {
|
|
369
|
+
return this.$async().$andThen(f);
|
|
154
370
|
}
|
|
155
371
|
$andThrough(f) {
|
|
156
|
-
const res = f(this[1]);
|
|
372
|
+
const res = asResult(f(this[1]));
|
|
157
373
|
return res instanceof ResultErr ? res : this;
|
|
158
374
|
}
|
|
375
|
+
$andThroughAsync(f) {
|
|
376
|
+
return this.$async().$andThrough(f);
|
|
377
|
+
}
|
|
159
378
|
$andSafe(f, mapError = ensureError) {
|
|
160
379
|
try {
|
|
161
|
-
return
|
|
380
|
+
return Ok(f(this[1]));
|
|
162
381
|
}
|
|
163
382
|
catch (err) {
|
|
164
|
-
return
|
|
383
|
+
return Err(mapError(err));
|
|
165
384
|
}
|
|
166
385
|
}
|
|
386
|
+
$andSafeAsync(f, mapError = ensureError) {
|
|
387
|
+
return this.$async().$andSafe(f, mapError);
|
|
388
|
+
}
|
|
389
|
+
$andSafePromise(promise, mapError = ensureError) {
|
|
390
|
+
return this.$async().$andSafePromise(promise, mapError);
|
|
391
|
+
}
|
|
167
392
|
$peek(f) {
|
|
168
393
|
f(this);
|
|
169
394
|
return this;
|
|
@@ -184,11 +409,14 @@ class ResultOk extends Array {
|
|
|
184
409
|
$promise() {
|
|
185
410
|
return Promise.resolve(this);
|
|
186
411
|
}
|
|
412
|
+
*$iter() {
|
|
413
|
+
yield* this[1];
|
|
414
|
+
}
|
|
187
415
|
}
|
|
188
416
|
/**
|
|
189
|
-
* ##
|
|
417
|
+
* ## ResultErr
|
|
190
418
|
*
|
|
191
|
-
*
|
|
419
|
+
* This is the `Err` variant of a `Result`, used internally and not exported.
|
|
192
420
|
*/
|
|
193
421
|
class ResultErr extends Array {
|
|
194
422
|
constructor(err) {
|
|
@@ -196,8 +424,11 @@ class ResultErr extends Array {
|
|
|
196
424
|
this[0] = err;
|
|
197
425
|
this[1] = undefined;
|
|
198
426
|
}
|
|
199
|
-
|
|
200
|
-
return this[0];
|
|
427
|
+
[ResultLikeSymbol]() {
|
|
428
|
+
return { ok: false, value: this[0] };
|
|
429
|
+
}
|
|
430
|
+
toJSON() {
|
|
431
|
+
return null;
|
|
201
432
|
}
|
|
202
433
|
$isOk() {
|
|
203
434
|
return false;
|
|
@@ -209,7 +440,7 @@ class ResultErr extends Array {
|
|
|
209
440
|
return true;
|
|
210
441
|
}
|
|
211
442
|
$isErrAnd(f) {
|
|
212
|
-
return f(this[0]);
|
|
443
|
+
return !!f(this[0]);
|
|
213
444
|
}
|
|
214
445
|
$expect() {
|
|
215
446
|
if (this[0] instanceof Error) {
|
|
@@ -233,40 +464,73 @@ class ResultErr extends Array {
|
|
|
233
464
|
return this;
|
|
234
465
|
}
|
|
235
466
|
$mapErr(f) {
|
|
236
|
-
return
|
|
467
|
+
return Err(f(this[0]));
|
|
237
468
|
}
|
|
238
469
|
$mapOr(def) {
|
|
239
|
-
return
|
|
470
|
+
return Ok(def);
|
|
240
471
|
}
|
|
241
472
|
$mapOrElse(def) {
|
|
242
|
-
return
|
|
473
|
+
return Ok(def(this[0]));
|
|
474
|
+
}
|
|
475
|
+
$andAssertOr() {
|
|
476
|
+
return this;
|
|
477
|
+
}
|
|
478
|
+
$andAssertOrElse() {
|
|
479
|
+
return this;
|
|
243
480
|
}
|
|
244
481
|
$or(or) {
|
|
245
|
-
return or;
|
|
482
|
+
return asResult(or);
|
|
483
|
+
}
|
|
484
|
+
$orAsync(or) {
|
|
485
|
+
return this.$async().$or(or);
|
|
246
486
|
}
|
|
247
487
|
$orElse(f) {
|
|
248
|
-
return f(this[0]);
|
|
488
|
+
return asResult(f(this[0]));
|
|
489
|
+
}
|
|
490
|
+
$orElseAsync(f) {
|
|
491
|
+
return this.$async().$orElse(f);
|
|
249
492
|
}
|
|
250
493
|
$orSafe(f, mapError = ensureError) {
|
|
251
494
|
try {
|
|
252
|
-
return
|
|
495
|
+
return Ok(f(this[0]));
|
|
253
496
|
}
|
|
254
497
|
catch (err) {
|
|
255
|
-
return
|
|
498
|
+
return Err(mapError(err));
|
|
256
499
|
}
|
|
257
500
|
}
|
|
501
|
+
$orSafeAsync(f, mapError = ensureError) {
|
|
502
|
+
return this.$async().$orSafe(f, mapError);
|
|
503
|
+
}
|
|
504
|
+
$orSafePromise(promise, mapError = ensureError) {
|
|
505
|
+
return this.$async().$orSafePromise(promise, mapError);
|
|
506
|
+
}
|
|
258
507
|
$and() {
|
|
259
508
|
return this;
|
|
260
509
|
}
|
|
510
|
+
$andAsync() {
|
|
511
|
+
return this.$async();
|
|
512
|
+
}
|
|
261
513
|
$andThen() {
|
|
262
514
|
return this;
|
|
263
515
|
}
|
|
516
|
+
$andThenAsync() {
|
|
517
|
+
return this.$async();
|
|
518
|
+
}
|
|
264
519
|
$andThrough() {
|
|
265
520
|
return this;
|
|
266
521
|
}
|
|
522
|
+
$andThroughAsync() {
|
|
523
|
+
return this.$async();
|
|
524
|
+
}
|
|
267
525
|
$andSafe() {
|
|
268
526
|
return this;
|
|
269
527
|
}
|
|
528
|
+
$andSafeAsync() {
|
|
529
|
+
return this.$async();
|
|
530
|
+
}
|
|
531
|
+
$andSafePromise() {
|
|
532
|
+
return this.$async();
|
|
533
|
+
}
|
|
270
534
|
$peek(f) {
|
|
271
535
|
f(this);
|
|
272
536
|
return this;
|
|
@@ -287,6 +551,9 @@ class ResultErr extends Array {
|
|
|
287
551
|
$promise() {
|
|
288
552
|
return Promise.resolve(this);
|
|
289
553
|
}
|
|
554
|
+
*$iter() {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
290
557
|
}
|
|
291
558
|
/**
|
|
292
559
|
* ## ResultAsync
|
|
@@ -302,44 +569,42 @@ class ResultAsync {
|
|
|
302
569
|
return __classPrivateFieldGet(this, _ResultAsync_inner, "f").then(onfulfilled, onrejected);
|
|
303
570
|
}
|
|
304
571
|
/**
|
|
305
|
-
* @
|
|
306
|
-
*/
|
|
307
|
-
async $value() {
|
|
308
|
-
return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$value();
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* @TODO
|
|
572
|
+
* The same as {@link Retuple.$expect|$expect}, except it returns a `Promise`.
|
|
312
573
|
*/
|
|
313
574
|
async $expect() {
|
|
314
575
|
return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$expect();
|
|
315
576
|
}
|
|
316
577
|
/**
|
|
317
|
-
* @
|
|
578
|
+
* The same as {@link Retuple.$unwrap|$unwrap}, except it returns a `Promise`.
|
|
318
579
|
*/
|
|
319
580
|
async $unwrap(msg) {
|
|
320
581
|
return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$unwrap(msg);
|
|
321
582
|
}
|
|
322
583
|
/**
|
|
323
|
-
* @
|
|
584
|
+
* The same as {@link Retuple.$unwrapErr|$unwrapErr}, except it returns
|
|
585
|
+
* a `Promise`.
|
|
324
586
|
*/
|
|
325
587
|
async $unwrapErr(msg) {
|
|
326
588
|
return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$unwrapErr(msg);
|
|
327
589
|
}
|
|
328
590
|
/**
|
|
329
|
-
* @
|
|
591
|
+
* The same as {@link Retuple.$unwrapOr|$unwrapOr}, except it returns
|
|
592
|
+
* a `Promise`.
|
|
330
593
|
*/
|
|
331
594
|
async $unwrapOr(def) {
|
|
332
595
|
return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$unwrapOr(def);
|
|
333
596
|
}
|
|
334
597
|
/**
|
|
335
|
-
* @
|
|
598
|
+
* The same as {@link Retuple.$unwrapOrElse|$unwrapOrElse}, except it returns
|
|
599
|
+
* a `Promise`.
|
|
336
600
|
*/
|
|
337
601
|
async $unwrapOrElse(f) {
|
|
338
602
|
const res = await __classPrivateFieldGet(this, _ResultAsync_inner, "f");
|
|
339
603
|
return res instanceof ResultOk ? res[1] : f();
|
|
340
604
|
}
|
|
341
605
|
/**
|
|
342
|
-
* @
|
|
606
|
+
* The same as {@link Retuple.$map|$map}, except it returns
|
|
607
|
+
* {@link ResultAsync}.
|
|
343
608
|
*/
|
|
344
609
|
$map(f) {
|
|
345
610
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -349,7 +614,8 @@ class ResultAsync {
|
|
|
349
614
|
}));
|
|
350
615
|
}
|
|
351
616
|
/**
|
|
352
|
-
* @
|
|
617
|
+
* The same as {@link Retuple.$mapErr|$mapErr}, except it returns
|
|
618
|
+
* {@link ResultAsync}.
|
|
353
619
|
*/
|
|
354
620
|
$mapErr(f) {
|
|
355
621
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -359,7 +625,8 @@ class ResultAsync {
|
|
|
359
625
|
}));
|
|
360
626
|
}
|
|
361
627
|
/**
|
|
362
|
-
* @
|
|
628
|
+
* The same as {@link Retuple.$mapOr|$mapOr}, except it returns
|
|
629
|
+
* {@link ResultAsync}.
|
|
363
630
|
*/
|
|
364
631
|
$mapOr(def, f) {
|
|
365
632
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -369,7 +636,8 @@ class ResultAsync {
|
|
|
369
636
|
}));
|
|
370
637
|
}
|
|
371
638
|
/**
|
|
372
|
-
* @
|
|
639
|
+
* The same as {@link Retuple.$mapOrElse|$mapOrElse}, except it returns
|
|
640
|
+
* {@link ResultAsync}.
|
|
373
641
|
*/
|
|
374
642
|
$mapOrElse(def, f) {
|
|
375
643
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -378,25 +646,36 @@ class ResultAsync {
|
|
|
378
646
|
: new ResultOk(def(res[0]));
|
|
379
647
|
}));
|
|
380
648
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
649
|
+
$andAssertOr(def, condition = isTruthy) {
|
|
650
|
+
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
651
|
+
if (res instanceof ResultErr || condition(res[1])) {
|
|
652
|
+
return res;
|
|
653
|
+
}
|
|
654
|
+
return asResult(await def);
|
|
655
|
+
}));
|
|
656
|
+
}
|
|
657
|
+
$andAssertOrElse(def, condition = isTruthy) {
|
|
658
|
+
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
659
|
+
if (res instanceof ResultErr || condition(res[1])) {
|
|
660
|
+
return res;
|
|
661
|
+
}
|
|
662
|
+
return asResult(await def(res[1]));
|
|
663
|
+
}));
|
|
664
|
+
}
|
|
384
665
|
$or(or) {
|
|
385
666
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
386
|
-
return res instanceof ResultErr
|
|
667
|
+
return res instanceof ResultErr
|
|
668
|
+
? asResult(await or)
|
|
669
|
+
: res;
|
|
387
670
|
}));
|
|
388
671
|
}
|
|
389
|
-
/**
|
|
390
|
-
* @TODO
|
|
391
|
-
*/
|
|
392
672
|
$orElse(f) {
|
|
393
673
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
394
|
-
return res instanceof ResultErr
|
|
674
|
+
return res instanceof ResultErr
|
|
675
|
+
? asResult(await f(res[0]))
|
|
676
|
+
: res;
|
|
395
677
|
}));
|
|
396
678
|
}
|
|
397
|
-
/**
|
|
398
|
-
* @TODO
|
|
399
|
-
*/
|
|
400
679
|
$orSafe(f, mapError = ensureError) {
|
|
401
680
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
402
681
|
if (res instanceof ResultOk) {
|
|
@@ -410,29 +689,37 @@ class ResultAsync {
|
|
|
410
689
|
}
|
|
411
690
|
}));
|
|
412
691
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
692
|
+
$orSafePromise(promise, mapError = ensureError) {
|
|
693
|
+
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
694
|
+
if (res instanceof ResultOk) {
|
|
695
|
+
return res;
|
|
696
|
+
}
|
|
697
|
+
try {
|
|
698
|
+
return new ResultOk(await promise);
|
|
699
|
+
}
|
|
700
|
+
catch (err) {
|
|
701
|
+
return new ResultErr(mapError(err));
|
|
702
|
+
}
|
|
703
|
+
}));
|
|
704
|
+
}
|
|
416
705
|
$and(and) {
|
|
417
706
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
418
|
-
return res instanceof ResultOk
|
|
707
|
+
return res instanceof ResultOk
|
|
708
|
+
? asResult(await and)
|
|
709
|
+
: res;
|
|
419
710
|
}));
|
|
420
711
|
}
|
|
421
|
-
/**
|
|
422
|
-
* @TODO
|
|
423
|
-
*/
|
|
424
712
|
$andThen(f) {
|
|
425
713
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
426
|
-
return res instanceof ResultOk
|
|
714
|
+
return res instanceof ResultOk
|
|
715
|
+
? asResult(await f(res[1]))
|
|
716
|
+
: res;
|
|
427
717
|
}));
|
|
428
718
|
}
|
|
429
|
-
/**
|
|
430
|
-
* @TODO
|
|
431
|
-
*/
|
|
432
719
|
$andThrough(f) {
|
|
433
720
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
434
721
|
if (res instanceof ResultOk) {
|
|
435
|
-
const through = await f(res[1]);
|
|
722
|
+
const through = asResult(await f(res[1]));
|
|
436
723
|
if (through instanceof ResultErr) {
|
|
437
724
|
return through;
|
|
438
725
|
}
|
|
@@ -440,24 +727,37 @@ class ResultAsync {
|
|
|
440
727
|
return res;
|
|
441
728
|
}));
|
|
442
729
|
}
|
|
443
|
-
/**
|
|
444
|
-
* @TODO
|
|
445
|
-
*/
|
|
446
730
|
$andSafe(f, mapError = ensureError) {
|
|
447
731
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
448
732
|
if (res instanceof ResultErr) {
|
|
449
733
|
return res;
|
|
450
734
|
}
|
|
451
735
|
try {
|
|
452
|
-
return
|
|
736
|
+
return Ok(await f(res[1]));
|
|
453
737
|
}
|
|
454
738
|
catch (err) {
|
|
455
|
-
return
|
|
739
|
+
return Err(mapError(err));
|
|
740
|
+
}
|
|
741
|
+
}));
|
|
742
|
+
}
|
|
743
|
+
$andSafePromise(promise, mapError = ensureError) {
|
|
744
|
+
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
745
|
+
if (res instanceof ResultErr) {
|
|
746
|
+
return res;
|
|
747
|
+
}
|
|
748
|
+
try {
|
|
749
|
+
return Ok(await promise);
|
|
750
|
+
}
|
|
751
|
+
catch (err) {
|
|
752
|
+
return Err(mapError(err));
|
|
456
753
|
}
|
|
457
754
|
}));
|
|
458
755
|
}
|
|
459
756
|
/**
|
|
460
|
-
* @
|
|
757
|
+
* The same as {@link Retuple.$peek|$peek}, except it:
|
|
758
|
+
*
|
|
759
|
+
* - awaits the peek function;
|
|
760
|
+
* - returns {@link ResultAsync}.
|
|
461
761
|
*/
|
|
462
762
|
$peek(f) {
|
|
463
763
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -466,7 +766,10 @@ class ResultAsync {
|
|
|
466
766
|
}));
|
|
467
767
|
}
|
|
468
768
|
/**
|
|
469
|
-
* @
|
|
769
|
+
* The same as {@link Retuple.$tap|$tap}, except it:
|
|
770
|
+
*
|
|
771
|
+
* - awaits the tap function;
|
|
772
|
+
* - returns {@link ResultAsync}.
|
|
470
773
|
*/
|
|
471
774
|
$tap(f) {
|
|
472
775
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -477,7 +780,10 @@ class ResultAsync {
|
|
|
477
780
|
}));
|
|
478
781
|
}
|
|
479
782
|
/**
|
|
480
|
-
* @
|
|
783
|
+
* The same as {@link Retuple.$tapErr|$tapErr}, except it:
|
|
784
|
+
*
|
|
785
|
+
* - awaits the tap error function;
|
|
786
|
+
* - returns {@link ResultAsync}.
|
|
481
787
|
*/
|
|
482
788
|
$tapErr(f) {
|
|
483
789
|
return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
|
|
@@ -488,31 +794,165 @@ class ResultAsync {
|
|
|
488
794
|
}));
|
|
489
795
|
}
|
|
490
796
|
/**
|
|
491
|
-
* @
|
|
797
|
+
* The same as {@link Retuple.$promise|$promise}.
|
|
492
798
|
*/
|
|
493
799
|
$promise() {
|
|
494
800
|
return Promise.resolve(this);
|
|
495
801
|
}
|
|
802
|
+
/**
|
|
803
|
+
* The same as {@link Retuple.$iter|$iter}, except it returns a `Promise`.
|
|
804
|
+
*/
|
|
805
|
+
async $iter() {
|
|
806
|
+
return (await __classPrivateFieldGet(this, _ResultAsync_inner, "f")).$iter();
|
|
807
|
+
}
|
|
496
808
|
}
|
|
497
809
|
_ResultAsync_inner = new WeakMap();
|
|
810
|
+
/**
|
|
811
|
+
* ## ResultRetry
|
|
812
|
+
*/
|
|
813
|
+
class ResultRetry extends ResultAsync {
|
|
814
|
+
static zero() {
|
|
815
|
+
return 0;
|
|
816
|
+
}
|
|
817
|
+
static delay(ms) {
|
|
818
|
+
return new Promise((resolve) => setTimeout(resolve, Math.min(ms, _a.MAX_TIMEOUT)));
|
|
819
|
+
}
|
|
820
|
+
static integer(value) {
|
|
821
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
822
|
+
return Math.max(0, value);
|
|
823
|
+
}
|
|
824
|
+
return 0;
|
|
825
|
+
}
|
|
826
|
+
constructor(f) {
|
|
827
|
+
super(Promise.resolve().then(() => __classPrivateFieldGet(this, _ResultRetry_promise, "f")));
|
|
828
|
+
_ResultRetry_f.set(this, void 0);
|
|
829
|
+
_ResultRetry_promise.set(this, void 0);
|
|
830
|
+
_ResultRetry_times.set(this, 1);
|
|
831
|
+
_ResultRetry_attempt.set(this, 0);
|
|
832
|
+
_ResultRetry_aborted.set(this, false);
|
|
833
|
+
_ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
|
|
834
|
+
_ResultRetry_getDelay.set(this, _a.zero);
|
|
835
|
+
_ResultRetry_handler.set(this, void 0);
|
|
836
|
+
__classPrivateFieldSet(this, _ResultRetry_f, f, "f");
|
|
837
|
+
__classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
|
|
838
|
+
}
|
|
839
|
+
then(onfulfilled, onrejected) {
|
|
840
|
+
return super.then(onfulfilled, onrejected);
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Sets the maximum number of times the retry function can be executed,
|
|
844
|
+
* mutating this `ResultRetry` instance.
|
|
845
|
+
*
|
|
846
|
+
* **The default value is 1 - meaning that unless set, no retries will be
|
|
847
|
+
* attempted.**
|
|
848
|
+
*
|
|
849
|
+
* The retry function can be called up to the maximum number of times until
|
|
850
|
+
* it returns `Ok`. If it never returns `Ok`, the most recent `Err` is
|
|
851
|
+
* returned.
|
|
852
|
+
*
|
|
853
|
+
* This function accepts a positive integer between 1 and 100:
|
|
854
|
+
*
|
|
855
|
+
* - Integers outside of this range are clamped to the nearest valid value;
|
|
856
|
+
* - Any other value (NaN, Infinity, fractions, strings) are treated as 1.
|
|
857
|
+
*
|
|
858
|
+
* @example
|
|
859
|
+
*
|
|
860
|
+
* ```ts
|
|
861
|
+
* // Retry someResultFn up to 3 times until Ok is returned:
|
|
862
|
+
* const result = await Result.$retry(someResultFn).$times(3);
|
|
863
|
+
* ```
|
|
864
|
+
*/
|
|
865
|
+
$times(times) {
|
|
866
|
+
__classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
|
|
867
|
+
return this;
|
|
868
|
+
}
|
|
869
|
+
$delay(fnOrMs) {
|
|
870
|
+
if (typeof fnOrMs === "function") {
|
|
871
|
+
__classPrivateFieldSet(this, _ResultRetry_getDelay, fnOrMs, "f");
|
|
872
|
+
return this;
|
|
873
|
+
}
|
|
874
|
+
const delay = _a.integer(fnOrMs);
|
|
875
|
+
if (delay > 0) {
|
|
876
|
+
__classPrivateFieldSet(this, _ResultRetry_getDelay, () => delay, "f");
|
|
877
|
+
}
|
|
878
|
+
return this;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Sets a handler to be called when an attempt returns `Err`, mutating this
|
|
882
|
+
* `ResultRetry` instance. The handler can be used to capture information
|
|
883
|
+
* about each failure, and to abort early and prevent further retries.
|
|
884
|
+
*
|
|
885
|
+
* The handler function is called with `ResultRetryHandleState`, containing:
|
|
886
|
+
*
|
|
887
|
+
* - **error** - The error value from the last failed attempt;
|
|
888
|
+
* - **attempt** - The attempt number;
|
|
889
|
+
* - **abort** - A function which when called, prevents further retries.
|
|
890
|
+
*
|
|
891
|
+
* @example
|
|
892
|
+
*
|
|
893
|
+
* ```ts
|
|
894
|
+
* // Retry someResultFn up to 3 times until Ok is returned, logging each
|
|
895
|
+
* // attempt and aborting early if the error code is "UNAUTHORIZED".
|
|
896
|
+
* const result = await Result.$retry(someResultFn)
|
|
897
|
+
* .$times(3)
|
|
898
|
+
* .$handle(({ error, attempt, abort }) => {
|
|
899
|
+
* console.info(`Attempt ${attempt} failed: ${error}`);
|
|
900
|
+
* if (error === "UNAUTHORIZED") {
|
|
901
|
+
* abort();
|
|
902
|
+
* }
|
|
903
|
+
* });
|
|
904
|
+
* ```
|
|
905
|
+
*/
|
|
906
|
+
$handle(f) {
|
|
907
|
+
__classPrivateFieldSet(this, _ResultRetry_handler, f, "f");
|
|
908
|
+
return this;
|
|
909
|
+
}
|
|
910
|
+
async drain() {
|
|
911
|
+
var _b;
|
|
912
|
+
while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
|
|
913
|
+
const result = asResult(await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this));
|
|
914
|
+
__classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
|
|
915
|
+
if (result.$isOk()) {
|
|
916
|
+
return result;
|
|
917
|
+
}
|
|
918
|
+
if (__classPrivateFieldGet(this, _ResultRetry_handler, "f")) {
|
|
919
|
+
await __classPrivateFieldGet(this, _ResultRetry_handler, "f").call(this, {
|
|
920
|
+
error: result[0],
|
|
921
|
+
attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
|
|
922
|
+
abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") >= __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
|
|
926
|
+
return result;
|
|
927
|
+
}
|
|
928
|
+
const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
|
|
929
|
+
if (delay > 0) {
|
|
930
|
+
await _a.delay(delay);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
/* v8 ignore next */
|
|
934
|
+
throw new Error("Retuple: Unreachable code executed");
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
_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();
|
|
938
|
+
ResultRetry.MAX_TIMEOUT = 3600000;
|
|
939
|
+
ResultRetry.MAX_RETRY = 100;
|
|
940
|
+
function asResult(resultLike) {
|
|
941
|
+
if (resultLike instanceof ResultOk || resultLike instanceof ResultErr) {
|
|
942
|
+
return resultLike;
|
|
943
|
+
}
|
|
944
|
+
const result = resultLike[ResultLikeSymbol]();
|
|
945
|
+
return result.ok ? new ResultOk(result.value) : new ResultErr(result.value);
|
|
946
|
+
}
|
|
498
947
|
function ensureError(err) {
|
|
499
948
|
if (err instanceof Error) {
|
|
500
949
|
return err;
|
|
501
950
|
}
|
|
502
|
-
return new
|
|
951
|
+
return new RetupleCaughtValueError(err);
|
|
952
|
+
}
|
|
953
|
+
function mapTrue() {
|
|
954
|
+
return true;
|
|
955
|
+
}
|
|
956
|
+
function isTruthy(val) {
|
|
957
|
+
return !!val;
|
|
503
958
|
}
|
|
504
|
-
Object.freeze(Result);
|
|
505
|
-
Object.freeze(ResultOk);
|
|
506
|
-
Object.freeze(ResultErr);
|
|
507
|
-
Object.freeze(ResultAsync);
|
|
508
|
-
Object.freeze(RetupleUnwrapFailed);
|
|
509
|
-
Object.freeze(RetupleUnwrapErrFailed);
|
|
510
|
-
Object.freeze(RetupleExpectFailed);
|
|
511
|
-
Object.freeze(RetupleThrownValueError);
|
|
512
|
-
Object.freeze(ResultOk.prototype);
|
|
513
|
-
Object.freeze(ResultErr.prototype);
|
|
514
|
-
Object.freeze(ResultAsync.prototype);
|
|
515
|
-
Object.freeze(RetupleUnwrapFailed.prototype);
|
|
516
|
-
Object.freeze(RetupleUnwrapErrFailed.prototype);
|
|
517
|
-
Object.freeze(RetupleExpectFailed.prototype);
|
|
518
|
-
Object.freeze(RetupleThrownValueError.prototype);
|