@satoshibits/functional 1.0.2
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 +242 -0
- package/dist/array-utils.d.mts +317 -0
- package/dist/array-utils.d.mts.map +1 -0
- package/dist/array-utils.mjs +370 -0
- package/dist/array-utils.mjs.map +1 -0
- package/dist/composition.d.mts +603 -0
- package/dist/composition.d.mts.map +1 -0
- package/dist/composition.mjs +516 -0
- package/dist/composition.mjs.map +1 -0
- package/dist/object-utils.d.mts +267 -0
- package/dist/object-utils.d.mts.map +1 -0
- package/dist/object-utils.mjs +258 -0
- package/dist/object-utils.mjs.map +1 -0
- package/dist/option.d.mts +622 -0
- package/dist/option.d.mts.map +1 -0
- package/dist/option.mjs +637 -0
- package/dist/option.mjs.map +1 -0
- package/dist/performance.d.mts +265 -0
- package/dist/performance.d.mts.map +1 -0
- package/dist/performance.mjs +453 -0
- package/dist/performance.mjs.map +1 -0
- package/dist/pipeline.d.mts +431 -0
- package/dist/pipeline.d.mts.map +1 -0
- package/dist/pipeline.mjs +460 -0
- package/dist/pipeline.mjs.map +1 -0
- package/dist/predicates.d.mts +722 -0
- package/dist/predicates.d.mts.map +1 -0
- package/dist/predicates.mjs +802 -0
- package/dist/predicates.mjs.map +1 -0
- package/dist/reader-result.d.mts +422 -0
- package/dist/reader-result.d.mts.map +1 -0
- package/dist/reader-result.mjs +758 -0
- package/dist/reader-result.mjs.map +1 -0
- package/dist/result.d.mts +684 -0
- package/dist/result.d.mts.map +1 -0
- package/dist/result.mjs +814 -0
- package/dist/result.mjs.map +1 -0
- package/dist/types.d.mts +439 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +191 -0
- package/dist/types.mjs.map +1 -0
- package/dist/validation.d.mts +622 -0
- package/dist/validation.d.mts.map +1 -0
- package/dist/validation.mjs +852 -0
- package/dist/validation.mjs.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicates.mjs","sourceRoot":"","sources":["../src/predicates.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module reader-result
|
|
3
|
+
* @description Combines Reader (dependency injection) with Result (error handling)
|
|
4
|
+
* for asynchronous computations. This provides a powerful abstraction for
|
|
5
|
+
* building composable, testable applications with explicit error handling
|
|
6
|
+
* and dependency injection. Similar to fp-ts's ReaderTaskEither but tailored
|
|
7
|
+
* for our Result type and async/await patterns.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { ReaderResult, liftAsync } from './reader-result.mts';
|
|
12
|
+
*
|
|
13
|
+
* // define dependencies
|
|
14
|
+
* interface Deps {
|
|
15
|
+
* db: Database;
|
|
16
|
+
* logger: Logger;
|
|
17
|
+
* config: Config;
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* // create reusable operations
|
|
21
|
+
* const getUser = (id: string): ReaderResult<Deps, string, User> =>
|
|
22
|
+
* ReaderResult.tryCatch(
|
|
23
|
+
* async (deps) => deps.db.users.findById(id),
|
|
24
|
+
* (error) => `Failed to fetch user: ${error}`
|
|
25
|
+
* );
|
|
26
|
+
*
|
|
27
|
+
* // compose operations
|
|
28
|
+
* const program = ReaderResult.Do()
|
|
29
|
+
* .pipe(ReaderResult.bind('user', () => getUser('123')))
|
|
30
|
+
* .pipe(ReaderResult.bind('posts', ({ user }) => getUserPosts(user.id)))
|
|
31
|
+
* .pipe(ReaderResult.map(({ user, posts }) => ({ ...user, posts })));
|
|
32
|
+
*
|
|
33
|
+
* // run with dependencies
|
|
34
|
+
* const result = await ReaderResult.run(dependencies)(program);
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @category Core
|
|
38
|
+
* @since 2025-07-03
|
|
39
|
+
*/
|
|
40
|
+
import type { Result } from './result.mjs';
|
|
41
|
+
/**
|
|
42
|
+
* A computation that:
|
|
43
|
+
* - Reads from dependencies (R)
|
|
44
|
+
* - Is asynchronous (Promise)
|
|
45
|
+
* - Can fail with error E or succeed with value A
|
|
46
|
+
*
|
|
47
|
+
* @template R - The type of dependencies required by the computation
|
|
48
|
+
* @template E - The type of error that can occur
|
|
49
|
+
* @template A - The type of the success value
|
|
50
|
+
*
|
|
51
|
+
* @category Core Types
|
|
52
|
+
* @since 2025-07-03
|
|
53
|
+
*/
|
|
54
|
+
export type ReaderResult<R, E, A> = (deps: R) => Promise<Result<A, E>>;
|
|
55
|
+
/**
|
|
56
|
+
* Constructors and combinators for ReaderResult
|
|
57
|
+
*/
|
|
58
|
+
export declare const ReaderResult: {
|
|
59
|
+
/**
|
|
60
|
+
* Lift a pure value into ReaderResult context.
|
|
61
|
+
* @description Creates a ReaderResult that always succeeds with the given value,
|
|
62
|
+
* ignoring the dependencies.
|
|
63
|
+
*
|
|
64
|
+
* @template R - The type of dependencies
|
|
65
|
+
* @template E - The error type
|
|
66
|
+
* @template A - The type of the value
|
|
67
|
+
* @param {A} value - The value to wrap
|
|
68
|
+
* @returns {ReaderResult<R, E, A>} A ReaderResult that always succeeds with the value
|
|
69
|
+
*
|
|
70
|
+
* @category Constructors
|
|
71
|
+
* @example
|
|
72
|
+
* const always42 = ReaderResult.of<Deps, string, number>(42);
|
|
73
|
+
* const result = await ReaderResult.run(deps)(always42);
|
|
74
|
+
* // => { success: true, data: 42 }
|
|
75
|
+
*
|
|
76
|
+
* @since 2025-07-03
|
|
77
|
+
*/
|
|
78
|
+
of: <R, E, A>(value: A) => ReaderResult<R, E, A>;
|
|
79
|
+
/**
|
|
80
|
+
* Lift an error into ReaderResult context.
|
|
81
|
+
* @description Creates a ReaderResult that always fails with the given error,
|
|
82
|
+
* ignoring the dependencies.
|
|
83
|
+
*
|
|
84
|
+
* @template R - The type of dependencies
|
|
85
|
+
* @template E - The error type
|
|
86
|
+
* @template A - The success type
|
|
87
|
+
* @param {E} error - The error to wrap
|
|
88
|
+
* @returns {ReaderResult<R, E, A>} A ReaderResult that always fails with the error
|
|
89
|
+
*
|
|
90
|
+
* @category Constructors
|
|
91
|
+
* @example
|
|
92
|
+
* const alwaysFails = ReaderResult.fail<Deps, string, User>('User not found');
|
|
93
|
+
* const result = await ReaderResult.run(deps)(alwaysFails);
|
|
94
|
+
* // => { success: false, error: 'User not found' }
|
|
95
|
+
*
|
|
96
|
+
* @since 2025-07-03
|
|
97
|
+
*/
|
|
98
|
+
fail: <R, E, A>(error: E) => ReaderResult<R, E, A>;
|
|
99
|
+
/**
|
|
100
|
+
* Sequential composition - the heart of ReaderResult.
|
|
101
|
+
* @description If first computation fails, short-circuit. Otherwise, feed result to next computation.
|
|
102
|
+
* This is the monadic bind operation that enables chaining ReaderResult computations.
|
|
103
|
+
*
|
|
104
|
+
* @template R - The type of dependencies
|
|
105
|
+
* @template E - The error type
|
|
106
|
+
* @template A - The input value type
|
|
107
|
+
* @template B - The output value type
|
|
108
|
+
* @param {(a: A) => ReaderResult<R, E, B>} f - Function that takes the success value and returns a new ReaderResult
|
|
109
|
+
* @returns {(ma: ReaderResult<R, E, A>) => ReaderResult<R, E, B>} A function that chains ReaderResults
|
|
110
|
+
*
|
|
111
|
+
* @category Combinators
|
|
112
|
+
* @example
|
|
113
|
+
* const getUser = (id: string): ReaderResult<Deps, string, User> => ...
|
|
114
|
+
* const getUserPosts = (userId: string): ReaderResult<Deps, string, Post[]> => ...
|
|
115
|
+
*
|
|
116
|
+
* const getUserWithPosts = ReaderResult.chain((user: User) =>
|
|
117
|
+
* ReaderResult.map((posts: Post[]) => ({ ...user, posts }))(getUserPosts(user.id))
|
|
118
|
+
* )(getUser('123'));
|
|
119
|
+
*
|
|
120
|
+
* @since 2025-07-03
|
|
121
|
+
*/
|
|
122
|
+
chain: <R, E, A, B>(f: (a: A) => ReaderResult<R, E, B>) => (ma: ReaderResult<R, E, A>) => ReaderResult<R, E, B>;
|
|
123
|
+
/**
|
|
124
|
+
* Map a pure function over the success value.
|
|
125
|
+
* @description Transforms the success value using a pure function. If the computation
|
|
126
|
+
* fails, the error is propagated unchanged.
|
|
127
|
+
*
|
|
128
|
+
* @template R - The type of dependencies
|
|
129
|
+
* @template E - The error type
|
|
130
|
+
* @template A - The input value type
|
|
131
|
+
* @template B - The output value type
|
|
132
|
+
* @param {(a: A) => B} f - Function to transform the success value
|
|
133
|
+
* @returns {(ma: ReaderResult<R, E, A>) => ReaderResult<R, E, B>} A function that maps over ReaderResult
|
|
134
|
+
*
|
|
135
|
+
* @category Transformations
|
|
136
|
+
* @example
|
|
137
|
+
* const double = ReaderResult.map((n: number) => n * 2);
|
|
138
|
+
* const program = double(ReaderResult.of<Deps, string, number>(21));
|
|
139
|
+
* const result = await ReaderResult.run(deps)(program);
|
|
140
|
+
* // => { success: true, data: 42 }
|
|
141
|
+
*
|
|
142
|
+
* @since 2025-07-03
|
|
143
|
+
*/
|
|
144
|
+
map: <R, E, A, B>(f: (a: A) => B) => (ma: ReaderResult<R, E, A>) => ReaderResult<R, E, B>;
|
|
145
|
+
/**
|
|
146
|
+
* Map a function over the error value.
|
|
147
|
+
* @description Transforms the error value using a pure function. If the computation
|
|
148
|
+
* succeeds, the success value is propagated unchanged.
|
|
149
|
+
*
|
|
150
|
+
* @template R - The type of dependencies
|
|
151
|
+
* @template E - The input error type
|
|
152
|
+
* @template F - The output error type
|
|
153
|
+
* @template A - The value type
|
|
154
|
+
* @param {(e: E) => F} f - Function to transform the error
|
|
155
|
+
* @returns {(ma: ReaderResult<R, E, A>) => ReaderResult<R, F, A>} A function that maps over errors
|
|
156
|
+
*
|
|
157
|
+
* @category Transformations
|
|
158
|
+
* @example
|
|
159
|
+
* const enrichError = ReaderResult.mapError((e: string) => ({
|
|
160
|
+
* message: e,
|
|
161
|
+
* timestamp: new Date()
|
|
162
|
+
* }));
|
|
163
|
+
*
|
|
164
|
+
* @since 2025-07-03
|
|
165
|
+
*/
|
|
166
|
+
mapError: <R, E, F, A>(f: (e: E) => F) => (ma: ReaderResult<R, E, A>) => ReaderResult<R, F, A>;
|
|
167
|
+
/**
|
|
168
|
+
* Access the dependencies.
|
|
169
|
+
* @description Returns a ReaderResult that succeeds with the current dependencies.
|
|
170
|
+
* Useful when you need to access the dependencies within a computation chain.
|
|
171
|
+
*
|
|
172
|
+
* @template R - The type of dependencies
|
|
173
|
+
* @template E - The error type
|
|
174
|
+
* @returns {ReaderResult<R, E, R>} A ReaderResult that returns the dependencies
|
|
175
|
+
*
|
|
176
|
+
* @category Dependencies
|
|
177
|
+
* @example
|
|
178
|
+
* const program = ReaderResult.Do()
|
|
179
|
+
* .pipe(ReaderResult.bind('deps', () => ReaderResult.ask<Deps, string>()))
|
|
180
|
+
* .pipe(ReaderResult.bind('config', ({ deps }) =>
|
|
181
|
+
* ReaderResult.of(deps.config)
|
|
182
|
+
* ));
|
|
183
|
+
*
|
|
184
|
+
* @since 2025-07-03
|
|
185
|
+
*/
|
|
186
|
+
ask: <R, E>() => ReaderResult<R, E, R>;
|
|
187
|
+
/**
|
|
188
|
+
* Access a part of the dependencies.
|
|
189
|
+
* @description Returns a ReaderResult that succeeds with a projection of the dependencies.
|
|
190
|
+
* Useful for extracting specific values from the dependency container.
|
|
191
|
+
*
|
|
192
|
+
* @template R - The type of dependencies
|
|
193
|
+
* @template E - The error type
|
|
194
|
+
* @template A - The type of the extracted value
|
|
195
|
+
* @param {(deps: R) => A} f - Function to extract a value from dependencies
|
|
196
|
+
* @returns {ReaderResult<R, E, A>} A ReaderResult that returns the extracted value
|
|
197
|
+
*
|
|
198
|
+
* @category Dependencies
|
|
199
|
+
* @example
|
|
200
|
+
* const getConfig = ReaderResult.asks<Deps, string, Config>(deps => deps.config);
|
|
201
|
+
* const getLogger = ReaderResult.asks<Deps, string, Logger>(deps => deps.logger);
|
|
202
|
+
*
|
|
203
|
+
* @since 2025-07-03
|
|
204
|
+
*/
|
|
205
|
+
asks: <R, E, A>(f: (deps: R) => A) => ReaderResult<R, E, A>;
|
|
206
|
+
/**
|
|
207
|
+
* Lift a Result into ReaderResult
|
|
208
|
+
*/
|
|
209
|
+
fromResult: <R, E, A>(result: Result<A, E>) => ReaderResult<R, E, A>;
|
|
210
|
+
/**
|
|
211
|
+
* Lift an async operation that might throw into ReaderResult
|
|
212
|
+
*/
|
|
213
|
+
tryCatch: <R, E, A>(f: (deps: R) => Promise<A>, onError: (error: unknown) => E) => ReaderResult<R, E, A>;
|
|
214
|
+
/**
|
|
215
|
+
* Execute ReaderResult with dependencies
|
|
216
|
+
*/
|
|
217
|
+
run: <R, E, A>(deps: R) => (ma: ReaderResult<R, E, A>) => Promise<Result<A, E>>;
|
|
218
|
+
/**
|
|
219
|
+
* Combine two ReaderResults in parallel.
|
|
220
|
+
* @description Runs two ReaderResult computations in parallel and combines their results
|
|
221
|
+
* into a tuple. If either fails, returns the first failure.
|
|
222
|
+
*
|
|
223
|
+
* @template R - The type of dependencies
|
|
224
|
+
* @template E - The error type
|
|
225
|
+
* @template A - The first value type
|
|
226
|
+
* @template B - The second value type
|
|
227
|
+
* @param {ReaderResult<R, E, A>} ma - First computation
|
|
228
|
+
* @param {ReaderResult<R, E, B>} mb - Second computation
|
|
229
|
+
* @returns {ReaderResult<R, E, [A, B]>} A ReaderResult containing a tuple of both results
|
|
230
|
+
*
|
|
231
|
+
* @category Combinations
|
|
232
|
+
* @example
|
|
233
|
+
* const userAndPosts = ReaderResult.zip(
|
|
234
|
+
* getUser('123'),
|
|
235
|
+
* getUserPosts('123')
|
|
236
|
+
* );
|
|
237
|
+
*
|
|
238
|
+
* @since 2025-07-03
|
|
239
|
+
*/
|
|
240
|
+
zip: <R, E, A, B>(ma: ReaderResult<R, E, A>, mb: ReaderResult<R, E, B>) => ReaderResult<R, E, [A, B]>;
|
|
241
|
+
/**
|
|
242
|
+
* Sequence an array of ReaderResults.
|
|
243
|
+
* @description Transforms an array of ReaderResults into a ReaderResult of an array.
|
|
244
|
+
* Executes each computation sequentially. If any fails, returns the first failure.
|
|
245
|
+
*
|
|
246
|
+
* @template R - The type of dependencies
|
|
247
|
+
* @template E - The error type
|
|
248
|
+
* @template A - The value type
|
|
249
|
+
* @param {readonly ReaderResult<R, E, A>[]} rrs - Array of ReaderResult computations
|
|
250
|
+
* @returns {ReaderResult<R, E, readonly A[]>} A ReaderResult containing an array of all results
|
|
251
|
+
*
|
|
252
|
+
* @category Combinations
|
|
253
|
+
* @example
|
|
254
|
+
* const userIds = ['123', '456', '789'];
|
|
255
|
+
* const getUsers = ReaderResult.sequence(
|
|
256
|
+
* userIds.map(id => getUser(id))
|
|
257
|
+
* );
|
|
258
|
+
*
|
|
259
|
+
* @since 2025-07-03
|
|
260
|
+
*/
|
|
261
|
+
sequence: <R, E, A>(rrs: readonly ReaderResult<R, E, A>[]) => ReaderResult<R, E, readonly A[]>;
|
|
262
|
+
/**
|
|
263
|
+
* Do notation for building up computations.
|
|
264
|
+
* @description Starts a Do notation chain for building complex computations
|
|
265
|
+
* in a more imperative style. Use with bind and let methods.
|
|
266
|
+
*
|
|
267
|
+
* @template R - The type of dependencies
|
|
268
|
+
* @template E - The error type
|
|
269
|
+
* @returns {ReaderResult<R, E, Record<string, never>>} An empty ReaderResult to start the chain
|
|
270
|
+
*
|
|
271
|
+
* @category Do Notation
|
|
272
|
+
* @example
|
|
273
|
+
* const program = ReaderResult.Do<Deps, string>()
|
|
274
|
+
* .pipe(ReaderResult.bind('user', () => getUser('123')))
|
|
275
|
+
* .pipe(ReaderResult.bind('posts', ({ user }) => getUserPosts(user.id)))
|
|
276
|
+
* .pipe(ReaderResult.let('postCount', ({ posts }) => posts.length))
|
|
277
|
+
* .pipe(ReaderResult.map(({ user, posts, postCount }) => ({
|
|
278
|
+
* ...user,
|
|
279
|
+
* posts,
|
|
280
|
+
* stats: { postCount }
|
|
281
|
+
* })));
|
|
282
|
+
*
|
|
283
|
+
* @since 2025-07-03
|
|
284
|
+
*/
|
|
285
|
+
Do: <R, E>() => ReaderResult<R, E, Record<string, never>>;
|
|
286
|
+
/**
|
|
287
|
+
* Bind a computation result to a name (for Do notation)
|
|
288
|
+
*/
|
|
289
|
+
bind: <R, E, A extends object, K extends string, B>(name: K, f: (a: A) => ReaderResult<R, E, B>) => (fa: ReaderResult<R, E, A>) => ReaderResult<R, E, A & Record<K, B>>;
|
|
290
|
+
/**
|
|
291
|
+
* Bind a value to a name (for Do notation)
|
|
292
|
+
*/
|
|
293
|
+
let: <R, E, A extends object, K extends string, B>(name: K, f: (a: A) => B) => (fa: ReaderResult<R, E, A>) => ReaderResult<R, E, A & Record<K, B>>;
|
|
294
|
+
/**
|
|
295
|
+
* Provides a fallback ReaderResult if the original fails.
|
|
296
|
+
* @description The fallback function receives the error and returns a new ReaderResult.
|
|
297
|
+
* Useful for error recovery or providing default values.
|
|
298
|
+
*
|
|
299
|
+
* @template R - The type of dependencies
|
|
300
|
+
* @template E - The input error type
|
|
301
|
+
* @template F - The output error type
|
|
302
|
+
* @template A - The value type
|
|
303
|
+
* @param {(error: E) => ReaderResult<R, F, A>} onError - Function to handle the error
|
|
304
|
+
* @returns {(ma: ReaderResult<R, E, A>) => ReaderResult<R, F, A>} A function that adds fallback behavior
|
|
305
|
+
*
|
|
306
|
+
* @category Error Handling
|
|
307
|
+
* @example
|
|
308
|
+
* const getUserWithFallback = ReaderResult.orElse(
|
|
309
|
+
* (error: string) => getDefaultUser()
|
|
310
|
+
* )(getUser('123'));
|
|
311
|
+
*
|
|
312
|
+
* @since 2025-07-03
|
|
313
|
+
*/
|
|
314
|
+
orElse: <R, E, F, A>(onError: (error: E) => ReaderResult<R, F, A>) => (ma: ReaderResult<R, E, A>) => ReaderResult<R, F, A>;
|
|
315
|
+
/**
|
|
316
|
+
* Timeout for ReaderResult computations.
|
|
317
|
+
* If the computation doesn't complete within the specified time, it fails with the timeout error.
|
|
318
|
+
*/
|
|
319
|
+
timeout: <R, E, A>(ms: number, timeoutError: E) => (ma: ReaderResult<R, E, A>) => ReaderResult<R, E, A>;
|
|
320
|
+
/**
|
|
321
|
+
* Retry a ReaderResult computation with exponential backoff.
|
|
322
|
+
* Only retries on failures, not on successful results.
|
|
323
|
+
*/
|
|
324
|
+
retry: <R, E, A>(maxAttempts: number, baseDelay?: number, shouldRetry?: (error: E, attempt: number) => boolean) => (ma: ReaderResult<R, E, A>) => ReaderResult<R, E, A>;
|
|
325
|
+
/**
|
|
326
|
+
* Execute multiple ReaderResults in parallel and collect all results.
|
|
327
|
+
* @description Similar to sequence but runs in parallel rather than sequentially.
|
|
328
|
+
* More efficient for independent computations but still fails fast on first error.
|
|
329
|
+
*
|
|
330
|
+
* @template R - The type of dependencies
|
|
331
|
+
* @template E - The error type
|
|
332
|
+
* @template A - The value type
|
|
333
|
+
* @param {readonly ReaderResult<R, E, A>[]} rrs - Array of ReaderResult computations
|
|
334
|
+
* @returns {ReaderResult<R, E, readonly A[]>} A ReaderResult containing an array of all results
|
|
335
|
+
*
|
|
336
|
+
* @category Combinations
|
|
337
|
+
* @example
|
|
338
|
+
* // Fetch multiple users in parallel
|
|
339
|
+
* const userIds = ['123', '456', '789'];
|
|
340
|
+
* const getUsers = ReaderResult.sequencePar(
|
|
341
|
+
* userIds.map(id => getUser(id))
|
|
342
|
+
* );
|
|
343
|
+
*
|
|
344
|
+
* @since 2025-07-03
|
|
345
|
+
*/
|
|
346
|
+
sequencePar: <R, E, A>(rrs: readonly ReaderResult<R, E, A>[]) => ReaderResult<R, E, readonly A[]>;
|
|
347
|
+
/**
|
|
348
|
+
* Combine multiple ReaderResults in parallel into a tuple.
|
|
349
|
+
* Extends zip to work with any number of ReaderResults.
|
|
350
|
+
*/
|
|
351
|
+
zipAll: <R, E, T extends readonly ReaderResult<R, E, unknown>[]>(...rrs: T) => ReaderResult<R, E, { [K in keyof T]: T[K] extends ReaderResult<R, E, infer A> ? A : never; }>;
|
|
352
|
+
/**
|
|
353
|
+
* Run multiple ReaderResults in parallel and collect all results or all errors.
|
|
354
|
+
* @description Unlike sequencePar, this doesn't short-circuit on the first error.
|
|
355
|
+
* Collects all errors if any computations fail, making it useful for validation scenarios.
|
|
356
|
+
*
|
|
357
|
+
* @template R - The type of dependencies
|
|
358
|
+
* @template E - The error type
|
|
359
|
+
* @template T - The record type mapping keys to ReaderResults
|
|
360
|
+
*
|
|
361
|
+
* @category Combinations
|
|
362
|
+
* @example
|
|
363
|
+
* const validation = ReaderResult.parallel({
|
|
364
|
+
* name: validateName(input.name),
|
|
365
|
+
* email: validateEmail(input.email),
|
|
366
|
+
* age: validateAge(input.age)
|
|
367
|
+
* });
|
|
368
|
+
* // If any fail, returns all failures
|
|
369
|
+
*
|
|
370
|
+
* @since 2025-07-03
|
|
371
|
+
*/
|
|
372
|
+
parallel: <R, E, T extends Record<string, ReaderResult<R, E, unknown>>>(rrs: T) => ReaderResult<R, {
|
|
373
|
+
key: keyof T;
|
|
374
|
+
error: E;
|
|
375
|
+
}[], { [K in keyof T]: T[K] extends ReaderResult<R, E, infer A> ? A : never; }>;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Helper to create ReaderResult from a domain function that returns Result.
|
|
379
|
+
* @description Lifts a pure function that returns a Result into the ReaderResult context.
|
|
380
|
+
* Useful for integrating existing Result-based functions.
|
|
381
|
+
*
|
|
382
|
+
* @template R - The type of dependencies
|
|
383
|
+
* @template E - The error type
|
|
384
|
+
* @template A - The value type
|
|
385
|
+
* @template Args - The argument types
|
|
386
|
+
* @param {(...args: Args) => Result<A, E>} f - Function that returns a Result
|
|
387
|
+
* @returns {(...args: Args) => ReaderResult<R, E, A>} A function that returns a ReaderResult
|
|
388
|
+
*
|
|
389
|
+
* @category Helpers
|
|
390
|
+
* @example
|
|
391
|
+
* const validateAge = (age: number): Result<number, string> =>
|
|
392
|
+
* age >= 18 ? Result.ok(age) : Result.err('Must be 18 or older');
|
|
393
|
+
*
|
|
394
|
+
* const validateAgeRR = liftDomain<Deps, string, number, [number]>(validateAge);
|
|
395
|
+
*
|
|
396
|
+
* @since 2025-07-03
|
|
397
|
+
*/
|
|
398
|
+
export declare const liftDomain: <R, E, A, Args extends unknown[]>(f: (...args: Args) => Result<A, E>) => (...args: Args) => ReaderResult<R, E, A>;
|
|
399
|
+
/**
|
|
400
|
+
* Helper to create ReaderResult from an async function that might throw.
|
|
401
|
+
* @description Lifts an async function that might throw into the ReaderResult context,
|
|
402
|
+
* converting exceptions to typed errors.
|
|
403
|
+
*
|
|
404
|
+
* @template R - The type of dependencies
|
|
405
|
+
* @template E - The error type
|
|
406
|
+
* @template A - The value type
|
|
407
|
+
* @template Args - The argument types
|
|
408
|
+
* @param {(deps: R, ...args: Args) => Promise<A>} f - Async function that might throw
|
|
409
|
+
* @param {(error: unknown) => E} onError - Function to convert exceptions to errors
|
|
410
|
+
* @returns {(...args: Args) => ReaderResult<R, E, A>} A function that returns a ReaderResult
|
|
411
|
+
*
|
|
412
|
+
* @category Helpers
|
|
413
|
+
* @example
|
|
414
|
+
* const fetchUser = liftAsync<Deps, string, User, [string]>(
|
|
415
|
+
* async (deps, id) => deps.api.getUser(id),
|
|
416
|
+
* (error) => `Failed to fetch user: ${error}`
|
|
417
|
+
* );
|
|
418
|
+
*
|
|
419
|
+
* @since 2025-07-03
|
|
420
|
+
*/
|
|
421
|
+
export declare const liftAsync: <R, E, A, Args extends unknown[]>(f: (deps: R, ...args: Args) => Promise<A>, onError: (error: unknown) => E) => (...args: Args) => ReaderResult<R, E, A>;
|
|
422
|
+
//# sourceMappingURL=reader-result.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader-result.d.mts","sourceRoot":"","sources":["../src/reader-result.mts"],"names":[],"mappings":"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"}
|