@nlozgachev/pipelined 0.6.4
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 +85 -0
- package/esm/mod.js +3 -0
- package/esm/package.json +3 -0
- package/esm/src/Composition/compose.js +3 -0
- package/esm/src/Composition/converge.js +3 -0
- package/esm/src/Composition/curry.js +42 -0
- package/esm/src/Composition/flip.js +20 -0
- package/esm/src/Composition/flow.js +8 -0
- package/esm/src/Composition/fn.js +85 -0
- package/esm/src/Composition/index.js +13 -0
- package/esm/src/Composition/juxt.js +3 -0
- package/esm/src/Composition/memoize.js +66 -0
- package/esm/src/Composition/not.js +25 -0
- package/esm/src/Composition/on.js +12 -0
- package/esm/src/Composition/pipe.js +3 -0
- package/esm/src/Composition/tap.js +33 -0
- package/esm/src/Composition/uncurry.js +32 -0
- package/esm/src/Core/Arr.js +463 -0
- package/esm/src/Core/Deferred.js +26 -0
- package/esm/src/Core/InternalTypes.js +1 -0
- package/esm/src/Core/Lens.js +98 -0
- package/esm/src/Core/Option.js +186 -0
- package/esm/src/Core/Optional.js +160 -0
- package/esm/src/Core/Reader.js +134 -0
- package/esm/src/Core/Rec.js +167 -0
- package/esm/src/Core/RemoteData.js +206 -0
- package/esm/src/Core/Result.js +164 -0
- package/esm/src/Core/Task.js +187 -0
- package/esm/src/Core/TaskOption.js +105 -0
- package/esm/src/Core/TaskResult.js +125 -0
- package/esm/src/Core/TaskValidation.js +101 -0
- package/esm/src/Core/These.js +241 -0
- package/esm/src/Core/Validation.js +214 -0
- package/esm/src/Core/index.js +15 -0
- package/esm/src/Types/Brand.js +28 -0
- package/esm/src/Types/NonEmptyList.js +14 -0
- package/esm/src/Types/index.js +2 -0
- package/package.json +61 -0
- package/script/mod.js +19 -0
- package/script/package.json +3 -0
- package/script/src/Composition/compose.js +6 -0
- package/script/src/Composition/converge.js +6 -0
- package/script/src/Composition/curry.js +48 -0
- package/script/src/Composition/flip.js +24 -0
- package/script/src/Composition/flow.js +11 -0
- package/script/src/Composition/fn.js +98 -0
- package/script/src/Composition/index.js +29 -0
- package/script/src/Composition/juxt.js +6 -0
- package/script/src/Composition/memoize.js +71 -0
- package/script/src/Composition/not.js +29 -0
- package/script/src/Composition/on.js +16 -0
- package/script/src/Composition/pipe.js +6 -0
- package/script/src/Composition/tap.js +37 -0
- package/script/src/Composition/uncurry.js +38 -0
- package/script/src/Core/Arr.js +466 -0
- package/script/src/Core/Deferred.js +29 -0
- package/script/src/Core/InternalTypes.js +2 -0
- package/script/src/Core/Lens.js +101 -0
- package/script/src/Core/Option.js +189 -0
- package/script/src/Core/Optional.js +163 -0
- package/script/src/Core/Reader.js +137 -0
- package/script/src/Core/Rec.js +170 -0
- package/script/src/Core/RemoteData.js +209 -0
- package/script/src/Core/Result.js +167 -0
- package/script/src/Core/Task.js +190 -0
- package/script/src/Core/TaskOption.js +108 -0
- package/script/src/Core/TaskResult.js +128 -0
- package/script/src/Core/TaskValidation.js +104 -0
- package/script/src/Core/These.js +244 -0
- package/script/src/Core/Validation.js +217 -0
- package/script/src/Core/index.js +31 -0
- package/script/src/Types/Brand.js +31 -0
- package/script/src/Types/NonEmptyList.js +18 -0
- package/script/src/Types/index.js +18 -0
- package/types/mod.d.ts +4 -0
- package/types/mod.d.ts.map +1 -0
- package/types/src/Composition/compose.d.ts +33 -0
- package/types/src/Composition/compose.d.ts.map +1 -0
- package/types/src/Composition/converge.d.ts +21 -0
- package/types/src/Composition/converge.d.ts.map +1 -0
- package/types/src/Composition/curry.d.ts +43 -0
- package/types/src/Composition/curry.d.ts.map +1 -0
- package/types/src/Composition/flip.d.ts +21 -0
- package/types/src/Composition/flip.d.ts.map +1 -0
- package/types/src/Composition/flow.d.ts +56 -0
- package/types/src/Composition/flow.d.ts.map +1 -0
- package/types/src/Composition/fn.d.ts +76 -0
- package/types/src/Composition/fn.d.ts.map +1 -0
- package/types/src/Composition/index.d.ts +14 -0
- package/types/src/Composition/index.d.ts.map +1 -0
- package/types/src/Composition/juxt.d.ts +18 -0
- package/types/src/Composition/juxt.d.ts.map +1 -0
- package/types/src/Composition/memoize.d.ts +46 -0
- package/types/src/Composition/memoize.d.ts.map +1 -0
- package/types/src/Composition/not.d.ts +26 -0
- package/types/src/Composition/not.d.ts.map +1 -0
- package/types/src/Composition/on.d.ts +13 -0
- package/types/src/Composition/on.d.ts.map +1 -0
- package/types/src/Composition/pipe.d.ts +56 -0
- package/types/src/Composition/pipe.d.ts.map +1 -0
- package/types/src/Composition/tap.d.ts +31 -0
- package/types/src/Composition/tap.d.ts.map +1 -0
- package/types/src/Composition/uncurry.d.ts +54 -0
- package/types/src/Composition/uncurry.d.ts.map +1 -0
- package/types/src/Core/Arr.d.ts +355 -0
- package/types/src/Core/Arr.d.ts.map +1 -0
- package/types/src/Core/Deferred.d.ts +49 -0
- package/types/src/Core/Deferred.d.ts.map +1 -0
- package/types/src/Core/InternalTypes.d.ts +20 -0
- package/types/src/Core/InternalTypes.d.ts.map +1 -0
- package/types/src/Core/Lens.d.ts +118 -0
- package/types/src/Core/Lens.d.ts.map +1 -0
- package/types/src/Core/Option.d.ts +205 -0
- package/types/src/Core/Option.d.ts.map +1 -0
- package/types/src/Core/Optional.d.ts +158 -0
- package/types/src/Core/Optional.d.ts.map +1 -0
- package/types/src/Core/Reader.d.ts +156 -0
- package/types/src/Core/Reader.d.ts.map +1 -0
- package/types/src/Core/Rec.d.ts +121 -0
- package/types/src/Core/Rec.d.ts.map +1 -0
- package/types/src/Core/RemoteData.d.ts +192 -0
- package/types/src/Core/RemoteData.d.ts.map +1 -0
- package/types/src/Core/Result.d.ts +176 -0
- package/types/src/Core/Result.d.ts.map +1 -0
- package/types/src/Core/Task.d.ts +189 -0
- package/types/src/Core/Task.d.ts.map +1 -0
- package/types/src/Core/TaskOption.d.ts +120 -0
- package/types/src/Core/TaskOption.d.ts.map +1 -0
- package/types/src/Core/TaskResult.d.ts +117 -0
- package/types/src/Core/TaskResult.d.ts.map +1 -0
- package/types/src/Core/TaskValidation.d.ts +119 -0
- package/types/src/Core/TaskValidation.d.ts.map +1 -0
- package/types/src/Core/These.d.ts +221 -0
- package/types/src/Core/These.d.ts.map +1 -0
- package/types/src/Core/Validation.d.ts +213 -0
- package/types/src/Core/Validation.d.ts.map +1 -0
- package/types/src/Core/index.d.ts +16 -0
- package/types/src/Core/index.d.ts.map +1 -0
- package/types/src/Types/Brand.d.ts +52 -0
- package/types/src/Types/Brand.d.ts.map +1 -0
- package/types/src/Types/NonEmptyList.d.ts +29 -0
- package/types/src/Types/NonEmptyList.d.ts.map +1 -0
- package/types/src/Types/index.d.ts +3 -0
- package/types/src/Types/index.d.ts.map +1 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { Deferred } from "./Deferred.js";
|
|
2
|
+
import { Result } from "./Result.js";
|
|
3
|
+
/**
|
|
4
|
+
* A lazy async computation that always resolves.
|
|
5
|
+
*
|
|
6
|
+
* Two guarantees:
|
|
7
|
+
* - **Lazy** — nothing starts until you call it.
|
|
8
|
+
* - **Infallible** — it never rejects. If failure is possible, encode it in the
|
|
9
|
+
* return type using `TaskResult<E, A>` instead.
|
|
10
|
+
*
|
|
11
|
+
* Calling a Task returns a `Deferred<A>` — a one-shot async value that supports
|
|
12
|
+
* `await` but has no `.catch()`, `.finally()`, or chainable `.then()`.
|
|
13
|
+
*
|
|
14
|
+
* **Consuming a Task:**
|
|
15
|
+
*
|
|
16
|
+
* Use `await task()` to run it and get the value directly:
|
|
17
|
+
* ```ts
|
|
18
|
+
* const value: number = await task();
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* When you need an explicit `Promise<A>` (e.g. for a third-party API), convert
|
|
22
|
+
* the `Deferred` with `Deferred.toPromise`:
|
|
23
|
+
* ```ts
|
|
24
|
+
* const p: Promise<number> = Deferred.toPromise(task());
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const getTimestamp: Task<number> = Task.resolve(Date.now());
|
|
30
|
+
*
|
|
31
|
+
* // Nothing runs yet — getTimestamp is just a description
|
|
32
|
+
* const formatted = pipe(
|
|
33
|
+
* getTimestamp,
|
|
34
|
+
* Task.map(ts => new Date(ts).toISOString())
|
|
35
|
+
* );
|
|
36
|
+
*
|
|
37
|
+
* // Execute when ready
|
|
38
|
+
* const result = await formatted();
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export type Task<A> = () => Deferred<A>;
|
|
42
|
+
export declare namespace Task {
|
|
43
|
+
/**
|
|
44
|
+
* Creates a Task that immediately resolves to the given value.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const task = Task.resolve(42);
|
|
49
|
+
* const value = await task(); // 42
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
const resolve: <A>(value: A) => Task<A>;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a Task from a function that returns a Promise.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const getTimestamp = Task.from(() => Promise.resolve(Date.now()));
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
const from: <A>(f: () => Promise<A>) => Task<A>;
|
|
62
|
+
/**
|
|
63
|
+
* Transforms the value inside a Task.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* pipe(
|
|
68
|
+
* Task.resolve(5),
|
|
69
|
+
* Task.map(n => n * 2)
|
|
70
|
+
* )(); // Deferred<10>
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
const map: <A, B>(f: (a: A) => B) => (data: Task<A>) => Task<B>;
|
|
74
|
+
/**
|
|
75
|
+
* Chains Task computations. Passes the resolved value of the first Task to f.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* const readUserId: Task<string> = Task.resolve(session.userId);
|
|
80
|
+
* const loadPrefs = (id: string): Task<Preferences> =>
|
|
81
|
+
* Task.resolve(prefsCache.get(id));
|
|
82
|
+
*
|
|
83
|
+
* pipe(
|
|
84
|
+
* readUserId,
|
|
85
|
+
* Task.chain(loadPrefs)
|
|
86
|
+
* )(); // Deferred<Preferences>
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
const chain: <A, B>(f: (a: A) => Task<B>) => (data: Task<A>) => Task<B>;
|
|
90
|
+
/**
|
|
91
|
+
* Applies a function wrapped in a Task to a value wrapped in a Task.
|
|
92
|
+
* Both Tasks run in parallel.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* const add = (a: number) => (b: number) => a + b;
|
|
97
|
+
* pipe(
|
|
98
|
+
* Task.resolve(add),
|
|
99
|
+
* Task.ap(Task.resolve(5)),
|
|
100
|
+
* Task.ap(Task.resolve(3))
|
|
101
|
+
* )(); // Deferred<8>
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
const ap: <A>(arg: Task<A>) => <B>(data: Task<(a: A) => B>) => Task<B>;
|
|
105
|
+
/**
|
|
106
|
+
* Executes a side effect on the value without changing the Task.
|
|
107
|
+
* Useful for logging or debugging.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* pipe(
|
|
112
|
+
* loadConfig,
|
|
113
|
+
* Task.tap(cfg => console.log("Config:", cfg)),
|
|
114
|
+
* Task.map(buildReport)
|
|
115
|
+
* );
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
const tap: <A>(f: (a: A) => void) => (data: Task<A>) => Task<A>;
|
|
119
|
+
/**
|
|
120
|
+
* Runs multiple Tasks in parallel and collects their results.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* Task.all([loadConfig, detectLocale, loadTheme])();
|
|
125
|
+
* // Deferred<[Config, string, Theme]>
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
const all: <T extends readonly Task<unknown>[]>(tasks: T) => Task<{ [K in keyof T]: T[K] extends Task<infer A> ? A : never; }>;
|
|
129
|
+
/**
|
|
130
|
+
* Delays the execution of a Task by the specified milliseconds.
|
|
131
|
+
* Useful for debouncing or rate limiting.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* pipe(
|
|
136
|
+
* Task.resolve(42),
|
|
137
|
+
* Task.delay(1000)
|
|
138
|
+
* )(); // Resolves after 1 second
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
const delay: (ms: number) => <A>(data: Task<A>) => Task<A>;
|
|
142
|
+
/**
|
|
143
|
+
* Runs a Task a fixed number of times sequentially, collecting all results into an array.
|
|
144
|
+
* An optional delay (ms) can be inserted between runs.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* pipe(
|
|
149
|
+
* pollSensor,
|
|
150
|
+
* Task.repeat({ times: 5, delay: 1000 })
|
|
151
|
+
* )(); // Task<Reading[]> — 5 readings, one per second
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
const repeat: (options: {
|
|
155
|
+
times: number;
|
|
156
|
+
delay?: number;
|
|
157
|
+
}) => <A>(task: Task<A>) => Task<A[]>;
|
|
158
|
+
/**
|
|
159
|
+
* Runs a Task repeatedly until the result satisfies a predicate, returning that result.
|
|
160
|
+
* An optional delay (ms) can be inserted between runs.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* pipe(
|
|
165
|
+
* checkStatus,
|
|
166
|
+
* Task.repeatUntil({ when: (s) => s === "ready", delay: 500 })
|
|
167
|
+
* )(); // polls every 500ms until status is "ready"
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
const repeatUntil: <A>(options: {
|
|
171
|
+
when: (a: A) => boolean;
|
|
172
|
+
delay?: number;
|
|
173
|
+
}) => (task: Task<A>) => Task<A>;
|
|
174
|
+
/**
|
|
175
|
+
* Converts a `Task<A>` into a `Task<Result<E, A>>`, resolving to `Err` if the
|
|
176
|
+
* Task does not complete within the given time.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* pipe(
|
|
181
|
+
* heavyComputation,
|
|
182
|
+
* Task.timeout(5000, () => "timed out"),
|
|
183
|
+
* TaskResult.chain(processResult)
|
|
184
|
+
* );
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
const timeout: <E>(ms: number, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=Task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Task.d.ts","sourceRoot":"","sources":["../../../src/src/Core/Task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;AAOxC,yBAAiB,IAAI,CAAC;IACpB;;;;;;;;OAQG;IACI,MAAM,OAAO,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,IAAI,CAAC,CAAC,CACE,CAAC;IAE/C;;;;;;;OAOG;IACI,MAAM,IAAI,GAAI,CAAC,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAAoC,CAAC;IAEzF;;;;;;;;;;OAUG;IACI,MAAM,GAAG,GAAI,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAC/B,CAAC;IAEtC;;;;;;;;;;;;;;OAcG;IACI,MAAM,KAAK,GAAI,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAClB,CAAC;IAE3D;;;;;;;;;;;;;OAaG;IACI,MAAM,EAAE,GAAI,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAMxE,CAAC;IAEJ;;;;;;;;;;;;OAYG;IACI,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAMjE,CAAC;IAEJ;;;;;;;;OAQG;IACI,MAAM,GAAG,GAAI,CAAC,SAAS,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,EACpD,OAAO,CAAC,KACP,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,GAAE,CAQ/D,CAAC;IAEJ;;;;;;;;;;;OAWG;IACI,MAAM,KAAK,GAAI,IAAI,MAAM,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAS5D,CAAC;IAEJ;;;;;;;;;;;OAWG;IACI,MAAM,MAAM,GAChB,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,EAAE,CAcxE,CAAC;IAEP;;;;;;;;;;;OAWG;IACI,MAAM,WAAW,GACrB,CAAC,EAAE,SAAS;QAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAWhF,CAAC;IAEP;;;;;;;;;;;;OAYG;IACI,MAAM,OAAO,GACjB,CAAC,EAAE,IAAI,MAAM,EAAE,WAAW,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAYxE,CAAC;CACR"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Option } from "./Option.js";
|
|
2
|
+
import { Task } from "./Task.js";
|
|
3
|
+
import { TaskResult } from "./TaskResult.js";
|
|
4
|
+
/**
|
|
5
|
+
* A Task that resolves to an optional value.
|
|
6
|
+
* Combines async operations with the Option type for values that may not exist.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const findUser = (id: string): TaskOption<User> =>
|
|
11
|
+
* TaskOption.tryCatch(() => db.users.findById(id));
|
|
12
|
+
*
|
|
13
|
+
* pipe(
|
|
14
|
+
* findUser("123"),
|
|
15
|
+
* TaskOption.map(user => user.name),
|
|
16
|
+
* TaskOption.getOrElse("Unknown")
|
|
17
|
+
* )();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export type TaskOption<A> = Task<Option<A>>;
|
|
21
|
+
export declare namespace TaskOption {
|
|
22
|
+
/**
|
|
23
|
+
* Wraps a value in a Some inside a Task.
|
|
24
|
+
*/
|
|
25
|
+
const some: <A>(value: A) => TaskOption<A>;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a TaskOption that resolves to None.
|
|
28
|
+
*/
|
|
29
|
+
const none: <A = never>() => TaskOption<A>;
|
|
30
|
+
/**
|
|
31
|
+
* Lifts an Option into a TaskOption.
|
|
32
|
+
*/
|
|
33
|
+
const fromOption: <A>(option: Option<A>) => TaskOption<A>;
|
|
34
|
+
/**
|
|
35
|
+
* Lifts a Task into a TaskOption by wrapping its result in Some.
|
|
36
|
+
*/
|
|
37
|
+
const fromTask: <A>(task: Task<A>) => TaskOption<A>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a TaskOption from a Promise-returning function.
|
|
40
|
+
* Returns Some if the promise resolves, None if it rejects.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const fetchUser = TaskOption.tryCatch(() =>
|
|
45
|
+
* fetch("/user/1").then(r => r.json())
|
|
46
|
+
* );
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
const tryCatch: <A>(f: () => Promise<A>) => TaskOption<A>;
|
|
50
|
+
/**
|
|
51
|
+
* Transforms the value inside a TaskOption.
|
|
52
|
+
*/
|
|
53
|
+
const map: <A, B>(f: (a: A) => B) => (data: TaskOption<A>) => TaskOption<B>;
|
|
54
|
+
/**
|
|
55
|
+
* Chains TaskOption computations. If the first resolves to Some, passes the
|
|
56
|
+
* value to f. If the first resolves to None, propagates None.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* pipe(
|
|
61
|
+
* findUser("123"),
|
|
62
|
+
* TaskOption.chain(user => findOrg(user.orgId))
|
|
63
|
+
* )();
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
const chain: <A, B>(f: (a: A) => TaskOption<B>) => (data: TaskOption<A>) => TaskOption<B>;
|
|
67
|
+
/**
|
|
68
|
+
* Applies a function wrapped in a TaskOption to a value wrapped in a TaskOption.
|
|
69
|
+
* Both Tasks run in parallel.
|
|
70
|
+
*/
|
|
71
|
+
const ap: <A>(arg: TaskOption<A>) => <B>(data: TaskOption<(a: A) => B>) => TaskOption<B>;
|
|
72
|
+
/**
|
|
73
|
+
* Extracts a value from a TaskOption by providing handlers for both cases.
|
|
74
|
+
*/
|
|
75
|
+
const fold: <A, B>(onNone: () => B, onSome: (a: A) => B) => (data: TaskOption<A>) => Task<B>;
|
|
76
|
+
/**
|
|
77
|
+
* Pattern matches on a TaskOption, returning a Task of the result.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* pipe(
|
|
82
|
+
* findUser("123"),
|
|
83
|
+
* TaskOption.match({
|
|
84
|
+
* some: user => `Hello, ${user.name}`,
|
|
85
|
+
* none: () => "User not found"
|
|
86
|
+
* })
|
|
87
|
+
* )();
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
const match: <A, B>(cases: {
|
|
91
|
+
none: () => B;
|
|
92
|
+
some: (a: A) => B;
|
|
93
|
+
}) => (data: TaskOption<A>) => Task<B>;
|
|
94
|
+
/**
|
|
95
|
+
* Returns the value or a default if the TaskOption resolves to None.
|
|
96
|
+
*/
|
|
97
|
+
const getOrElse: <A>(defaultValue: A) => (data: TaskOption<A>) => Task<A>;
|
|
98
|
+
/**
|
|
99
|
+
* Executes a side effect on the value without changing the TaskOption.
|
|
100
|
+
* Useful for logging or debugging.
|
|
101
|
+
*/
|
|
102
|
+
const tap: <A>(f: (a: A) => void) => (data: TaskOption<A>) => TaskOption<A>;
|
|
103
|
+
/**
|
|
104
|
+
* Filters the value inside a TaskOption. Returns None if the predicate fails.
|
|
105
|
+
*/
|
|
106
|
+
const filter: <A>(predicate: (a: A) => boolean) => (data: TaskOption<A>) => TaskOption<A>;
|
|
107
|
+
/**
|
|
108
|
+
* Converts a TaskOption to a TaskResult, using onNone to produce the error value.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* pipe(
|
|
113
|
+
* findUser("123"),
|
|
114
|
+
* TaskOption.toTaskResult(() => "User not found")
|
|
115
|
+
* );
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
const toTaskResult: <E>(onNone: () => E) => <A>(data: TaskOption<A>) => TaskResult<E, A>;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=TaskOption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskOption.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskOption.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Result } from "./Result.js";
|
|
2
|
+
import { Task } from "./Task.js";
|
|
3
|
+
/**
|
|
4
|
+
* A Task that can fail with an error of type E or succeed with a value of type A.
|
|
5
|
+
* Combines async operations with typed error handling.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const fetchUser = (id: string): TaskResult<Error, User> =>
|
|
10
|
+
* TaskResult.tryCatch(
|
|
11
|
+
* () => fetch(`/users/${id}`).then(r => r.json()),
|
|
12
|
+
* (e) => new Error(`Failed to fetch user: ${e}`)
|
|
13
|
+
* );
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export type TaskResult<E, A> = Task<Result<E, A>>;
|
|
17
|
+
export declare namespace TaskResult {
|
|
18
|
+
/**
|
|
19
|
+
* Wraps a value in a successful TaskResult.
|
|
20
|
+
*/
|
|
21
|
+
const ok: <E, A>(value: A) => TaskResult<E, A>;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a failed TaskResult with the given error.
|
|
24
|
+
*/
|
|
25
|
+
const err: <E, A>(error: E) => TaskResult<E, A>;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a TaskResult from a function that may throw.
|
|
28
|
+
* Catches any errors and transforms them using the onError function.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const parseJson = (s: string): TaskResult<string, unknown> =>
|
|
33
|
+
* TaskResult.tryCatch(
|
|
34
|
+
* async () => JSON.parse(s),
|
|
35
|
+
* (e) => `Parse error: ${e}`
|
|
36
|
+
* );
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
const tryCatch: <E, A>(f: () => Promise<A>, onError: (e: unknown) => E) => TaskResult<E, A>;
|
|
40
|
+
/**
|
|
41
|
+
* Transforms the success value inside a TaskResult.
|
|
42
|
+
*/
|
|
43
|
+
const map: <E, A, B>(f: (a: A) => B) => (data: TaskResult<E, A>) => TaskResult<E, B>;
|
|
44
|
+
/**
|
|
45
|
+
* Transforms the error value inside a TaskResult.
|
|
46
|
+
*/
|
|
47
|
+
const mapError: <E, F, A>(f: (e: E) => F) => (data: TaskResult<E, A>) => TaskResult<F, A>;
|
|
48
|
+
/**
|
|
49
|
+
* Chains TaskResult computations. If the first succeeds, passes the value to f.
|
|
50
|
+
* If the first fails, propagates the error.
|
|
51
|
+
*/
|
|
52
|
+
const chain: <E, A, B>(f: (a: A) => TaskResult<E, B>) => (data: TaskResult<E, A>) => TaskResult<E, B>;
|
|
53
|
+
/**
|
|
54
|
+
* Extracts the value from a TaskResult by providing handlers for both cases.
|
|
55
|
+
*/
|
|
56
|
+
const fold: <E, A, B>(onErr: (e: E) => B, onOk: (a: A) => B) => (data: TaskResult<E, A>) => Task<B>;
|
|
57
|
+
/**
|
|
58
|
+
* Pattern matches on a TaskResult, returning a Task of the result.
|
|
59
|
+
*/
|
|
60
|
+
const match: <E, A, B>(cases: {
|
|
61
|
+
err: (e: E) => B;
|
|
62
|
+
ok: (a: A) => B;
|
|
63
|
+
}) => (data: TaskResult<E, A>) => Task<B>;
|
|
64
|
+
/**
|
|
65
|
+
* Recovers from an error by providing a fallback TaskResult.
|
|
66
|
+
*/
|
|
67
|
+
const recover: <E, A>(fallback: (e: E) => TaskResult<E, A>) => (data: TaskResult<E, A>) => TaskResult<E, A>;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the success value or a default value if the TaskResult is an error.
|
|
70
|
+
*/
|
|
71
|
+
const getOrElse: <E, A>(defaultValue: A) => (data: TaskResult<E, A>) => Task<A>;
|
|
72
|
+
/**
|
|
73
|
+
* Executes a side effect on the success value without changing the TaskResult.
|
|
74
|
+
* Useful for logging or debugging.
|
|
75
|
+
*/
|
|
76
|
+
const tap: <E, A>(f: (a: A) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
|
|
77
|
+
/**
|
|
78
|
+
* Re-runs a TaskResult on `Err` with configurable attempts, backoff, and retry condition.
|
|
79
|
+
*
|
|
80
|
+
* @param options.attempts - Total number of attempts (1 = no retry, 3 = up to 3 tries)
|
|
81
|
+
* @param options.backoff - Fixed delay in ms, or a function `(attempt) => ms` for computed delay
|
|
82
|
+
* @param options.when - Only retry when this returns true; defaults to always retry on Err
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* // Retry up to 3 times with exponential backoff
|
|
87
|
+
* pipe(
|
|
88
|
+
* fetchUser,
|
|
89
|
+
* TaskResult.retry({ attempts: 3, backoff: n => n * 1000 })
|
|
90
|
+
* );
|
|
91
|
+
*
|
|
92
|
+
* // Only retry on network errors, not auth errors
|
|
93
|
+
* pipe(
|
|
94
|
+
* fetchUser,
|
|
95
|
+
* TaskResult.retry({ attempts: 3, when: e => e instanceof NetworkError })
|
|
96
|
+
* );
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
const retry: <E>(options: {
|
|
100
|
+
attempts: number;
|
|
101
|
+
backoff?: number | ((attempt: number) => number);
|
|
102
|
+
when?: (error: E) => boolean;
|
|
103
|
+
}) => <A>(data: TaskResult<E, A>) => TaskResult<E, A>;
|
|
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
|
+
const timeout: <E>(ms: number, onTimeout: () => E) => <A>(data: TaskResult<E, A>) => TaskResult<E, A>;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=TaskResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskResult.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskResult.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { NonEmptyList } from "../Types/NonEmptyList.js";
|
|
2
|
+
import { Task } from "./Task.js";
|
|
3
|
+
import { Validation } from "./Validation.js";
|
|
4
|
+
/**
|
|
5
|
+
* A Task that resolves to a Validation — combining async operations with
|
|
6
|
+
* error accumulation. Unlike TaskResult, multiple failures are collected
|
|
7
|
+
* rather than short-circuiting on the first error.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const validateName = (name: string): TaskValidation<string, string> =>
|
|
12
|
+
* name.length > 0
|
|
13
|
+
* ? TaskValidation.valid(name)
|
|
14
|
+
* : TaskValidation.invalid("Name is required");
|
|
15
|
+
*
|
|
16
|
+
* // Accumulate errors from multiple async validations using ap
|
|
17
|
+
* pipe(
|
|
18
|
+
* TaskValidation.valid((name: string) => (age: number) => ({ name, age })),
|
|
19
|
+
* TaskValidation.ap(validateName("")),
|
|
20
|
+
* TaskValidation.ap(validateAge(-1))
|
|
21
|
+
* )();
|
|
22
|
+
* // Invalid(["Name is required", "Age must be positive"])
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export type TaskValidation<E, A> = Task<Validation<E, A>>;
|
|
26
|
+
export declare namespace TaskValidation {
|
|
27
|
+
/**
|
|
28
|
+
* Wraps a value in a valid TaskValidation.
|
|
29
|
+
*/
|
|
30
|
+
const valid: <E, A>(value: A) => TaskValidation<E, A>;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a failed TaskValidation with a single error.
|
|
33
|
+
*/
|
|
34
|
+
const invalid: <E, A>(error: E) => TaskValidation<E, A>;
|
|
35
|
+
/**
|
|
36
|
+
* Creates an invalid TaskValidation from multiple errors.
|
|
37
|
+
*/
|
|
38
|
+
const invalidAll: <E, A>(errors: NonEmptyList<E>) => TaskValidation<E, A>;
|
|
39
|
+
/**
|
|
40
|
+
* Lifts a Validation into a TaskValidation.
|
|
41
|
+
*/
|
|
42
|
+
const fromValidation: <E, A>(validation: Validation<E, A>) => TaskValidation<E, A>;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a TaskValidation from a Promise-returning function.
|
|
45
|
+
* Catches any errors and transforms them using the onError function.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const fetchUser = (id: string): TaskValidation<string, User> =>
|
|
50
|
+
* TaskValidation.tryCatch(
|
|
51
|
+
* () => fetch(`/users/${id}`).then(r => r.json()),
|
|
52
|
+
* e => `Failed to fetch user: ${e}`
|
|
53
|
+
* );
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
const tryCatch: <E, A>(f: () => Promise<A>, onError: (e: unknown) => E) => TaskValidation<E, A>;
|
|
57
|
+
/**
|
|
58
|
+
* Transforms the success value inside a TaskValidation.
|
|
59
|
+
*/
|
|
60
|
+
const map: <E, A, B>(f: (a: A) => B) => (data: TaskValidation<E, A>) => TaskValidation<E, B>;
|
|
61
|
+
/**
|
|
62
|
+
* Chains TaskValidation computations. If the first is Valid, passes the value
|
|
63
|
+
* to f. If the first is Invalid, propagates the errors.
|
|
64
|
+
*
|
|
65
|
+
* Note: chain short-circuits on first error. Use ap to accumulate errors.
|
|
66
|
+
*/
|
|
67
|
+
const chain: <E, A, B>(f: (a: A) => TaskValidation<E, B>) => (data: TaskValidation<E, A>) => TaskValidation<E, B>;
|
|
68
|
+
/**
|
|
69
|
+
* Applies a function wrapped in a TaskValidation to a value wrapped in a
|
|
70
|
+
* TaskValidation. Both Tasks run in parallel and errors from both sides
|
|
71
|
+
* are accumulated.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* pipe(
|
|
76
|
+
* TaskValidation.valid((name: string) => (age: number) => ({ name, age })),
|
|
77
|
+
* TaskValidation.ap(validateName(name)),
|
|
78
|
+
* TaskValidation.ap(validateAge(age))
|
|
79
|
+
* )();
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
const ap: <E, A>(arg: TaskValidation<E, A>) => <B>(data: TaskValidation<E, (a: A) => B>) => TaskValidation<E, B>;
|
|
83
|
+
/**
|
|
84
|
+
* Extracts a value from a TaskValidation by providing handlers for both cases.
|
|
85
|
+
*/
|
|
86
|
+
const fold: <E, A, B>(onInvalid: (errors: NonEmptyList<E>) => B, onValid: (a: A) => B) => (data: TaskValidation<E, A>) => Task<B>;
|
|
87
|
+
/**
|
|
88
|
+
* Pattern matches on a TaskValidation, returning a Task of the result.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* pipe(
|
|
93
|
+
* validateForm(input),
|
|
94
|
+
* TaskValidation.match({
|
|
95
|
+
* valid: data => save(data),
|
|
96
|
+
* invalid: errors => showErrors(errors)
|
|
97
|
+
* })
|
|
98
|
+
* )();
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
const match: <E, A, B>(cases: {
|
|
102
|
+
valid: (a: A) => B;
|
|
103
|
+
invalid: (errors: NonEmptyList<E>) => B;
|
|
104
|
+
}) => (data: TaskValidation<E, A>) => Task<B>;
|
|
105
|
+
/**
|
|
106
|
+
* Returns the success value or a default value if the TaskValidation is invalid.
|
|
107
|
+
*/
|
|
108
|
+
const getOrElse: <E, A>(defaultValue: A) => (data: TaskValidation<E, A>) => Task<A>;
|
|
109
|
+
/**
|
|
110
|
+
* Executes a side effect on the success value without changing the TaskValidation.
|
|
111
|
+
* Useful for logging or debugging.
|
|
112
|
+
*/
|
|
113
|
+
const tap: <E, A>(f: (a: A) => void) => (data: TaskValidation<E, A>) => TaskValidation<E, A>;
|
|
114
|
+
/**
|
|
115
|
+
* Recovers from an Invalid state by providing a fallback TaskValidation.
|
|
116
|
+
*/
|
|
117
|
+
const recover: <E, A>(fallback: () => TaskValidation<E, A>) => (data: TaskValidation<E, A>) => TaskValidation<E, A>;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=TaskValidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskValidation.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskValidation.ts"],"names":[],"mappings":"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"}
|