errore 0.9.0 → 0.10.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 CHANGED
@@ -4,13 +4,20 @@ Type-safe errors as values for TypeScript. Like Go, but with full type inference
4
4
 
5
5
  ## Why?
6
6
 
7
- Instead of wrapping values in a `Result<T, E>` type, functions simply return `E | T`. TypeScript's type narrowing handles the rest:
7
+ Instead of wrapping values in a `Result<T, E>` type, functions simply return `E | T`. TypeScript's **type narrowing** handles the rest:
8
8
 
9
9
  ```ts
10
10
  // Go-style: errors as values
11
- const user = await fetchUser(id)
12
- if (user instanceof Error) return user // TypeScript narrows type
13
- console.log(user.name) // user is now User, not Error | User
11
+ const user = await getUser(id)
12
+ if (user instanceof NotFoundError) {
13
+ console.error('Missing:', user.id)
14
+ return
15
+ }
16
+ if (user instanceof DbError) {
17
+ console.error('DB failed:', user.reason)
18
+ return
19
+ }
20
+ console.log(user.username) // user is User, fully narrowed
14
21
  ```
15
22
 
16
23
  ## Install
@@ -21,6 +28,8 @@ npm install errore
21
28
 
22
29
  ## Quick Start
23
30
 
31
+ Define typed errors with **variable interpolation** and return **Error or Value** directly:
32
+
24
33
  ```ts
25
34
  import * as errore from 'errore'
26
35
 
@@ -67,7 +76,7 @@ console.log(user.name)
67
76
 
68
77
  ## Example: API Error Handling
69
78
 
70
- A complete example with custom base class, HTTP status codes, and error reporting:
79
+ A complete example with **custom base class** and HTTP status codes:
71
80
 
72
81
  ```ts
73
82
  import * as errore from 'errore'
@@ -139,7 +148,7 @@ app.post('/users/:id', async (req, res) => {
139
148
 
140
149
  ### createTaggedError
141
150
 
142
- Create typed errors with `$variable` interpolation in the message:
151
+ Create typed errors with **variable interpolation** in the message:
143
152
 
144
153
  ```ts
145
154
  import * as errore from 'errore'
@@ -186,8 +195,136 @@ err.statusCode // 500 (inherited from AppError)
186
195
  err instanceof AppError // true
187
196
  ```
188
197
 
198
+ ### Error Wrapping and Context
199
+
200
+ Wrap errors with additional context while **preserving the original error** via `cause`:
201
+
202
+ ```ts
203
+ // Wrap with context, preserve original in cause
204
+ async function processUser(id: string): Promise<ServiceError | ProcessedUser> {
205
+ const user = await getUser(id) // returns NotFoundError | User
206
+
207
+ if (user instanceof Error) {
208
+ return new ServiceError({ id, cause: user })
209
+ }
210
+
211
+ return process(user)
212
+ }
213
+
214
+ // Access original error via cause
215
+ const result = await processUser('123')
216
+ if (result instanceof Error) {
217
+ console.log(result.message) // "Failed to process user 123"
218
+
219
+ if (result.cause instanceof NotFoundError) {
220
+ console.log(result.cause.id) // access original error's properties
221
+ }
222
+ }
223
+ ```
224
+
225
+ The error definitions:
226
+
227
+ ```ts
228
+ class NotFoundError extends errore.createTaggedError({
229
+ name: 'NotFoundError',
230
+ message: 'User $id not found'
231
+ }) {}
232
+
233
+ class ServiceError extends errore.createTaggedError({
234
+ name: 'ServiceError',
235
+ message: 'Failed to process user $id'
236
+ }) {}
237
+ ```
238
+
239
+ **Browser console** prints the full cause chain:
240
+
241
+ ```
242
+ ServiceError: Failed to process user 123
243
+ at processUser (app.js:12)
244
+ at main (app.js:20)
245
+ Caused by: NotFoundError: User 123 not found
246
+ at getUser (app.js:5)
247
+ at processUser (app.js:8)
248
+ ```
249
+
250
+ ### findCause
251
+
252
+ Walk the `.cause` chain to find an ancestor matching a specific error class. Similar to Go's `errors.As` — checks the error itself first, then traverses `.cause` recursively:
253
+
254
+ ```ts
255
+ import * as errore from 'errore'
256
+
257
+ class NotFoundError extends errore.createTaggedError({
258
+ name: 'NotFoundError',
259
+ message: 'User $id not found'
260
+ }) {}
261
+
262
+ class ServiceError extends errore.createTaggedError({
263
+ name: 'ServiceError',
264
+ message: 'Failed to process user $id'
265
+ }) {}
266
+
267
+ // Deep chain: ServiceError -> NotFoundError
268
+ const notFound = new NotFoundError({ id: '123' })
269
+ const service = new ServiceError({ id: '123', cause: notFound })
270
+
271
+ // Instance method on tagged errors
272
+ const found = service.findCause(NotFoundError)
273
+ found?.id // '123' — type-safe access
274
+
275
+ // Standalone function for any Error
276
+ const found2 = errore.findCause(service, NotFoundError)
277
+ found2?.id // '123'
278
+ ```
279
+
280
+ This solves the problem where `result.cause instanceof MyError` only checks one level deep. `findCause` walks the entire chain:
281
+
282
+ ```ts
283
+ // A -> B -> C chain
284
+ const c = new DbError({ message: 'connection reset' })
285
+ const b = new ServiceError({ id: '123', cause: c })
286
+ const a = new ApiError({ message: 'request failed', cause: b })
287
+
288
+ // Manual check only finds B
289
+ a.cause instanceof DbError // false — only checks one level
290
+
291
+ // findCause walks the full chain
292
+ a.findCause(DbError) // finds C ✓
293
+ ```
294
+
295
+ Returns `undefined` if no matching ancestor is found. Safe against circular `.cause` references.
296
+
297
+ ### Custom Base Class with `extends`
298
+
299
+ Use `extends` to inherit from a custom base class. The error will pass `instanceof` for both the base class and the specific error class:
300
+
301
+ ```ts
302
+ class AppError extends Error {
303
+ statusCode = 500
304
+ toResponse() { return { error: this.message, code: this.statusCode } }
305
+ }
306
+
307
+ class NotFoundError extends errore.createTaggedError({
308
+ name: 'NotFoundError',
309
+ message: 'Resource $id not found',
310
+ extends: AppError
311
+ }) {
312
+ statusCode = 404
313
+ }
314
+
315
+ const err = new NotFoundError({ id: '123' })
316
+ err instanceof NotFoundError // true
317
+ err instanceof AppError // true
318
+ err instanceof Error // true
319
+
320
+ err.statusCode // 404
321
+ err.toResponse() // { error: 'Resource 123 not found', code: 404 }
322
+ ```
323
+
189
324
  ### Type Guards
190
325
 
326
+ Use **instanceof checks** to narrow union types:
327
+
191
328
  ```ts
192
329
  const result: NetworkError | User = await fetchUser(id)
193
330
 
@@ -200,14 +337,16 @@ if (result instanceof Error) {
200
337
 
201
338
  ### Try Functions
202
339
 
340
+ **Wrap exceptions** as error values:
341
+
203
342
  ```ts
204
343
  import * as errore from 'errore'
205
344
 
206
345
  // Sync - wraps exceptions in UnhandledError
207
- const parsed = errore.tryFn(() => JSON.parse(input))
346
+ const parsed = errore.try(() => JSON.parse(input))
208
347
 
209
348
  // Sync - with custom error type
210
- const parsed = errore.tryFn({
349
+ const parsed = errore.try({
211
350
  try: () => JSON.parse(input),
212
351
  catch: e => new ParseError({ reason: e.message, cause: e })
213
352
  })
@@ -224,6 +363,8 @@ const response = await errore.tryAsync({
224
363
 
225
364
  ### Transformations
226
365
 
366
+ **Transform and chain** operations:
367
+
227
368
  ```ts
228
369
  import * as errore from 'errore'
229
370
 
@@ -242,6 +383,8 @@ const logged = errore.tap(user, u => console.log('Got user:', u.name))
242
383
 
243
384
  ### Extraction
244
385
 
386
+ **Extract values** or throw, **split arrays** by success/error:
387
+
245
388
  ```ts
246
389
  import * as errore from 'errore'
247
390
 
@@ -264,7 +407,7 @@ const [users, errors] = errore.partition(results)
264
407
 
265
408
  ### Error Matching
266
409
 
267
- Always assign `matchError` results to a variable. Keep callbacks pure (return values only) and move side effects outside:
410
+ **Exhaustive pattern matching** with `matchError`. Always assign results to a variable and keep callbacks pure:
268
411
 
269
412
  ```ts
270
413
  import * as errore from 'errore'
@@ -298,7 +441,7 @@ ValidationError.is(value) // specific class
298
441
 
299
442
  ## How Type Safety Works
300
443
 
301
- TypeScript narrows types after `instanceof Error` checks:
444
+ TypeScript **narrows types** after `instanceof Error` checks:
302
445
 
303
446
  ```ts
304
447
  function example(result: NetworkError | User): string {
@@ -318,7 +461,7 @@ This works because:
318
461
 
319
462
  ## Result + Option Combined: `Error | T | null`
320
463
 
321
- One of errore's best features: you can naturally combine error handling with optional values. No wrapper nesting needed!
464
+ Naturally combine **error handling with optional values**. No wrapper nesting needed!
322
465
 
323
466
  ```ts
324
467
  import * as errore from 'errore'
@@ -362,14 +505,80 @@ console.log(user.name)
362
505
  | Zig | `!?T` (error union + optional) | Yes, specific syntax |
363
506
  | **errore** | `Error \| T \| null` | **No!** Check in any order |
364
507
 
365
- With errore:
508
+ With errore you **check in any order**:
366
509
  - Use `?.` and `??` naturally
367
510
  - Check `instanceof Error` or `=== null` in any order
368
511
  - No unwrapping ceremony
369
512
  - TypeScript infers everything
370
513
 
514
+ ## Why This Is Better Than Go
515
+
516
+ Go's error handling uses **two separate return values**:
517
+
518
+ ```go
519
+ user, err := fetchUser(id)
520
+ // Oops! Forgot to check err
521
+ fmt.Println(user.Name) // Compiles fine, crashes at runtime
522
+ ```
523
+
524
+ The compiler can't save you here. You can ignore `err` entirely and use `user` directly.
525
+
526
+ With errore, **forgetting to check is impossible**:
527
+
528
+ ```ts
529
+ const user = await fetchUser(id) // type: NotFoundError | User
530
+
531
+ console.log(user.id) // TS Error: Property 'id' does not exist on type 'NotFoundError'
532
+ ```
533
+
534
+ Since errore uses a **single union variable** instead of two separate values, TypeScript forces you to narrow the type before accessing value-specific properties. You literally cannot use the value without first doing an `instanceof Error` check.
535
+
536
+ > **Note:** Properties that exist on both `Error` and your value type (like `name`, `message`) can still be accessed without narrowing. This is a small set of 4 fields: `name`, `message`, `stack`, `cause`.
537
+
538
+ ### The Remaining Gap
539
+
540
+ There's still one case errore can't catch: **ignored return values**:
541
+
542
+ ```ts
543
+ // Oops! Completely ignoring the return value
544
+ updateUser(id, data) // No error, but we should check!
545
+ ```
546
+
547
+ For this, use **TypeScript's built-in checks** or a linter:
548
+
549
+ **TypeScript `tsconfig.json`:**
550
+ ```json
551
+ {
552
+ "compilerOptions": {
553
+ "noUnusedLocals": true
554
+ }
555
+ }
556
+ ```
557
+
558
+ This catches unused variables, though not ignored return values directly.
559
+
560
+ **oxlint `no-unused-expressions`:**
561
+
562
+ `oxlint.json`:
563
+ ```json
564
+ {
565
+ "rules": {
566
+ "no-unused-expressions": "error"
567
+ }
568
+ }
569
+ ```
570
+
571
+ Or via CLI:
572
+ ```bash
573
+ oxlint --deny no-unused-expressions
574
+ ```
575
+
576
+ Combined with errore's type safety, these tools give you near-complete protection against ignored errors.
577
+
371
578
  ## Comparison with Result Types
372
579
 
580
+ **Direct returns** vs wrapper methods:
581
+
373
582
  | Result Pattern | errore |
374
583
  |---------------|--------|
375
584
  | `Result.ok(value)` | just `return value` |
@@ -379,9 +588,150 @@ With errore:
379
588
  | `Result<User, Error>` | `Error \| User` |
380
589
  | `Result<Option<T>, E>` | `Error \| T \| null` |
381
590
 
591
+ ## Vs neverthrow / better-result
592
+
593
+ These libraries wrap values in a **Result container**. You construct results with `ok()` and `err()`, then unwrap them with `.value` and `.error`:
594
+
595
+ ```ts
596
+ // neverthrow
597
+ import { ok, err, Result } from 'neverthrow'
598
+
599
+ function getUser(id: string): Result<User, NotFoundError> {
600
+ const user = db.find(id)
601
+ if (!user) return err(new NotFoundError({ id }))
602
+ return ok(user) // must wrap
603
+ }
604
+
605
+ const result = getUser('123')
606
+ if (result.isErr()) {
607
+ console.log(result.error) // must unwrap
608
+ return
609
+ }
610
+ console.log(result.value.name) // must unwrap
611
+ ```
612
+
613
+ ```ts
614
+ // errore
615
+ function getUser(id: string): User | NotFoundError {
616
+ const user = db.find(id)
617
+ if (!user) return new NotFoundError({ id })
618
+ return user // just return
619
+ }
620
+
621
+ const user = getUser('123')
622
+ if (user instanceof Error) {
623
+ console.log(user) // it's already the error
624
+ return
625
+ }
626
+ console.log(user.name) // it's already the user
627
+ ```
628
+
629
+ **The key insight**: `T | Error` already encodes success/failure. TypeScript's type narrowing does the rest. No wrapper needed.
630
+
631
+ | Feature | neverthrow | errore |
632
+ |---------|------------|--------|
633
+ | Type-safe errors | ✓ | ✓ |
634
+ | Exhaustive handling | ✓ | ✓ |
635
+ | Works with null | `Result<T \| null, E>` | `T \| E \| null` |
636
+ | Learning curve | New API (`ok`, `err`, `map`, `andThen`, ...) | Just `instanceof` |
637
+ | Bundle size | ~3KB min | **~0 bytes** |
638
+ | Interop | Requires wrapping/unwrapping at boundaries | Native TypeScript |
639
+
640
+ neverthrow also requires an [eslint plugin](https://github.com/mdbetancourt/eslint-plugin-neverthrow) to catch unhandled results. With errore, TypeScript itself prevents you from using a value without checking the error first.
641
+
642
+ ## Vs Effect.ts
643
+
644
+ Effect is not just error handling—it's a **complete functional programming framework** with dependency injection, concurrency primitives, resource management, streaming, and more.
645
+
646
+ ```ts
647
+ // Effect.ts - a paradigm shift
648
+ import { Effect, pipe } from 'effect'
649
+
650
+ const program = pipe(
651
+ fetchUser(id),
652
+ Effect.flatMap(user => fetchPosts(user.id)),
653
+ Effect.map(posts => posts.filter(p => p.published)),
654
+ Effect.catchTag('NotFoundError', () => Effect.succeed([]))
655
+ )
656
+
657
+ const result = await Effect.runPromise(program)
658
+ ```
659
+
660
+ ```ts
661
+ // errore - regular TypeScript
662
+ const user = await fetchUser(id)
663
+ if (user instanceof Error) return []
664
+
665
+ const posts = await fetchPosts(user.id)
666
+ if (posts instanceof Error) return []
667
+
668
+ return posts.filter(p => p.published)
669
+ ```
670
+
671
+ Effect is powerful if you need its full feature set. But if you just want type-safe errors:
672
+
673
+ | | Effect | errore |
674
+ |-|--------|--------|
675
+ | Learning curve | Steep (new paradigm) | Minimal (just `instanceof`) |
676
+ | Codebase impact | Pervasive (everything becomes an Effect) | Surgical (adopt incrementally) |
677
+ | Bundle size | ~50KB+ | **~0 bytes** |
678
+ | Use case | Full FP framework | Just error handling |
679
+
680
+ **Use Effect** when you want dependency injection, structured concurrency, and the full functional programming experience.
681
+
682
+ **Use errore** when you just want type-safe errors without rewriting your codebase.
683
+
684
+ ## Zero-Dependency Philosophy
685
+
686
+ errore is more a **way of writing code** than a library. The core pattern requires nothing:
687
+
688
+ ```ts
689
+ // You can write this without installing errore at all
690
+ class NotFoundError extends Error {
691
+ readonly _tag = 'NotFoundError'
692
+ constructor(public id: string) {
693
+ super(`User ${id} not found`)
694
+ }
695
+ }
696
+
697
+ async function getUser(id: string): Promise<User | NotFoundError> {
698
+ const user = await db.find(id)
699
+ if (!user) return new NotFoundError(id)
700
+ return user
701
+ }
702
+
703
+ const user = await getUser('123')
704
+ if (user instanceof Error) return user
705
+ console.log(user.name)
706
+ ```
707
+
708
+ The `errore` package just provides conveniences: `createTaggedError` for less boilerplate, `matchError` for exhaustive pattern matching, `tryAsync` for catching exceptions. But the core pattern—**errors as union types**—works with zero dependencies.
709
+
710
+ ### Perfect for Libraries
711
+
712
+ Ideal for library authors. Return **plain TypeScript unions** instead of forcing users to adopt your error handling framework:
713
+
714
+ ```ts
715
+ // ❌ Library that forces a dependency on users
716
+ import { Result } from 'some-result-lib'
717
+ export function parse(input: string): Result<AST, ParseError>
718
+
719
+ // Users must now install and learn 'some-result-lib'
720
+ ```
721
+
722
+ ```ts
723
+ // ✓ Library using plain TypeScript unions
724
+ export function parse(input: string): AST | ParseError
725
+
726
+ // Users handle errors with standard instanceof checks
727
+ // No new dependencies, no new concepts to learn
728
+ ```
729
+
730
+ Your library stays lightweight. Users get type-safe errors without adopting an opinionated wrapper. Everyone wins.
731
+
382
732
  ## Import Style
383
733
 
384
- > **Note:** Always use `import * as errore from 'errore'` instead of named imports. This makes code easier to move between files, and more readable for people unfamiliar with errore since every function call is clearly namespaced (e.g. `errore.isOk()` instead of just `isOk()`).
734
+ > **Note:** Always use `import * as errore from 'errore'` instead of named imports. This makes code easier to move between files, and more readable since every function call is **clearly namespaced** (e.g. `errore.isOk()` instead of just `isOk()`).
385
735
 
386
736
  ## License
387
737
 
package/dist/error.d.ts CHANGED
@@ -1,3 +1,19 @@
1
+ /**
2
+ * Walk the .cause chain of an error to find an ancestor matching a specific error class.
3
+ * Checks the error itself first, then traverses .cause recursively.
4
+ * Similar to Go's `errors.As`.
5
+ *
6
+ * @example
7
+ * const notFound = findCause(err, NotFoundError)
8
+ * if (notFound) {
9
+ * console.log(notFound.id) // type-safe access
10
+ * }
11
+ *
12
+ * @example
13
+ * // With optional chaining
14
+ * const id = findCause(err, NotFoundError)?.id
15
+ */
16
+ export declare function findCause<T extends Error>(error: Error, ErrorClass: new (...args: any[]) => T): T | undefined;
1
17
  /**
2
18
  * Any tagged error (for generic constraints)
3
19
  */
@@ -14,6 +30,8 @@ type ErrorClass = new (...args: any[]) => Error;
14
30
  export type TaggedErrorInstance<Tag extends string, Props, Base extends Error = Error> = Base & {
15
31
  readonly _tag: Tag;
16
32
  toJSON(): object;
33
+ /** Walk the .cause chain to find an ancestor matching a specific error class. */
34
+ findCause<T extends Error>(ErrorClass: new (...args: any[]) => T): T | undefined;
17
35
  } & Readonly<Props>;
18
36
  /**
19
37
  * Class type produced by TaggedError factory
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
package/dist/error.js CHANGED
@@ -7,6 +7,34 @@ const serializeCause = (cause) => {
7
7
  }
8
8
  return cause;
9
9
  };
10
+ /**
11
+ * Walk the .cause chain of an error to find an ancestor matching a specific error class.
12
+ * Checks the error itself first, then traverses .cause recursively.
13
+ * Similar to Go's `errors.As`.
14
+ *
15
+ * @example
16
+ * const notFound = findCause(err, NotFoundError)
17
+ * if (notFound) {
18
+ * console.log(notFound.id) // type-safe access
19
+ * }
20
+ *
21
+ * @example
22
+ * // With optional chaining
23
+ * const id = findCause(err, NotFoundError)?.id
24
+ */
25
+ export function findCause(error, ErrorClass) {
26
+ const seen = new Set();
27
+ let current = error;
28
+ while (current instanceof Error) {
29
+ if (seen.has(current))
30
+ break;
31
+ seen.add(current);
32
+ if (current instanceof ErrorClass)
33
+ return current;
34
+ current = current.cause;
35
+ }
36
+ return undefined;
37
+ }
10
38
  /**
11
39
  * Type guard for any tagged error
12
40
  */
@@ -71,6 +99,9 @@ export const TaggedError = Object.assign((tag, BaseClass) => () => {
71
99
  this.stack = `${this.stack}\nCaused by: ${indented}`;
72
100
  }
73
101
  }
102
+ findCause(ErrorClass) {
103
+ return findCause(this, ErrorClass);
104
+ }
74
105
  toJSON() {
75
106
  return {
76
107
  ...this,
package/dist/factory.d.ts CHANGED
@@ -62,6 +62,8 @@ export type FactoryTaggedErrorInstance<Tag extends string, Msg extends string, B
62
62
  readonly _tag: Tag;
63
63
  readonly message: string;
64
64
  toJSON(): object;
65
+ /** Walk the .cause chain to find an ancestor matching a specific error class. */
66
+ findCause<T extends Error>(ErrorClass: new (...args: any[]) => T): T | undefined;
65
67
  } & Readonly<VarProps<Msg>>;
66
68
  /**
67
69
  * Class type returned by createTaggedError factory.
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
package/dist/factory.js CHANGED
@@ -1,21 +1,4 @@
1
- /**
2
- * Factory API for creating tagged errors with $variable interpolation in messages.
3
- *
4
- * Extracts variable names from the message template and requires them in the constructor.
5
- * Use `class X extends createTaggedError({...}) {}` so X is both a value and a type.
6
- *
7
- * @example
8
- * class NotFoundError extends createTaggedError({
9
- * name: 'NotFoundError',
10
- * message: 'User $id not found in $database'
11
- * }) {}
12
- *
13
- * throw new NotFoundError({ id: '123', database: 'users' })
14
- * // err._tag = 'NotFoundError'
15
- * // err.message = 'User 123 not found in users'
16
- * // err.id = '123'
17
- * // err.database = 'users'
18
- */
1
+ import { findCause } from './error.js';
19
2
  /**
20
3
  * Serialize cause for JSON output
21
4
  */
@@ -143,6 +126,9 @@ export function createTaggedError(opts) {
143
126
  this.stack = `${this.stack}\nCaused by: ${indented}`;
144
127
  }
145
128
  }
129
+ findCause(ErrorClass) {
130
+ return findCause(this, ErrorClass);
131
+ }
146
132
  toJSON() {
147
133
  const json = {
148
134
  _tag: this._tag,
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export type { Errore, InferError, InferValue, EnsureNotError } from './types.js'
2
2
  export { isError, isOk, tryFn, tryFn as try, tryAsync } from './core.js';
3
3
  export { map, mapError, andThen, andThenAsync, tap, tapAsync } from './transform.js';
4
4
  export { unwrap, unwrapOr, match, partition, flatten } from './extract.js';
5
- export { TaggedError, matchError, matchErrorPartial, isTaggedError, UnhandledError } from './error.js';
5
+ export { TaggedError, matchError, matchErrorPartial, isTaggedError, UnhandledError, findCause } from './error.js';
6
6
  export type { TaggedErrorInstance, TaggedErrorClass } from './error.js';
7
7
  export { createTaggedError } from './factory.js';
8
8
  export type { FactoryTaggedErrorClass, FactoryTaggedErrorInstance } from './factory.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGhF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGxE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGpF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG1E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AACtG,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,YAAY,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGhF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAGxE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGpF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG1E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACjH,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,YAAY,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js CHANGED
@@ -5,6 +5,6 @@ export { map, mapError, andThen, andThenAsync, tap, tapAsync } from './transform
5
5
  // Extraction
6
6
  export { unwrap, unwrapOr, match, partition, flatten } from './extract.js';
7
7
  // Tagged errors
8
- export { TaggedError, matchError, matchErrorPartial, isTaggedError, UnhandledError } from './error.js';
8
+ export { TaggedError, matchError, matchErrorPartial, isTaggedError, UnhandledError, findCause } from './error.js';
9
9
  // Factory API for tagged errors with $variable interpolation
10
10
  export { createTaggedError } from './factory.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}