@praha/byethrow 0.0.1
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/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/cjs/exports.cjs +186 -0
- package/dist/cjs/exports.d.ts +15 -0
- package/dist/cjs/functions/and-then.cjs +44 -0
- package/dist/cjs/functions/and-then.d.ts +45 -0
- package/dist/cjs/functions/and-through.cjs +50 -0
- package/dist/cjs/functions/and-through.d.ts +57 -0
- package/dist/cjs/functions/bind.cjs +50 -0
- package/dist/cjs/functions/bind.d.ts +61 -0
- package/dist/cjs/functions/do.cjs +37 -0
- package/dist/cjs/functions/do.d.ts +17 -0
- package/dist/cjs/functions/fail.cjs +50 -0
- package/dist/cjs/functions/fail.d.ts +38 -0
- package/dist/cjs/functions/is-failure.cjs +36 -0
- package/dist/cjs/functions/is-failure.d.ts +22 -0
- package/dist/cjs/functions/is-success.cjs +36 -0
- package/dist/cjs/functions/is-success.d.ts +22 -0
- package/dist/cjs/functions/map-error.cjs +46 -0
- package/dist/cjs/functions/map-error.d.ts +37 -0
- package/dist/cjs/functions/map.cjs +46 -0
- package/dist/cjs/functions/map.d.ts +37 -0
- package/dist/cjs/functions/pipe.cjs +40 -0
- package/dist/cjs/functions/pipe.d.ts +58 -0
- package/dist/cjs/functions/succeed.cjs +50 -0
- package/dist/cjs/functions/succeed.d.ts +39 -0
- package/dist/cjs/functions/try.cjs +52 -0
- package/dist/cjs/functions/try.d.ts +84 -0
- package/dist/cjs/functions/unwrap-error.cjs +40 -0
- package/dist/cjs/functions/unwrap-error.d.ts +31 -0
- package/dist/cjs/functions/unwrap.cjs +40 -0
- package/dist/cjs/functions/unwrap.d.ts +31 -0
- package/dist/cjs/index.cjs +39 -0
- package/dist/cjs/index.d.ts +69 -0
- package/dist/cjs/internals/helpers/is-promise.cjs +36 -0
- package/dist/cjs/internals/helpers/is-promise.d.ts +9 -0
- package/dist/cjs/internals/types/has-promise.cjs +18 -0
- package/dist/cjs/internals/types/has-promise.d.ts +17 -0
- package/dist/cjs/result.cjs +18 -0
- package/dist/cjs/result.d.ts +193 -0
- package/dist/esm/exports.d.ts +15 -0
- package/dist/esm/exports.js +15 -0
- package/dist/esm/functions/and-then.d.ts +45 -0
- package/dist/esm/functions/and-then.js +10 -0
- package/dist/esm/functions/and-through.d.ts +57 -0
- package/dist/esm/functions/and-through.js +16 -0
- package/dist/esm/functions/bind.d.ts +61 -0
- package/dist/esm/functions/bind.js +16 -0
- package/dist/esm/functions/do.d.ts +17 -0
- package/dist/esm/functions/do.js +3 -0
- package/dist/esm/functions/fail.d.ts +38 -0
- package/dist/esm/functions/fail.js +16 -0
- package/dist/esm/functions/is-failure.d.ts +22 -0
- package/dist/esm/functions/is-failure.js +2 -0
- package/dist/esm/functions/is-success.d.ts +22 -0
- package/dist/esm/functions/is-success.js +2 -0
- package/dist/esm/functions/map-error.d.ts +37 -0
- package/dist/esm/functions/map-error.js +12 -0
- package/dist/esm/functions/map.d.ts +37 -0
- package/dist/esm/functions/map.js +12 -0
- package/dist/esm/functions/pipe.d.ts +58 -0
- package/dist/esm/functions/pipe.js +6 -0
- package/dist/esm/functions/succeed.d.ts +39 -0
- package/dist/esm/functions/succeed.js +16 -0
- package/dist/esm/functions/try.d.ts +84 -0
- package/dist/esm/functions/try.js +18 -0
- package/dist/esm/functions/unwrap-error.d.ts +31 -0
- package/dist/esm/functions/unwrap-error.js +6 -0
- package/dist/esm/functions/unwrap.d.ts +31 -0
- package/dist/esm/functions/unwrap.js +6 -0
- package/dist/esm/index.d.ts +69 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/internals/helpers/is-promise.d.ts +9 -0
- package/dist/esm/internals/helpers/is-promise.js +2 -0
- package/dist/esm/internals/types/has-promise.d.ts +17 -0
- package/dist/esm/internals/types/has-promise.js +0 -0
- package/dist/esm/result.d.ts +193 -0
- package/dist/esm/result.js +0 -0
- package/package.json +61 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
import type { InferFailure, InferSuccess, ResultFor, ResultMaybeAsync } from '../result';
|
2
|
+
/**
|
3
|
+
* Chains the next computation using the success value of a {@link Result} or {@link ResultAsync}.
|
4
|
+
* If the original result is a {@link Failure}, it is returned unchanged.
|
5
|
+
* Otherwise, the provided function is called, and its result is returned as-is.
|
6
|
+
*
|
7
|
+
* @function
|
8
|
+
* @typeParam R1 - The input {@link Result} or {@link ResultAsync}.
|
9
|
+
* @typeParam R2 - The result type returned by `fn`.
|
10
|
+
*
|
11
|
+
* @example Success Case
|
12
|
+
* ```ts
|
13
|
+
* import { Result } from '@praha/byethrow';
|
14
|
+
*
|
15
|
+
* const result = Result.pipe(
|
16
|
+
* Result.succeed(3),
|
17
|
+
* Result.andThen((x) => Result.succeed(x * 2)),
|
18
|
+
* );
|
19
|
+
* // { type: 'Success', value: 6 }
|
20
|
+
* ```
|
21
|
+
*
|
22
|
+
* @example Failure Case (input is a Failure)
|
23
|
+
* ```ts
|
24
|
+
* const result = Result.pipe(
|
25
|
+
* Result.fail('error'),
|
26
|
+
* Result.andThen((x) => Result.succeed(x * 2)),
|
27
|
+
* );
|
28
|
+
* // result: { type: 'Failure', error: 'error' }
|
29
|
+
* ```
|
30
|
+
*
|
31
|
+
* @example Failure Case (function returns a Failure)
|
32
|
+
* ```ts
|
33
|
+
* const result = Result.pipe(
|
34
|
+
* Result.succeed(3),
|
35
|
+
* Result.andThen((x) => Result.fail('error: ' + x)),
|
36
|
+
* );
|
37
|
+
* // result: { type: 'Failure', error: 'error: 3' }
|
38
|
+
* ```
|
39
|
+
*
|
40
|
+
* @category Combinators
|
41
|
+
*/
|
42
|
+
export declare const andThen: {
|
43
|
+
<R1 extends ResultMaybeAsync<any, any>, R2 extends ResultMaybeAsync<any, any>>(fn: (a: InferSuccess<R1>) => R2): (result: R1) => ResultFor<R1 | R2, InferSuccess<R2>, InferFailure<R1> | InferFailure<R2>>;
|
44
|
+
<F extends (a: any) => ResultMaybeAsync<any, any>>(fn: F): <R1 extends ResultMaybeAsync<Parameters<F>[0], any>>(result: R1) => ResultFor<R1 | ReturnType<F>, InferSuccess<F>, InferFailure<R1> | InferFailure<F>>;
|
45
|
+
};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { isFailure } from "./is-failure.js";
|
2
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
3
|
+
const andThen = (fn)=>(result)=>{
|
4
|
+
const apply = (r)=>{
|
5
|
+
if (isFailure(r)) return r;
|
6
|
+
return fn(r.value);
|
7
|
+
};
|
8
|
+
return isPromise(result) ? result.then(apply) : apply(result);
|
9
|
+
};
|
10
|
+
export { andThen };
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import type { InferFailure, InferSuccess, ResultFor, ResultMaybeAsync } from '../result';
|
2
|
+
/**
|
3
|
+
* Runs an additional computation using the success value of a {@link Result} or {@link ResultAsync},
|
4
|
+
* but **returns the original result** if the additional computation is successful.
|
5
|
+
*
|
6
|
+
* If either the original result or the side effect result is a {@link Failure}, that failure is returned.
|
7
|
+
* Useful for running validations or side effects without altering the main result on success.
|
8
|
+
*
|
9
|
+
* @function
|
10
|
+
* @typeParam R1 - The input {@link Result} or {@link ResultAsync}.
|
11
|
+
* @typeParam R2 - The result type returned by `fn`.
|
12
|
+
*
|
13
|
+
* @example Success Case
|
14
|
+
* ```ts
|
15
|
+
* import { Result } from '@praha/byethrow';
|
16
|
+
*
|
17
|
+
* const result = Result.pipe(
|
18
|
+
* Result.succeed(5),
|
19
|
+
* Result.andThrough((x) => {
|
20
|
+
* return x > 0 ? Result.succeed(null) : Result.fail('Must be > 0');
|
21
|
+
* }),
|
22
|
+
* );
|
23
|
+
* // { type: 'Success', value: 5 }
|
24
|
+
* ```
|
25
|
+
*
|
26
|
+
* @example Failure Case (input is a Failure)
|
27
|
+
* ```ts
|
28
|
+
* import { Result } from '@praha/byethrow';
|
29
|
+
*
|
30
|
+
* const result = Result.pipe(
|
31
|
+
* Result.fail('error),
|
32
|
+
* Result.andThrough((x) => {
|
33
|
+
* return x > 0 ? Result.succeed(null) : Result.fail('Must be > 0');
|
34
|
+
* }),
|
35
|
+
* );
|
36
|
+
* // { type: 'Failure', error: 'error' }
|
37
|
+
* ```
|
38
|
+
*
|
39
|
+
* @example Failure Case (function returns a Failure)
|
40
|
+
* ```ts
|
41
|
+
* import { Result } from '@praha/byethrow';
|
42
|
+
*
|
43
|
+
* const result = Result.pipe(
|
44
|
+
* Result.succeed(-10),
|
45
|
+
* Result.andThrough((x) => {
|
46
|
+
* return x > 0 ? Result.succeed(null) : Result.fail('Must be > 0');
|
47
|
+
* }),
|
48
|
+
* );
|
49
|
+
* // { type: 'Failure', error: 'Must be > 0' }
|
50
|
+
* ```
|
51
|
+
*
|
52
|
+
* @category Combinators
|
53
|
+
*/
|
54
|
+
export declare const andThrough: {
|
55
|
+
<R1 extends ResultMaybeAsync<any, any>, R2 extends ResultMaybeAsync<any, any>>(fn: (a: InferSuccess<R1>) => R2): (result: R1) => ResultFor<R1 | R2, InferSuccess<R1>, InferFailure<R1> | InferFailure<R2>>;
|
56
|
+
<F extends (a: any) => ResultMaybeAsync<any, any>>(fn: F): <R1 extends ResultMaybeAsync<Parameters<F>[0], any>>(result: R1) => ResultFor<R1 | ReturnType<F>, InferSuccess<R1>, InferFailure<R1> | InferFailure<F>>;
|
57
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { isFailure } from "./is-failure.js";
|
2
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
3
|
+
const andThrough = (fn)=>(result)=>{
|
4
|
+
const apply = (r)=>{
|
5
|
+
if (isFailure(r)) return r;
|
6
|
+
const next = fn(r.value);
|
7
|
+
if (next instanceof Promise) return next.then((n)=>{
|
8
|
+
if (isFailure(n)) return n;
|
9
|
+
return r;
|
10
|
+
});
|
11
|
+
if (isFailure(next)) return next;
|
12
|
+
return r;
|
13
|
+
};
|
14
|
+
return isPromise(result) ? result.then(apply) : apply(result);
|
15
|
+
};
|
16
|
+
export { andThrough };
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import type { InferFailure, InferSuccess, ResultFor, ResultMaybeAsync } from '../result';
|
2
|
+
/**
|
3
|
+
* Chains another {@link Result}-producing computation and **merges its success value**
|
4
|
+
* into the existing object under the specified key.
|
5
|
+
*
|
6
|
+
* - If the original result is a {@link Failure}, it is returned as-is.
|
7
|
+
* - If the next result is a {@link Failure}, it is returned as-is.
|
8
|
+
* - If both are {@link Success}, a new object is returned by shallow-merging:
|
9
|
+
* the original success object and `{ [name]: nextSuccess }`.
|
10
|
+
*
|
11
|
+
* This is useful for building up objects in a compositional and type-safe way,
|
12
|
+
* especially in validation or data-fetching pipelines.
|
13
|
+
*
|
14
|
+
* @function
|
15
|
+
* @typeParam N - The key to assign the result of the `fn` computation.
|
16
|
+
* @typeParam R1 - The input {@link Result} or {@link ResultAsync}.
|
17
|
+
* @typeParam R2 - The result type returned by `fn`.
|
18
|
+
*
|
19
|
+
* @example Success Case
|
20
|
+
* ```ts
|
21
|
+
* import { Result } from '@praha/byethrow';
|
22
|
+
*
|
23
|
+
* const result = Result.pipe(
|
24
|
+
* Result.succeed({ name: 'Alice' }),
|
25
|
+
* Result.bind('age', (user) => Result.succeed(20)),
|
26
|
+
* );
|
27
|
+
* // { type: 'Success', value: { name: 1, age: 20 } }
|
28
|
+
* ```
|
29
|
+
*
|
30
|
+
* @example Failure Case (input is a Failure)
|
31
|
+
* ```ts
|
32
|
+
* import { Result } from '@praha/byethrow';
|
33
|
+
*
|
34
|
+
* const result = Result.pipe(
|
35
|
+
* Result.fail('error'),
|
36
|
+
* Result.bind('age', (user) => Result.succeed(20)),
|
37
|
+
* );
|
38
|
+
* // { type: 'Failure', error: 'error' }
|
39
|
+
* ```
|
40
|
+
*
|
41
|
+
* @example Failure Case (function returns a Failure)
|
42
|
+
* ```ts
|
43
|
+
* import { Result } from '@praha/byethrow';
|
44
|
+
*
|
45
|
+
* const result = Result.pipe(
|
46
|
+
* Result.succeed({ name: 'Alice' }),
|
47
|
+
* Result.bind('age', (user) => Result.fail('error')),
|
48
|
+
* );
|
49
|
+
* // { type: 'Failure', error: 'error' }
|
50
|
+
* ```
|
51
|
+
*
|
52
|
+
* @category Combinators
|
53
|
+
*/
|
54
|
+
export declare const bind: {
|
55
|
+
<N extends string, R1 extends ResultMaybeAsync<any, any>, R2 extends ResultMaybeAsync<any, any>>(name: N, fn: (a: InferSuccess<R1>) => R2): (result: R1) => InferSuccess<R1> extends object ? ResultFor<R1 | R2, {
|
56
|
+
[K in N | keyof InferSuccess<R1>]: K extends keyof InferSuccess<R1> ? InferSuccess<R1>[K] : InferSuccess<R2>;
|
57
|
+
}, InferFailure<R1> | InferFailure<R2>> : unknown;
|
58
|
+
<N extends string, F extends (a: any) => ResultMaybeAsync<any, any>>(name: N, fn: F): <R1 extends ResultMaybeAsync<Parameters<F>[0], any>>(result: R1) => Parameters<F>[0] extends object ? ResultFor<R1 | ReturnType<F>, {
|
59
|
+
[K in N | keyof Parameters<F>[0]]: K extends keyof Parameters<F>[0] ? Parameters<F>[0][K] : InferSuccess<F>;
|
60
|
+
}, InferFailure<R1> | InferFailure<F>> : unknown;
|
61
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { isFailure } from "./is-failure.js";
|
2
|
+
import { succeed } from "./succeed.js";
|
3
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
4
|
+
const bind = (name, fn)=>(result)=>{
|
5
|
+
const apply = (r)=>{
|
6
|
+
if (isFailure(r)) return r;
|
7
|
+
const fr = fn(r.value);
|
8
|
+
const attach = (fr)=>isFailure(fr) ? fr : succeed({
|
9
|
+
...r.value,
|
10
|
+
[name]: fr.value
|
11
|
+
});
|
12
|
+
return isPromise(fr) ? fr.then(attach) : attach(fr);
|
13
|
+
};
|
14
|
+
return isPromise(result) ? result.then(apply) : apply(result);
|
15
|
+
};
|
16
|
+
export { bind };
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/**
|
2
|
+
* Alias for `succeed({})`. Commonly used as a neutral base value in functional chains or monadic pipelines.
|
3
|
+
*
|
4
|
+
* @function
|
5
|
+
*
|
6
|
+
* @example
|
7
|
+
* ```ts
|
8
|
+
* import { Result } from '@praha/byethrow';
|
9
|
+
*
|
10
|
+
* const result = Result.do();
|
11
|
+
* // Result.Result<{}, never>
|
12
|
+
* ```
|
13
|
+
*
|
14
|
+
* @category Creators
|
15
|
+
*/
|
16
|
+
declare const do_: () => import("../result").Result<{}, never>;
|
17
|
+
export { do_ as do };
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import type { ResultFor } from '../result';
|
2
|
+
/**
|
3
|
+
* Creates a {@link Failure} result from a given error.
|
4
|
+
* Automatically wraps the error in a `Promise` if it is asynchronous.
|
5
|
+
*
|
6
|
+
* @function
|
7
|
+
* @typeParam E - The type of the error to wrap.
|
8
|
+
* @returns A {@link Result} or {@link ResultAsync} depending on whether the input is a promise.
|
9
|
+
*
|
10
|
+
* @example Synchronous Usage
|
11
|
+
* ```ts
|
12
|
+
* import { Result } from '@praha/byethrow';
|
13
|
+
*
|
14
|
+
* const result = Result.fail('Something went wrong');
|
15
|
+
* // Result.Result<never, string>
|
16
|
+
* ```
|
17
|
+
*
|
18
|
+
* @example Asynchronous Usage
|
19
|
+
* ```ts
|
20
|
+
* import { Result } from '@praha/byethrow';
|
21
|
+
*
|
22
|
+
* const result = Result.fail(Promise.resolve('Async error'));
|
23
|
+
* // Result.ResultAsync<never, string>
|
24
|
+
* ```
|
25
|
+
*
|
26
|
+
* @example With No Value
|
27
|
+
* ```ts
|
28
|
+
* import { Result } from '@praha/byethrow';
|
29
|
+
*
|
30
|
+
* const result = Result.fail();
|
31
|
+
* // Result.Result<never, void>
|
32
|
+
* ```
|
33
|
+
* @category Creators
|
34
|
+
*/
|
35
|
+
export declare const fail: {
|
36
|
+
(): ResultFor<never, never, void>;
|
37
|
+
<E>(error: E): ResultFor<E, never, Awaited<E>>;
|
38
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
2
|
+
const fail = (...args)=>{
|
3
|
+
const error = args[0];
|
4
|
+
if (void 0 === error) return {
|
5
|
+
type: 'Failure'
|
6
|
+
};
|
7
|
+
if (isPromise(error)) return error.then((error)=>({
|
8
|
+
type: 'Failure',
|
9
|
+
error: error
|
10
|
+
}));
|
11
|
+
return {
|
12
|
+
type: 'Failure',
|
13
|
+
error
|
14
|
+
};
|
15
|
+
};
|
16
|
+
export { fail };
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import type { Failure, Result } from '../result';
|
2
|
+
/**
|
3
|
+
* Type guard to check if a {@link Result} is a {@link Failure}.
|
4
|
+
*
|
5
|
+
* @function
|
6
|
+
* @typeParam E - The type of the error value.
|
7
|
+
* @param result - The {@link Result} to check.
|
8
|
+
* @returns `true` if the result is a {@link Failure}, otherwise `false`.
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```ts
|
12
|
+
* import { Result } from '@praha/byethrow';
|
13
|
+
*
|
14
|
+
* const result: Result.Result<number, string> = { type: 'Failure', error: 'Something went wrong' };
|
15
|
+
* if (Result.isFailure(result)) {
|
16
|
+
* console.error(result.error); // Safe access to error
|
17
|
+
* }
|
18
|
+
* ```
|
19
|
+
*
|
20
|
+
* @category Type Guards
|
21
|
+
*/
|
22
|
+
export declare const isFailure: <E>(result: Result<unknown, E>) => result is Failure<E>;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import type { Result, Success } from '../result';
|
2
|
+
/**
|
3
|
+
* Type guard to check if a {@link Result} is a {@link Success}.
|
4
|
+
*
|
5
|
+
* @function
|
6
|
+
* @typeParam T - The type of the success value.
|
7
|
+
* @param result - The {@link Result} to check.
|
8
|
+
* @returns `true` if the result is a {@link Success}, otherwise `false`.
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```ts
|
12
|
+
* import { Result } from '@praha/byethrow';
|
13
|
+
*
|
14
|
+
* const result: Result.Result<number, string> = { type: 'Success', value: 10 };
|
15
|
+
* if (Result.isSuccess(result)) {
|
16
|
+
* console.log(result.value); // Safe access to value
|
17
|
+
* }
|
18
|
+
* ```
|
19
|
+
*
|
20
|
+
* @category Type Guards
|
21
|
+
*/
|
22
|
+
export declare const isSuccess: <T>(result: Result<T, unknown>) => result is Success<T>;
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import type { InferFailure, InferSuccess, ResultFor, ResultMaybeAsync } from '../result';
|
2
|
+
/**
|
3
|
+
* Applies a transformation function to the error value of a {@link Result} or {@link ResultAsync}.
|
4
|
+
* If the input is a {@link Success}, it will be returned unchanged.
|
5
|
+
*
|
6
|
+
* @function
|
7
|
+
* @typeParam R1 - The input {@link Result} or {@link ResultAsync}.
|
8
|
+
* @typeParam E2 - The transformed error value type.
|
9
|
+
*
|
10
|
+
* @example Failure Case (unchanged)
|
11
|
+
* ```ts
|
12
|
+
* import { Result } from '@praha/byethrow';
|
13
|
+
*
|
14
|
+
* const result = Result.pipe(
|
15
|
+
* Result.fail('NotFound'),
|
16
|
+
* Result.mapError((error) => new Error(error)),
|
17
|
+
* );
|
18
|
+
* // { type: 'Failure', error: Error('NotFound') }
|
19
|
+
* ```
|
20
|
+
*
|
21
|
+
* @example Success Case (unchanged)
|
22
|
+
* ```ts
|
23
|
+
* import { Result } from '@praha/byethrow';
|
24
|
+
*
|
25
|
+
* const result = Result.pipe(
|
26
|
+
* Result.succeed(123),
|
27
|
+
* Result.mapError((error) => new Error(error)),
|
28
|
+
* );
|
29
|
+
* // { type: 'Success', value: 123 }
|
30
|
+
* ```
|
31
|
+
*
|
32
|
+
* @category Combinators
|
33
|
+
*/
|
34
|
+
export declare const mapError: {
|
35
|
+
<R1 extends ResultMaybeAsync<any, any>, E2>(fn: (a: InferFailure<R1>) => E2): (result: R1) => ResultFor<R1, InferSuccess<R1>, E2>;
|
36
|
+
<E1, E2>(fn: (a: E1) => E2): <R1 extends ResultMaybeAsync<any, E1>>(result: R1) => ResultFor<R1, InferSuccess<R1>, E2>;
|
37
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { fail } from "./fail.js";
|
2
|
+
import { isSuccess } from "./is-success.js";
|
3
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
4
|
+
const mapError = (fn)=>(result)=>{
|
5
|
+
const apply = (r)=>{
|
6
|
+
if (isSuccess(r)) return r;
|
7
|
+
return fail(fn(r.error));
|
8
|
+
};
|
9
|
+
if (isPromise(result)) return result.then(apply);
|
10
|
+
return apply(result);
|
11
|
+
};
|
12
|
+
export { mapError };
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import type { InferFailure, InferSuccess, ResultFor, ResultMaybeAsync } from '../result';
|
2
|
+
/**
|
3
|
+
* Applies a transformation function to the success value of a {@link Result} or {@link ResultAsync}.
|
4
|
+
* If the input is a {@link Failure}, it will be returned unchanged.
|
5
|
+
*
|
6
|
+
* @function
|
7
|
+
* @typeParam R1 - The input {@link Result} or {@link ResultAsync}.
|
8
|
+
* @typeParam T2 - The transformed success value type.
|
9
|
+
*
|
10
|
+
* @example Success Case
|
11
|
+
* ```ts
|
12
|
+
* import { Result } from '@praha/byethrow';
|
13
|
+
*
|
14
|
+
* const result = Result.pipe(
|
15
|
+
* Result.succeed(2),
|
16
|
+
* Result.map((x) => x * 10),
|
17
|
+
* );
|
18
|
+
* // { type: 'Success', value: 20 }
|
19
|
+
* ```
|
20
|
+
*
|
21
|
+
* @example Failure Case (unchanged)
|
22
|
+
* ```ts
|
23
|
+
* import { Result } from '@praha/byethrow';
|
24
|
+
*
|
25
|
+
* const result = Result.pipe(
|
26
|
+
* Result.fail('error'),
|
27
|
+
* Result.map((x) => x * 10),
|
28
|
+
* );
|
29
|
+
* // { type: 'Failure', error: 'error' }
|
30
|
+
* ```
|
31
|
+
*
|
32
|
+
* @category Combinators
|
33
|
+
*/
|
34
|
+
export declare const map: {
|
35
|
+
<R1 extends ResultMaybeAsync<any, any>, T2>(fn: (a: InferSuccess<R1>) => T2): (result: R1) => ResultFor<R1, T2, InferFailure<R1>>;
|
36
|
+
<T1, T2>(fn: (a: T1) => T2): <R1 extends ResultMaybeAsync<T1, any>>(result: R1) => ResultFor<R1, T2, InferFailure<R1>>;
|
37
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { isFailure } from "./is-failure.js";
|
2
|
+
import { succeed } from "./succeed.js";
|
3
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
4
|
+
const map = (fn)=>(result)=>{
|
5
|
+
const apply = (r)=>{
|
6
|
+
if (isFailure(r)) return r;
|
7
|
+
return succeed(fn(r.value));
|
8
|
+
};
|
9
|
+
if (isPromise(result)) return result.then(apply);
|
10
|
+
return apply(result);
|
11
|
+
};
|
12
|
+
export { map };
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/**
|
2
|
+
* Applies a sequence of functions to a value, from left to right.
|
3
|
+
*
|
4
|
+
* This utility enables function composition in a left-to-right manner.
|
5
|
+
* It supports up to 26 chained functions from `A` through `Z`.
|
6
|
+
*
|
7
|
+
* @function
|
8
|
+
* @typeParam A - The initial input value type.
|
9
|
+
* @typeParam B-Z - Intermediate and final function return types.
|
10
|
+
*
|
11
|
+
* @param value - The initial input value.
|
12
|
+
* @param functions - Additional unary functions composing of the previous result.
|
13
|
+
*
|
14
|
+
* @returns The final result after applying all functions.
|
15
|
+
*
|
16
|
+
* @example
|
17
|
+
* ```ts
|
18
|
+
* import { Result } from '@praha/byethrow';
|
19
|
+
*
|
20
|
+
* const result = Result.pipe(
|
21
|
+
* 2,
|
22
|
+
* x => x + 1,
|
23
|
+
* x => x * 3,
|
24
|
+
* x => `Result: ${x}`
|
25
|
+
* );
|
26
|
+
* // Result: 9
|
27
|
+
* ```
|
28
|
+
*
|
29
|
+
* @category Utilities
|
30
|
+
*/
|
31
|
+
export declare const pipe: {
|
32
|
+
<A>(a: A): A;
|
33
|
+
<A, B = never>(a: A, ab: (a: A) => B): B;
|
34
|
+
<A, B = never, C = never>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
|
35
|
+
<A, B = never, C = never, D = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;
|
36
|
+
<A, B = never, C = never, D = never, E = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E;
|
37
|
+
<A, B = never, C = never, D = never, E = never, F = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F): F;
|
38
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): G;
|
39
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): H;
|
40
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): I;
|
41
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J): J;
|
42
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K): K;
|
43
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L): L;
|
44
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M): M;
|
45
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N): N;
|
46
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O): O;
|
47
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P): P;
|
48
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q): Q;
|
49
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R): R;
|
50
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S): S;
|
51
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T): T;
|
52
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U): U;
|
53
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V): V;
|
54
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W): W;
|
55
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X): X;
|
56
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never, Y = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X, xy: (x: X) => Y): Y;
|
57
|
+
<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never, Y = never, Z = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X, xy: (x: X) => Y, yz: (y: Y) => Z): Z;
|
58
|
+
};
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import type { ResultFor } from '../result';
|
2
|
+
/**
|
3
|
+
* Creates a {@link Success} result from a given value.
|
4
|
+
* Automatically wraps the value in a `Promise` if it is asynchronous.
|
5
|
+
*
|
6
|
+
* @function
|
7
|
+
* @typeParam T - The type of the value to wrap.
|
8
|
+
* @returns A {@link Result} or {@link ResultAsync} depending on whether the input is a promise.
|
9
|
+
*
|
10
|
+
* @example Synchronous Usage
|
11
|
+
* ```ts
|
12
|
+
* import { Result } from '@praha/byethrow';
|
13
|
+
*
|
14
|
+
* const result = Result.succeed(42);
|
15
|
+
* // Result.Result<number, never>
|
16
|
+
* ```
|
17
|
+
*
|
18
|
+
* @example Asynchronous Usage
|
19
|
+
* ```ts
|
20
|
+
* import { Result } from '@praha/byethrow';
|
21
|
+
*
|
22
|
+
* const result = Result.succeed(Promise.resolve(42));
|
23
|
+
* // Result.ResultAsync<number, never>
|
24
|
+
* ```
|
25
|
+
*
|
26
|
+
* @example With No Value
|
27
|
+
* ```ts
|
28
|
+
* import { Result } from '@praha/byethrow';
|
29
|
+
*
|
30
|
+
* const result = Result.succeed();
|
31
|
+
* // Result.Result<void, never>
|
32
|
+
* ```
|
33
|
+
*
|
34
|
+
* @category Creators
|
35
|
+
*/
|
36
|
+
export declare const succeed: {
|
37
|
+
(): ResultFor<never, void, never>;
|
38
|
+
<T>(value: T): ResultFor<T, Awaited<T>, never>;
|
39
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { isPromise } from "../internals/helpers/is-promise.js";
|
2
|
+
const succeed = (...args)=>{
|
3
|
+
const value = args[0];
|
4
|
+
if (void 0 === value) return {
|
5
|
+
type: 'Success'
|
6
|
+
};
|
7
|
+
if (isPromise(value)) return value.then((value)=>({
|
8
|
+
type: 'Success',
|
9
|
+
value: value
|
10
|
+
}));
|
11
|
+
return {
|
12
|
+
type: 'Success',
|
13
|
+
value
|
14
|
+
};
|
15
|
+
};
|
16
|
+
export { succeed };
|