@oscarpalmer/atoms 0.147.0 → 0.149.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.
- package/dist/atoms.full.js +114 -32
- package/dist/function/work.js +29 -10
- package/dist/index.js +2 -1
- package/dist/internal/result.js +25 -0
- package/dist/{result.js → result/index.js} +8 -25
- package/dist/result/match.js +25 -0
- package/dist/result/models.js +0 -0
- package/dist/result/work/flow.js +25 -0
- package/dist/result/work/pipe.js +21 -0
- package/package.json +3 -3
- package/src/function/work.ts +316 -254
- package/src/index.ts +1 -1
- package/src/internal/result.ts +80 -0
- package/src/{result.ts → result/index.ts} +17 -114
- package/src/result/match.ts +112 -0
- package/src/result/models.ts +81 -0
- package/src/result/work/flow.ts +433 -0
- package/src/result/work/pipe.ts +791 -0
- package/types/function/work.d.ts +51 -50
- package/types/index.d.ts +1 -1
- package/types/internal/result.d.ts +37 -0
- package/types/{result.d.ts → result/index.d.ts} +11 -67
- package/types/result/match.d.ts +31 -0
- package/types/result/models.d.ts +60 -0
- package/types/result/work/flow.d.ts +134 -0
- package/types/result/work/pipe.d.ts +271 -0
package/src/index.ts
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type {Err, ExtendedErr, Ok, Result} from '../result/models';
|
|
2
|
+
import {isPlainObject} from './is';
|
|
3
|
+
|
|
4
|
+
// #region Functions
|
|
5
|
+
|
|
6
|
+
function _isResult(value: unknown, okValue: boolean): value is Result<unknown, unknown> {
|
|
7
|
+
if (!isPlainObject(value)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return value.ok === okValue && (okValue ? 'value' : 'error') in value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Is the result an extended error?
|
|
16
|
+
* @param result Result to check
|
|
17
|
+
* @returns `true` if the result is an extended error, `false` otherwise
|
|
18
|
+
*/
|
|
19
|
+
export function isError<Value, E = Error>(
|
|
20
|
+
value: ExtendedErr<E> | Result<Value, E>,
|
|
21
|
+
extended: true,
|
|
22
|
+
): value is ExtendedErr<E>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Is the result an error?
|
|
26
|
+
* @param result Result to check
|
|
27
|
+
* @returns `true` if the result is an error, `false` otherwise
|
|
28
|
+
*/
|
|
29
|
+
export function isError<Value, E = Error>(value: Result<Value, E>): value is Err<E>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Is the value an error?
|
|
33
|
+
* @param value Value to check
|
|
34
|
+
* @returns `true` if the value is an error, `false` otherwise
|
|
35
|
+
*/
|
|
36
|
+
export function isError(value: unknown): value is Err<unknown> | ExtendedErr<unknown>;
|
|
37
|
+
|
|
38
|
+
export function isError(
|
|
39
|
+
value: unknown,
|
|
40
|
+
extended?: boolean,
|
|
41
|
+
): value is Err<unknown> | ExtendedErr<unknown> {
|
|
42
|
+
return (
|
|
43
|
+
_isResult(value, false) &&
|
|
44
|
+
(extended === true ? (value as ExtendedErr<unknown>).original instanceof Error : true)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Is the result ok?
|
|
50
|
+
* @param value Result to check
|
|
51
|
+
* @returns `true` if the result is ok, `false` otherwise
|
|
52
|
+
*/
|
|
53
|
+
export function isOk<Value, E = Error>(value: Result<Value, E>): value is Ok<Value>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Is the value ok?
|
|
57
|
+
* @param value Value to check
|
|
58
|
+
* @returns `true` if the value is ok, `false` otherwise
|
|
59
|
+
*/
|
|
60
|
+
export function isOk(value: unknown): value is Ok<unknown>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Is the result ok?
|
|
64
|
+
* @param result Result to check
|
|
65
|
+
* @returns `true` if the result is ok, `false` otherwise
|
|
66
|
+
*/
|
|
67
|
+
export function isOk(value: unknown): value is Ok<unknown> {
|
|
68
|
+
return _isResult(value, true);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Is the value a result?
|
|
73
|
+
* @param value Value to check
|
|
74
|
+
* @returns `true` if the value is a result, `false` otherwise
|
|
75
|
+
*/
|
|
76
|
+
export function isResult(value: unknown): value is ExtendedErr<unknown> | Result<unknown, unknown> {
|
|
77
|
+
return _isResult(value, true) || _isResult(value, false);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// #endregion
|
|
@@ -1,53 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {attemptPromise} from '
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* An error result
|
|
8
|
-
*/
|
|
9
|
-
export type Err<Error> = {
|
|
10
|
-
ok: false;
|
|
11
|
-
error: Error;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* An extended error result
|
|
16
|
-
*/
|
|
17
|
-
export type ExtendedErr<E> = Err<E> & {
|
|
18
|
-
original: Error;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* An extended, unknown result
|
|
23
|
-
*/
|
|
24
|
-
export type ExtendedResult<Value, E> = ExtendedErr<E> | Ok<Value>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* A successful result
|
|
28
|
-
*/
|
|
29
|
-
export type Ok<Value> = {
|
|
30
|
-
ok: true;
|
|
31
|
-
value: Value;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* An unknown result
|
|
36
|
-
*/
|
|
37
|
-
export type Result<Value, E = Error> = Err<E> | Ok<Value>;
|
|
38
|
-
|
|
39
|
-
// #endregion
|
|
1
|
+
import {isOk} from '../internal/result';
|
|
2
|
+
import {attemptPromise} from '../promise';
|
|
3
|
+
import {matchResult} from './match';
|
|
4
|
+
import type {Err, ExtendedErr, ExtendedResult, Ok, Result} from './models';
|
|
5
|
+
import {attemptFlow} from './work/flow';
|
|
6
|
+
import {attemptPipe} from './work/pipe';
|
|
40
7
|
|
|
41
8
|
// #region Functions
|
|
42
9
|
|
|
43
|
-
function _isResult(value: unknown, okValue: boolean): value is Result<unknown, unknown> {
|
|
44
|
-
if (!isPlainObject(value)) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return value.ok === okValue && (okValue ? 'value' : 'error') in value;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
10
|
/**
|
|
52
11
|
* Executes a promise, catching any errors, and returns a result
|
|
53
12
|
* @param promise Promise to execute
|
|
@@ -107,7 +66,7 @@ async function asyncAttempt<Value, E>(
|
|
|
107
66
|
* @param error Error value
|
|
108
67
|
* @returns Callback result
|
|
109
68
|
*/
|
|
110
|
-
export function attempt<Value, E>(callback: () => Value, error: E):
|
|
69
|
+
export function attempt<Value, E>(callback: () => Value, error: E): ExtendedResult<Value, E>;
|
|
111
70
|
|
|
112
71
|
/**
|
|
113
72
|
* Executes a callback, catching any errors, and returns a result
|
|
@@ -130,6 +89,9 @@ export function attempt<Value, E>(
|
|
|
130
89
|
}
|
|
131
90
|
|
|
132
91
|
attempt.async = asyncAttempt;
|
|
92
|
+
attempt.flow = attemptFlow;
|
|
93
|
+
attempt.match = matchResult;
|
|
94
|
+
attempt.pipe = attemptPipe;
|
|
133
95
|
attempt.promise = attemptPromise;
|
|
134
96
|
|
|
135
97
|
/**
|
|
@@ -164,72 +126,6 @@ function getError<E>(value: E, original?: Error): Err<E> | ExtendedErr<E> {
|
|
|
164
126
|
return errorResult;
|
|
165
127
|
}
|
|
166
128
|
|
|
167
|
-
/**
|
|
168
|
-
* Is the result an extended error?
|
|
169
|
-
* @param result Result to check
|
|
170
|
-
* @returns `true` if the result is an extended error, `false` otherwise
|
|
171
|
-
*/
|
|
172
|
-
export function isError<Value, E = Error>(
|
|
173
|
-
value: ExtendedErr<E> | Result<Value, E>,
|
|
174
|
-
extended: true,
|
|
175
|
-
): value is ExtendedErr<E>;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Is the result an error?
|
|
179
|
-
* @param result Result to check
|
|
180
|
-
* @returns `true` if the result is an error, `false` otherwise
|
|
181
|
-
*/
|
|
182
|
-
export function isError<Value, E = Error>(value: Result<Value, E>): value is Err<E>;
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Is the value an error?
|
|
186
|
-
* @param value Value to check
|
|
187
|
-
* @returns `true` if the value is an error, `false` otherwise
|
|
188
|
-
*/
|
|
189
|
-
export function isError(value: unknown): value is Err<unknown> | ExtendedErr<unknown>;
|
|
190
|
-
|
|
191
|
-
export function isError(
|
|
192
|
-
value: unknown,
|
|
193
|
-
extended?: boolean,
|
|
194
|
-
): value is Err<unknown> | ExtendedErr<unknown> {
|
|
195
|
-
return (
|
|
196
|
-
_isResult(value, false) &&
|
|
197
|
-
(extended === true ? (value as ExtendedErr<unknown>).original instanceof Error : true)
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Is the result ok?
|
|
203
|
-
* @param value Result to check
|
|
204
|
-
* @returns `true` if the result is ok, `false` otherwise
|
|
205
|
-
*/
|
|
206
|
-
export function isOk<Value, E = Error>(value: Result<Value, E>): value is Ok<Value>;
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Is the value ok?
|
|
210
|
-
* @param value Value to check
|
|
211
|
-
* @returns `true` if the value is ok, `false` otherwise
|
|
212
|
-
*/
|
|
213
|
-
export function isOk(value: unknown): value is Ok<unknown>;
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Is the result ok?
|
|
217
|
-
* @param result Result to check
|
|
218
|
-
* @returns `true` if the result is ok, `false` otherwise
|
|
219
|
-
*/
|
|
220
|
-
export function isOk(value: unknown): value is Ok<unknown> {
|
|
221
|
-
return _isResult(value, true);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Is the value a result?
|
|
226
|
-
* @param value Value to check
|
|
227
|
-
* @returns `true` if the value is a result, `false` otherwise
|
|
228
|
-
*/
|
|
229
|
-
export function isResult(value: unknown): value is ExtendedErr<unknown> | Result<unknown, unknown> {
|
|
230
|
-
return _isResult(value, true) || _isResult(value, false);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
129
|
/**
|
|
234
130
|
* Creates an ok result
|
|
235
131
|
* @param value Value
|
|
@@ -263,3 +159,10 @@ export function unwrap(value: unknown, defaultValue: unknown): unknown {
|
|
|
263
159
|
}
|
|
264
160
|
|
|
265
161
|
// #endregion
|
|
162
|
+
|
|
163
|
+
// #region Exports
|
|
164
|
+
|
|
165
|
+
export {isError, isOk, isResult} from '../internal/result';
|
|
166
|
+
export type {Err, ExtendedErr, ExtendedResult, Ok, Result} from './models';
|
|
167
|
+
|
|
168
|
+
// #endregion
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {isOk, isResult} from '../internal/result';
|
|
2
|
+
import type {AnyResult, ExtendedErr, ResultMatch} from './models';
|
|
3
|
+
|
|
4
|
+
// #region Functions
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Handles a result with match callbacks
|
|
8
|
+
* @param result Result to handle
|
|
9
|
+
* @param handler Match callbacks
|
|
10
|
+
*/
|
|
11
|
+
async function asyncMatchResult<Value, Returned, E = Error>(
|
|
12
|
+
result: AnyResult<Value, E> | Promise<AnyResult<Value, E>> | (() => Promise<AnyResult<Value, E>>),
|
|
13
|
+
handler: ResultMatch<Value, Returned, E>,
|
|
14
|
+
): Promise<Returned>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Handles a result with match callbacks
|
|
18
|
+
* @param result Result to handle
|
|
19
|
+
* @param ok Ok callback
|
|
20
|
+
* @param error Error callback
|
|
21
|
+
*/
|
|
22
|
+
async function asyncMatchResult<Value, Returned, E = Error>(
|
|
23
|
+
result: AnyResult<Value, E> | Promise<AnyResult<Value, E>> | (() => Promise<AnyResult<Value, E>>),
|
|
24
|
+
ok: ResultMatch<Value, Returned, E>['ok'],
|
|
25
|
+
error: ResultMatch<Value, Returned, E>['error'],
|
|
26
|
+
): Promise<Returned>;
|
|
27
|
+
|
|
28
|
+
async function asyncMatchResult<Value, Returned, E = Error>(
|
|
29
|
+
result: AnyResult<Value, E> | Promise<AnyResult<Value, E>> | (() => Promise<AnyResult<Value, E>>),
|
|
30
|
+
first: ResultMatch<Value, Returned, E> | ResultMatch<Value, Returned, E>['ok'],
|
|
31
|
+
error?: ResultMatch<Value, Returned, E>['error'],
|
|
32
|
+
): Promise<Returned> {
|
|
33
|
+
let value: AnyResult<Value, E>;
|
|
34
|
+
|
|
35
|
+
if (typeof result === 'function') {
|
|
36
|
+
value = await result();
|
|
37
|
+
} else if (result instanceof Promise) {
|
|
38
|
+
value = await result;
|
|
39
|
+
} else {
|
|
40
|
+
value = result;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!isResult(value)) {
|
|
44
|
+
throw new Error(MESSAGE_RESULT);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const hasObj = typeof first === 'object' && first !== null;
|
|
48
|
+
|
|
49
|
+
const okHandler = hasObj ? first.ok : first;
|
|
50
|
+
const errorHandler = hasObj ? first.error : error;
|
|
51
|
+
|
|
52
|
+
if (isOk(value)) {
|
|
53
|
+
return okHandler(value.value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return errorHandler!(value.error, (value as ExtendedErr<E>).original);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Handles a result with match callbacks
|
|
61
|
+
* @param result Result to handle
|
|
62
|
+
* @param handler Match callbacks
|
|
63
|
+
*/
|
|
64
|
+
export function matchResult<Value, Returned, E = Error>(
|
|
65
|
+
result: AnyResult<Value, E> | (() => AnyResult<Value, E>),
|
|
66
|
+
handler: ResultMatch<Value, Returned, E>,
|
|
67
|
+
): Returned;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Handles a result with match callbacks
|
|
71
|
+
* @param result Result to handle
|
|
72
|
+
* @param ok Ok callback
|
|
73
|
+
* @param error Error callback
|
|
74
|
+
*/
|
|
75
|
+
export function matchResult<Value, Returned, E = Error>(
|
|
76
|
+
result: AnyResult<Value, E> | (() => AnyResult<Value, E>),
|
|
77
|
+
ok: ResultMatch<Value, Returned, E>['ok'],
|
|
78
|
+
error: ResultMatch<Value, Returned, E>['error'],
|
|
79
|
+
): Returned;
|
|
80
|
+
|
|
81
|
+
export function matchResult<Value, Returned, E = Error>(
|
|
82
|
+
result: AnyResult<Value, E> | (() => AnyResult<Value, E>),
|
|
83
|
+
first: ResultMatch<Value, Returned, E> | ResultMatch<Value, Returned, E>['ok'],
|
|
84
|
+
error?: ResultMatch<Value, Returned, E>['error'],
|
|
85
|
+
): Returned {
|
|
86
|
+
const value = typeof result === 'function' ? result() : result;
|
|
87
|
+
|
|
88
|
+
if (!isResult(value)) {
|
|
89
|
+
throw new Error(MESSAGE_RESULT);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const hasObj = typeof first === 'object' && first !== null;
|
|
93
|
+
|
|
94
|
+
const okHandler = hasObj ? first.ok : first;
|
|
95
|
+
const errorHandler = hasObj ? first.error : error;
|
|
96
|
+
|
|
97
|
+
if (isOk(value)) {
|
|
98
|
+
return okHandler(value.value);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return errorHandler!(value.error, (value as ExtendedErr<E>).original);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
matchResult.async = asyncMatchResult;
|
|
105
|
+
|
|
106
|
+
// #endregion
|
|
107
|
+
|
|
108
|
+
// #region Variables
|
|
109
|
+
|
|
110
|
+
const MESSAGE_RESULT = '`result.match` expected a Result or a function that returns a Result';
|
|
111
|
+
|
|
112
|
+
// #endregion
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type {GenericCallback} from '../models';
|
|
2
|
+
|
|
3
|
+
// #region Types
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* An unknown result
|
|
7
|
+
*/
|
|
8
|
+
export type AnyResult<Value, E> = Err<E> | ExtendedErr<E> | Ok<Value>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* An error result
|
|
12
|
+
*/
|
|
13
|
+
export type Err<Error> = {
|
|
14
|
+
ok: false;
|
|
15
|
+
error: Error;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* An extended error result
|
|
20
|
+
*/
|
|
21
|
+
export type ExtendedErr<E> = Err<E> & {
|
|
22
|
+
original: Error;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* An extended, unknown result
|
|
27
|
+
*/
|
|
28
|
+
export type ExtendedResult<Value, E> = ExtendedErr<E> | Ok<Value>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A successful result
|
|
32
|
+
*/
|
|
33
|
+
export type Ok<Value> = {
|
|
34
|
+
ok: true;
|
|
35
|
+
value: Value;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* An unknown result
|
|
40
|
+
*/
|
|
41
|
+
export type Result<Value, E = Error> = Err<E> | Ok<Value>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Match callbacks for a result
|
|
45
|
+
*/
|
|
46
|
+
export type ResultMatch<Value, Returned, E = Error> = {
|
|
47
|
+
/**
|
|
48
|
+
* Callback for error result
|
|
49
|
+
* @param error Error value
|
|
50
|
+
* @param original Original error, if available
|
|
51
|
+
* @returns Value to return
|
|
52
|
+
*/
|
|
53
|
+
error: (error: E, original?: Error) => Returned;
|
|
54
|
+
/**
|
|
55
|
+
* Callback for ok result
|
|
56
|
+
* @param value Ok value
|
|
57
|
+
* @returns Value to return
|
|
58
|
+
*/
|
|
59
|
+
ok: (value: Value) => Returned;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Unwrap a result value
|
|
64
|
+
*/
|
|
65
|
+
type UnwrapResult<Original extends Result<unknown, unknown>> =
|
|
66
|
+
Original extends Ok<infer Value> ? Value : never;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Unwrap any value
|
|
70
|
+
*/
|
|
71
|
+
export type UnwrapValue<Original> = Original extends GenericCallback
|
|
72
|
+
? ReturnType<Original> extends Result<unknown, unknown>
|
|
73
|
+
? UnwrapResult<ReturnType<Original>>
|
|
74
|
+
: ReturnType<Original>
|
|
75
|
+
: Original extends Result<unknown, unknown>
|
|
76
|
+
? UnwrapResult<Original>
|
|
77
|
+
: Original extends Promise<infer Value>
|
|
78
|
+
? Awaited<Value>
|
|
79
|
+
: Original;
|
|
80
|
+
|
|
81
|
+
// #endregion
|