go-go-try 7.2.0 → 7.3.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/AGENTS.md +81 -23
- package/README.md +0 -16
- package/dist/index.cjs +82 -59
- package/dist/index.d.cts +176 -115
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +176 -115
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +81 -60
- package/package.json +1 -1
- package/src/assert.ts +59 -0
- package/src/goTry.ts +45 -0
- package/src/goTryAll.ts +141 -0
- package/src/goTryOr.ts +55 -0
- package/src/goTryRaw.ts +89 -0
- package/src/index.test.ts +188 -21
- package/src/index.ts +23 -474
- package/src/internals.ts +45 -0
- package/src/result-helpers.ts +46 -0
- package/src/tagged-error.ts +38 -0
- package/src/types.ts +50 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Result types for go-go-try
|
|
3
|
+
*/
|
|
1
4
|
type Success<T> = readonly [undefined, T];
|
|
2
5
|
type Failure<E> = readonly [E, undefined];
|
|
3
6
|
type Result<E, T> = Success<T> | Failure<E>;
|
|
7
|
+
type ResultWithDefault<E, T> = readonly [E | undefined, T];
|
|
8
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
4
9
|
/**
|
|
5
10
|
* Base interface for tagged errors.
|
|
6
11
|
* The `_tag` property enables discriminated union narrowing.
|
|
@@ -10,55 +15,101 @@ interface TaggedError<T extends string> {
|
|
|
10
15
|
readonly message: string;
|
|
11
16
|
readonly cause?: unknown;
|
|
12
17
|
}
|
|
18
|
+
interface GoTryAllOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Maximum number of concurrent promises.
|
|
21
|
+
* Set to 0 (default) for unlimited concurrency (all promises run in parallel).
|
|
22
|
+
*/
|
|
23
|
+
concurrency?: number;
|
|
24
|
+
}
|
|
13
25
|
/**
|
|
14
|
-
*
|
|
26
|
+
* Type for error constructors that can be used with goTryRaw.
|
|
27
|
+
*/
|
|
28
|
+
type ErrorConstructor<E> = new (message: string, options?: {
|
|
29
|
+
cause?: unknown;
|
|
30
|
+
}) => E;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a union type from multiple tagged error classes.
|
|
15
33
|
*
|
|
16
|
-
* @template T
|
|
17
|
-
* @
|
|
18
|
-
* @returns A class constructor for creating tagged errors
|
|
34
|
+
* @template T A tuple of tagged error class types
|
|
35
|
+
* @returns A union of all instance types
|
|
19
36
|
*
|
|
20
37
|
* @example
|
|
21
38
|
* const DatabaseError = taggedError('DatabaseError')
|
|
22
39
|
* const NetworkError = taggedError('NetworkError')
|
|
23
40
|
*
|
|
24
|
-
* type
|
|
41
|
+
* type AppError = TaggedUnion<[typeof DatabaseError, typeof NetworkError]>
|
|
42
|
+
* // Equivalent to: DatabaseError | NetworkError
|
|
43
|
+
*/
|
|
44
|
+
type TaggedUnion<T extends readonly ErrorConstructor<unknown>[]> = {
|
|
45
|
+
[K in keyof T]: T[K] extends ErrorConstructor<infer E> ? E : never;
|
|
46
|
+
}[number];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Executes a function, promise, or value and returns a Result type.
|
|
50
|
+
* If an error occurs, it returns a Failure with the error message as a string.
|
|
25
51
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* // ...
|
|
30
|
-
* }
|
|
52
|
+
* @template T The type of the successful result
|
|
53
|
+
* @param {T | Promise<T> | (() => T | Promise<T>)} value - The value, promise, or function to execute
|
|
54
|
+
* @returns {Result<string, T> | Promise<Result<string, T>>} A Result type or a Promise of a Result type
|
|
31
55
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
56
|
+
* @example
|
|
57
|
+
* // With a value
|
|
58
|
+
* const [err, result] = goTry(42);
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // With a function
|
|
62
|
+
* const [err, result] = goTry(() => JSON.parse('{"key": "value"}'));
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* // With a promise
|
|
66
|
+
* const [err, result] = await goTry(fetch('https://api.example.com/data'));
|
|
36
67
|
*/
|
|
37
|
-
declare function
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
declare function goTry<T>(fn: () => never): Result<string, never>;
|
|
69
|
+
declare function goTry<T>(fn: () => Promise<T>): Promise<Result<string, T>>;
|
|
70
|
+
declare function goTry<T>(promise: Promise<T>): Promise<Result<string, T>>;
|
|
71
|
+
declare function goTry<T>(fn: () => T): Result<string, T>;
|
|
72
|
+
declare function goTry<T>(value: T): Result<string, T>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Executes a function, promise, or value and returns a Result type.
|
|
76
|
+
* If an error occurs, it returns a Failure with the raw error object.
|
|
77
|
+
*
|
|
78
|
+
* @template T The type of the successful result
|
|
79
|
+
* @template E The type of the error, defaults to Error
|
|
80
|
+
* @param {T | Promise<T> | (() => T | Promise<T>)} value - The value, promise, or function to execute
|
|
81
|
+
* @param {ErrorConstructor<E>} [ErrorClass] - Optional error constructor to wrap caught errors
|
|
82
|
+
* @returns {Result<E, T> | Promise<Result<E, T>>} A Result type or a Promise of a Result type
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* // With a value
|
|
86
|
+
* const [err, result] = goTryRaw(42);
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* // With a function
|
|
90
|
+
* const [err, result] = goTryRaw(() => JSON.parse('{"key": "value"}'));
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* // With a promise
|
|
94
|
+
* const [err, result] = await goTryRaw(fetch('https://api.example.com/data'));
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* // With tagged error for discriminated unions
|
|
98
|
+
* const DatabaseError = taggedError('DatabaseError');
|
|
99
|
+
* const [err, result] = await goTryRaw(fetchData(), DatabaseError);
|
|
100
|
+
* // err is InstanceType<typeof DatabaseError> | undefined
|
|
101
|
+
*/
|
|
102
|
+
declare function goTryRaw<T, E = Error>(fn: () => never): Result<E, never>;
|
|
103
|
+
declare function goTryRaw<T, E = Error>(fn: () => never, ErrorClass: ErrorConstructor<E>): Result<E, never>;
|
|
104
|
+
declare function goTryRaw<T, E = Error>(fn: () => Promise<T>): Promise<Result<E, T>>;
|
|
105
|
+
declare function goTryRaw<T, E = Error>(fn: () => Promise<T>, ErrorClass: ErrorConstructor<E>): Promise<Result<E, T>>;
|
|
106
|
+
declare function goTryRaw<T, E = Error>(promise: Promise<T>): Promise<Result<E, T>>;
|
|
107
|
+
declare function goTryRaw<T, E = Error>(promise: Promise<T>, ErrorClass: ErrorConstructor<E>): Promise<Result<E, T>>;
|
|
108
|
+
declare function goTryRaw<T, E = Error>(fn: () => T): Result<E, T>;
|
|
109
|
+
declare function goTryRaw<T, E = Error>(fn: () => T, ErrorClass: ErrorConstructor<E>): Result<E, T>;
|
|
110
|
+
declare function goTryRaw<T, E = Error>(value: T): Result<E, T>;
|
|
111
|
+
declare function goTryRaw<T, E = Error>(value: T, ErrorClass: ErrorConstructor<E>): Result<E, T>;
|
|
112
|
+
|
|
62
113
|
/**
|
|
63
114
|
* Executes a function, promise, or value and returns a Result type with a fallback default.
|
|
64
115
|
* If an error occurs, it returns the error message and the default value.
|
|
@@ -85,6 +136,7 @@ declare function goTryOr<T>(fn: () => Promise<T>, defaultValue: T | (() => T)):
|
|
|
85
136
|
declare function goTryOr<T>(promise: Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault<string, T>>;
|
|
86
137
|
declare function goTryOr<T>(fn: () => T, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
|
|
87
138
|
declare function goTryOr<T>(value: T, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
|
|
139
|
+
|
|
88
140
|
/**
|
|
89
141
|
* Executes multiple promises or factory functions in parallel (or with limited concurrency)
|
|
90
142
|
* and returns a tuple of [errors, results]. Unlike Promise.all, this doesn't fail fast -
|
|
@@ -141,105 +193,114 @@ declare function goTryAllRaw<T extends readonly unknown[]>(items: {
|
|
|
141
193
|
}, {
|
|
142
194
|
[K in keyof T]: T[K] | undefined;
|
|
143
195
|
}]>;
|
|
196
|
+
|
|
144
197
|
/**
|
|
145
|
-
*
|
|
146
|
-
* If an error occurs, it returns a Failure with the error message as a string.
|
|
198
|
+
* Creates a tagged error class for discriminated error handling.
|
|
147
199
|
*
|
|
148
|
-
* @template T The type of the
|
|
149
|
-
* @param
|
|
150
|
-
* @returns
|
|
200
|
+
* @template T The literal type of the tag
|
|
201
|
+
* @param tag The string tag to identify this error type (e.g., 'DatabaseError')
|
|
202
|
+
* @returns A class constructor for creating tagged errors
|
|
151
203
|
*
|
|
152
204
|
* @example
|
|
153
|
-
*
|
|
154
|
-
* const
|
|
205
|
+
* const DatabaseError = taggedError('DatabaseError')
|
|
206
|
+
* const NetworkError = taggedError('NetworkError')
|
|
155
207
|
*
|
|
156
|
-
*
|
|
157
|
-
* // With a function
|
|
158
|
-
* const [err, result] = goTry(() => JSON.parse('{"key": "value"}'));
|
|
208
|
+
* type MyError = InstanceType<typeof DatabaseError> | InstanceType<typeof NetworkError>
|
|
159
209
|
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
* Type for error constructors that can be used with goTryRaw.
|
|
210
|
+
* function fetchUser(id: string): Result<MyError, User> {
|
|
211
|
+
* const [err, user] = goTryRaw(fetch(`/users/${id}`), DatabaseError)
|
|
212
|
+
* if (err) return failure(err)
|
|
213
|
+
* // ...
|
|
214
|
+
* }
|
|
215
|
+
*
|
|
216
|
+
* // Pattern matching on errors
|
|
217
|
+
* if (err._tag === 'DatabaseError') {
|
|
218
|
+
* // TypeScript knows this is DatabaseError
|
|
219
|
+
* }
|
|
171
220
|
*/
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
221
|
+
declare function taggedError<T extends string>(tag: T): {
|
|
222
|
+
new (message: string, options?: {
|
|
223
|
+
cause?: unknown;
|
|
224
|
+
}): {
|
|
225
|
+
readonly _tag: T;
|
|
226
|
+
readonly cause?: unknown;
|
|
227
|
+
name: string;
|
|
228
|
+
message: string;
|
|
229
|
+
stack?: string;
|
|
230
|
+
};
|
|
231
|
+
isError(error: unknown): error is Error;
|
|
232
|
+
};
|
|
233
|
+
|
|
175
234
|
/**
|
|
176
|
-
*
|
|
177
|
-
*
|
|
235
|
+
* Asserts that a condition is true, otherwise throws the provided error.
|
|
236
|
+
* Provides type narrowing when used with Result types.
|
|
178
237
|
*
|
|
179
|
-
* @
|
|
180
|
-
* @
|
|
238
|
+
* @param condition - The condition to assert
|
|
239
|
+
* @param error - An Error instance or string message to throw if condition is falsy
|
|
240
|
+
* @throws {Error} Throws the provided error if condition is falsy
|
|
181
241
|
*
|
|
182
242
|
* @example
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
|
|
187
|
-
type TaggedInstance<T extends ErrorConstructor<unknown>> = T extends ErrorConstructor<infer E> ? E : never;
|
|
188
|
-
/**
|
|
189
|
-
* Creates a union type from multiple tagged error classes.
|
|
190
|
-
*
|
|
191
|
-
* @template T A tuple of tagged error class types
|
|
192
|
-
* @returns A union of all instance types
|
|
243
|
+
* // With Result type - narrows error to undefined after assertion
|
|
244
|
+
* const [err, user] = goTryRaw(fetchUser(), DatabaseError)
|
|
245
|
+
* assert(err === undefined, new DatabaseError('Failed to fetch user'))
|
|
246
|
+
* // TypeScript now knows: err is undefined, user is User
|
|
193
247
|
*
|
|
194
248
|
* @example
|
|
195
|
-
*
|
|
196
|
-
*
|
|
249
|
+
* // With string message
|
|
250
|
+
* assert(response.ok, 'Response was not ok')
|
|
197
251
|
*
|
|
198
|
-
*
|
|
199
|
-
* //
|
|
252
|
+
* @example
|
|
253
|
+
* // With custom Error instance
|
|
254
|
+
* assert(value > 0, new ValidationError('Value must be positive'))
|
|
200
255
|
*/
|
|
201
|
-
|
|
202
|
-
[K in keyof T]: T[K] extends ErrorConstructor<infer E> ? E : never;
|
|
203
|
-
}[number];
|
|
256
|
+
declare function assert(condition: unknown, error: Error | string): asserts condition;
|
|
204
257
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
258
|
+
* Asserts that a condition is true, otherwise instantiates and throws the error class.
|
|
259
|
+
* Provides type narrowing when used with Result types.
|
|
207
260
|
*
|
|
208
|
-
* @
|
|
209
|
-
* @
|
|
210
|
-
* @param
|
|
211
|
-
* @
|
|
212
|
-
* @returns {Result<E, T> | Promise<Result<E, T>>} A Result type or a Promise of a Result type
|
|
261
|
+
* @param condition - The condition to assert
|
|
262
|
+
* @param ErrorClass - An Error class constructor (e.g., from taggedError)
|
|
263
|
+
* @param message - The error message to pass to the constructor
|
|
264
|
+
* @throws {Error} Throws a new instance of ErrorClass if condition is falsy
|
|
213
265
|
*
|
|
214
266
|
* @example
|
|
215
|
-
*
|
|
216
|
-
*
|
|
267
|
+
* const ValidationError = taggedError('ValidationError')
|
|
268
|
+
* assert(value > 0, ValidationError, 'Value must be positive')
|
|
269
|
+
* // Equivalent to: if (!(value > 0)) throw new ValidationError('Value must be positive')
|
|
270
|
+
*/
|
|
271
|
+
declare function assert<T extends Error>(condition: unknown, ErrorClass: new (message: string) => T, message: string): asserts condition;
|
|
272
|
+
|
|
273
|
+
declare function isSuccess<E, T>(result: Result<E, T>): result is Success<T>;
|
|
274
|
+
declare function isFailure<E, T>(result: Result<E, T>): result is Failure<E>;
|
|
275
|
+
declare function success<T>(value: T): Success<T>;
|
|
276
|
+
declare function failure<E>(error: E): Failure<E>;
|
|
277
|
+
/**
|
|
278
|
+
* Helper for exhaustive switch checks on discriminated unions.
|
|
279
|
+
* If this function is called, it means a case was forgotten in a switch statement.
|
|
280
|
+
* Use this in the `default` case of switch statements handling tagged errors.
|
|
217
281
|
*
|
|
218
|
-
* @
|
|
219
|
-
*
|
|
220
|
-
* const [err, result] = goTryRaw(() => JSON.parse('{"key": "value"}'));
|
|
282
|
+
* @param value - The value that should be of type `never` if all cases are handled
|
|
283
|
+
* @throws {Error} Always throws an error indicating unhandled case
|
|
221
284
|
*
|
|
222
285
|
* @example
|
|
223
|
-
*
|
|
224
|
-
* const
|
|
286
|
+
* const DatabaseError = taggedError('DatabaseError')
|
|
287
|
+
* const NetworkError = taggedError('NetworkError')
|
|
288
|
+
* type AppError = InstanceType<typeof DatabaseError> | InstanceType<typeof NetworkError>
|
|
225
289
|
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
290
|
+
* function handleError(err: AppError): string {
|
|
291
|
+
* switch (err._tag) {
|
|
292
|
+
* case 'DatabaseError':
|
|
293
|
+
* return `DB: ${err.message}`
|
|
294
|
+
* case 'NetworkError':
|
|
295
|
+
* return `NET: ${err.message}`
|
|
296
|
+
* default:
|
|
297
|
+
* // TypeScript will error if we forget a case above
|
|
298
|
+
* return assertNever(err)
|
|
299
|
+
* }
|
|
300
|
+
* }
|
|
231
301
|
*/
|
|
232
|
-
declare function
|
|
233
|
-
declare function goTryRaw<T, E = Error>(fn: () => never, ErrorClass: ErrorConstructor<E>): Result<E, never>;
|
|
234
|
-
declare function goTryRaw<T, E = Error>(fn: () => Promise<T>): Promise<Result<E, T>>;
|
|
235
|
-
declare function goTryRaw<T, E = Error>(fn: () => Promise<T>, ErrorClass: ErrorConstructor<E>): Promise<Result<E, T>>;
|
|
236
|
-
declare function goTryRaw<T, E = Error>(promise: Promise<T>): Promise<Result<E, T>>;
|
|
237
|
-
declare function goTryRaw<T, E = Error>(promise: Promise<T>, ErrorClass: ErrorConstructor<E>): Promise<Result<E, T>>;
|
|
238
|
-
declare function goTryRaw<T, E = Error>(fn: () => T): Result<E, T>;
|
|
239
|
-
declare function goTryRaw<T, E = Error>(fn: () => T, ErrorClass: ErrorConstructor<E>): Result<E, T>;
|
|
240
|
-
declare function goTryRaw<T, E = Error>(value: T): Result<E, T>;
|
|
241
|
-
declare function goTryRaw<T, E = Error>(value: T, ErrorClass: ErrorConstructor<E>): Result<E, T>;
|
|
302
|
+
declare function assertNever(value: never): never;
|
|
242
303
|
|
|
243
|
-
export { failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
|
|
244
|
-
export type { ErrorConstructor, Failure, GoTryAllOptions, MaybePromise, Result, ResultWithDefault, Success, TaggedError,
|
|
304
|
+
export { assert, assertNever, failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
|
|
305
|
+
export type { ErrorConstructor, Failure, GoTryAllOptions, MaybePromise, Result, ResultWithDefault, Success, TaggedError, TaggedUnion };
|
|
245
306
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sources":["../src/
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/types.ts","../src/goTry.ts","../src/goTryRaw.ts","../src/goTryOr.ts","../src/goTryAll.ts","../src/tagged-error.ts","../src/assert.ts","../src/result-helpers.ts"],"mappings":"AAAA;;;AAIM,KAAM,OAAO;AACb,KAAM,OAAO;AACb,KAAM,MAAM,SAAS,OAAO,MAAM,OAAO;AAEzC,KAAM,iBAAiB;AAEvB,KAAM,YAAY,UAAU,OAAO;AAEzC;;;;AAIM,UAAW,WAAW;;;;;AAMtB,UAAW,eAAe;;;;;;;AAQhC;;;AAGM,KAAM,gBAAgB;;;AAE5B;;;;;;;;;;;;;AAaM,KAAM,WAAW,oBAAoB,gBAAgB;iCAC1B,gBAAgB;;;AC7CjD;;;;;;;;;;;;;;;;;;;;AAoBA,iBAAgB,KAAK,sBAAsB,MAAM;AACjD,iBAAgB,KAAK,cAAc,OAAO,MAAM,OAAO,CAAC,MAAM;AAC9D,iBAAgB,KAAK,aAAa,OAAO,MAAM,OAAO,CAAC,MAAM;AAC7D,iBAAgB,KAAK,kBAAkB,MAAM;AAC7C,iBAAgB,KAAK,eAAe,MAAM;;ACxB1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,iBAAgB,QAAQ,QAAQ,KAAK,oBAAoB,MAAM;AAC/D,iBAAgB,QAAQ,QAAQ,KAAK,+BAA+B,gBAAgB,MAAM,MAAM;AAChG,iBAAgB,QAAQ,QAAQ,KAAK,YACzB,OAAO,MAChB,OAAO,CAAC,MAAM;AACjB,iBAAgB,QAAQ,QAAQ,KAAK,YACzB,OAAO,iBACL,gBAAgB,MAC3B,OAAO,CAAC,MAAM;AACjB,iBAAgB,QAAQ,QAAQ,KAAK,WAC1B,OAAO,MACf,OAAO,CAAC,MAAM;AACjB,iBAAgB,QAAQ,QAAQ,KAAK,WAC1B,OAAO,iBACJ,gBAAgB,MAC3B,OAAO,CAAC,MAAM;AACjB,iBAAgB,QAAQ,QAAQ,KAAK,gBAAgB,MAAM;AAC3D,iBAAgB,QAAQ,QAAQ,KAAK,2BAA2B,gBAAgB,MAAM,MAAM;AAC5F,iBAAgB,QAAQ,QAAQ,KAAK,aAAa,MAAM;AACxD,iBAAgB,QAAQ,QAAQ,KAAK,wBAAwB,gBAAgB,MAAM,MAAM;;AC/CzF;;;;;;;;;;;;;;;;;;;;;AAqBA,iBAAgB,OAAO,mDAAmD,iBAAiB;AAC3F,iBAAgB,OAAO,cACX,OAAO,mCAEhB,OAAO,CAAC,iBAAiB;AAC5B,iBAAgB,OAAO,aACZ,OAAO,mCAEf,OAAO,CAAC,iBAAiB;AAC5B,iBAAgB,OAAO,+CAA+C,iBAAiB;AACvF,iBAAgB,OAAO,4CAA4C,iBAAiB;;ACgBpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,iBAAsB,QAAQ;oBACH,OAAO,gBAAgB,OAAO;aAC7C,eAAe,GACxB,OAAO;;;;;AAoBV;;;;;;;;;;AAUA,iBAAsB,WAAW;oBACN,OAAO,gBAAgB,OAAO;aAC7C,eAAe,GACxB,OAAO;oBAAoB,KAAK;;;;;ACrHnC;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,iBAAgB,WAAW;;;;;;;;;;;;;AC1B3B;;;;;;;;;;;;;;;;;;;;;;AAsBA,iBAAgB,MAAM,4BAA4B,KAAK;AAEvD;;;;;;;;;;;;;;AAcA,iBAAgB,MAAM,WAAW,KAAK;;ACpCtC,iBAAgB,SAAS,eAAe,MAAM,mBAAmB,OAAO;AAIxE,iBAAgB,SAAS,eAAe,MAAM,mBAAmB,OAAO;AAIxE,iBAAgB,OAAO,eAAe,OAAO;AAI7C,iBAAgB,OAAO,eAAe,OAAO;AAI7C;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,iBAAgB,WAAW","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
function taggedError(tag) {
|
|
2
|
-
return class TaggedErrorClass extends Error {
|
|
3
|
-
constructor(message, options) {
|
|
4
|
-
super(message);
|
|
5
|
-
this._tag = tag;
|
|
6
|
-
this.name = tag;
|
|
7
|
-
this.cause = options?.cause;
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
1
|
function isSuccess(result) {
|
|
12
2
|
return result[0] === void 0;
|
|
13
3
|
}
|
|
@@ -20,9 +10,71 @@ function success(value) {
|
|
|
20
10
|
function failure(error) {
|
|
21
11
|
return [error, void 0];
|
|
22
12
|
}
|
|
13
|
+
function assertNever(value) {
|
|
14
|
+
throw new Error(`Unhandled case: ${String(value)}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getErrorMessage(error) {
|
|
18
|
+
if (error === void 0) return "undefined";
|
|
19
|
+
if (typeof error === "string") return error;
|
|
20
|
+
if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") {
|
|
21
|
+
return error.message;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
return JSON.stringify(error);
|
|
25
|
+
} catch {
|
|
26
|
+
return String(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function isPromise(value) {
|
|
30
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
31
|
+
}
|
|
32
|
+
function isError(value) {
|
|
33
|
+
return value instanceof Error;
|
|
34
|
+
}
|
|
23
35
|
function resolveDefault(defaultValue) {
|
|
24
36
|
return typeof defaultValue === "function" ? defaultValue() : defaultValue;
|
|
25
37
|
}
|
|
38
|
+
|
|
39
|
+
function goTry(value) {
|
|
40
|
+
try {
|
|
41
|
+
const result = typeof value === "function" ? value() : value;
|
|
42
|
+
if (isPromise(result)) {
|
|
43
|
+
return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(getErrorMessage(err)));
|
|
44
|
+
}
|
|
45
|
+
return success(result);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
return failure(getErrorMessage(err));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function goTryRaw(value, ErrorClass) {
|
|
52
|
+
const wrapError = (err) => {
|
|
53
|
+
if (ErrorClass) {
|
|
54
|
+
if (err === void 0) {
|
|
55
|
+
return new ErrorClass("undefined");
|
|
56
|
+
}
|
|
57
|
+
if (isError(err)) {
|
|
58
|
+
return new ErrorClass(err.message, { cause: err });
|
|
59
|
+
}
|
|
60
|
+
return new ErrorClass(String(err));
|
|
61
|
+
}
|
|
62
|
+
if (err === void 0) {
|
|
63
|
+
return new Error("undefined");
|
|
64
|
+
}
|
|
65
|
+
return isError(err) ? err : new Error(String(err));
|
|
66
|
+
};
|
|
67
|
+
try {
|
|
68
|
+
const result = typeof value === "function" ? value() : value;
|
|
69
|
+
if (isPromise(result)) {
|
|
70
|
+
return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(wrapError(err)));
|
|
71
|
+
}
|
|
72
|
+
return success(result);
|
|
73
|
+
} catch (err) {
|
|
74
|
+
return failure(wrapError(err));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
26
78
|
function goTryOr(value, defaultValue) {
|
|
27
79
|
try {
|
|
28
80
|
const result = typeof value === "function" ? value() : value;
|
|
@@ -34,6 +86,7 @@ function goTryOr(value, defaultValue) {
|
|
|
34
86
|
return [getErrorMessage(err), resolveDefault(defaultValue)];
|
|
35
87
|
}
|
|
36
88
|
}
|
|
89
|
+
|
|
37
90
|
async function runWithConcurrency(items, concurrency) {
|
|
38
91
|
if (items.length === 0) {
|
|
39
92
|
return [];
|
|
@@ -97,60 +150,28 @@ async function goTryAllRaw(items, options) {
|
|
|
97
150
|
}
|
|
98
151
|
return [errors, results];
|
|
99
152
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
} catch {
|
|
109
|
-
return String(error);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function isPromise(value) {
|
|
113
|
-
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
114
|
-
}
|
|
115
|
-
function isError(value) {
|
|
116
|
-
return value instanceof Error;
|
|
117
|
-
}
|
|
118
|
-
function goTry(value) {
|
|
119
|
-
try {
|
|
120
|
-
const result = typeof value === "function" ? value() : value;
|
|
121
|
-
if (isPromise(result)) {
|
|
122
|
-
return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(getErrorMessage(err)));
|
|
153
|
+
|
|
154
|
+
function taggedError(tag) {
|
|
155
|
+
return class TaggedErrorClass extends Error {
|
|
156
|
+
constructor(message, options) {
|
|
157
|
+
super(message);
|
|
158
|
+
this._tag = tag;
|
|
159
|
+
this.name = tag;
|
|
160
|
+
this.cause = options?.cause;
|
|
123
161
|
}
|
|
124
|
-
|
|
125
|
-
} catch (err) {
|
|
126
|
-
return failure(getErrorMessage(err));
|
|
127
|
-
}
|
|
162
|
+
};
|
|
128
163
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
if (isError(err)) {
|
|
136
|
-
return new ErrorClass(err.message, { cause: err });
|
|
137
|
-
}
|
|
138
|
-
return new ErrorClass(String(err));
|
|
139
|
-
}
|
|
140
|
-
if (err === void 0) {
|
|
141
|
-
return new Error("undefined");
|
|
164
|
+
|
|
165
|
+
function assert(condition, errorOrClass, message) {
|
|
166
|
+
if (!condition) {
|
|
167
|
+
if (typeof errorOrClass === "string") {
|
|
168
|
+
throw new Error(errorOrClass);
|
|
142
169
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
const result = typeof value === "function" ? value() : value;
|
|
147
|
-
if (isPromise(result)) {
|
|
148
|
-
return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(wrapError(err)));
|
|
170
|
+
if (typeof errorOrClass === "function" && message !== void 0) {
|
|
171
|
+
throw new errorOrClass(message);
|
|
149
172
|
}
|
|
150
|
-
|
|
151
|
-
} catch (err) {
|
|
152
|
-
return failure(wrapError(err));
|
|
173
|
+
throw errorOrClass;
|
|
153
174
|
}
|
|
154
175
|
}
|
|
155
176
|
|
|
156
|
-
export { failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
|
|
177
|
+
export { assert, assertNever, failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
|
package/package.json
CHANGED
package/src/assert.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asserts that a condition is true, otherwise throws the provided error.
|
|
3
|
+
* Provides type narrowing when used with Result types.
|
|
4
|
+
*
|
|
5
|
+
* @param condition - The condition to assert
|
|
6
|
+
* @param error - An Error instance or string message to throw if condition is falsy
|
|
7
|
+
* @throws {Error} Throws the provided error if condition is falsy
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // With Result type - narrows error to undefined after assertion
|
|
11
|
+
* const [err, user] = goTryRaw(fetchUser(), DatabaseError)
|
|
12
|
+
* assert(err === undefined, new DatabaseError('Failed to fetch user'))
|
|
13
|
+
* // TypeScript now knows: err is undefined, user is User
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // With string message
|
|
17
|
+
* assert(response.ok, 'Response was not ok')
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // With custom Error instance
|
|
21
|
+
* assert(value > 0, new ValidationError('Value must be positive'))
|
|
22
|
+
*/
|
|
23
|
+
export function assert(condition: unknown, error: Error | string): asserts condition
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Asserts that a condition is true, otherwise instantiates and throws the error class.
|
|
27
|
+
* Provides type narrowing when used with Result types.
|
|
28
|
+
*
|
|
29
|
+
* @param condition - The condition to assert
|
|
30
|
+
* @param ErrorClass - An Error class constructor (e.g., from taggedError)
|
|
31
|
+
* @param message - The error message to pass to the constructor
|
|
32
|
+
* @throws {Error} Throws a new instance of ErrorClass if condition is falsy
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* const ValidationError = taggedError('ValidationError')
|
|
36
|
+
* assert(value > 0, ValidationError, 'Value must be positive')
|
|
37
|
+
* // Equivalent to: if (!(value > 0)) throw new ValidationError('Value must be positive')
|
|
38
|
+
*/
|
|
39
|
+
export function assert<T extends Error>(
|
|
40
|
+
condition: unknown,
|
|
41
|
+
ErrorClass: new (message: string) => T,
|
|
42
|
+
message: string,
|
|
43
|
+
): asserts condition
|
|
44
|
+
|
|
45
|
+
export function assert(
|
|
46
|
+
condition: unknown,
|
|
47
|
+
errorOrClass: Error | string | (new (message: string) => Error),
|
|
48
|
+
message?: string,
|
|
49
|
+
): asserts condition {
|
|
50
|
+
if (!condition) {
|
|
51
|
+
if (typeof errorOrClass === 'string') {
|
|
52
|
+
throw new Error(errorOrClass)
|
|
53
|
+
}
|
|
54
|
+
if (typeof errorOrClass === 'function' && message !== undefined) {
|
|
55
|
+
throw new errorOrClass(message)
|
|
56
|
+
}
|
|
57
|
+
throw errorOrClass
|
|
58
|
+
}
|
|
59
|
+
}
|