@nlozgachev/pipekit 0.1.8 → 0.3.0

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.
Files changed (59) hide show
  1. package/README.md +18 -13
  2. package/esm/src/Composition/flip.js +2 -2
  3. package/esm/src/Composition/fn.js +1 -1
  4. package/esm/src/Composition/tap.js +1 -1
  5. package/esm/src/Core/Arr.js +16 -16
  6. package/esm/src/Core/Option.js +27 -36
  7. package/esm/src/Core/Rec.js +1 -1
  8. package/esm/src/Core/RemoteData.js +9 -13
  9. package/esm/src/Core/Result.js +23 -32
  10. package/esm/src/Core/Task.js +95 -24
  11. package/esm/src/Core/TaskOption.js +8 -6
  12. package/esm/src/Core/TaskResult.js +67 -6
  13. package/esm/src/Core/TaskValidation.js +12 -8
  14. package/esm/src/Core/These.js +42 -42
  15. package/esm/src/Core/Validation.js +42 -43
  16. package/esm/src/Types/Brand.js +3 -3
  17. package/package.json +1 -1
  18. package/script/src/Composition/flip.js +2 -2
  19. package/script/src/Composition/fn.js +1 -1
  20. package/script/src/Composition/tap.js +1 -1
  21. package/script/src/Core/Arr.js +16 -16
  22. package/script/src/Core/Option.js +27 -36
  23. package/script/src/Core/Rec.js +1 -1
  24. package/script/src/Core/RemoteData.js +9 -13
  25. package/script/src/Core/Result.js +23 -32
  26. package/script/src/Core/Task.js +95 -24
  27. package/script/src/Core/TaskOption.js +8 -6
  28. package/script/src/Core/TaskResult.js +67 -6
  29. package/script/src/Core/TaskValidation.js +12 -8
  30. package/script/src/Core/These.js +42 -42
  31. package/script/src/Core/Validation.js +42 -43
  32. package/script/src/Types/Brand.js +3 -3
  33. package/types/src/Composition/flip.d.ts +2 -2
  34. package/types/src/Composition/fn.d.ts +1 -1
  35. package/types/src/Composition/pipe.d.ts +1 -1
  36. package/types/src/Composition/tap.d.ts +1 -1
  37. package/types/src/Composition/uncurry.d.ts +3 -3
  38. package/types/src/Core/Arr.d.ts +5 -5
  39. package/types/src/Core/Arr.d.ts.map +1 -1
  40. package/types/src/Core/Option.d.ts +21 -30
  41. package/types/src/Core/Option.d.ts.map +1 -1
  42. package/types/src/Core/Rec.d.ts.map +1 -1
  43. package/types/src/Core/RemoteData.d.ts +9 -13
  44. package/types/src/Core/RemoteData.d.ts.map +1 -1
  45. package/types/src/Core/Result.d.ts +19 -28
  46. package/types/src/Core/Result.d.ts.map +1 -1
  47. package/types/src/Core/Task.d.ts +81 -34
  48. package/types/src/Core/Task.d.ts.map +1 -1
  49. package/types/src/Core/TaskOption.d.ts +1 -1
  50. package/types/src/Core/TaskOption.d.ts.map +1 -1
  51. package/types/src/Core/TaskResult.d.ts +41 -2
  52. package/types/src/Core/TaskResult.d.ts.map +1 -1
  53. package/types/src/Core/TaskValidation.d.ts +10 -6
  54. package/types/src/Core/TaskValidation.d.ts.map +1 -1
  55. package/types/src/Core/These.d.ts +33 -33
  56. package/types/src/Core/These.d.ts.map +1 -1
  57. package/types/src/Core/Validation.d.ts +38 -42
  58. package/types/src/Core/Validation.d.ts.map +1 -1
  59. package/types/src/Types/Brand.d.ts +5 -5
@@ -4,22 +4,13 @@ exports.Result = void 0;
4
4
  var Result;
5
5
  (function (Result) {
6
6
  /**
7
- * Wraps a value in a successful Result (Ok).
8
- *
9
- * @example
10
- * ```ts
11
- * Result.of(42); // Ok(42)
12
- * ```
7
+ * Creates a successful Result with the given value.
13
8
  */
14
- Result.of = (value) => Result.toOk(value);
9
+ Result.ok = (value) => ({ kind: "Ok", value });
15
10
  /**
16
11
  * Creates a failed Result with the given error.
17
12
  */
18
- Result.toErr = (error) => ({ kind: "Error", error });
19
- /**
20
- * Creates a successful Result with the given value.
21
- */
22
- Result.toOk = (value) => ({ kind: "Ok", value });
13
+ Result.err = (error) => ({ kind: "Error", error });
23
14
  /**
24
15
  * Type guard that checks if an Result is Ok.
25
16
  */
@@ -43,10 +34,10 @@ var Result;
43
34
  */
44
35
  Result.tryCatch = (f, onError) => {
45
36
  try {
46
- return Result.toOk(f());
37
+ return Result.ok(f());
47
38
  }
48
39
  catch (e) {
49
- return Result.toErr(onError(e));
40
+ return Result.err(onError(e));
50
41
  }
51
42
  };
52
43
  /**
@@ -54,20 +45,20 @@ var Result;
54
45
  *
55
46
  * @example
56
47
  * ```ts
57
- * pipe(Result.of(5), Result.map(n => n * 2)); // Ok(10)
58
- * pipe(Result.toErr("error"), Result.map(n => n * 2)); // Err("error")
48
+ * pipe(Result.ok(5), Result.map(n => n * 2)); // Ok(10)
49
+ * pipe(Result.err("error"), Result.map(n => n * 2)); // Err("error")
59
50
  * ```
60
51
  */
61
- Result.map = (f) => (data) => Result.isOk(data) ? Result.toOk(f(data.value)) : data;
52
+ Result.map = (f) => (data) => Result.isOk(data) ? Result.ok(f(data.value)) : data;
62
53
  /**
63
54
  * Transforms the error value inside an Result.
64
55
  *
65
56
  * @example
66
57
  * ```ts
67
- * pipe(Result.toErr("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
58
+ * pipe(Result.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
68
59
  * ```
69
60
  */
70
- Result.mapError = (f) => (data) => Result.isErr(data) ? Result.toErr(f(data.error)) : data;
61
+ Result.mapError = (f) => (data) => Result.isErr(data) ? Result.err(f(data.error)) : data;
71
62
  /**
72
63
  * Chains Result computations. If the first is Ok, passes the value to f.
73
64
  * If the first is Err, propagates the error.
@@ -75,10 +66,10 @@ var Result;
75
66
  * @example
76
67
  * ```ts
77
68
  * const validatePositive = (n: number): Result<string, number> =>
78
- * n > 0 ? Result.of(n) : Result.toErr("Must be positive");
69
+ * n > 0 ? Result.ok(n) : Result.err("Must be positive");
79
70
  *
80
- * pipe(Result.of(5), Result.chain(validatePositive)); // Ok(5)
81
- * pipe(Result.of(-1), Result.chain(validatePositive)); // Err("Must be positive")
71
+ * pipe(Result.ok(5), Result.chain(validatePositive)); // Ok(5)
72
+ * pipe(Result.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
82
73
  * ```
83
74
  */
84
75
  Result.chain = (f) => (data) => Result.isOk(data) ? f(data.value) : data;
@@ -88,7 +79,7 @@ var Result;
88
79
  * @example
89
80
  * ```ts
90
81
  * pipe(
91
- * Result.of(5),
82
+ * Result.ok(5),
92
83
  * Result.fold(
93
84
  * e => `Error: ${e}`,
94
85
  * n => `Value: ${n}`
@@ -117,8 +108,8 @@ var Result;
117
108
  *
118
109
  * @example
119
110
  * ```ts
120
- * pipe(Result.of(5), Result.getOrElse(0)); // 5
121
- * pipe(Result.toErr("error"), Result.getOrElse(0)); // 0
111
+ * pipe(Result.ok(5), Result.getOrElse(0)); // 5
112
+ * pipe(Result.err("error"), Result.getOrElse(0)); // 0
122
113
  * ```
123
114
  */
124
115
  Result.getOrElse = (defaultValue) => (data) => Result.isOk(data) ? data.value : defaultValue;
@@ -129,7 +120,7 @@ var Result;
129
120
  * @example
130
121
  * ```ts
131
122
  * pipe(
132
- * Result.of(5),
123
+ * Result.ok(5),
133
124
  * Result.tap(n => console.log("Value:", n)),
134
125
  * Result.map(n => n * 2)
135
126
  * );
@@ -154,8 +145,8 @@ var Result;
154
145
  *
155
146
  * @example
156
147
  * ```ts
157
- * Result.toOption(Result.toOk(42)); // Some(42)
158
- * Result.toOption(Result.toErr("oops")); // None
148
+ * Result.toOption(Result.ok(42)); // Some(42)
149
+ * Result.toOption(Result.err("oops")); // None
159
150
  * ```
160
151
  */
161
152
  Result.toOption = (data) => Result.isOk(data) ? { kind: "Some", value: data.value } : { kind: "None" };
@@ -166,11 +157,11 @@ var Result;
166
157
  * ```ts
167
158
  * const add = (a: number) => (b: number) => a + b;
168
159
  * pipe(
169
- * Result.of(add),
170
- * Result.ap(Result.of(5)),
171
- * Result.ap(Result.of(3))
160
+ * Result.ok(add),
161
+ * Result.ap(Result.ok(5)),
162
+ * Result.ap(Result.ok(3))
172
163
  * ); // Ok(8)
173
164
  * ```
174
165
  */
175
- Result.ap = (arg) => (data) => Result.isOk(data) && Result.isOk(arg) ? Result.toOk(data.value(arg.value)) : Result.isErr(data) ? data : arg;
166
+ Result.ap = (arg) => (data) => Result.isOk(data) && Result.isOk(arg) ? Result.ok(data.value(arg.value)) : Result.isErr(data) ? data : arg;
176
167
  })(Result || (exports.Result = Result = {}));
@@ -1,29 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Task = void 0;
4
+ const Result_js_1 = require("./Result.js");
4
5
  var Task;
5
6
  (function (Task) {
6
7
  /**
7
- * Wraps a value in a Task that immediately resolves to that value.
8
+ * Creates a Task that immediately resolves to the given value.
8
9
  *
9
10
  * @example
10
11
  * ```ts
11
- * const task = Task.of(42);
12
+ * const task = Task.resolve(42);
12
13
  * task().then(console.log); // 42
13
14
  * ```
14
15
  */
15
- Task.of = (value) => () => Promise.resolve(value);
16
- /**
17
- * Creates a Task that will reject with the given error.
18
- */
19
- Task.fail = (error) => () => Promise.reject(error);
16
+ Task.resolve = (value) => () => Promise.resolve(value);
20
17
  /**
21
18
  * Creates a Task from a function that returns a Promise.
22
19
  * Alias for directly creating a Task.
23
20
  *
24
21
  * @example
25
22
  * ```ts
26
- * const fetchUser = Task.from(() => fetch('/user').then(r => r.json()));
23
+ * const getTimestamp = Task.from(() => Promise.resolve(Date.now()));
27
24
  * ```
28
25
  */
29
26
  Task.from = (f) => f;
@@ -33,24 +30,24 @@ var Task;
33
30
  * @example
34
31
  * ```ts
35
32
  * pipe(
36
- * Task.of(5),
33
+ * Task.resolve(5),
37
34
  * Task.map(n => n * 2)
38
35
  * )(); // Promise<10>
39
36
  * ```
40
37
  */
41
38
  Task.map = (f) => (data) => () => data().then(f);
42
39
  /**
43
- * Chains Task computations. If the first succeeds, passes the value to f.
40
+ * Chains Task computations. Passes the resolved value of the first Task to f.
44
41
  *
45
42
  * @example
46
43
  * ```ts
47
- * const fetchUser = (id: string): Task<User> => () => fetch(`/users/${id}`).then(r => r.json());
48
- * const fetchPosts = (user: User): Task<Post[]> => () => fetch(`/posts?userId=${user.id}`).then(r => r.json());
44
+ * const readUserId: Task<string> = () => Promise.resolve(session.userId);
45
+ * const loadPrefs = (id: string): Task<Preferences> => () => Promise.resolve(prefsCache.get(id));
49
46
  *
50
47
  * pipe(
51
- * fetchUser("123"),
52
- * Task.chain(fetchPosts)
53
- * )(); // Promise<Post[]>
48
+ * readUserId,
49
+ * Task.chain(loadPrefs)
50
+ * )(); // Promise<Preferences>
54
51
  * ```
55
52
  */
56
53
  Task.chain = (f) => (data) => () => data().then((a) => f(a)());
@@ -62,9 +59,9 @@ var Task;
62
59
  * ```ts
63
60
  * const add = (a: number) => (b: number) => a + b;
64
61
  * pipe(
65
- * Task.of(add),
66
- * Task.ap(Task.of(5)),
67
- * Task.ap(Task.of(3))
62
+ * Task.resolve(add),
63
+ * Task.ap(Task.resolve(5)),
64
+ * Task.ap(Task.resolve(3))
68
65
  * )(); // Promise<8>
69
66
  * ```
70
67
  */
@@ -76,9 +73,9 @@ var Task;
76
73
  * @example
77
74
  * ```ts
78
75
  * pipe(
79
- * fetchData,
80
- * Task.tap(data => console.log("Fetched:", data)),
81
- * Task.map(transform)
76
+ * loadConfig,
77
+ * Task.tap(cfg => console.log("Config:", cfg)),
78
+ * Task.map(buildReport)
82
79
  * );
83
80
  * ```
84
81
  */
@@ -91,21 +88,95 @@ var Task;
91
88
  *
92
89
  * @example
93
90
  * ```ts
94
- * Task.all([fetchUser, fetchPosts, fetchComments])();
95
- * // Promise<[User, Post[], Comment[]]>
91
+ * Task.all([loadConfig, detectLocale, loadTheme])();
92
+ * // Promise<[Config, string, Theme]>
96
93
  * ```
97
94
  */
98
95
  Task.all = (tasks) => () => Promise.all(tasks.map((t) => t()));
99
96
  /**
100
97
  * Delays the execution of a Task by the specified milliseconds.
98
+ * Useful for debouncing or rate limiting.
101
99
  *
102
100
  * @example
103
101
  * ```ts
104
102
  * pipe(
105
- * Task.of(42),
103
+ * Task.resolve(42),
106
104
  * Task.delay(1000)
107
105
  * )(); // Resolves after 1 second
108
106
  * ```
109
107
  */
110
108
  Task.delay = (ms) => (data) => () => new Promise((resolve, reject) => setTimeout(() => data().then(resolve, reject), ms));
109
+ /**
110
+ * Runs a Task a fixed number of times sequentially, collecting all results into an array.
111
+ * An optional delay (ms) can be inserted between runs.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * pipe(
116
+ * pollSensor,
117
+ * Task.repeat({ times: 5, delay: 1000 })
118
+ * )(); // Task<Reading[]> — 5 readings, one per second
119
+ * ```
120
+ */
121
+ Task.repeat = (options) => (task) => () => {
122
+ const { times, delay: ms } = options;
123
+ if (times <= 0)
124
+ return Promise.resolve([]);
125
+ const results = [];
126
+ const wait = () => ms !== undefined && ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve();
127
+ const run = (left) => task().then((a) => {
128
+ results.push(a);
129
+ if (left <= 1)
130
+ return results;
131
+ return wait().then(() => run(left - 1));
132
+ });
133
+ return run(times);
134
+ };
135
+ /**
136
+ * Runs a Task repeatedly until the result satisfies a predicate, returning that result.
137
+ * An optional delay (ms) can be inserted between runs.
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * pipe(
142
+ * checkStatus,
143
+ * Task.repeatUntil({ when: (s) => s === "ready", delay: 500 })
144
+ * )(); // polls every 500ms until status is "ready"
145
+ * ```
146
+ */
147
+ Task.repeatUntil = (options) => (task) => () => {
148
+ const { when: predicate, delay: ms } = options;
149
+ const wait = () => ms !== undefined && ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve();
150
+ const run = () => task().then((a) => {
151
+ if (predicate(a))
152
+ return a;
153
+ return wait().then(run);
154
+ });
155
+ return run();
156
+ };
157
+ /**
158
+ * Converts a `Task<A>` into a `Task<Result<E, A>>`, resolving to `Err` if the
159
+ * Task does not complete within the given time.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * pipe(
164
+ * heavyComputation,
165
+ * Task.timeout(5000, () => "timed out"),
166
+ * TaskResult.chain(processResult)
167
+ * );
168
+ * ```
169
+ */
170
+ Task.timeout = (ms, onTimeout) => (task) => () => {
171
+ let timerId;
172
+ return Promise.race([
173
+ task().then((a) => {
174
+ clearTimeout(timerId);
175
+ return Result_js_1.Result.ok(a);
176
+ }),
177
+ new Promise((resolve) => {
178
+ timerId = setTimeout(() => resolve(Result_js_1.Result.err(onTimeout())), ms);
179
+ }),
180
+ ]);
181
+ };
111
182
  })(Task || (exports.Task = Task = {}));
@@ -8,19 +8,19 @@ var TaskOption;
8
8
  /**
9
9
  * Wraps a value in a Some inside a Task.
10
10
  */
11
- TaskOption.of = (value) => Task_js_1.Task.of(Option_js_1.Option.of(value));
11
+ TaskOption.some = (value) => Task_js_1.Task.resolve(Option_js_1.Option.some(value));
12
12
  /**
13
13
  * Creates a TaskOption that resolves to None.
14
14
  */
15
- TaskOption.none = () => Task_js_1.Task.of(Option_js_1.Option.toNone());
15
+ TaskOption.none = () => Task_js_1.Task.resolve(Option_js_1.Option.none());
16
16
  /**
17
17
  * Lifts an Option into a TaskOption.
18
18
  */
19
- TaskOption.fromOption = (option) => Task_js_1.Task.of(option);
19
+ TaskOption.fromOption = (option) => Task_js_1.Task.resolve(option);
20
20
  /**
21
21
  * Lifts a Task into a TaskOption by wrapping its result in Some.
22
22
  */
23
- TaskOption.fromTask = (task) => Task_js_1.Task.map(Option_js_1.Option.of)(task);
23
+ TaskOption.fromTask = (task) => Task_js_1.Task.map(Option_js_1.Option.some)(task);
24
24
  /**
25
25
  * Creates a TaskOption from a Promise-returning function.
26
26
  * Returns Some if the promise resolves, None if it rejects.
@@ -32,7 +32,9 @@ var TaskOption;
32
32
  * );
33
33
  * ```
34
34
  */
35
- TaskOption.tryCatch = (f) => () => f().then(Option_js_1.Option.of).catch(() => Option_js_1.Option.toNone());
35
+ TaskOption.tryCatch = (f) => () => f()
36
+ .then(Option_js_1.Option.some)
37
+ .catch(() => Option_js_1.Option.none());
36
38
  /**
37
39
  * Transforms the value inside a TaskOption.
38
40
  */
@@ -49,7 +51,7 @@ var TaskOption;
49
51
  * )();
50
52
  * ```
51
53
  */
52
- TaskOption.chain = (f) => (data) => Task_js_1.Task.chain((option) => Option_js_1.Option.isSome(option) ? f(option.value) : Task_js_1.Task.of(Option_js_1.Option.toNone()))(data);
54
+ TaskOption.chain = (f) => (data) => Task_js_1.Task.chain((option) => Option_js_1.Option.isSome(option) ? f(option.value) : Task_js_1.Task.resolve(Option_js_1.Option.none()))(data);
53
55
  /**
54
56
  * Applies a function wrapped in a TaskOption to a value wrapped in a TaskOption.
55
57
  * Both Tasks run in parallel.
@@ -8,11 +8,11 @@ var TaskResult;
8
8
  /**
9
9
  * Wraps a value in a successful TaskResult.
10
10
  */
11
- TaskResult.of = (value) => Task_js_1.Task.of(Result_js_1.Result.toOk(value));
11
+ TaskResult.ok = (value) => Task_js_1.Task.resolve(Result_js_1.Result.ok(value));
12
12
  /**
13
13
  * Creates a failed TaskResult with the given error.
14
14
  */
15
- TaskResult.fail = (error) => Task_js_1.Task.of(Result_js_1.Result.toErr(error));
15
+ TaskResult.err = (error) => Task_js_1.Task.resolve(Result_js_1.Result.err(error));
16
16
  /**
17
17
  * Creates a TaskResult from a function that may throw.
18
18
  * Catches any errors and transforms them using the onError function.
@@ -27,8 +27,8 @@ var TaskResult;
27
27
  * ```
28
28
  */
29
29
  TaskResult.tryCatch = (f, onError) => () => f()
30
- .then(Result_js_1.Result.toOk)
31
- .catch((e) => Result_js_1.Result.toErr(onError(e)));
30
+ .then(Result_js_1.Result.ok)
31
+ .catch((e) => Result_js_1.Result.err(onError(e)));
32
32
  /**
33
33
  * Transforms the success value inside a TaskResult.
34
34
  */
@@ -41,7 +41,7 @@ var TaskResult;
41
41
  * Chains TaskResult computations. If the first succeeds, passes the value to f.
42
42
  * If the first fails, propagates the error.
43
43
  */
44
- TaskResult.chain = (f) => (data) => Task_js_1.Task.chain((result) => Result_js_1.Result.isOk(result) ? f(result.value) : Task_js_1.Task.of(Result_js_1.Result.toErr(result.error)))(data);
44
+ TaskResult.chain = (f) => (data) => Task_js_1.Task.chain((result) => Result_js_1.Result.isOk(result) ? f(result.value) : Task_js_1.Task.resolve(Result_js_1.Result.err(result.error)))(data);
45
45
  /**
46
46
  * Extracts the value from a TaskResult by providing handlers for both cases.
47
47
  */
@@ -53,7 +53,7 @@ var TaskResult;
53
53
  /**
54
54
  * Recovers from an error by providing a fallback TaskResult.
55
55
  */
56
- TaskResult.recover = (fallback) => (data) => Task_js_1.Task.chain((result) => Result_js_1.Result.isErr(result) ? fallback(result.error) : Task_js_1.Task.of(result))(data);
56
+ TaskResult.recover = (fallback) => (data) => Task_js_1.Task.chain((result) => Result_js_1.Result.isErr(result) ? fallback(result.error) : Task_js_1.Task.resolve(result))(data);
57
57
  /**
58
58
  * Returns the success value or a default value if the TaskResult is an error.
59
59
  */
@@ -63,4 +63,65 @@ var TaskResult;
63
63
  * Useful for logging or debugging.
64
64
  */
65
65
  TaskResult.tap = (f) => (data) => Task_js_1.Task.map(Result_js_1.Result.tap(f))(data);
66
+ /**
67
+ * Re-runs a TaskResult on `Err` with configurable attempts, backoff, and retry condition.
68
+ *
69
+ * @param options.attempts - Total number of attempts (1 = no retry, 3 = up to 3 tries)
70
+ * @param options.backoff - Fixed delay in ms, or a function `(attempt) => ms` for computed delay
71
+ * @param options.when - Only retry when this returns true; defaults to always retry on Err
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * // Retry up to 3 times with exponential backoff
76
+ * pipe(
77
+ * fetchUser,
78
+ * TaskResult.retry({ attempts: 3, backoff: n => n * 1000 })
79
+ * );
80
+ *
81
+ * // Only retry on network errors, not auth errors
82
+ * pipe(
83
+ * fetchUser,
84
+ * TaskResult.retry({ attempts: 3, when: e => e instanceof NetworkError })
85
+ * );
86
+ * ```
87
+ */
88
+ TaskResult.retry = (options) => (data) => () => {
89
+ const { attempts, backoff, when: shouldRetry } = options;
90
+ const getDelay = (n) => backoff === undefined ? 0 : typeof backoff === "function" ? backoff(n) : backoff;
91
+ const run = (left) => data().then((result) => {
92
+ if (Result_js_1.Result.isOk(result))
93
+ return result;
94
+ if (left <= 1)
95
+ return result;
96
+ if (shouldRetry !== undefined && !shouldRetry(result.error)) {
97
+ return result;
98
+ }
99
+ const ms = getDelay(attempts - left + 1);
100
+ return (ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve()).then(() => run(left - 1));
101
+ });
102
+ return run(attempts);
103
+ };
104
+ /**
105
+ * Fails a TaskResult with a typed error if it does not resolve within the given time.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * pipe(
110
+ * fetchUser,
111
+ * TaskResult.timeout(5000, () => new TimeoutError("fetch user timed out"))
112
+ * );
113
+ * ```
114
+ */
115
+ TaskResult.timeout = (ms, onTimeout) => (data) => () => {
116
+ let timerId;
117
+ return Promise.race([
118
+ data().then((result) => {
119
+ clearTimeout(timerId);
120
+ return result;
121
+ }),
122
+ new Promise((resolve) => {
123
+ timerId = setTimeout(() => resolve(Result_js_1.Result.err(onTimeout())), ms);
124
+ }),
125
+ ]);
126
+ };
66
127
  })(TaskResult || (exports.TaskResult = TaskResult = {}));
@@ -8,15 +8,19 @@ var TaskValidation;
8
8
  /**
9
9
  * Wraps a value in a valid TaskValidation.
10
10
  */
11
- TaskValidation.of = (value) => Task_js_1.Task.of(Validation_js_1.Validation.of(value));
11
+ TaskValidation.valid = (value) => Task_js_1.Task.resolve(Validation_js_1.Validation.valid(value));
12
12
  /**
13
13
  * Creates a failed TaskValidation with a single error.
14
14
  */
15
- TaskValidation.fail = (error) => Task_js_1.Task.of(Validation_js_1.Validation.fail(error));
15
+ TaskValidation.invalid = (error) => Task_js_1.Task.resolve(Validation_js_1.Validation.invalid(error));
16
+ /**
17
+ * Creates an invalid TaskValidation from multiple errors.
18
+ */
19
+ TaskValidation.invalidAll = (errors) => Task_js_1.Task.resolve(Validation_js_1.Validation.invalidAll(errors));
16
20
  /**
17
21
  * Lifts a Validation into a TaskValidation.
18
22
  */
19
- TaskValidation.fromValidation = (validation) => Task_js_1.Task.of(validation);
23
+ TaskValidation.fromValidation = (validation) => Task_js_1.Task.resolve(validation);
20
24
  /**
21
25
  * Creates a TaskValidation from a Promise-returning function.
22
26
  * Catches any errors and transforms them using the onError function.
@@ -31,8 +35,8 @@ var TaskValidation;
31
35
  * ```
32
36
  */
33
37
  TaskValidation.tryCatch = (f, onError) => () => f()
34
- .then((Validation_js_1.Validation.of))
35
- .catch((e) => Validation_js_1.Validation.fail(onError(e)));
38
+ .then((Validation_js_1.Validation.valid))
39
+ .catch((e) => Validation_js_1.Validation.invalid(onError(e)));
36
40
  /**
37
41
  * Transforms the success value inside a TaskValidation.
38
42
  */
@@ -45,7 +49,7 @@ var TaskValidation;
45
49
  */
46
50
  TaskValidation.chain = (f) => (data) => Task_js_1.Task.chain((validation) => Validation_js_1.Validation.isValid(validation)
47
51
  ? f(validation.value)
48
- : Task_js_1.Task.of(Validation_js_1.Validation.toInvalid(validation.errors)))(data);
52
+ : Task_js_1.Task.resolve(Validation_js_1.Validation.invalidAll(validation.errors)))(data);
49
53
  /**
50
54
  * Applies a function wrapped in a TaskValidation to a value wrapped in a
51
55
  * TaskValidation. Both Tasks run in parallel and errors from both sides
@@ -54,7 +58,7 @@ var TaskValidation;
54
58
  * @example
55
59
  * ```ts
56
60
  * pipe(
57
- * TaskValidation.of((name: string) => (age: number) => ({ name, age })),
61
+ * TaskValidation.valid((name: string) => (age: number) => ({ name, age })),
58
62
  * TaskValidation.ap(validateName(name)),
59
63
  * TaskValidation.ap(validateAge(age))
60
64
  * )();
@@ -92,5 +96,5 @@ var TaskValidation;
92
96
  /**
93
97
  * Recovers from an Invalid state by providing a fallback TaskValidation.
94
98
  */
95
- TaskValidation.recover = (fallback) => (data) => Task_js_1.Task.chain((validation) => Validation_js_1.Validation.isValid(validation) ? Task_js_1.Task.of(validation) : fallback())(data);
99
+ TaskValidation.recover = (fallback) => (data) => Task_js_1.Task.chain((validation) => Validation_js_1.Validation.isValid(validation) ? Task_js_1.Task.resolve(validation) : fallback())(data);
96
100
  })(TaskValidation || (exports.TaskValidation = TaskValidation = {}));