errore 0.8.1 → 0.8.2

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/core.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { UnhandledError } from './error.js';
2
+ /**
3
+ * Type guard: checks if value is an Error.
4
+ * After this check, TypeScript narrows the type to the error types in the union.
5
+ *
6
+ * @example
7
+ * const result = await fetchUser(id)
8
+ * if (isError(result)) {
9
+ * // result is narrowed to the error type
10
+ * return result
11
+ * }
12
+ * // result is narrowed to User
13
+ * console.log(result.name)
14
+ */
15
+ export declare function isError<V>(value: V): value is Extract<V, Error>;
16
+ /**
17
+ * Type guard: checks if value is NOT an Error.
18
+ * Inverse of isError for convenience.
19
+ *
20
+ * @example
21
+ * const result = await fetchUser(id)
22
+ * if (isOk(result)) {
23
+ * console.log(result.name) // result is User
24
+ * }
25
+ */
26
+ export declare function isOk<V>(value: V): value is Exclude<V, Error>;
27
+ /**
28
+ * Execute a sync function and return either the value or an error.
29
+ *
30
+ * @overload Simple form - wraps exceptions in UnhandledError
31
+ * @example
32
+ * const result = tryFn(() => JSON.parse(input))
33
+ * // result: UnhandledError | unknown
34
+ *
35
+ * @overload With custom catch - you control the error type
36
+ * @example
37
+ * const result = tryFn({
38
+ * try: () => JSON.parse(input),
39
+ * catch: (e) => new ParseError({ cause: e })
40
+ * })
41
+ * // result: ParseError | unknown
42
+ */
43
+ export declare function tryFn<T>(fn: () => T): UnhandledError | T;
44
+ export declare function tryFn<T, E extends Error>(opts: {
45
+ try: () => T;
46
+ catch: (e: unknown) => E;
47
+ }): E | T;
48
+ /**
49
+ * Execute an async function and return either the value or an error.
50
+ *
51
+ * @overload Simple form - wraps exceptions in UnhandledError
52
+ * @example
53
+ * const result = await tryAsync(() => fetch(url).then(r => r.json()))
54
+ * // result: UnhandledError | unknown
55
+ *
56
+ * @overload With custom catch - you control the error type
57
+ * @example
58
+ * const result = await tryAsync({
59
+ * try: () => fetch(url),
60
+ * catch: (e) => new NetworkError({ cause: e })
61
+ * })
62
+ * // result: NetworkError | Response
63
+ */
64
+ export declare function tryAsync<T>(fn: () => Promise<T>): Promise<UnhandledError | T>;
65
+ export declare function tryAsync<T, E extends Error>(opts: {
66
+ try: () => Promise<T>;
67
+ catch: (e: unknown) => E | Promise<E>;
68
+ }): Promise<E | T>;
69
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAE/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAE5D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,cAAc,GAAG,CAAC,CAAA;AACzD,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,CAAC,CAAA;AAmBlG;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,cAAc,GAAG,CAAC,CAAC,CAAA;AAC9E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE;IACjD,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;IACrB,KAAK,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACtC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA"}
package/dist/core.js ADDED
@@ -0,0 +1,62 @@
1
+ import { UnhandledError } from './error.js';
2
+ /**
3
+ * Type guard: checks if value is an Error.
4
+ * After this check, TypeScript narrows the type to the error types in the union.
5
+ *
6
+ * @example
7
+ * const result = await fetchUser(id)
8
+ * if (isError(result)) {
9
+ * // result is narrowed to the error type
10
+ * return result
11
+ * }
12
+ * // result is narrowed to User
13
+ * console.log(result.name)
14
+ */
15
+ export function isError(value) {
16
+ return value instanceof Error;
17
+ }
18
+ /**
19
+ * Type guard: checks if value is NOT an Error.
20
+ * Inverse of isError for convenience.
21
+ *
22
+ * @example
23
+ * const result = await fetchUser(id)
24
+ * if (isOk(result)) {
25
+ * console.log(result.name) // result is User
26
+ * }
27
+ */
28
+ export function isOk(value) {
29
+ return !(value instanceof Error);
30
+ }
31
+ export function tryFn(fnOrOpts) {
32
+ if (typeof fnOrOpts === 'function') {
33
+ try {
34
+ return fnOrOpts();
35
+ }
36
+ catch (cause) {
37
+ return new UnhandledError({ cause });
38
+ }
39
+ }
40
+ try {
41
+ return fnOrOpts.try();
42
+ }
43
+ catch (cause) {
44
+ return fnOrOpts.catch(cause);
45
+ }
46
+ }
47
+ export async function tryAsync(fnOrOpts) {
48
+ if (typeof fnOrOpts === 'function') {
49
+ try {
50
+ return await fnOrOpts();
51
+ }
52
+ catch (cause) {
53
+ return new UnhandledError({ cause });
54
+ }
55
+ }
56
+ try {
57
+ return await fnOrOpts.try();
58
+ }
59
+ catch (cause) {
60
+ return await fnOrOpts.catch(cause);
61
+ }
62
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Any tagged error (for generic constraints)
3
+ */
4
+ type AnyTaggedError = Error & {
5
+ readonly _tag: string;
6
+ };
7
+ /**
8
+ * Any class that extends Error
9
+ */
10
+ type ErrorClass = new (...args: any[]) => Error;
11
+ /**
12
+ * Instance type produced by TaggedError factory
13
+ */
14
+ export type TaggedErrorInstance<Tag extends string, Props, Base extends Error = Error> = Base & {
15
+ readonly _tag: Tag;
16
+ toJSON(): object;
17
+ } & Readonly<Props>;
18
+ /**
19
+ * Class type produced by TaggedError factory
20
+ */
21
+ export type TaggedErrorClass<Tag extends string, Props, Base extends Error = Error> = {
22
+ new (...args: keyof Props extends never ? [args?: {}] : [args: Props]): TaggedErrorInstance<Tag, Props, Base>;
23
+ /** Type guard for this error class */
24
+ is(value: unknown): value is TaggedErrorInstance<Tag, Props, Base>;
25
+ };
26
+ /**
27
+ * Factory for tagged error classes with discriminated _tag property.
28
+ * Enables exhaustive pattern matching on error unions.
29
+ *
30
+ * @example
31
+ * class NotFoundError extends TaggedError("NotFoundError")<{
32
+ * id: string;
33
+ * message: string;
34
+ * }>() {}
35
+ *
36
+ * const err = new NotFoundError({ id: "123", message: "Not found" });
37
+ * err._tag // "NotFoundError"
38
+ * err.id // "123"
39
+ *
40
+ * // Type guard
41
+ * NotFoundError.is(err) // true
42
+ * TaggedError.is(err) // true (any tagged error)
43
+ *
44
+ * @example
45
+ * // With custom base class
46
+ * class AppError extends Error {
47
+ * statusCode: number = 500
48
+ * report() { console.log(this.message) }
49
+ * }
50
+ *
51
+ * class NotFoundError extends TaggedError("NotFoundError", AppError)<{
52
+ * id: string;
53
+ * message: string;
54
+ * }>() {
55
+ * statusCode = 404
56
+ * }
57
+ *
58
+ * const err = new NotFoundError({ id: "123", message: "Not found" });
59
+ * err.statusCode // 404
60
+ * err.report() // works
61
+ */
62
+ export declare const TaggedError: {
63
+ <Tag extends string, BaseClass extends ErrorClass = typeof Error>(tag: Tag, BaseClass?: BaseClass): <Props extends Record<string, unknown> = {}>() => TaggedErrorClass<Tag, Props, InstanceType<BaseClass>>;
64
+ /** Type guard for any TaggedError instance */
65
+ is(value: unknown): value is AnyTaggedError;
66
+ };
67
+ /**
68
+ * Type guard for tagged error instances.
69
+ *
70
+ * @example
71
+ * if (isTaggedError(value)) { value._tag }
72
+ */
73
+ export declare const isTaggedError: (value: unknown) => value is AnyTaggedError;
74
+ /**
75
+ * Handler map that includes `_` for plain Error (untagged)
76
+ */
77
+ type MatchHandlersWithPlain<E extends Error, R> = {
78
+ [K in Extract<E, AnyTaggedError>['_tag']]: (err: Extract<E, {
79
+ _tag: K;
80
+ }>) => R;
81
+ } & (Exclude<E, AnyTaggedError> extends never ? {} : {
82
+ _: (err: Exclude<E, AnyTaggedError>) => R;
83
+ });
84
+ /**
85
+ * Exhaustive pattern match on error union by _tag.
86
+ * Use `_` handler for plain Error instances without _tag.
87
+ *
88
+ * @example
89
+ * // Tagged errors only
90
+ * matchError(err, {
91
+ * NotFoundError: (e) => `Missing: ${e.id}`,
92
+ * ValidationError: (e) => `Invalid: ${e.field}`,
93
+ * });
94
+ *
95
+ * @example
96
+ * // Mixed tagged and plain Error
97
+ * matchError(err, {
98
+ * NotFoundError: (e) => `Missing: ${e.id}`,
99
+ * _: (e) => `Unknown error: ${e.message}`,
100
+ * });
101
+ */
102
+ export declare function matchError<E extends Error, R>(err: E, handlers: MatchHandlersWithPlain<E, R>): R;
103
+ /**
104
+ * Partial pattern match with fallback for unhandled tags.
105
+ *
106
+ * @example
107
+ * matchErrorPartial(err, {
108
+ * NotFoundError: (e) => `Missing: ${e.id}`,
109
+ * }, (e) => `Unknown: ${e.message}`);
110
+ */
111
+ export declare function matchErrorPartial<E extends Error, R>(err: E, handlers: Partial<MatchHandlersWithPlain<E, R>>, fallback: (e: E) => R): R;
112
+ declare const UnhandledError_base: TaggedErrorClass<"UnhandledError", {
113
+ message: string;
114
+ cause: unknown;
115
+ }, Error>;
116
+ /**
117
+ * Default error type when catching unknown exceptions.
118
+ */
119
+ export declare class UnhandledError extends UnhandledError_base {
120
+ constructor(args: {
121
+ cause: unknown;
122
+ });
123
+ }
124
+ export {};
125
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
package/dist/error.js ADDED
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Serialize cause for JSON output
3
+ */
4
+ const serializeCause = (cause) => {
5
+ if (cause instanceof Error) {
6
+ return { name: cause.name, message: cause.message, stack: cause.stack };
7
+ }
8
+ return cause;
9
+ };
10
+ /**
11
+ * Type guard for any tagged error
12
+ */
13
+ const isAnyTaggedError = (value) => {
14
+ return value instanceof Error && '_tag' in value && typeof value._tag === 'string';
15
+ };
16
+ /**
17
+ * Factory for tagged error classes with discriminated _tag property.
18
+ * Enables exhaustive pattern matching on error unions.
19
+ *
20
+ * @example
21
+ * class NotFoundError extends TaggedError("NotFoundError")<{
22
+ * id: string;
23
+ * message: string;
24
+ * }>() {}
25
+ *
26
+ * const err = new NotFoundError({ id: "123", message: "Not found" });
27
+ * err._tag // "NotFoundError"
28
+ * err.id // "123"
29
+ *
30
+ * // Type guard
31
+ * NotFoundError.is(err) // true
32
+ * TaggedError.is(err) // true (any tagged error)
33
+ *
34
+ * @example
35
+ * // With custom base class
36
+ * class AppError extends Error {
37
+ * statusCode: number = 500
38
+ * report() { console.log(this.message) }
39
+ * }
40
+ *
41
+ * class NotFoundError extends TaggedError("NotFoundError", AppError)<{
42
+ * id: string;
43
+ * message: string;
44
+ * }>() {
45
+ * statusCode = 404
46
+ * }
47
+ *
48
+ * const err = new NotFoundError({ id: "123", message: "Not found" });
49
+ * err.statusCode // 404
50
+ * err.report() // works
51
+ */
52
+ export const TaggedError = Object.assign((tag, BaseClass) => () => {
53
+ const ActualBase = (BaseClass ?? Error);
54
+ class Tagged extends ActualBase {
55
+ _tag = tag;
56
+ /** Type guard for this error class */
57
+ static is(value) {
58
+ return value instanceof Tagged;
59
+ }
60
+ constructor(args) {
61
+ const message = args && 'message' in args && typeof args.message === 'string' ? args.message : undefined;
62
+ const cause = args && 'cause' in args ? args.cause : undefined;
63
+ super(message, cause !== undefined ? { cause } : undefined);
64
+ if (args) {
65
+ Object.assign(this, args);
66
+ }
67
+ Object.setPrototypeOf(this, new.target.prototype);
68
+ this.name = tag;
69
+ if (cause instanceof Error && cause.stack) {
70
+ const indented = cause.stack.replace(/\n/g, '\n ');
71
+ this.stack = `${this.stack}\nCaused by: ${indented}`;
72
+ }
73
+ }
74
+ toJSON() {
75
+ return {
76
+ ...this,
77
+ _tag: this._tag,
78
+ name: this.name,
79
+ message: this.message,
80
+ cause: serializeCause(this.cause),
81
+ stack: this.stack,
82
+ };
83
+ }
84
+ }
85
+ return Tagged;
86
+ }, { is: isAnyTaggedError });
87
+ /**
88
+ * Type guard for tagged error instances.
89
+ *
90
+ * @example
91
+ * if (isTaggedError(value)) { value._tag }
92
+ */
93
+ export const isTaggedError = isAnyTaggedError;
94
+ /**
95
+ * Exhaustive pattern match on error union by _tag.
96
+ * Use `_` handler for plain Error instances without _tag.
97
+ *
98
+ * @example
99
+ * // Tagged errors only
100
+ * matchError(err, {
101
+ * NotFoundError: (e) => `Missing: ${e.id}`,
102
+ * ValidationError: (e) => `Invalid: ${e.field}`,
103
+ * });
104
+ *
105
+ * @example
106
+ * // Mixed tagged and plain Error
107
+ * matchError(err, {
108
+ * NotFoundError: (e) => `Missing: ${e.id}`,
109
+ * _: (e) => `Unknown error: ${e.message}`,
110
+ * });
111
+ */
112
+ export function matchError(err, handlers) {
113
+ const h = handlers;
114
+ if ('_tag' in err && typeof err._tag === 'string') {
115
+ const handler = h[err._tag];
116
+ if (handler) {
117
+ return handler(err);
118
+ }
119
+ }
120
+ // Fall through to _ handler for plain Error
121
+ const fallbackHandler = h['_'];
122
+ if (fallbackHandler) {
123
+ return fallbackHandler(err);
124
+ }
125
+ throw new Error(`No handler for error: ${err.message}`);
126
+ }
127
+ /**
128
+ * Partial pattern match with fallback for unhandled tags.
129
+ *
130
+ * @example
131
+ * matchErrorPartial(err, {
132
+ * NotFoundError: (e) => `Missing: ${e.id}`,
133
+ * }, (e) => `Unknown: ${e.message}`);
134
+ */
135
+ export function matchErrorPartial(err, handlers, fallback) {
136
+ const h = handlers;
137
+ if ('_tag' in err && typeof err._tag === 'string') {
138
+ const handler = h[err._tag];
139
+ if (handler) {
140
+ return handler(err);
141
+ }
142
+ }
143
+ // Check for _ handler before fallback
144
+ const underscoreHandler = h['_'];
145
+ if (underscoreHandler) {
146
+ return underscoreHandler(err);
147
+ }
148
+ return fallback(err);
149
+ }
150
+ /**
151
+ * Default error type when catching unknown exceptions.
152
+ */
153
+ export class UnhandledError extends TaggedError('UnhandledError')() {
154
+ constructor(args) {
155
+ const message = args.cause instanceof Error
156
+ ? `Unhandled exception: ${args.cause.message}`
157
+ : `Unhandled exception: ${String(args.cause)}`;
158
+ super({ message, cause: args.cause });
159
+ }
160
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Extract the value or throw if it's an error.
3
+ *
4
+ * @example
5
+ * const user = unwrap(result) // throws if result is an error
6
+ * console.log(user.name)
7
+ *
8
+ * @example With custom message
9
+ * const user = unwrap(result, 'Failed to get user')
10
+ */
11
+ export declare function unwrap<V>(value: V, message?: string): Exclude<V, Error>;
12
+ /**
13
+ * Extract the value or return a fallback if it's an error.
14
+ *
15
+ * @example
16
+ * const name = unwrapOr(result, 'Anonymous')
17
+ * // If result is User, returns user
18
+ * // If result is Error, returns 'Anonymous'
19
+ */
20
+ export declare function unwrapOr<V, U>(value: V, fallback: U): Exclude<V, Error> | U;
21
+ /**
22
+ * Pattern match on an errore value.
23
+ * Handles both success and error cases.
24
+ *
25
+ * @example
26
+ * const message = match(result, {
27
+ * ok: user => `Hello, ${user.name}`,
28
+ * err: error => `Failed: ${error.message}`
29
+ * })
30
+ */
31
+ export declare function match<V, R>(value: V, handlers: {
32
+ ok: (v: Exclude<V, Error>) => R;
33
+ err: (e: Extract<V, Error>) => R;
34
+ }): R;
35
+ /**
36
+ * Partition an array of errore values into [successes, errors].
37
+ *
38
+ * @example
39
+ * const results = await Promise.all(ids.map(fetchUser))
40
+ * const [users, errors] = partition(results)
41
+ */
42
+ export declare function partition<V>(values: V[]): [Exclude<V, Error>[], Extract<V, Error>[]];
43
+ /**
44
+ * Flatten a nested errore: (E1 | (E2 | T)) becomes (E1 | E2 | T).
45
+ * Useful when chaining operations that can fail.
46
+ *
47
+ * @example
48
+ * const nested: NetworkError | (ParseError | User) = await fetchAndParse()
49
+ * const flat: NetworkError | ParseError | User = flatten(nested)
50
+ */
51
+ export declare function flatten<V>(value: V): V;
52
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAKvE;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAK3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EACxB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE;IACR,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC/B,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;CACjC,GACA,CAAC,CAKH;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAWpF;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEtC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Extract the value or throw if it's an error.
3
+ *
4
+ * @example
5
+ * const user = unwrap(result) // throws if result is an error
6
+ * console.log(user.name)
7
+ *
8
+ * @example With custom message
9
+ * const user = unwrap(result, 'Failed to get user')
10
+ */
11
+ export function unwrap(value, message) {
12
+ if (value instanceof Error) {
13
+ throw new Error(message ?? `Unwrap called on error: ${value.message}`, { cause: value });
14
+ }
15
+ return value;
16
+ }
17
+ /**
18
+ * Extract the value or return a fallback if it's an error.
19
+ *
20
+ * @example
21
+ * const name = unwrapOr(result, 'Anonymous')
22
+ * // If result is User, returns user
23
+ * // If result is Error, returns 'Anonymous'
24
+ */
25
+ export function unwrapOr(value, fallback) {
26
+ if (value instanceof Error) {
27
+ return fallback;
28
+ }
29
+ return value;
30
+ }
31
+ /**
32
+ * Pattern match on an errore value.
33
+ * Handles both success and error cases.
34
+ *
35
+ * @example
36
+ * const message = match(result, {
37
+ * ok: user => `Hello, ${user.name}`,
38
+ * err: error => `Failed: ${error.message}`
39
+ * })
40
+ */
41
+ export function match(value, handlers) {
42
+ if (value instanceof Error) {
43
+ return handlers.err(value);
44
+ }
45
+ return handlers.ok(value);
46
+ }
47
+ /**
48
+ * Partition an array of errore values into [successes, errors].
49
+ *
50
+ * @example
51
+ * const results = await Promise.all(ids.map(fetchUser))
52
+ * const [users, errors] = partition(results)
53
+ */
54
+ export function partition(values) {
55
+ const oks = [];
56
+ const errs = [];
57
+ for (const v of values) {
58
+ if (v instanceof Error) {
59
+ errs.push(v);
60
+ }
61
+ else {
62
+ oks.push(v);
63
+ }
64
+ }
65
+ return [oks, errs];
66
+ }
67
+ /**
68
+ * Flatten a nested errore: (E1 | (E2 | T)) becomes (E1 | E2 | T).
69
+ * Useful when chaining operations that can fail.
70
+ *
71
+ * @example
72
+ * const nested: NetworkError | (ParseError | User) = await fetchAndParse()
73
+ * const flat: NetworkError | ParseError | User = flatten(nested)
74
+ */
75
+ export function flatten(value) {
76
+ return value;
77
+ }