@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/src/index.ts CHANGED
@@ -42,7 +42,7 @@ export * from './promise';
42
42
  export * from './query';
43
43
  export * from './queue';
44
44
  export * from './random';
45
- export * from './result';
45
+ export * from './result/index';
46
46
  export * from './sized/map';
47
47
  export * from './sized/set';
48
48
 
@@ -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 {isPlainObject} from './internal/is';
2
- import {attemptPromise} from './promise';
3
-
4
- // #region Types
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): ExtendedErr<E> | Ok<Value>;
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