@nlozgachev/pipekit 0.1.8 → 0.2.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/README.md +1 -1
- package/esm/src/Core/Arr.js +14 -14
- package/esm/src/Core/Option.js +16 -16
- package/esm/src/Core/Rec.js +1 -1
- package/esm/src/Core/Result.js +14 -14
- package/esm/src/Core/Task.js +73 -5
- package/esm/src/Core/TaskOption.js +3 -3
- package/esm/src/Core/TaskResult.js +62 -5
- package/esm/src/Core/These.js +40 -40
- package/esm/src/Types/Brand.js +3 -3
- package/package.json +1 -1
- package/script/src/Core/Arr.js +14 -14
- package/script/src/Core/Option.js +16 -16
- package/script/src/Core/Rec.js +1 -1
- package/script/src/Core/Result.js +14 -14
- package/script/src/Core/Task.js +73 -5
- package/script/src/Core/TaskOption.js +3 -3
- package/script/src/Core/TaskResult.js +62 -5
- package/script/src/Core/These.js +40 -40
- package/script/src/Types/Brand.js +3 -3
- package/types/src/Core/Arr.d.ts +3 -3
- package/types/src/Core/Arr.d.ts.map +1 -1
- package/types/src/Core/Option.d.ts +9 -9
- package/types/src/Core/Option.d.ts.map +1 -1
- package/types/src/Core/Rec.d.ts.map +1 -1
- package/types/src/Core/Result.d.ts +9 -9
- package/types/src/Core/Result.d.ts.map +1 -1
- package/types/src/Core/Task.d.ts +49 -5
- package/types/src/Core/Task.d.ts.map +1 -1
- package/types/src/Core/TaskOption.d.ts.map +1 -1
- package/types/src/Core/TaskResult.d.ts +40 -1
- package/types/src/Core/TaskResult.d.ts.map +1 -1
- package/types/src/Core/These.d.ts +31 -31
- package/types/src/Core/These.d.ts.map +1 -1
- package/types/src/Types/Brand.d.ts +5 -5
package/types/src/Core/Task.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Result } from "./Result.js";
|
|
1
2
|
/**
|
|
2
3
|
* Task represents a lazy asynchronous computation.
|
|
3
4
|
* Unlike Promise, a Task doesn't execute until you call it.
|
|
@@ -29,10 +30,6 @@ export declare namespace Task {
|
|
|
29
30
|
* ```
|
|
30
31
|
*/
|
|
31
32
|
const of: <A>(value: A) => Task<A>;
|
|
32
|
-
/**
|
|
33
|
-
* Creates a Task that will reject with the given error.
|
|
34
|
-
*/
|
|
35
|
-
const fail: <A>(error: unknown) => Task<A>;
|
|
36
33
|
/**
|
|
37
34
|
* Creates a Task from a function that returns a Promise.
|
|
38
35
|
* Alias for directly creating a Task.
|
|
@@ -56,7 +53,7 @@ export declare namespace Task {
|
|
|
56
53
|
*/
|
|
57
54
|
const map: <A, B>(f: (a: A) => B) => (data: Task<A>) => Task<B>;
|
|
58
55
|
/**
|
|
59
|
-
* Chains Task computations.
|
|
56
|
+
* Chains Task computations. Passes the resolved value of the first Task to f.
|
|
60
57
|
*
|
|
61
58
|
* @example
|
|
62
59
|
* ```ts
|
|
@@ -111,6 +108,7 @@ export declare namespace Task {
|
|
|
111
108
|
const all: <T extends readonly Task<unknown>[]>(tasks: T) => Task<{ [K in keyof T]: T[K] extends Task<infer A> ? A : never; }>;
|
|
112
109
|
/**
|
|
113
110
|
* Delays the execution of a Task by the specified milliseconds.
|
|
111
|
+
* Useful for debouncing or rate limiting.
|
|
114
112
|
*
|
|
115
113
|
* @example
|
|
116
114
|
* ```ts
|
|
@@ -121,5 +119,51 @@ export declare namespace Task {
|
|
|
121
119
|
* ```
|
|
122
120
|
*/
|
|
123
121
|
const delay: (ms: number) => <A>(data: Task<A>) => Task<A>;
|
|
122
|
+
/**
|
|
123
|
+
* Runs a Task a fixed number of times sequentially, collecting all results into an array.
|
|
124
|
+
* An optional delay (ms) can be inserted between runs.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* pipe(
|
|
129
|
+
* pollSensor,
|
|
130
|
+
* Task.repeat({ times: 5, delay: 1000 })
|
|
131
|
+
* )(); // Task<Reading[]> — 5 readings, one per second
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
const repeat: (options: {
|
|
135
|
+
times: number;
|
|
136
|
+
delay?: number;
|
|
137
|
+
}) => <A>(task: Task<A>) => Task<A[]>;
|
|
138
|
+
/**
|
|
139
|
+
* Runs a Task repeatedly until the result satisfies a predicate, returning that result.
|
|
140
|
+
* An optional delay (ms) can be inserted between runs.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* pipe(
|
|
145
|
+
* checkStatus,
|
|
146
|
+
* Task.repeatUntil({ when: (s) => s === "ready", delay: 500 })
|
|
147
|
+
* )(); // polls every 500ms until status is "ready"
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
const repeatUntil: <A>(options: {
|
|
151
|
+
when: (a: A) => boolean;
|
|
152
|
+
delay?: number;
|
|
153
|
+
}) => (task: Task<A>) => Task<A>;
|
|
154
|
+
/**
|
|
155
|
+
* Converts a `Task<A>` into a `Task<Result<E, A>>`, resolving to `Err` if the
|
|
156
|
+
* Task does not complete within the given time.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* pipe(
|
|
161
|
+
* fetchUser,
|
|
162
|
+
* Task.timeout(5000, () => new TimeoutError("fetch user timed out")),
|
|
163
|
+
* TaskResult.chain(processUser)
|
|
164
|
+
* );
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
const timeout: <E>(ms: number, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
|
|
124
168
|
}
|
|
125
169
|
//# sourceMappingURL=Task.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Task.d.ts","sourceRoot":"","sources":["../../../src/src/Core/Task.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;AAEvC,yBAAiB,IAAI,CAAC;IACpB;;;;;;;;OAQG;IACI,MAAM,EAAE,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,IAAI,CAAC,CAAC,CAAiC,CAAC;IAEzE
|
|
1
|
+
{"version":3,"file":"Task.d.ts","sourceRoot":"","sources":["../../../src/src/Core/Task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;AAEvC,yBAAiB,IAAI,CAAC;IACpB;;;;;;;;OAQG;IACI,MAAM,EAAE,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,IAAI,CAAC,CAAC,CAAiC,CAAC;IAEzE;;;;;;;;OAQG;IACI,MAAM,IAAI,GAAI,CAAC,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAAM,CAAC;IAE3D;;;;;;;;;;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,CAAyB,CAAC;IAE9F;;;;;;;;;;;;;OAaG;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,CAChD,CAAC;IAE7B;;;;;;;;;;;;;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,CACtB,CAAC;IAEtD;;;;;;;;;;;;OAYG;IACI,MAAM,GAAG,GAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAIhE,CAAC;IAEL;;;;;;;;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,CAI/D,CAAC;IAEJ;;;;;;;;;;;OAWG;IACI,MAAM,KAAK,GAAI,IAAI,MAAM,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CACuB,CAAC;IAEvF;;;;;;;;;;;OAWG;IACI,MAAM,MAAM,GAChB,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,MAC1C,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,EAAE,CAc3B,CAAC;IAEJ;;;;;;;;;;;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,MACvD,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,CAAC,CAWtB,CAAC;IAEJ;;;;;;;;;;;;OAYG;IACI,MAAM,OAAO,GACjB,CAAC,EAAE,IAAI,MAAM,EAAE,WAAW,MAAM,CAAC,MACjC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CASpC,CAAC;CACL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskOption.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskOption.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAE5C,yBAAiB,UAAU,CAAC;IAC1B;;OAEG;IACI,MAAM,EAAE,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,UAAU,CAAC,CAAC,CAA8B,CAAC;IAE5E;;OAEG;IACI,MAAM,IAAI,GAAI,CAAC,GAAG,KAAK,OAAK,UAAU,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"TaskOption.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskOption.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ export declare namespace TaskResult {
|
|
|
22
22
|
/**
|
|
23
23
|
* Creates a failed TaskResult with the given error.
|
|
24
24
|
*/
|
|
25
|
-
const
|
|
25
|
+
const err: <E, A>(error: E) => TaskResult<E, A>;
|
|
26
26
|
/**
|
|
27
27
|
* Creates a TaskResult from a function that may throw.
|
|
28
28
|
* Catches any errors and transforms them using the onError function.
|
|
@@ -74,5 +74,44 @@ export declare namespace TaskResult {
|
|
|
74
74
|
* Useful for logging or debugging.
|
|
75
75
|
*/
|
|
76
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>;
|
|
77
116
|
}
|
|
78
117
|
//# sourceMappingURL=TaskResult.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskResult.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskResult.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAElD,yBAAiB,UAAU,CAAC;IAC1B;;OAEG;IACI,MAAM,EAAE,GAAI,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAG,UAAU,CAAC,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"TaskResult.d.ts","sourceRoot":"","sources":["../../../src/src/Core/TaskResult.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,9 +13,9 @@ import { WithError, WithKind, WithValue } from "./InternalTypes.js";
|
|
|
13
13
|
* ```ts
|
|
14
14
|
* const parse = (s: string): These<string, number> => {
|
|
15
15
|
* const n = parseFloat(s.trim());
|
|
16
|
-
* if (isNaN(n)) return These.
|
|
17
|
-
* if (s !== s.trim()) return These.
|
|
18
|
-
* return These.
|
|
16
|
+
* if (isNaN(n)) return These.err("Not a number");
|
|
17
|
+
* if (s !== s.trim()) return These.both("Leading/trailing whitespace trimmed", n);
|
|
18
|
+
* return These.ok(n);
|
|
19
19
|
* };
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
@@ -27,28 +27,28 @@ export declare namespace These {
|
|
|
27
27
|
*
|
|
28
28
|
* @example
|
|
29
29
|
* ```ts
|
|
30
|
-
* These.
|
|
30
|
+
* These.err("Something went wrong");
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
const
|
|
33
|
+
const err: <E>(error: E) => Err<E>;
|
|
34
34
|
/**
|
|
35
35
|
* Creates a These holding only a success value (no error).
|
|
36
36
|
*
|
|
37
37
|
* @example
|
|
38
38
|
* ```ts
|
|
39
|
-
* These.
|
|
39
|
+
* These.ok(42);
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
|
-
const
|
|
42
|
+
const ok: <A>(value: A) => Ok<A>;
|
|
43
43
|
/**
|
|
44
44
|
* Creates a These holding both an error/warning and a success value.
|
|
45
45
|
*
|
|
46
46
|
* @example
|
|
47
47
|
* ```ts
|
|
48
|
-
* These.
|
|
48
|
+
* These.both("Deprecated API used", result);
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
|
-
const
|
|
51
|
+
const both: <E, A>(error: E, value: A) => Both<E, A>;
|
|
52
52
|
/**
|
|
53
53
|
* Type guard — checks if a These holds only an error/warning.
|
|
54
54
|
*/
|
|
@@ -74,9 +74,9 @@ export declare namespace These {
|
|
|
74
74
|
*
|
|
75
75
|
* @example
|
|
76
76
|
* ```ts
|
|
77
|
-
* pipe(These.
|
|
78
|
-
* pipe(These.
|
|
79
|
-
* pipe(These.
|
|
77
|
+
* pipe(These.ok(5), These.map(n => n * 2)); // Ok(10)
|
|
78
|
+
* pipe(These.both("warn", 5), These.map(n => n * 2)); // Both("warn", 10)
|
|
79
|
+
* pipe(These.err("err"), These.map(n => n * 2)); // Err("err")
|
|
80
80
|
* ```
|
|
81
81
|
*/
|
|
82
82
|
const map: <A, B>(f: (a: A) => B) => <E>(data: These<E, A>) => These<E, B>;
|
|
@@ -85,8 +85,8 @@ export declare namespace These {
|
|
|
85
85
|
*
|
|
86
86
|
* @example
|
|
87
87
|
* ```ts
|
|
88
|
-
* pipe(These.
|
|
89
|
-
* pipe(These.
|
|
88
|
+
* pipe(These.err("err"), These.mapErr(e => e.toUpperCase())); // Err("ERR")
|
|
89
|
+
* pipe(These.both("warn", 5), These.mapErr(e => e.toUpperCase())); // Both("WARN", 5)
|
|
90
90
|
* ```
|
|
91
91
|
*/
|
|
92
92
|
const mapErr: <E, F>(f: (e: E) => F) => <A>(data: These<E, A>) => These<F, A>;
|
|
@@ -96,7 +96,7 @@ export declare namespace These {
|
|
|
96
96
|
* @example
|
|
97
97
|
* ```ts
|
|
98
98
|
* pipe(
|
|
99
|
-
* These.
|
|
99
|
+
* These.both("warn", 5),
|
|
100
100
|
* These.bimap(e => e.toUpperCase(), n => n * 2)
|
|
101
101
|
* ); // Both("WARN", 10)
|
|
102
102
|
* ```
|
|
@@ -111,11 +111,11 @@ export declare namespace These {
|
|
|
111
111
|
*
|
|
112
112
|
* @example
|
|
113
113
|
* ```ts
|
|
114
|
-
* const double = (n: number): These<string, number> => These.
|
|
114
|
+
* const double = (n: number): These<string, number> => These.ok(n * 2);
|
|
115
115
|
*
|
|
116
|
-
* pipe(These.
|
|
117
|
-
* pipe(These.
|
|
118
|
-
* pipe(These.
|
|
116
|
+
* pipe(These.ok(5), These.chain(double)); // Ok(10)
|
|
117
|
+
* pipe(These.both("warn", 5), These.chain(double)); // Both("warn", 10)
|
|
118
|
+
* pipe(These.err("err"), These.chain(double)); // Err("err")
|
|
119
119
|
* ```
|
|
120
120
|
*/
|
|
121
121
|
const chain: <E, A, B>(f: (a: A) => These<E, B>) => (data: These<E, A>) => These<E, B>;
|
|
@@ -160,9 +160,9 @@ export declare namespace These {
|
|
|
160
160
|
*
|
|
161
161
|
* @example
|
|
162
162
|
* ```ts
|
|
163
|
-
* pipe(These.
|
|
164
|
-
* pipe(These.
|
|
165
|
-
* pipe(These.
|
|
163
|
+
* pipe(These.ok(5), These.getOrElse(0)); // 5
|
|
164
|
+
* pipe(These.both("warn", 5), These.getOrElse(0)); // 5
|
|
165
|
+
* pipe(These.err("err"), These.getOrElse(0)); // 0
|
|
166
166
|
* ```
|
|
167
167
|
*/
|
|
168
168
|
const getOrElse: <A>(defaultValue: A) => <E>(data: These<E, A>) => A;
|
|
@@ -179,9 +179,9 @@ export declare namespace These {
|
|
|
179
179
|
*
|
|
180
180
|
* @example
|
|
181
181
|
* ```ts
|
|
182
|
-
* These.swap(These.
|
|
183
|
-
* These.swap(These.
|
|
184
|
-
* These.swap(These.
|
|
182
|
+
* These.swap(These.err("err")); // Ok("err")
|
|
183
|
+
* These.swap(These.ok(5)); // Err(5)
|
|
184
|
+
* These.swap(These.both("warn", 5)); // Both(5, "warn")
|
|
185
185
|
* ```
|
|
186
186
|
*/
|
|
187
187
|
const swap: <E, A>(data: These<E, A>) => These<A, E>;
|
|
@@ -191,9 +191,9 @@ export declare namespace These {
|
|
|
191
191
|
*
|
|
192
192
|
* @example
|
|
193
193
|
* ```ts
|
|
194
|
-
* These.toOption(These.
|
|
195
|
-
* These.toOption(These.
|
|
196
|
-
* These.toOption(These.
|
|
194
|
+
* These.toOption(These.ok(42)); // Some(42)
|
|
195
|
+
* These.toOption(These.both("warn", 42)); // Some(42)
|
|
196
|
+
* These.toOption(These.err("err")); // None
|
|
197
197
|
* ```
|
|
198
198
|
*/
|
|
199
199
|
const toOption: <E, A>(data: These<E, A>) => import("./Option.ts").Option<A>;
|
|
@@ -203,9 +203,9 @@ export declare namespace These {
|
|
|
203
203
|
*
|
|
204
204
|
* @example
|
|
205
205
|
* ```ts
|
|
206
|
-
* These.toResult(These.
|
|
207
|
-
* These.toResult(These.
|
|
208
|
-
* These.toResult(These.
|
|
206
|
+
* These.toResult(These.ok(42)); // Ok(42)
|
|
207
|
+
* These.toResult(These.both("warn", 42)); // Ok(42)
|
|
208
|
+
* These.toResult(These.err("err")); // Err("err")
|
|
209
209
|
* ```
|
|
210
210
|
*/
|
|
211
211
|
const toResult: <E, A>(data: These<E, A>) => Result<E, A>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"These.d.ts","sourceRoot":"","sources":["../../../src/src/Core/These.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEtD,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AAExE,yBAAiB,KAAK,CAAC;IACrB;;;;;;;OAOG;IACI,MAAM,
|
|
1
|
+
{"version":3,"file":"These.d.ts","sourceRoot":"","sources":["../../../src/src/Core/These.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,8 +8,8 @@ declare const _brand: unique symbol;
|
|
|
8
8
|
* type UserId = Brand<"UserId", string>;
|
|
9
9
|
* type ProductId = Brand<"ProductId", string>;
|
|
10
10
|
*
|
|
11
|
-
* const toUserId = Brand.
|
|
12
|
-
* const toProductId = Brand.
|
|
11
|
+
* const toUserId = Brand.wrap<"UserId", string>();
|
|
12
|
+
* const toProductId = Brand.wrap<"ProductId", string>();
|
|
13
13
|
*
|
|
14
14
|
* const userId: UserId = toUserId("user-123");
|
|
15
15
|
* const productId: ProductId = toProductId("prod-456");
|
|
@@ -23,19 +23,19 @@ export type Brand<K extends string, T> = T & {
|
|
|
23
23
|
};
|
|
24
24
|
export declare namespace Brand {
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Returns a constructor that wraps a value of type T in brand K.
|
|
27
27
|
* The resulting function performs an unchecked cast — only use when the raw
|
|
28
28
|
* value is known to satisfy the brand's invariants.
|
|
29
29
|
*
|
|
30
30
|
* @example
|
|
31
31
|
* ```ts
|
|
32
32
|
* type PositiveNumber = Brand<"PositiveNumber", number>;
|
|
33
|
-
* const toPositiveNumber = Brand.
|
|
33
|
+
* const toPositiveNumber = Brand.wrap<"PositiveNumber", number>();
|
|
34
34
|
*
|
|
35
35
|
* const n: PositiveNumber = toPositiveNumber(42);
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
|
-
const
|
|
38
|
+
const wrap: <K extends string, T>() => (value: T) => Brand<K, T>;
|
|
39
39
|
/**
|
|
40
40
|
* Strips the brand and returns the underlying value.
|
|
41
41
|
* Since Brand<K, T> extends T this is rarely needed, but can improve readability.
|