retuple 1.0.0-next.12 → 1.0.0-next.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +115 -1
- package/dist/index.d.cts +70 -15
- package/dist/index.d.ts +70 -15
- package/dist/index.js +115 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _ResultAsync_inner;
|
|
13
|
+
var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_errorHandler;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.RetupleArrayMethodUnavailableError = exports.RetupleInvalidUnionError = exports.RetupleInvalidResultError = exports.RetupleThrownValueError = exports.RetupleFlattenFailed = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
|
|
16
16
|
exports.Result = Result;
|
|
@@ -148,6 +148,8 @@ Result.$union = union;
|
|
|
148
148
|
Result.$safe = safe;
|
|
149
149
|
Result.$safeAsync = safeAsync;
|
|
150
150
|
Result.$safePromise = safePromise;
|
|
151
|
+
Result.$retry = retry;
|
|
152
|
+
Result.$safeRetry = safeRetry;
|
|
151
153
|
Object.freeze(Result);
|
|
152
154
|
function Ok(val) {
|
|
153
155
|
return new ResultOk(val);
|
|
@@ -155,6 +157,9 @@ function Ok(val) {
|
|
|
155
157
|
function Err(err) {
|
|
156
158
|
return new ResultErr(err);
|
|
157
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* @TODO
|
|
162
|
+
*/
|
|
158
163
|
function resolve(result) {
|
|
159
164
|
if (result instanceof ResultAsync) {
|
|
160
165
|
return result;
|
|
@@ -178,6 +183,9 @@ function truthy(value, error = mapTrue) {
|
|
|
178
183
|
}
|
|
179
184
|
return Err(error());
|
|
180
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* @TODO
|
|
188
|
+
*/
|
|
181
189
|
function union(union) {
|
|
182
190
|
if (union.success === true) {
|
|
183
191
|
return Ok(union.data);
|
|
@@ -208,6 +216,22 @@ function safeAsync(f, mapError = ensureError) {
|
|
|
208
216
|
function safePromise(promise, mapError = ensureError) {
|
|
209
217
|
return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
|
|
210
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* @TODO
|
|
221
|
+
*/
|
|
222
|
+
function retry(f) {
|
|
223
|
+
return new ResultRetry(f);
|
|
224
|
+
}
|
|
225
|
+
function safeRetry(f, mapError = ensureError) {
|
|
226
|
+
return new ResultRetry(async () => {
|
|
227
|
+
try {
|
|
228
|
+
return Ok(await f());
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
return Err(mapError(err));
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
211
235
|
/**
|
|
212
236
|
* ## RetupleArray
|
|
213
237
|
*
|
|
@@ -1108,6 +1132,96 @@ class ResultAsync {
|
|
|
1108
1132
|
}
|
|
1109
1133
|
}
|
|
1110
1134
|
_ResultAsync_inner = new WeakMap();
|
|
1135
|
+
/**
|
|
1136
|
+
* @TODO
|
|
1137
|
+
*/
|
|
1138
|
+
class ResultRetry {
|
|
1139
|
+
static zero() {
|
|
1140
|
+
return 0;
|
|
1141
|
+
}
|
|
1142
|
+
static delay(ms) {
|
|
1143
|
+
return new Promise((resolve) => setTimeout(resolve, Math.min(ms, _a.MAX_TIMEOUT)));
|
|
1144
|
+
}
|
|
1145
|
+
static integer(value) {
|
|
1146
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
1147
|
+
return Math.max(0, value);
|
|
1148
|
+
}
|
|
1149
|
+
return 0;
|
|
1150
|
+
}
|
|
1151
|
+
constructor(f) {
|
|
1152
|
+
_ResultRetry_f.set(this, void 0);
|
|
1153
|
+
_ResultRetry_promise.set(this, void 0);
|
|
1154
|
+
_ResultRetry_times.set(this, 1);
|
|
1155
|
+
_ResultRetry_attempt.set(this, 0);
|
|
1156
|
+
_ResultRetry_aborted.set(this, false);
|
|
1157
|
+
_ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
|
|
1158
|
+
_ResultRetry_getDelay.set(this, _a.zero);
|
|
1159
|
+
_ResultRetry_errorHandler.set(this, void 0);
|
|
1160
|
+
__classPrivateFieldSet(this, _ResultRetry_f, f, "f");
|
|
1161
|
+
__classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
|
|
1162
|
+
}
|
|
1163
|
+
then(onfulfilled, onrejected) {
|
|
1164
|
+
return __classPrivateFieldGet(this, _ResultRetry_promise, "f").then(onfulfilled, onrejected);
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* @TODO - Capped 100
|
|
1168
|
+
*/
|
|
1169
|
+
$times(times) {
|
|
1170
|
+
__classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
|
|
1171
|
+
return this;
|
|
1172
|
+
}
|
|
1173
|
+
$delay(fnOrMs) {
|
|
1174
|
+
if (typeof fnOrMs === "function") {
|
|
1175
|
+
__classPrivateFieldSet(this, _ResultRetry_getDelay, fnOrMs, "f");
|
|
1176
|
+
return this;
|
|
1177
|
+
}
|
|
1178
|
+
const delay = _a.integer(fnOrMs);
|
|
1179
|
+
if (delay > 0) {
|
|
1180
|
+
__classPrivateFieldSet(this, _ResultRetry_getDelay, () => delay, "f");
|
|
1181
|
+
}
|
|
1182
|
+
return this;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* @TODO
|
|
1186
|
+
*/
|
|
1187
|
+
$monitor(f) {
|
|
1188
|
+
__classPrivateFieldSet(this, _ResultRetry_errorHandler, f, "f");
|
|
1189
|
+
return this;
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* @TODO
|
|
1193
|
+
*/
|
|
1194
|
+
$async() {
|
|
1195
|
+
return new ResultAsync(this);
|
|
1196
|
+
}
|
|
1197
|
+
async drain() {
|
|
1198
|
+
var _b;
|
|
1199
|
+
while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
|
|
1200
|
+
const result = await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this);
|
|
1201
|
+
__classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
|
|
1202
|
+
if (result.$isOk()) {
|
|
1203
|
+
return result;
|
|
1204
|
+
}
|
|
1205
|
+
if (__classPrivateFieldGet(this, _ResultRetry_errorHandler, "f")) {
|
|
1206
|
+
await __classPrivateFieldGet(this, _ResultRetry_errorHandler, "f").call(this, {
|
|
1207
|
+
error: result[0],
|
|
1208
|
+
attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
|
|
1209
|
+
abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") === __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
|
|
1213
|
+
return result;
|
|
1214
|
+
}
|
|
1215
|
+
const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
|
|
1216
|
+
if (delay > 0) {
|
|
1217
|
+
await _a.delay(delay);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
_a = ResultRetry, _ResultRetry_f = new WeakMap(), _ResultRetry_promise = new WeakMap(), _ResultRetry_times = new WeakMap(), _ResultRetry_attempt = new WeakMap(), _ResultRetry_aborted = new WeakMap(), _ResultRetry_abort = new WeakMap(), _ResultRetry_getDelay = new WeakMap(), _ResultRetry_errorHandler = new WeakMap();
|
|
1223
|
+
ResultRetry.MAX_TIMEOUT = 3600000;
|
|
1224
|
+
ResultRetry.MAX_RETRY = 100;
|
|
1111
1225
|
function ensureError(err) {
|
|
1112
1226
|
if (err instanceof Error) {
|
|
1113
1227
|
return err;
|
package/dist/index.d.cts
CHANGED
|
@@ -99,6 +99,8 @@ export declare namespace Result {
|
|
|
99
99
|
var $safe: typeof safe;
|
|
100
100
|
var $safeAsync: typeof safeAsync;
|
|
101
101
|
var $safePromise: typeof safePromise;
|
|
102
|
+
var $retry: typeof retry;
|
|
103
|
+
var $safeRetry: typeof safeRetry;
|
|
102
104
|
}
|
|
103
105
|
/**
|
|
104
106
|
* Create a new {@link Result} with the `Ok` variant. When called without
|
|
@@ -142,6 +144,9 @@ export declare function Ok<const T>(val: T): Result<T, never>;
|
|
|
142
144
|
*/
|
|
143
145
|
export declare function Err(): Result<never, void>;
|
|
144
146
|
export declare function Err<const E>(err: E): Result<never, E>;
|
|
147
|
+
/**
|
|
148
|
+
* @TODO
|
|
149
|
+
*/
|
|
145
150
|
declare function resolve<T, E>(result: Retuple<T, E> | PromiseLike<Retuple<T, E>>): ResultAsync<T, E>;
|
|
146
151
|
/**
|
|
147
152
|
* Construct a {@link Result} from a value. If the value is neither null or
|
|
@@ -237,6 +242,9 @@ declare function nonNullable<const T, E>(value: T, error: () => E): Result<NonNu
|
|
|
237
242
|
*/
|
|
238
243
|
declare function truthy<const T>(value: T): Result<Truthy<T>, true>;
|
|
239
244
|
declare function truthy<const T, E>(value: T, error: () => E): Result<Truthy<T>, E>;
|
|
245
|
+
/**
|
|
246
|
+
* @TODO
|
|
247
|
+
*/
|
|
240
248
|
declare function union<U extends ObjectUnionOk<any> | ObjectUnionErr<any>>(union: U): Result<U extends ObjectUnionOk<infer T> ? T : never, U extends ObjectUnionErr<infer E> ? E : never>;
|
|
241
249
|
/**
|
|
242
250
|
* Construct a {@link Result} from a synchronous function call. If the function
|
|
@@ -435,6 +443,15 @@ declare function safeAsync<T, E>(f: () => T | PromiseLike<T>, mapError: (err: un
|
|
|
435
443
|
*/
|
|
436
444
|
declare function safePromise<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;
|
|
437
445
|
declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (err: unknown) => E): ResultAsync<T, E>;
|
|
446
|
+
/**
|
|
447
|
+
* @TODO
|
|
448
|
+
*/
|
|
449
|
+
declare function retry<T, E>(f: () => Retuple<T, E> | PromiseLike<Retuple<T, E>>): ResultRetry<T, E>;
|
|
450
|
+
/**
|
|
451
|
+
* @TODO
|
|
452
|
+
*/
|
|
453
|
+
declare function safeRetry<T>(f: () => T | PromiseLike<T>): ResultRetry<T, Error>;
|
|
454
|
+
declare function safeRetry<T, E>(f: () => T | PromiseLike<T>, mapError: (err: unknown) => E): ResultRetry<T, E>;
|
|
438
455
|
/**
|
|
439
456
|
* ## RetupleArray
|
|
440
457
|
*
|
|
@@ -948,22 +965,42 @@ declare class ResultAsync<T, E> {
|
|
|
948
965
|
*/
|
|
949
966
|
$iter<U>(this: ResultAsync<Iterable<U>, E>): Promise<IterableIterator<U, undefined, unknown>>;
|
|
950
967
|
}
|
|
951
|
-
|
|
952
|
-
type OkTuple<T> = [err: undefined, value: T];
|
|
953
|
-
type ErrTuple<E> = [err: E, value: undefined];
|
|
954
|
-
type ThisOk<T> = OkTuple<T> & Retuple<T, never>;
|
|
955
|
-
type ThisErr<E> = ErrTuple<E> & Retuple<never, E>;
|
|
956
|
-
type ObjectUnionOk<T> = {
|
|
957
|
-
success: true;
|
|
958
|
-
data: T;
|
|
959
|
-
error?: never | undefined;
|
|
960
|
-
};
|
|
961
|
-
type ObjectUnionErr<E> = {
|
|
962
|
-
success: false;
|
|
963
|
-
data?: never | undefined;
|
|
968
|
+
interface ResultRetryMonitor<E> {
|
|
964
969
|
error: E;
|
|
965
|
-
|
|
966
|
-
|
|
970
|
+
attempt: number;
|
|
971
|
+
abort: () => void;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* @TODO
|
|
975
|
+
*/
|
|
976
|
+
declare class ResultRetry<T, E> implements PromiseLike<Result<T, E>> {
|
|
977
|
+
#private;
|
|
978
|
+
private static MAX_TIMEOUT;
|
|
979
|
+
private static MAX_RETRY;
|
|
980
|
+
private static zero;
|
|
981
|
+
private static delay;
|
|
982
|
+
private static integer;
|
|
983
|
+
constructor(f: () => RetupleAwaitable<T, E>);
|
|
984
|
+
then<U = Result<T, E>, F = never>(onfulfilled?: ((value: Result<T, E>) => U | PromiseLike<U>) | null | undefined, onrejected?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<U | F>;
|
|
985
|
+
/**
|
|
986
|
+
* @TODO - Capped 100
|
|
987
|
+
*/
|
|
988
|
+
$times<N extends number>(this: ResultRetry<T, E>, times: NonZero<N> & NonNegativeOrDecimal<N>): ResultRetry<T, E>;
|
|
989
|
+
/**
|
|
990
|
+
* @TODO - Capped 1 hour
|
|
991
|
+
*/
|
|
992
|
+
$delay<N extends number>(this: ResultRetry<T, E>, f: (attempt: number) => NonNegativeOrDecimal<N>): ResultRetry<T, E>;
|
|
993
|
+
$delay<N extends number>(this: ResultRetry<T, E>, ms: NonNegativeOrDecimal<N>): ResultRetry<T, E>;
|
|
994
|
+
/**
|
|
995
|
+
* @TODO
|
|
996
|
+
*/
|
|
997
|
+
$monitor(f: (state: ResultRetryMonitor<E>) => void): ResultRetry<T, E>;
|
|
998
|
+
/**
|
|
999
|
+
* @TODO
|
|
1000
|
+
*/
|
|
1001
|
+
$async(this: ResultRetry<T, E>): ResultAsync<T, E>;
|
|
1002
|
+
private drain;
|
|
1003
|
+
}
|
|
967
1004
|
interface Retuple<T, E> extends RetupleArray<T | E | undefined> {
|
|
968
1005
|
/**
|
|
969
1006
|
* Returns true when this result is `Ok`. Acts as a type guard.
|
|
@@ -1974,3 +2011,21 @@ interface Retuple<T, E> extends RetupleArray<T | E | undefined> {
|
|
|
1974
2011
|
*/
|
|
1975
2012
|
$iter<U>(this: Result<Iterable<U>, E>): IterableIterator<U, undefined, unknown>;
|
|
1976
2013
|
}
|
|
2014
|
+
type OkTuple<T> = [err: undefined, value: T];
|
|
2015
|
+
type ErrTuple<E> = [err: E, value: undefined];
|
|
2016
|
+
type ThisOk<T> = OkTuple<T> & Retuple<T, never>;
|
|
2017
|
+
type ThisErr<E> = ErrTuple<E> & Retuple<never, E>;
|
|
2018
|
+
type RetupleAwaitable<T, E> = Retuple<T, E> | PromiseLike<Retuple<T, E>>;
|
|
2019
|
+
type ObjectUnionOk<T> = {
|
|
2020
|
+
success: true;
|
|
2021
|
+
data: T;
|
|
2022
|
+
error?: never | undefined;
|
|
2023
|
+
};
|
|
2024
|
+
type ObjectUnionErr<E> = {
|
|
2025
|
+
success: false;
|
|
2026
|
+
data?: never | undefined;
|
|
2027
|
+
error: E;
|
|
2028
|
+
};
|
|
2029
|
+
type Truthy<T> = Exclude<T, false | null | undefined | 0 | 0n | "">;
|
|
2030
|
+
type NonZero<N extends number> = N & (`${N}` extends "0" ? never : N);
|
|
2031
|
+
type NonNegativeOrDecimal<N extends number> = N & (`${N}` extends `-${string}` | `${string}.${string}` ? never : N);
|
package/dist/index.d.ts
CHANGED
|
@@ -99,6 +99,8 @@ export declare namespace Result {
|
|
|
99
99
|
var $safe: typeof safe;
|
|
100
100
|
var $safeAsync: typeof safeAsync;
|
|
101
101
|
var $safePromise: typeof safePromise;
|
|
102
|
+
var $retry: typeof retry;
|
|
103
|
+
var $safeRetry: typeof safeRetry;
|
|
102
104
|
}
|
|
103
105
|
/**
|
|
104
106
|
* Create a new {@link Result} with the `Ok` variant. When called without
|
|
@@ -142,6 +144,9 @@ export declare function Ok<const T>(val: T): Result<T, never>;
|
|
|
142
144
|
*/
|
|
143
145
|
export declare function Err(): Result<never, void>;
|
|
144
146
|
export declare function Err<const E>(err: E): Result<never, E>;
|
|
147
|
+
/**
|
|
148
|
+
* @TODO
|
|
149
|
+
*/
|
|
145
150
|
declare function resolve<T, E>(result: Retuple<T, E> | PromiseLike<Retuple<T, E>>): ResultAsync<T, E>;
|
|
146
151
|
/**
|
|
147
152
|
* Construct a {@link Result} from a value. If the value is neither null or
|
|
@@ -237,6 +242,9 @@ declare function nonNullable<const T, E>(value: T, error: () => E): Result<NonNu
|
|
|
237
242
|
*/
|
|
238
243
|
declare function truthy<const T>(value: T): Result<Truthy<T>, true>;
|
|
239
244
|
declare function truthy<const T, E>(value: T, error: () => E): Result<Truthy<T>, E>;
|
|
245
|
+
/**
|
|
246
|
+
* @TODO
|
|
247
|
+
*/
|
|
240
248
|
declare function union<U extends ObjectUnionOk<any> | ObjectUnionErr<any>>(union: U): Result<U extends ObjectUnionOk<infer T> ? T : never, U extends ObjectUnionErr<infer E> ? E : never>;
|
|
241
249
|
/**
|
|
242
250
|
* Construct a {@link Result} from a synchronous function call. If the function
|
|
@@ -435,6 +443,15 @@ declare function safeAsync<T, E>(f: () => T | PromiseLike<T>, mapError: (err: un
|
|
|
435
443
|
*/
|
|
436
444
|
declare function safePromise<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;
|
|
437
445
|
declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (err: unknown) => E): ResultAsync<T, E>;
|
|
446
|
+
/**
|
|
447
|
+
* @TODO
|
|
448
|
+
*/
|
|
449
|
+
declare function retry<T, E>(f: () => Retuple<T, E> | PromiseLike<Retuple<T, E>>): ResultRetry<T, E>;
|
|
450
|
+
/**
|
|
451
|
+
* @TODO
|
|
452
|
+
*/
|
|
453
|
+
declare function safeRetry<T>(f: () => T | PromiseLike<T>): ResultRetry<T, Error>;
|
|
454
|
+
declare function safeRetry<T, E>(f: () => T | PromiseLike<T>, mapError: (err: unknown) => E): ResultRetry<T, E>;
|
|
438
455
|
/**
|
|
439
456
|
* ## RetupleArray
|
|
440
457
|
*
|
|
@@ -948,22 +965,42 @@ declare class ResultAsync<T, E> {
|
|
|
948
965
|
*/
|
|
949
966
|
$iter<U>(this: ResultAsync<Iterable<U>, E>): Promise<IterableIterator<U, undefined, unknown>>;
|
|
950
967
|
}
|
|
951
|
-
|
|
952
|
-
type OkTuple<T> = [err: undefined, value: T];
|
|
953
|
-
type ErrTuple<E> = [err: E, value: undefined];
|
|
954
|
-
type ThisOk<T> = OkTuple<T> & Retuple<T, never>;
|
|
955
|
-
type ThisErr<E> = ErrTuple<E> & Retuple<never, E>;
|
|
956
|
-
type ObjectUnionOk<T> = {
|
|
957
|
-
success: true;
|
|
958
|
-
data: T;
|
|
959
|
-
error?: never | undefined;
|
|
960
|
-
};
|
|
961
|
-
type ObjectUnionErr<E> = {
|
|
962
|
-
success: false;
|
|
963
|
-
data?: never | undefined;
|
|
968
|
+
interface ResultRetryMonitor<E> {
|
|
964
969
|
error: E;
|
|
965
|
-
|
|
966
|
-
|
|
970
|
+
attempt: number;
|
|
971
|
+
abort: () => void;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* @TODO
|
|
975
|
+
*/
|
|
976
|
+
declare class ResultRetry<T, E> implements PromiseLike<Result<T, E>> {
|
|
977
|
+
#private;
|
|
978
|
+
private static MAX_TIMEOUT;
|
|
979
|
+
private static MAX_RETRY;
|
|
980
|
+
private static zero;
|
|
981
|
+
private static delay;
|
|
982
|
+
private static integer;
|
|
983
|
+
constructor(f: () => RetupleAwaitable<T, E>);
|
|
984
|
+
then<U = Result<T, E>, F = never>(onfulfilled?: ((value: Result<T, E>) => U | PromiseLike<U>) | null | undefined, onrejected?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<U | F>;
|
|
985
|
+
/**
|
|
986
|
+
* @TODO - Capped 100
|
|
987
|
+
*/
|
|
988
|
+
$times<N extends number>(this: ResultRetry<T, E>, times: NonZero<N> & NonNegativeOrDecimal<N>): ResultRetry<T, E>;
|
|
989
|
+
/**
|
|
990
|
+
* @TODO - Capped 1 hour
|
|
991
|
+
*/
|
|
992
|
+
$delay<N extends number>(this: ResultRetry<T, E>, f: (attempt: number) => NonNegativeOrDecimal<N>): ResultRetry<T, E>;
|
|
993
|
+
$delay<N extends number>(this: ResultRetry<T, E>, ms: NonNegativeOrDecimal<N>): ResultRetry<T, E>;
|
|
994
|
+
/**
|
|
995
|
+
* @TODO
|
|
996
|
+
*/
|
|
997
|
+
$monitor(f: (state: ResultRetryMonitor<E>) => void): ResultRetry<T, E>;
|
|
998
|
+
/**
|
|
999
|
+
* @TODO
|
|
1000
|
+
*/
|
|
1001
|
+
$async(this: ResultRetry<T, E>): ResultAsync<T, E>;
|
|
1002
|
+
private drain;
|
|
1003
|
+
}
|
|
967
1004
|
interface Retuple<T, E> extends RetupleArray<T | E | undefined> {
|
|
968
1005
|
/**
|
|
969
1006
|
* Returns true when this result is `Ok`. Acts as a type guard.
|
|
@@ -1974,3 +2011,21 @@ interface Retuple<T, E> extends RetupleArray<T | E | undefined> {
|
|
|
1974
2011
|
*/
|
|
1975
2012
|
$iter<U>(this: Result<Iterable<U>, E>): IterableIterator<U, undefined, unknown>;
|
|
1976
2013
|
}
|
|
2014
|
+
type OkTuple<T> = [err: undefined, value: T];
|
|
2015
|
+
type ErrTuple<E> = [err: E, value: undefined];
|
|
2016
|
+
type ThisOk<T> = OkTuple<T> & Retuple<T, never>;
|
|
2017
|
+
type ThisErr<E> = ErrTuple<E> & Retuple<never, E>;
|
|
2018
|
+
type RetupleAwaitable<T, E> = Retuple<T, E> | PromiseLike<Retuple<T, E>>;
|
|
2019
|
+
type ObjectUnionOk<T> = {
|
|
2020
|
+
success: true;
|
|
2021
|
+
data: T;
|
|
2022
|
+
error?: never | undefined;
|
|
2023
|
+
};
|
|
2024
|
+
type ObjectUnionErr<E> = {
|
|
2025
|
+
success: false;
|
|
2026
|
+
data?: never | undefined;
|
|
2027
|
+
error: E;
|
|
2028
|
+
};
|
|
2029
|
+
type Truthy<T> = Exclude<T, false | null | undefined | 0 | 0n | "">;
|
|
2030
|
+
type NonZero<N extends number> = N & (`${N}` extends "0" ? never : N);
|
|
2031
|
+
type NonNegativeOrDecimal<N extends number> = N & (`${N}` extends `-${string}` | `${string}.${string}` ? never : N);
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ 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_errorHandler;
|
|
13
13
|
/**
|
|
14
14
|
* ## Retuple Unwrap Failed
|
|
15
15
|
*
|
|
@@ -134,6 +134,8 @@ Result.$union = union;
|
|
|
134
134
|
Result.$safe = safe;
|
|
135
135
|
Result.$safeAsync = safeAsync;
|
|
136
136
|
Result.$safePromise = safePromise;
|
|
137
|
+
Result.$retry = retry;
|
|
138
|
+
Result.$safeRetry = safeRetry;
|
|
137
139
|
Object.freeze(Result);
|
|
138
140
|
export function Ok(val) {
|
|
139
141
|
return new ResultOk(val);
|
|
@@ -141,6 +143,9 @@ export function Ok(val) {
|
|
|
141
143
|
export function Err(err) {
|
|
142
144
|
return new ResultErr(err);
|
|
143
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* @TODO
|
|
148
|
+
*/
|
|
144
149
|
function resolve(result) {
|
|
145
150
|
if (result instanceof ResultAsync) {
|
|
146
151
|
return result;
|
|
@@ -164,6 +169,9 @@ function truthy(value, error = mapTrue) {
|
|
|
164
169
|
}
|
|
165
170
|
return Err(error());
|
|
166
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* @TODO
|
|
174
|
+
*/
|
|
167
175
|
function union(union) {
|
|
168
176
|
if (union.success === true) {
|
|
169
177
|
return Ok(union.data);
|
|
@@ -194,6 +202,22 @@ function safeAsync(f, mapError = ensureError) {
|
|
|
194
202
|
function safePromise(promise, mapError = ensureError) {
|
|
195
203
|
return new ResultAsync(promise.then((Ok), async (err) => Err(await mapError(err))));
|
|
196
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* @TODO
|
|
207
|
+
*/
|
|
208
|
+
function retry(f) {
|
|
209
|
+
return new ResultRetry(f);
|
|
210
|
+
}
|
|
211
|
+
function safeRetry(f, mapError = ensureError) {
|
|
212
|
+
return new ResultRetry(async () => {
|
|
213
|
+
try {
|
|
214
|
+
return Ok(await f());
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
return Err(mapError(err));
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
197
221
|
/**
|
|
198
222
|
* ## RetupleArray
|
|
199
223
|
*
|
|
@@ -1094,6 +1118,96 @@ class ResultAsync {
|
|
|
1094
1118
|
}
|
|
1095
1119
|
}
|
|
1096
1120
|
_ResultAsync_inner = new WeakMap();
|
|
1121
|
+
/**
|
|
1122
|
+
* @TODO
|
|
1123
|
+
*/
|
|
1124
|
+
class ResultRetry {
|
|
1125
|
+
static zero() {
|
|
1126
|
+
return 0;
|
|
1127
|
+
}
|
|
1128
|
+
static delay(ms) {
|
|
1129
|
+
return new Promise((resolve) => setTimeout(resolve, Math.min(ms, _a.MAX_TIMEOUT)));
|
|
1130
|
+
}
|
|
1131
|
+
static integer(value) {
|
|
1132
|
+
if (typeof value === "number" && Number.isInteger(value)) {
|
|
1133
|
+
return Math.max(0, value);
|
|
1134
|
+
}
|
|
1135
|
+
return 0;
|
|
1136
|
+
}
|
|
1137
|
+
constructor(f) {
|
|
1138
|
+
_ResultRetry_f.set(this, void 0);
|
|
1139
|
+
_ResultRetry_promise.set(this, void 0);
|
|
1140
|
+
_ResultRetry_times.set(this, 1);
|
|
1141
|
+
_ResultRetry_attempt.set(this, 0);
|
|
1142
|
+
_ResultRetry_aborted.set(this, false);
|
|
1143
|
+
_ResultRetry_abort.set(this, () => (__classPrivateFieldSet(this, _ResultRetry_aborted, true, "f")));
|
|
1144
|
+
_ResultRetry_getDelay.set(this, _a.zero);
|
|
1145
|
+
_ResultRetry_errorHandler.set(this, void 0);
|
|
1146
|
+
__classPrivateFieldSet(this, _ResultRetry_f, f, "f");
|
|
1147
|
+
__classPrivateFieldSet(this, _ResultRetry_promise, this.drain(), "f");
|
|
1148
|
+
}
|
|
1149
|
+
then(onfulfilled, onrejected) {
|
|
1150
|
+
return __classPrivateFieldGet(this, _ResultRetry_promise, "f").then(onfulfilled, onrejected);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* @TODO - Capped 100
|
|
1154
|
+
*/
|
|
1155
|
+
$times(times) {
|
|
1156
|
+
__classPrivateFieldSet(this, _ResultRetry_times, Math.min(Math.max(1, _a.integer(times)), _a.MAX_RETRY), "f");
|
|
1157
|
+
return this;
|
|
1158
|
+
}
|
|
1159
|
+
$delay(fnOrMs) {
|
|
1160
|
+
if (typeof fnOrMs === "function") {
|
|
1161
|
+
__classPrivateFieldSet(this, _ResultRetry_getDelay, fnOrMs, "f");
|
|
1162
|
+
return this;
|
|
1163
|
+
}
|
|
1164
|
+
const delay = _a.integer(fnOrMs);
|
|
1165
|
+
if (delay > 0) {
|
|
1166
|
+
__classPrivateFieldSet(this, _ResultRetry_getDelay, () => delay, "f");
|
|
1167
|
+
}
|
|
1168
|
+
return this;
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* @TODO
|
|
1172
|
+
*/
|
|
1173
|
+
$monitor(f) {
|
|
1174
|
+
__classPrivateFieldSet(this, _ResultRetry_errorHandler, f, "f");
|
|
1175
|
+
return this;
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* @TODO
|
|
1179
|
+
*/
|
|
1180
|
+
$async() {
|
|
1181
|
+
return new ResultAsync(this);
|
|
1182
|
+
}
|
|
1183
|
+
async drain() {
|
|
1184
|
+
var _b;
|
|
1185
|
+
while (__classPrivateFieldGet(this, _ResultRetry_attempt, "f") < __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
|
|
1186
|
+
const result = await __classPrivateFieldGet(this, _ResultRetry_f, "f").call(this);
|
|
1187
|
+
__classPrivateFieldSet(this, _ResultRetry_attempt, (_b = __classPrivateFieldGet(this, _ResultRetry_attempt, "f"), _b++, _b), "f");
|
|
1188
|
+
if (result.$isOk()) {
|
|
1189
|
+
return result;
|
|
1190
|
+
}
|
|
1191
|
+
if (__classPrivateFieldGet(this, _ResultRetry_errorHandler, "f")) {
|
|
1192
|
+
await __classPrivateFieldGet(this, _ResultRetry_errorHandler, "f").call(this, {
|
|
1193
|
+
error: result[0],
|
|
1194
|
+
attempt: __classPrivateFieldGet(this, _ResultRetry_attempt, "f"),
|
|
1195
|
+
abort: __classPrivateFieldGet(this, _ResultRetry_abort, "f"),
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
if (__classPrivateFieldGet(this, _ResultRetry_aborted, "f") || __classPrivateFieldGet(this, _ResultRetry_attempt, "f") === __classPrivateFieldGet(this, _ResultRetry_times, "f")) {
|
|
1199
|
+
return result;
|
|
1200
|
+
}
|
|
1201
|
+
const delay = _a.integer(__classPrivateFieldGet(this, _ResultRetry_getDelay, "f").call(this, __classPrivateFieldGet(this, _ResultRetry_attempt, "f")));
|
|
1202
|
+
if (delay > 0) {
|
|
1203
|
+
await _a.delay(delay);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
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();
|
|
1209
|
+
ResultRetry.MAX_TIMEOUT = 3600000;
|
|
1210
|
+
ResultRetry.MAX_RETRY = 100;
|
|
1097
1211
|
function ensureError(err) {
|
|
1098
1212
|
if (err instanceof Error) {
|
|
1099
1213
|
return err;
|