go-go-try 7.4.1 → 8.0.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/index.cjs CHANGED
@@ -28,7 +28,7 @@ function getErrorMessage(error) {
28
28
  return String(error);
29
29
  }
30
30
  }
31
- function isPromise(value) {
31
+ function isPromise$1(value) {
32
32
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
33
33
  }
34
34
  function isError(value) {
@@ -41,7 +41,7 @@ function resolveDefault(defaultValue) {
41
41
  function goTry(value) {
42
42
  try {
43
43
  const result = typeof value === "function" ? value() : value;
44
- if (isPromise(result)) {
44
+ if (isPromise$1(result)) {
45
45
  return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(getErrorMessage(err)));
46
46
  }
47
47
  return success(result);
@@ -98,7 +98,7 @@ function goTryRaw(value, options) {
98
98
  };
99
99
  try {
100
100
  const result = typeof value === "function" ? value() : value;
101
- if (isPromise(result)) {
101
+ if (isPromise$1(result)) {
102
102
  return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(wrapError(err)));
103
103
  }
104
104
  return success(result);
@@ -110,7 +110,7 @@ function goTryRaw(value, options) {
110
110
  function goTryOr(value, defaultValue) {
111
111
  try {
112
112
  const result = typeof value === "function" ? value() : value;
113
- if (isPromise(result)) {
113
+ if (isPromise$1(result)) {
114
114
  return result.then((resolvedValue) => success(resolvedValue)).catch((err) => [getErrorMessage(err), resolveDefault(defaultValue)]);
115
115
  }
116
116
  return success(result);
@@ -221,10 +221,72 @@ function assert(condition, errorOrClass, message) {
221
221
  }
222
222
  }
223
223
 
224
+ function isPromise(value) {
225
+ return value instanceof Promise;
226
+ }
227
+ function isErrorConstructor(error) {
228
+ return typeof error === "function" && error.prototype !== void 0 && error.prototype instanceof Error;
229
+ }
230
+ function throwError(value, error) {
231
+ if (isErrorConstructor(error)) {
232
+ throw new error(String(value), { cause: value });
233
+ }
234
+ throw error(value);
235
+ }
236
+ function ensure(value, predicate, error = UnknownError) {
237
+ if (typeof value === "function") {
238
+ const result = value();
239
+ if (isPromise(result)) {
240
+ return result.then((resolved) => {
241
+ if (!predicate(resolved)) {
242
+ throwError(resolved, error);
243
+ }
244
+ return resolved;
245
+ });
246
+ }
247
+ if (!predicate(result)) {
248
+ throwError(result, error);
249
+ }
250
+ return result;
251
+ }
252
+ if (isPromise(value)) {
253
+ return value.then((resolved) => {
254
+ if (!predicate(resolved)) {
255
+ throwError(resolved, error);
256
+ }
257
+ return resolved;
258
+ });
259
+ }
260
+ if (!predicate(value)) {
261
+ throwError(value, error);
262
+ }
263
+ return value;
264
+ }
265
+
266
+ function goElse(value, defaultValue) {
267
+ try {
268
+ const result = typeof value === "function" ? value() : value;
269
+ if (isPromise$1(result)) {
270
+ return result.then((resolvedValue) => [void 0, resolvedValue]).catch((err) => {
271
+ const error = err instanceof Error ? err : new Error(String(err));
272
+ return [error, resolveDefault(defaultValue)];
273
+ });
274
+ }
275
+ return [void 0, result];
276
+ } catch (err) {
277
+ const error = err instanceof Error ? err : new Error(String(err));
278
+ return [error, resolveDefault(defaultValue)];
279
+ }
280
+ }
281
+
224
282
  exports.UnknownError = UnknownError;
225
283
  exports.assert = assert;
226
284
  exports.assertNever = assertNever;
285
+ exports.ensure = ensure;
227
286
  exports.failure = failure;
287
+ exports.go = goTryRaw;
288
+ exports.goAll = goTryAllRaw;
289
+ exports.goElse = goElse;
228
290
  exports.goTry = goTry;
229
291
  exports.goTryAll = goTryAll;
230
292
  exports.goTryAllRaw = goTryAllRaw;
package/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@
4
4
  type Success<T> = readonly [undefined, T];
5
5
  type Failure<E> = readonly [E, undefined];
6
6
  type Result<E, T> = Success<T> | Failure<E>;
7
- type ResultWithDefault<E, T> = readonly [E | undefined, T];
7
+ type ResultWithDefault$1<E, T> = readonly [E | undefined, T];
8
8
  type MaybePromise<T> = T | Promise<T>;
9
9
  /**
10
10
  * Base interface for tagged errors.
@@ -25,7 +25,7 @@ interface GoTryAllOptions {
25
25
  /**
26
26
  * Type for error constructors that can be used with goTryRaw.
27
27
  */
28
- type ErrorConstructor<E> = new (message: string, options?: {
28
+ type ErrorConstructor$1<E> = new (message: string, options?: {
29
29
  cause?: unknown;
30
30
  }) => E;
31
31
  /**
@@ -33,11 +33,11 @@ type ErrorConstructor<E> = new (message: string, options?: {
33
33
  * errorClass and systemErrorClass are mutually exclusive - you can only provide one.
34
34
  */
35
35
  type GoTryRawOptions<E = Error> = {
36
- errorClass: ErrorConstructor<E>;
36
+ errorClass: ErrorConstructor$1<E>;
37
37
  systemErrorClass?: never;
38
38
  } | {
39
39
  errorClass?: never;
40
- systemErrorClass: ErrorConstructor<E>;
40
+ systemErrorClass: ErrorConstructor$1<E>;
41
41
  } | {
42
42
  errorClass?: never;
43
43
  systemErrorClass?: never;
@@ -49,12 +49,12 @@ type GoTryRawOptions<E = Error> = {
49
49
  */
50
50
  type GoTryAllRawOptions<E = Error> = {
51
51
  concurrency?: number;
52
- errorClass: ErrorConstructor<E>;
52
+ errorClass: ErrorConstructor$1<E>;
53
53
  systemErrorClass?: never;
54
54
  } | {
55
55
  concurrency?: number;
56
56
  errorClass?: never;
57
- systemErrorClass: ErrorConstructor<E>;
57
+ systemErrorClass: ErrorConstructor$1<E>;
58
58
  } | {
59
59
  concurrency?: number;
60
60
  errorClass?: never;
@@ -73,8 +73,8 @@ type GoTryAllRawOptions<E = Error> = {
73
73
  * type AppError = TaggedUnion<[typeof DatabaseError, typeof NetworkError]>
74
74
  * // Equivalent to: DatabaseError | NetworkError
75
75
  */
76
- type TaggedUnion<T extends readonly ErrorConstructor<unknown>[]> = {
77
- [K in keyof T]: T[K] extends ErrorConstructor<infer E> ? E : never;
76
+ type TaggedUnion<T extends readonly ErrorConstructor$1<unknown>[]> = {
77
+ [K in keyof T]: T[K] extends ErrorConstructor$1<infer E> ? E : never;
78
78
  }[number];
79
79
 
80
80
  /**
@@ -198,11 +198,11 @@ declare function goTryRaw<T, E = InstanceType<typeof UnknownError>>(value: T, op
198
198
  * name: 'Guest'
199
199
  * }))
200
200
  */
201
- declare function goTryOr<T>(fn: () => never, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
202
- declare function goTryOr<T>(fn: () => Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault<string, T>>;
203
- declare function goTryOr<T>(promise: Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault<string, T>>;
204
- declare function goTryOr<T>(fn: () => T, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
205
- declare function goTryOr<T>(value: T, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
201
+ declare function goTryOr<T>(fn: () => never, defaultValue: T | (() => T)): ResultWithDefault$1<string, T>;
202
+ declare function goTryOr<T>(fn: () => Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault$1<string, T>>;
203
+ declare function goTryOr<T>(promise: Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault$1<string, T>>;
204
+ declare function goTryOr<T>(fn: () => T, defaultValue: T | (() => T)): ResultWithDefault$1<string, T>;
205
+ declare function goTryOr<T>(value: T, defaultValue: T | (() => T)): ResultWithDefault$1<string, T>;
206
206
 
207
207
  /**
208
208
  * Executes multiple promises or factory functions in parallel (or with limited concurrency)
@@ -344,6 +344,47 @@ declare function assert(condition: unknown, error: Error | string): asserts cond
344
344
  */
345
345
  declare function assert<T extends Error>(condition: unknown, ErrorClass: new (message: string) => T, message: string): asserts condition;
346
346
 
347
+ /**
348
+ * Error class constructor type.
349
+ */
350
+ type ErrorConstructor<E extends Error = Error> = new (message: string, options?: {
351
+ cause?: unknown;
352
+ }) => E;
353
+ /**
354
+ * Ensures a value satisfies a predicate, throwing an error if not.
355
+ * Returns the value if the predicate passes.
356
+ *
357
+ * Accepts sync values, promises, or functions - just like `go`.
358
+ *
359
+ * The error can be either:
360
+ * - An Error class constructor (instantiated with the value as cause)
361
+ * - A function that creates and returns an Error
362
+ * - If omitted, defaults to UnknownError
363
+ *
364
+ * @example
365
+ * ```typescript
366
+ * // With sync value (uses UnknownError by default)
367
+ * ensure(42, n => n > 0)
368
+ *
369
+ * // With promise (awaited internally)
370
+ * const res = await ensure(fetch('/api'), r => r.ok, RequestFailedError)
371
+ *
372
+ * // With function
373
+ * const res = ensure(() => parseInt('42'), n => !isNaN(n), Error)
374
+ *
375
+ * // With error factory function
376
+ * const res = ensure(
377
+ * await fetch('/api'),
378
+ * r => r.ok,
379
+ * r => new Error(`HTTP ${r.status}`)
380
+ * )
381
+ * ```
382
+ */
383
+ declare function ensure<T>(value: Promise<T>, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): Promise<T>;
384
+ declare function ensure<T>(fn: () => Promise<T>, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): Promise<T>;
385
+ declare function ensure<T>(fn: () => T, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): T;
386
+ declare function ensure<T>(value: T, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): T;
387
+
347
388
  declare function isSuccess<E, T>(result: Result<E, T>): result is Success<T>;
348
389
  declare function isFailure<E, T>(result: Result<E, T>): result is Failure<E>;
349
390
  declare function success<T>(value: T): Success<T>;
@@ -375,6 +416,40 @@ declare function failure<E>(error: E): Failure<E>;
375
416
  */
376
417
  declare function assertNever(value: never): never;
377
418
 
378
- export { UnknownError, assert, assertNever, failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
379
- export type { ErrorConstructor, Failure, GoTryAllOptions, GoTryAllRawOptions, GoTryRawOptions, MaybePromise, Result, ResultWithDefault, Success, TaggedError, TaggedUnion };
419
+ /**
420
+ * Result type with Error and a default value.
421
+ * On error, returns [Error, DefaultT]
422
+ * On success, returns [undefined, T]
423
+ */
424
+ type ResultWithDefault<E, T, D = T> = readonly [E, D] | readonly [undefined, T];
425
+ /**
426
+ * Executes a function, promise, or value and returns a Result type with a fallback default.
427
+ * If an error occurs, it returns the actual Error object and the default value.
428
+ *
429
+ * @template T The type of the successful result
430
+ * @template D The type of the default value (defaults to T)
431
+ * @param {T | Promise<T> | (() => T | Promise<T>)} value - The value, promise, or function to execute
432
+ * @param {D | (() => D)} defaultValue - The default value or a function to compute it (only called on failure)
433
+ * @returns {ResultWithDefault<Error, T, D> | Promise<ResultWithDefault<Error, T, D>>} A tuple of [error, value] or Promise thereof
434
+ *
435
+ * @example
436
+ * // With a static default
437
+ * const [err, config] = goElse(() => JSON.parse('invalid'), { port: 3000 })
438
+ * // err is the Error object, config is { port: 3000 }
439
+ *
440
+ * @example
441
+ * // With a computed default (lazy evaluation)
442
+ * const [err, user] = await goElse(fetchUser(id), () => ({
443
+ * id: 'anonymous',
444
+ * name: 'Guest'
445
+ * }))
446
+ */
447
+ declare function goElse<T, D = T>(fn: () => never, defaultValue: D | (() => D)): ResultWithDefault<Error, never, D>;
448
+ declare function goElse<T, D = T>(fn: () => Promise<T>, defaultValue: D | (() => D)): Promise<ResultWithDefault<Error, T, D>>;
449
+ declare function goElse<T, D = T>(promise: Promise<T>, defaultValue: D | (() => D)): Promise<ResultWithDefault<Error, T, D>>;
450
+ declare function goElse<T, D = T>(fn: () => T, defaultValue: D | (() => D)): ResultWithDefault<Error, T, D>;
451
+ declare function goElse<T, D = T>(value: T, defaultValue: D | (() => D)): ResultWithDefault<Error, T, D>;
452
+
453
+ export { UnknownError, assert, assertNever, ensure, failure, goTryRaw as go, goTryAllRaw as goAll, goElse, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
454
+ export type { ErrorConstructor$1 as ErrorConstructor, Failure, GoTryAllOptions, GoTryAllRawOptions, GoTryRawOptions, MaybePromise, Result, ResultWithDefault$1 as ResultWithDefault, Success, TaggedError, TaggedUnion };
380
455
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/goTry.ts","../src/unknown-error.ts","../src/goTryRaw.ts","../src/goTryOr.ts","../src/goTryAll.ts","../src/tagged-error.ts","../src/assert.ts","../src/result-helpers.ts"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/goTry.ts","../src/unknown-error.ts","../src/goTryRaw.ts","../src/goTryOr.ts","../src/goTryAll.ts","../src/tagged-error.ts","../src/assert.ts","../src/ensure.ts","../src/result-helpers.ts","../src/goElse.ts"],"mappings":"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","names":["ResultWithDefault","ErrorConstructor"]}
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@
4
4
  type Success<T> = readonly [undefined, T];
5
5
  type Failure<E> = readonly [E, undefined];
6
6
  type Result<E, T> = Success<T> | Failure<E>;
7
- type ResultWithDefault<E, T> = readonly [E | undefined, T];
7
+ type ResultWithDefault$1<E, T> = readonly [E | undefined, T];
8
8
  type MaybePromise<T> = T | Promise<T>;
9
9
  /**
10
10
  * Base interface for tagged errors.
@@ -25,7 +25,7 @@ interface GoTryAllOptions {
25
25
  /**
26
26
  * Type for error constructors that can be used with goTryRaw.
27
27
  */
28
- type ErrorConstructor<E> = new (message: string, options?: {
28
+ type ErrorConstructor$1<E> = new (message: string, options?: {
29
29
  cause?: unknown;
30
30
  }) => E;
31
31
  /**
@@ -33,11 +33,11 @@ type ErrorConstructor<E> = new (message: string, options?: {
33
33
  * errorClass and systemErrorClass are mutually exclusive - you can only provide one.
34
34
  */
35
35
  type GoTryRawOptions<E = Error> = {
36
- errorClass: ErrorConstructor<E>;
36
+ errorClass: ErrorConstructor$1<E>;
37
37
  systemErrorClass?: never;
38
38
  } | {
39
39
  errorClass?: never;
40
- systemErrorClass: ErrorConstructor<E>;
40
+ systemErrorClass: ErrorConstructor$1<E>;
41
41
  } | {
42
42
  errorClass?: never;
43
43
  systemErrorClass?: never;
@@ -49,12 +49,12 @@ type GoTryRawOptions<E = Error> = {
49
49
  */
50
50
  type GoTryAllRawOptions<E = Error> = {
51
51
  concurrency?: number;
52
- errorClass: ErrorConstructor<E>;
52
+ errorClass: ErrorConstructor$1<E>;
53
53
  systemErrorClass?: never;
54
54
  } | {
55
55
  concurrency?: number;
56
56
  errorClass?: never;
57
- systemErrorClass: ErrorConstructor<E>;
57
+ systemErrorClass: ErrorConstructor$1<E>;
58
58
  } | {
59
59
  concurrency?: number;
60
60
  errorClass?: never;
@@ -73,8 +73,8 @@ type GoTryAllRawOptions<E = Error> = {
73
73
  * type AppError = TaggedUnion<[typeof DatabaseError, typeof NetworkError]>
74
74
  * // Equivalent to: DatabaseError | NetworkError
75
75
  */
76
- type TaggedUnion<T extends readonly ErrorConstructor<unknown>[]> = {
77
- [K in keyof T]: T[K] extends ErrorConstructor<infer E> ? E : never;
76
+ type TaggedUnion<T extends readonly ErrorConstructor$1<unknown>[]> = {
77
+ [K in keyof T]: T[K] extends ErrorConstructor$1<infer E> ? E : never;
78
78
  }[number];
79
79
 
80
80
  /**
@@ -198,11 +198,11 @@ declare function goTryRaw<T, E = InstanceType<typeof UnknownError>>(value: T, op
198
198
  * name: 'Guest'
199
199
  * }))
200
200
  */
201
- declare function goTryOr<T>(fn: () => never, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
202
- declare function goTryOr<T>(fn: () => Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault<string, T>>;
203
- declare function goTryOr<T>(promise: Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault<string, T>>;
204
- declare function goTryOr<T>(fn: () => T, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
205
- declare function goTryOr<T>(value: T, defaultValue: T | (() => T)): ResultWithDefault<string, T>;
201
+ declare function goTryOr<T>(fn: () => never, defaultValue: T | (() => T)): ResultWithDefault$1<string, T>;
202
+ declare function goTryOr<T>(fn: () => Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault$1<string, T>>;
203
+ declare function goTryOr<T>(promise: Promise<T>, defaultValue: T | (() => T)): Promise<ResultWithDefault$1<string, T>>;
204
+ declare function goTryOr<T>(fn: () => T, defaultValue: T | (() => T)): ResultWithDefault$1<string, T>;
205
+ declare function goTryOr<T>(value: T, defaultValue: T | (() => T)): ResultWithDefault$1<string, T>;
206
206
 
207
207
  /**
208
208
  * Executes multiple promises or factory functions in parallel (or with limited concurrency)
@@ -344,6 +344,47 @@ declare function assert(condition: unknown, error: Error | string): asserts cond
344
344
  */
345
345
  declare function assert<T extends Error>(condition: unknown, ErrorClass: new (message: string) => T, message: string): asserts condition;
346
346
 
347
+ /**
348
+ * Error class constructor type.
349
+ */
350
+ type ErrorConstructor<E extends Error = Error> = new (message: string, options?: {
351
+ cause?: unknown;
352
+ }) => E;
353
+ /**
354
+ * Ensures a value satisfies a predicate, throwing an error if not.
355
+ * Returns the value if the predicate passes.
356
+ *
357
+ * Accepts sync values, promises, or functions - just like `go`.
358
+ *
359
+ * The error can be either:
360
+ * - An Error class constructor (instantiated with the value as cause)
361
+ * - A function that creates and returns an Error
362
+ * - If omitted, defaults to UnknownError
363
+ *
364
+ * @example
365
+ * ```typescript
366
+ * // With sync value (uses UnknownError by default)
367
+ * ensure(42, n => n > 0)
368
+ *
369
+ * // With promise (awaited internally)
370
+ * const res = await ensure(fetch('/api'), r => r.ok, RequestFailedError)
371
+ *
372
+ * // With function
373
+ * const res = ensure(() => parseInt('42'), n => !isNaN(n), Error)
374
+ *
375
+ * // With error factory function
376
+ * const res = ensure(
377
+ * await fetch('/api'),
378
+ * r => r.ok,
379
+ * r => new Error(`HTTP ${r.status}`)
380
+ * )
381
+ * ```
382
+ */
383
+ declare function ensure<T>(value: Promise<T>, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): Promise<T>;
384
+ declare function ensure<T>(fn: () => Promise<T>, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): Promise<T>;
385
+ declare function ensure<T>(fn: () => T, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): T;
386
+ declare function ensure<T>(value: T, predicate: (value: T) => boolean, error?: ErrorConstructor<Error> | ((value: T) => Error)): T;
387
+
347
388
  declare function isSuccess<E, T>(result: Result<E, T>): result is Success<T>;
348
389
  declare function isFailure<E, T>(result: Result<E, T>): result is Failure<E>;
349
390
  declare function success<T>(value: T): Success<T>;
@@ -375,6 +416,40 @@ declare function failure<E>(error: E): Failure<E>;
375
416
  */
376
417
  declare function assertNever(value: never): never;
377
418
 
378
- export { UnknownError, assert, assertNever, failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
379
- export type { ErrorConstructor, Failure, GoTryAllOptions, GoTryAllRawOptions, GoTryRawOptions, MaybePromise, Result, ResultWithDefault, Success, TaggedError, TaggedUnion };
419
+ /**
420
+ * Result type with Error and a default value.
421
+ * On error, returns [Error, DefaultT]
422
+ * On success, returns [undefined, T]
423
+ */
424
+ type ResultWithDefault<E, T, D = T> = readonly [E, D] | readonly [undefined, T];
425
+ /**
426
+ * Executes a function, promise, or value and returns a Result type with a fallback default.
427
+ * If an error occurs, it returns the actual Error object and the default value.
428
+ *
429
+ * @template T The type of the successful result
430
+ * @template D The type of the default value (defaults to T)
431
+ * @param {T | Promise<T> | (() => T | Promise<T>)} value - The value, promise, or function to execute
432
+ * @param {D | (() => D)} defaultValue - The default value or a function to compute it (only called on failure)
433
+ * @returns {ResultWithDefault<Error, T, D> | Promise<ResultWithDefault<Error, T, D>>} A tuple of [error, value] or Promise thereof
434
+ *
435
+ * @example
436
+ * // With a static default
437
+ * const [err, config] = goElse(() => JSON.parse('invalid'), { port: 3000 })
438
+ * // err is the Error object, config is { port: 3000 }
439
+ *
440
+ * @example
441
+ * // With a computed default (lazy evaluation)
442
+ * const [err, user] = await goElse(fetchUser(id), () => ({
443
+ * id: 'anonymous',
444
+ * name: 'Guest'
445
+ * }))
446
+ */
447
+ declare function goElse<T, D = T>(fn: () => never, defaultValue: D | (() => D)): ResultWithDefault<Error, never, D>;
448
+ declare function goElse<T, D = T>(fn: () => Promise<T>, defaultValue: D | (() => D)): Promise<ResultWithDefault<Error, T, D>>;
449
+ declare function goElse<T, D = T>(promise: Promise<T>, defaultValue: D | (() => D)): Promise<ResultWithDefault<Error, T, D>>;
450
+ declare function goElse<T, D = T>(fn: () => T, defaultValue: D | (() => D)): ResultWithDefault<Error, T, D>;
451
+ declare function goElse<T, D = T>(value: T, defaultValue: D | (() => D)): ResultWithDefault<Error, T, D>;
452
+
453
+ export { UnknownError, assert, assertNever, ensure, failure, goTryRaw as go, goTryAllRaw as goAll, goElse, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
454
+ export type { ErrorConstructor$1 as ErrorConstructor, Failure, GoTryAllOptions, GoTryAllRawOptions, GoTryRawOptions, MaybePromise, Result, ResultWithDefault$1 as ResultWithDefault, Success, TaggedError, TaggedUnion };
380
455
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sources":["../src/types.ts","../src/goTry.ts","../src/unknown-error.ts","../src/goTryRaw.ts","../src/goTryOr.ts","../src/goTryAll.ts","../src/tagged-error.ts","../src/assert.ts","../src/result-helpers.ts"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"index.d.mts","sources":["../src/types.ts","../src/goTry.ts","../src/unknown-error.ts","../src/goTryRaw.ts","../src/goTryOr.ts","../src/goTryAll.ts","../src/tagged-error.ts","../src/assert.ts","../src/ensure.ts","../src/result-helpers.ts","../src/goElse.ts"],"mappings":"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","names":["ResultWithDefault","ErrorConstructor"]}
package/dist/index.mjs CHANGED
@@ -26,7 +26,7 @@ function getErrorMessage(error) {
26
26
  return String(error);
27
27
  }
28
28
  }
29
- function isPromise(value) {
29
+ function isPromise$1(value) {
30
30
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
31
31
  }
32
32
  function isError(value) {
@@ -39,7 +39,7 @@ function resolveDefault(defaultValue) {
39
39
  function goTry(value) {
40
40
  try {
41
41
  const result = typeof value === "function" ? value() : value;
42
- if (isPromise(result)) {
42
+ if (isPromise$1(result)) {
43
43
  return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(getErrorMessage(err)));
44
44
  }
45
45
  return success(result);
@@ -96,7 +96,7 @@ function goTryRaw(value, options) {
96
96
  };
97
97
  try {
98
98
  const result = typeof value === "function" ? value() : value;
99
- if (isPromise(result)) {
99
+ if (isPromise$1(result)) {
100
100
  return result.then((resolvedValue) => success(resolvedValue)).catch((err) => failure(wrapError(err)));
101
101
  }
102
102
  return success(result);
@@ -108,7 +108,7 @@ function goTryRaw(value, options) {
108
108
  function goTryOr(value, defaultValue) {
109
109
  try {
110
110
  const result = typeof value === "function" ? value() : value;
111
- if (isPromise(result)) {
111
+ if (isPromise$1(result)) {
112
112
  return result.then((resolvedValue) => success(resolvedValue)).catch((err) => [getErrorMessage(err), resolveDefault(defaultValue)]);
113
113
  }
114
114
  return success(result);
@@ -219,4 +219,62 @@ function assert(condition, errorOrClass, message) {
219
219
  }
220
220
  }
221
221
 
222
- export { UnknownError, assert, assertNever, failure, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
222
+ function isPromise(value) {
223
+ return value instanceof Promise;
224
+ }
225
+ function isErrorConstructor(error) {
226
+ return typeof error === "function" && error.prototype !== void 0 && error.prototype instanceof Error;
227
+ }
228
+ function throwError(value, error) {
229
+ if (isErrorConstructor(error)) {
230
+ throw new error(String(value), { cause: value });
231
+ }
232
+ throw error(value);
233
+ }
234
+ function ensure(value, predicate, error = UnknownError) {
235
+ if (typeof value === "function") {
236
+ const result = value();
237
+ if (isPromise(result)) {
238
+ return result.then((resolved) => {
239
+ if (!predicate(resolved)) {
240
+ throwError(resolved, error);
241
+ }
242
+ return resolved;
243
+ });
244
+ }
245
+ if (!predicate(result)) {
246
+ throwError(result, error);
247
+ }
248
+ return result;
249
+ }
250
+ if (isPromise(value)) {
251
+ return value.then((resolved) => {
252
+ if (!predicate(resolved)) {
253
+ throwError(resolved, error);
254
+ }
255
+ return resolved;
256
+ });
257
+ }
258
+ if (!predicate(value)) {
259
+ throwError(value, error);
260
+ }
261
+ return value;
262
+ }
263
+
264
+ function goElse(value, defaultValue) {
265
+ try {
266
+ const result = typeof value === "function" ? value() : value;
267
+ if (isPromise$1(result)) {
268
+ return result.then((resolvedValue) => [void 0, resolvedValue]).catch((err) => {
269
+ const error = err instanceof Error ? err : new Error(String(err));
270
+ return [error, resolveDefault(defaultValue)];
271
+ });
272
+ }
273
+ return [void 0, result];
274
+ } catch (err) {
275
+ const error = err instanceof Error ? err : new Error(String(err));
276
+ return [error, resolveDefault(defaultValue)];
277
+ }
278
+ }
279
+
280
+ export { UnknownError, assert, assertNever, ensure, failure, goTryRaw as go, goTryAllRaw as goAll, goElse, goTry, goTryAll, goTryAllRaw, goTryOr, goTryRaw, isFailure, isSuccess, success, taggedError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "go-go-try",
3
- "version": "7.4.1",
3
+ "version": "8.0.0",
4
4
  "description": "Tries to execute a sync/async function, returns a result tuple",
5
5
  "license": "MIT",
6
6
  "repository": "thelinuxlich/go-go-try",
@@ -0,0 +1,116 @@
1
+ import { describe, test, expect } from 'vitest'
2
+ import { ensure } from './ensure.js'
3
+ import { taggedError } from './tagged-error.js'
4
+ import { UnknownError } from './unknown-error.js'
5
+
6
+ describe('ensure', () => {
7
+ test('returns value when predicate passes', () => {
8
+ const result = ensure(42, (n) => n > 0, () => new Error('negative'))
9
+ expect(result).toBe(42)
10
+ })
11
+
12
+ test('uses UnknownError when error parameter is omitted', () => {
13
+ expect(() => ensure(-1, (n) => n > 0)).toThrow(UnknownError)
14
+ })
15
+
16
+ test('uses UnknownError with async when error parameter is omitted', async () => {
17
+ await expect(ensure(Promise.resolve(-1), (n) => n > 0)).rejects.toThrow(UnknownError)
18
+ })
19
+
20
+ test('returns value when predicate passes with error class', () => {
21
+ const MyError = taggedError('MyError')
22
+ const result = ensure(42, (n) => n > 0, MyError)
23
+ expect(result).toBe(42)
24
+ })
25
+
26
+ test('returns value with complex predicate', () => {
27
+ const result = ensure([1, 2, 3], (arr) => arr.length > 0, () => new Error('empty'))
28
+ expect(result).toEqual([1, 2, 3])
29
+ })
30
+
31
+ test('throws error when predicate fails', () => {
32
+ expect(() => ensure(-1, (n) => n > 0, (n) => new Error(`${n} is negative`))).toThrow('-1 is negative')
33
+ })
34
+
35
+ test('throws with access to value in error factory', () => {
36
+ const obj = { status: 404 }
37
+ expect(() =>
38
+ ensure(
39
+ obj,
40
+ (o) => o.status === 200,
41
+ (o) => new Error(`HTTP ${o.status}`)
42
+ )
43
+ ).toThrow('HTTP 404')
44
+ })
45
+
46
+ test('throws with error class constructor', () => {
47
+ const RequestFailed = taggedError('RequestFailed')
48
+ const obj = { status: 404 }
49
+ expect(() =>
50
+ ensure(
51
+ obj,
52
+ (o: { status: number }) => o.status === 200,
53
+ RequestFailed
54
+ )
55
+ ).toThrow()
56
+ try {
57
+ ensure(obj, (o: { status: number }) => o.status === 200, RequestFailed)
58
+ } catch (e) {
59
+ expect(e).toBeInstanceOf(RequestFailed)
60
+ expect((e as Error & { cause?: unknown }).cause).toBe(obj)
61
+ }
62
+ })
63
+
64
+ test('narrows type when predicate is type guard', () => {
65
+ interface User {
66
+ name: string
67
+ }
68
+ const maybeUser: unknown = { name: 'Alice' }
69
+
70
+ const user = ensure(
71
+ maybeUser as unknown,
72
+ (u): u is User => typeof u === 'object' && u !== null && 'name' in u,
73
+ () => new Error('Not a user')
74
+ )
75
+
76
+ // TypeScript knows this is User, not unknown
77
+ expect((user as User).name).toBe('Alice')
78
+ })
79
+
80
+ test('works with async values (promise passed directly)', async () => {
81
+ const result = await ensure(Promise.resolve(42), (n) => n > 0, () => new Error('negative'))
82
+ expect(result).toBe(42)
83
+ })
84
+
85
+ test('throws with async values when predicate fails', async () => {
86
+ await expect(
87
+ ensure(Promise.resolve(-1), (n) => n > 0, (n) => new Error(`${n} is negative`))
88
+ ).rejects.toThrow('-1 is negative')
89
+ })
90
+
91
+ test('works with sync functions', () => {
92
+ const result = ensure(() => 42, (n) => n > 0, () => new Error('negative'))
93
+ expect(result).toBe(42)
94
+ })
95
+
96
+ test('throws with sync functions when predicate fails', () => {
97
+ expect(() =>
98
+ ensure(() => -1, (n) => n > 0, (n) => new Error(`${n} is negative`))
99
+ ).toThrow('-1 is negative')
100
+ })
101
+
102
+ test('works with async functions', async () => {
103
+ const result = await ensure(
104
+ () => Promise.resolve(42),
105
+ (n) => n > 0,
106
+ () => new Error('negative')
107
+ )
108
+ expect(result).toBe(42)
109
+ })
110
+
111
+ test('throws with async functions when predicate fails', async () => {
112
+ await expect(
113
+ ensure(() => Promise.resolve(-1), (n) => n > 0, (n) => new Error(`${n} is negative`))
114
+ ).rejects.toThrow('-1 is negative')
115
+ })
116
+ })
package/src/ensure.ts ADDED
@@ -0,0 +1,137 @@
1
+ import { UnknownError } from './unknown-error.js'
2
+
3
+ /**
4
+ * Error class constructor type.
5
+ */
6
+ type ErrorConstructor<E extends Error = Error> = new (
7
+ message: string,
8
+ options?: { cause?: unknown },
9
+ ) => E
10
+
11
+ /**
12
+ * Helper to check if value is a Promise.
13
+ */
14
+ function isPromise<T>(value: unknown): value is Promise<T> {
15
+ return value instanceof Promise
16
+ }
17
+
18
+ /**
19
+ * Type guard to check if error is an Error class constructor.
20
+ */
21
+ function isErrorConstructor<E extends Error>(
22
+ error: ErrorConstructor<E> | ((value: unknown) => E) | ((value: never) => E),
23
+ ): error is ErrorConstructor<E> {
24
+ return (
25
+ typeof error === 'function' &&
26
+ error.prototype !== undefined &&
27
+ error.prototype instanceof Error
28
+ )
29
+ }
30
+
31
+ /**
32
+ * Helper to throw error from class or factory.
33
+ */
34
+ function throwError<T, E extends Error>(
35
+ value: T,
36
+ error: ErrorConstructor<E> | ((value: never) => E),
37
+ ): never {
38
+ if (isErrorConstructor(error)) {
39
+ // It's an Error class constructor
40
+ throw new error(String(value), { cause: value })
41
+ }
42
+ // It's a factory function - cast to any to handle type variance
43
+ throw (error as (value: T) => E)(value)
44
+ }
45
+
46
+ /**
47
+ * Ensures a value satisfies a predicate, throwing an error if not.
48
+ * Returns the value if the predicate passes.
49
+ *
50
+ * Accepts sync values, promises, or functions - just like `go`.
51
+ *
52
+ * The error can be either:
53
+ * - An Error class constructor (instantiated with the value as cause)
54
+ * - A function that creates and returns an Error
55
+ * - If omitted, defaults to UnknownError
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * // With sync value (uses UnknownError by default)
60
+ * ensure(42, n => n > 0)
61
+ *
62
+ * // With promise (awaited internally)
63
+ * const res = await ensure(fetch('/api'), r => r.ok, RequestFailedError)
64
+ *
65
+ * // With function
66
+ * const res = ensure(() => parseInt('42'), n => !isNaN(n), Error)
67
+ *
68
+ * // With error factory function
69
+ * const res = ensure(
70
+ * await fetch('/api'),
71
+ * r => r.ok,
72
+ * r => new Error(`HTTP ${r.status}`)
73
+ * )
74
+ * ```
75
+ */
76
+ // Promise overloads first (more specific)
77
+ export function ensure<T>(
78
+ value: Promise<T>,
79
+ predicate: (value: T) => boolean,
80
+ error?: ErrorConstructor<Error> | ((value: T) => Error),
81
+ ): Promise<T>
82
+ // Function returning Promise
83
+ export function ensure<T>(
84
+ fn: () => Promise<T>,
85
+ predicate: (value: T) => boolean,
86
+ error?: ErrorConstructor<Error> | ((value: T) => Error),
87
+ ): Promise<T>
88
+ // Sync function
89
+ export function ensure<T>(
90
+ fn: () => T,
91
+ predicate: (value: T) => boolean,
92
+ error?: ErrorConstructor<Error> | ((value: T) => Error),
93
+ ): T
94
+ // Sync value (catch-all)
95
+ export function ensure<T>(
96
+ value: T,
97
+ predicate: (value: T) => boolean,
98
+ error?: ErrorConstructor<Error> | ((value: T) => Error),
99
+ ): T
100
+ export function ensure<T>(
101
+ value: T | Promise<T> | (() => T | Promise<T>),
102
+ predicate: (value: T) => boolean,
103
+ error: ErrorConstructor<Error> | ((value: T) => Error) = UnknownError,
104
+ ): T | Promise<T> {
105
+ // Handle function
106
+ if (typeof value === 'function') {
107
+ const result = (value as () => T | Promise<T>)()
108
+ if (isPromise<T>(result)) {
109
+ return result.then((resolved) => {
110
+ if (!predicate(resolved)) {
111
+ throwError(resolved, error)
112
+ }
113
+ return resolved
114
+ })
115
+ }
116
+ if (!predicate(result)) {
117
+ throwError(result, error)
118
+ }
119
+ return result
120
+ }
121
+
122
+ // Handle promise
123
+ if (isPromise<T>(value)) {
124
+ return value.then((resolved) => {
125
+ if (!predicate(resolved)) {
126
+ throwError(resolved, error)
127
+ }
128
+ return resolved
129
+ })
130
+ }
131
+
132
+ // Handle sync value
133
+ if (!predicate(value)) {
134
+ throwError(value, error)
135
+ }
136
+ return value
137
+ }
package/src/go.test.ts ADDED
@@ -0,0 +1,107 @@
1
+ import { describe, test, expect } from 'vitest'
2
+ import { go, goAll, goElse } from './index.js'
3
+
4
+ describe('go (alias for goTryRaw)', () => {
5
+ test('returns value on success', async () => {
6
+ const result = await go(Promise.resolve(42))
7
+ expect(result).toEqual([undefined, 42])
8
+ })
9
+
10
+ test('returns error on failure', async () => {
11
+ const error = new Error('oops')
12
+ const result = await go(Promise.reject(error))
13
+ // goTryRaw wraps errors in UnknownError by default
14
+ expect(result[0]).toBeInstanceOf(Error)
15
+ expect(result[0]?.message).toBe('oops')
16
+ expect(result[1]).toBeUndefined()
17
+ })
18
+
19
+ test('works with non-promise values', async () => {
20
+ const result = await go(42)
21
+ expect(result).toEqual([undefined, 42])
22
+ })
23
+
24
+ test('works with sync functions', async () => {
25
+ const result = await go(() => 'hello')
26
+ expect(result).toEqual([undefined, 'hello'])
27
+ })
28
+
29
+ test('catches sync errors', async () => {
30
+ const result = await go(() => {
31
+ throw new Error('sync error')
32
+ })
33
+ expect(result[0]?.message).toBe('sync error')
34
+ expect(result[1]).toBeUndefined()
35
+ })
36
+
37
+ test('is exported from index', () => {
38
+ // Verified by the import at the top of the file
39
+ expect(go).toBeDefined()
40
+ })
41
+ })
42
+
43
+ describe('goAll (alias for goTryAllRaw)', () => {
44
+ test('returns all results', async () => {
45
+ const [errors, results] = await goAll([
46
+ () => Promise.resolve(1),
47
+ () => Promise.resolve(2),
48
+ () => Promise.resolve(3),
49
+ ])
50
+ expect(errors).toEqual([undefined, undefined, undefined])
51
+ expect(results).toEqual([1, 2, 3])
52
+ })
53
+
54
+ test('handles mixed success and failure', async () => {
55
+ const [errors, results] = await goAll([
56
+ () => Promise.resolve(1),
57
+ () => Promise.reject(new Error('failed')),
58
+ () => Promise.resolve(3),
59
+ ])
60
+ expect(errors[0]).toBeUndefined()
61
+ expect(errors[1]).toBeInstanceOf(Error)
62
+ expect(errors[2]).toBeUndefined()
63
+ expect(results).toEqual([1, undefined, 3])
64
+ })
65
+
66
+ test('is exported from index', () => {
67
+ expect(goAll).toBeDefined()
68
+ })
69
+ })
70
+
71
+ describe('goElse', () => {
72
+ test('returns value on success', async () => {
73
+ const [err, value] = await goElse(Promise.resolve(42), 0)
74
+ expect(err).toBeUndefined()
75
+ expect(value).toBe(42)
76
+ })
77
+
78
+ test('returns default on failure with Error object', async () => {
79
+ const originalError = new Error('oops')
80
+ const [err, value] = await goElse(() => Promise.reject(originalError), 'default')
81
+ expect(err).toBeInstanceOf(Error)
82
+ expect(err?.message).toBe('oops')
83
+ expect(value).toBe('default')
84
+ })
85
+
86
+ test('returns default on sync error with Error object', async () => {
87
+ const [err, value] = await goElse(() => {
88
+ throw new Error('sync error')
89
+ }, 'fallback')
90
+ expect(err).toBeInstanceOf(Error)
91
+ expect(err?.message).toBe('sync error')
92
+ expect(value).toBe('fallback')
93
+ })
94
+
95
+ test('wraps non-Error throws in Error', async () => {
96
+ const [err, value] = await goElse(() => {
97
+ throw 'string error'
98
+ }, 'fallback')
99
+ expect(err).toBeInstanceOf(Error)
100
+ expect(err?.message).toBe('string error')
101
+ expect(value).toBe('fallback')
102
+ })
103
+
104
+ test('is exported from index', () => {
105
+ expect(goElse).toBeDefined()
106
+ })
107
+ })
package/src/go.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Alias for goTryRaw - the most common usage of go-go-try.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const [err, data] = await go(fetch('/api'))
7
+ * const [err2, result] = await go(() => computeSomething())
8
+ * ```
9
+ */
10
+ export { goTryRaw as go } from './goTryRaw.js'
11
+
12
+ /**
13
+ * Alias for goTryAllRaw - run multiple operations in parallel.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const results = await goAll([
18
+ * fetch('/api/users'),
19
+ * fetch('/api/posts'),
20
+ * fetch('/api/comments')
21
+ * ])
22
+ * // results is [Result<Error, Response>, Result<Error, Response>, Result<Error, Response>]
23
+ * ```
24
+ */
25
+ export { goTryAllRaw as goAll } from './goTryAll.js'
26
+
27
+ /**
28
+ * Alias for goElse - returns a default value on error.
29
+ * Returns the actual Error object (not just message) on failure.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const [err, data] = await goElse(fetch('/api'), { users: [] })
34
+ * // err is Error | undefined, data is the response or { users: [] }
35
+ * ```
36
+ */
37
+ export { goElse } from './goElse.js'
package/src/goElse.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { isPromise, resolveDefault } from './internals.js'
2
+
3
+ /**
4
+ * Result type with Error and a default value.
5
+ * On error, returns [Error, DefaultT]
6
+ * On success, returns [undefined, T]
7
+ */
8
+ export type ResultWithDefault<E, T, D = T> = readonly [E, D] | readonly [undefined, T]
9
+
10
+ /**
11
+ * Executes a function, promise, or value and returns a Result type with a fallback default.
12
+ * If an error occurs, it returns the actual Error object and the default value.
13
+ *
14
+ * @template T The type of the successful result
15
+ * @template D The type of the default value (defaults to T)
16
+ * @param {T | Promise<T> | (() => T | Promise<T>)} value - The value, promise, or function to execute
17
+ * @param {D | (() => D)} defaultValue - The default value or a function to compute it (only called on failure)
18
+ * @returns {ResultWithDefault<Error, T, D> | Promise<ResultWithDefault<Error, T, D>>} A tuple of [error, value] or Promise thereof
19
+ *
20
+ * @example
21
+ * // With a static default
22
+ * const [err, config] = goElse(() => JSON.parse('invalid'), { port: 3000 })
23
+ * // err is the Error object, config is { port: 3000 }
24
+ *
25
+ * @example
26
+ * // With a computed default (lazy evaluation)
27
+ * const [err, user] = await goElse(fetchUser(id), () => ({
28
+ * id: 'anonymous',
29
+ * name: 'Guest'
30
+ * }))
31
+ */
32
+ export function goElse<T, D = T>(
33
+ fn: () => never,
34
+ defaultValue: D | (() => D),
35
+ ): ResultWithDefault<Error, never, D>
36
+ export function goElse<T, D = T>(
37
+ fn: () => Promise<T>,
38
+ defaultValue: D | (() => D),
39
+ ): Promise<ResultWithDefault<Error, T, D>>
40
+ export function goElse<T, D = T>(
41
+ promise: Promise<T>,
42
+ defaultValue: D | (() => D),
43
+ ): Promise<ResultWithDefault<Error, T, D>>
44
+ export function goElse<T, D = T>(
45
+ fn: () => T,
46
+ defaultValue: D | (() => D),
47
+ ): ResultWithDefault<Error, T, D>
48
+ export function goElse<T, D = T>(
49
+ value: T,
50
+ defaultValue: D | (() => D),
51
+ ): ResultWithDefault<Error, T, D>
52
+ export function goElse<T, D = T>(
53
+ value: T | Promise<T> | (() => T | Promise<T>),
54
+ defaultValue: D | (() => D),
55
+ ): ResultWithDefault<Error, T, D> | Promise<ResultWithDefault<Error, T, D>> {
56
+ try {
57
+ const result =
58
+ typeof value === 'function' ? (value as () => T | Promise<T>)() : value
59
+
60
+ if (isPromise<T>(result)) {
61
+ return result
62
+ .then((resolvedValue): ResultWithDefault<Error, T, D> => [undefined, resolvedValue])
63
+ .catch((err): ResultWithDefault<Error, T, D> => {
64
+ const error = err instanceof Error ? err : new Error(String(err))
65
+ return [error, resolveDefault(defaultValue)]
66
+ })
67
+ }
68
+
69
+ return [undefined, result]
70
+ } catch (err) {
71
+ const error = err instanceof Error ? err : new Error(String(err))
72
+ return [error, resolveDefault(defaultValue)]
73
+ }
74
+ }
package/src/index.ts CHANGED
@@ -22,7 +22,11 @@ export { goTryAll, goTryAllRaw } from './goTryAll.js'
22
22
  // Export helper functions
23
23
  export { taggedError } from './tagged-error.js'
24
24
  export { assert } from './assert.js'
25
+ export { ensure } from './ensure.js'
25
26
  export { isSuccess, isFailure, success, failure, assertNever } from './result-helpers.js'
26
27
 
27
28
  // Export UnknownError tagged error
28
29
  export { UnknownError } from './unknown-error.js'
30
+
31
+ // Export go aliases
32
+ export { go, goAll, goElse } from './go.js'