@consolidados/results 0.4.0 → 0.5.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.
Files changed (42) hide show
  1. package/README.md +65 -0
  2. package/dist/helpers/match.cjs +23 -41
  3. package/dist/helpers/match.cjs.map +1 -1
  4. package/dist/helpers/match.d.cts +1 -1
  5. package/dist/helpers/match.d.ts +1 -1
  6. package/dist/helpers/match.js +23 -41
  7. package/dist/helpers/match.js.map +1 -1
  8. package/dist/index.cjs +36 -41
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +36 -41
  13. package/dist/index.js.map +1 -1
  14. package/dist/option/index.cjs +13 -0
  15. package/dist/option/index.cjs.map +1 -1
  16. package/dist/option/index.d.cts +1 -1
  17. package/dist/option/index.d.ts +1 -1
  18. package/dist/option/index.js +13 -0
  19. package/dist/option/index.js.map +1 -1
  20. package/dist/option/option.cjs +13 -0
  21. package/dist/option/option.cjs.map +1 -1
  22. package/dist/option/option.d.cts +2 -2
  23. package/dist/option/option.d.ts +2 -2
  24. package/dist/option/option.js +13 -0
  25. package/dist/option/option.js.map +1 -1
  26. package/dist/{option-B_KKIecf.d.cts → option-CYCiGxtw.d.cts} +13 -0
  27. package/dist/{option-B_KKIecf.d.ts → option-CYCiGxtw.d.ts} +13 -0
  28. package/dist/result/index.cjs +7 -0
  29. package/dist/result/index.cjs.map +1 -1
  30. package/dist/result/index.d.cts +1 -1
  31. package/dist/result/index.d.ts +1 -1
  32. package/dist/result/index.js +7 -0
  33. package/dist/result/index.js.map +1 -1
  34. package/dist/result/result.cjs +7 -0
  35. package/dist/result/result.cjs.map +1 -1
  36. package/dist/result/result.d.cts +2 -2
  37. package/dist/result/result.d.ts +2 -2
  38. package/dist/result/result.js +7 -0
  39. package/dist/result/result.js.map +1 -1
  40. package/dist/types/globals.d.cts +1 -1
  41. package/dist/types/globals.d.ts +1 -1
  42. package/package.json +2 -1
package/README.md CHANGED
@@ -48,6 +48,71 @@ const result = Ok(42);
48
48
  const option = Some("hello");
49
49
  ```
50
50
 
51
+ ### Monorepo / workspace setup
52
+
53
+ In a monorepo (Turborepo, Nx, pnpm workspaces, etc.) you usually don't want
54
+ to repeat the global wiring in every `tsconfig.json` and every entrypoint.
55
+ Wrap it once in a shared types package and have the other workspaces depend
56
+ on that.
57
+
58
+ **1. Create a shared package, e.g. `packages/types`:**
59
+
60
+ `packages/types/src/globals.ts` — runtime side-effect (registers
61
+ `Ok`, `Err`, `Some`, `None`, `match` on `globalThis`):
62
+
63
+ ```typescript
64
+ import "@consolidados/results";
65
+ ```
66
+
67
+ `packages/types/src/globals-types.d.ts` — ambient TypeScript types so
68
+ `Result<T, E>` and `Option<T>` work without per-file imports:
69
+
70
+ ```typescript
71
+ import type { Option as _Option, Result as _Result } from "@consolidados/results";
72
+
73
+ declare global {
74
+ type Result<T, E> = _Result<T, E>;
75
+ type Option<T> = _Option<T>;
76
+ }
77
+
78
+ export {};
79
+ ```
80
+
81
+ `packages/types/package.json` — expose both as subpath exports:
82
+
83
+ ```json
84
+ {
85
+ "name": "@your-org/types",
86
+ "dependencies": { "@consolidados/results": "^0.5.0" },
87
+ "exports": {
88
+ "./globals": "./src/globals.ts",
89
+ "./globals-types": "./src/globals-types.d.ts"
90
+ }
91
+ }
92
+ ```
93
+
94
+ **2. In each consuming workspace:**
95
+
96
+ `services/<name>/tsconfig.json`:
97
+
98
+ ```json
99
+ {
100
+ "compilerOptions": {
101
+ "types": ["node", "@your-org/types/globals-types"]
102
+ }
103
+ }
104
+ ```
105
+
106
+ `services/<name>/src/main.ts` (first import of the entrypoint):
107
+
108
+ ```typescript
109
+ import "@your-org/types/globals";
110
+ ```
111
+
112
+ Now every file in that workspace can use `Ok`, `Err`, `Some`, `None`, `match`,
113
+ `Result<T, E>`, and `Option<T>` without any import — and the wiring lives in
114
+ one place.
115
+
51
116
  ## Quick Start
52
117
 
53
118
  ### Result - Handle Success/Failure
@@ -1,59 +1,41 @@
1
1
  'use strict';
2
2
 
3
3
  // src/helpers/match.ts
4
+ var TAG = Symbol.for("@consolidados/results.tag");
4
5
  function match(matcher, cases, discriminant) {
5
- if (typeof matcher === "string" || typeof matcher === "number" || typeof matcher === "symbol") {
6
+ const t = typeof matcher;
7
+ if (t === "string" || t === "number" || t === "symbol") {
6
8
  const handler = cases[matcher];
7
- if (handler) {
9
+ if (handler) return handler();
10
+ if (cases.default) return cases.default();
11
+ throw new Error(`No case found for value: ${String(matcher)}`);
12
+ }
13
+ if (matcher !== null && t === "object") {
14
+ const tag = matcher[TAG];
15
+ if (tag !== void 0) {
16
+ const handler = cases[tag];
17
+ if (!handler) throw new Error(`Missing case for ${tag}`);
18
+ if (tag === "Ok" || tag === "Some") return handler(matcher.unwrap());
19
+ if (tag === "Err") return handler(matcher.unwrapErr());
8
20
  return handler();
9
21
  }
10
- if (cases.default) {
11
- return cases.default();
22
+ if (discriminant) {
23
+ const dv = matcher[discriminant];
24
+ const handler = cases[dv];
25
+ if (handler) return handler(matcher);
26
+ if (cases.default) return cases.default(matcher);
27
+ throw new Error(`No case found for discriminant value: ${String(dv)}`);
12
28
  }
13
- throw new Error(`No case found for value: ${String(matcher)}`);
14
- }
15
- if (typeof matcher === "object" && matcher !== null && !discriminant) {
16
- for (const key in cases) {
29
+ for (const key in matcher) {
17
30
  if (key === "default") continue;
18
- if (key in matcher) {
31
+ if (key in cases) {
19
32
  const handler = cases[key];
20
33
  if (handler) {
21
34
  return typeof handler === "function" ? handler(matcher[key]) : handler();
22
35
  }
23
36
  }
24
37
  }
25
- if (cases.default) {
26
- return cases.default();
27
- }
28
- }
29
- if (discriminant && typeof matcher === "object" && matcher !== null) {
30
- const discriminantValue = matcher[discriminant];
31
- const handler = cases[discriminantValue];
32
- if (handler) {
33
- return handler(matcher);
34
- }
35
- if (cases.default) {
36
- return cases.default(matcher);
37
- }
38
- throw new Error(
39
- `No case found for discriminant value: ${String(discriminantValue)}`
40
- );
41
- }
42
- if (typeof matcher === "object" && matcher !== null && "isOk" in matcher && matcher.isOk()) {
43
- if (!cases.Ok) throw new Error("Missing case for Ok");
44
- return cases.Ok(matcher.unwrap());
45
- }
46
- if (typeof matcher === "object" && matcher !== null && "isErr" in matcher && matcher.isErr()) {
47
- if (!cases.Err) throw new Error("Missing case for Err");
48
- return cases.Err(matcher.unwrapErr());
49
- }
50
- if (typeof matcher === "object" && matcher !== null && "isSome" in matcher && matcher.isSome()) {
51
- if (!cases.Some) throw new Error("Missing case for Some");
52
- return cases.Some(matcher.unwrap());
53
- }
54
- if (typeof matcher === "object" && matcher !== null && "isNone" in matcher && matcher.isNone()) {
55
- if (!cases.None) throw new Error("Missing case for None");
56
- return cases.None();
38
+ if (cases.default) return cases.default();
57
39
  }
58
40
  throw new Error("Invalid matcher or missing case");
59
41
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers/match.ts"],"names":[],"mappings":"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","file":"match.cjs","sourcesContent":["import type { Option } from \"../option\";\nimport type { Result } from \"../result\";\n\n// Utility types for mixed primitive + object unions\ntype PrimitiveMembers<T> = Extract<T, PropertyKey>;\ntype ObjectKeys<T> = T extends object ? keyof T : never;\ntype ObjectPropertyType<T, K extends PropertyKey> = T extends object\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\n// Helper to determine if a key K is a primitive member or object key\ntype HandlerFor<T, K extends PropertyKey, R> = K extends PrimitiveMembers<T>\n ? () => R\n : K extends ObjectKeys<T>\n ? (value: ObjectPropertyType<T, K>) => R\n : never;\n\n// Build cases type with a single mapped type\ntype MatchCases<T, R, HasDefault extends boolean = false> = (HasDefault extends true\n ? Partial<{\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }>\n : {\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }) &\n (HasDefault extends true ? { default: () => R } : {});\n\n// Overload for Result type\nexport function match<T, E, ROk, RErr>(\n matcher: Result<T, E>,\n cases: {\n Ok: (value: T) => ROk;\n Err: (error: E) => RErr;\n },\n): ROk | RErr;\n\n// Overload for Option type\nexport function match<T, RSome, RNone>(\n matcher: Option<T>,\n cases: {\n Some: (value: T) => RSome;\n None: () => RNone;\n },\n): RSome | RNone;\n\n// Overload for mixed primitive + object unions WITH default (cases optional)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, true>,\n): R;\n\n// Overload for mixed primitive + object unions WITHOUT default (exhaustive)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, false>,\n): R;\n\n// Overload for discriminated unions with default case\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]?: (value: Extract<T, { [P in D]: K }>) => R } & {\n default: (value: T) => R;\n },\n discriminant: D,\n): R;\n\n// Overload for discriminated unions without default case (exhaustive)\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]: (value: Extract<T, { [P in D]: K }>) => R },\n discriminant: D,\n): R;\n\n// Overload for primitives with default case\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Partial<Record<T, () => R>> & { default: () => R },\n): R;\n\n// Overload for primitives without default case (exhaustive)\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Record<T, () => R>,\n): R;\n\n// Implementation\nexport function match<T, E, R>(\n matcher: Result<T, E> | Option<T> | any,\n cases: any,\n discriminant?: keyof any,\n): R {\n // Handle primitives (string, number, symbol) FIRST\n if (\n typeof matcher === \"string\" ||\n typeof matcher === \"number\" ||\n typeof matcher === \"symbol\"\n ) {\n const handler = cases[matcher];\n\n if (handler) {\n return handler();\n }\n\n if (cases.default) {\n return cases.default();\n }\n\n throw new Error(`No case found for value: ${String(matcher)}`);\n }\n\n // NEW: Handle objects with specific property keys (like { Other: [...] })\n // This must come BEFORE discriminated union check to handle mixed unions\n if (typeof matcher === \"object\" && matcher !== null && !discriminant) {\n // Check if any case key matches a property in the matcher object\n for (const key in cases) {\n if (key === \"default\") continue;\n\n if (key in matcher) {\n const handler = cases[key];\n if (handler) {\n return typeof handler === \"function\"\n ? handler(matcher[key])\n : handler();\n }\n }\n }\n\n // If no match found and there's a default, use it\n if (cases.default) {\n return cases.default();\n }\n }\n\n // Handle discriminated unions\n if (discriminant && typeof matcher === \"object\" && matcher !== null) {\n const discriminantValue = matcher[discriminant];\n const handler = cases[discriminantValue];\n\n if (handler) {\n return handler(matcher);\n }\n\n if (cases.default) {\n return cases.default(matcher);\n }\n\n throw new Error(\n `No case found for discriminant value: ${String(discriminantValue)}`,\n );\n }\n\n // Early return for Result.Ok\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isOk\" in matcher &&\n matcher.isOk()\n ) {\n if (!cases.Ok) throw new Error(\"Missing case for Ok\");\n return cases.Ok(matcher.unwrap());\n }\n\n // Early return for Result.Err\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isErr\" in matcher &&\n matcher.isErr()\n ) {\n if (!cases.Err) throw new Error(\"Missing case for Err\");\n return cases.Err(matcher.unwrapErr() as E);\n }\n\n // Early return for Option.Some\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isSome\" in matcher &&\n matcher.isSome()\n ) {\n if (!cases.Some) throw new Error(\"Missing case for Some\");\n return cases.Some(matcher.unwrap());\n }\n\n // Early return for Option.None\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isNone\" in matcher &&\n matcher.isNone()\n ) {\n if (!cases.None) throw new Error(\"Missing case for None\");\n return cases.None();\n }\n\n throw new Error(\"Invalid matcher or missing case\");\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n(globalThis as any).match = match;\n"]}
1
+ {"version":3,"sources":["../../src/helpers/match.ts"],"names":[],"mappings":";;;AAKA,IAAM,GAAA,GAAM,MAAO,CAAA,GAAA,CAAI,2BAA2B,CAAA;AA+F3C,SAAS,KAAA,CACd,OACA,EAAA,KAAA,EACA,YACG,EAAA;AAEH,EAAA,MAAM,IAAI,OAAO,OAAA;AACjB,EAAA,IAAI,CAAM,KAAA,QAAA,IAAY,CAAM,KAAA,QAAA,IAAY,MAAM,QAAU,EAAA;AACtD,IAAM,MAAA,OAAA,GAAU,MAAM,OAAO,CAAA;AAC7B,IAAI,IAAA,OAAA,SAAgB,OAAQ,EAAA;AAC5B,IAAA,IAAI,KAAM,CAAA,OAAA,EAAgB,OAAA,KAAA,CAAM,OAAQ,EAAA;AACxC,IAAA,MAAM,IAAI,KAAM,CAAA,CAAA,yBAAA,EAA4B,MAAO,CAAA,OAAO,CAAC,CAAE,CAAA,CAAA;AAAA;AAG/D,EAAI,IAAA,OAAA,KAAY,IAAQ,IAAA,CAAA,KAAM,QAAU,EAAA;AAKtC,IAAM,MAAA,GAAA,GAAM,QAAQ,GAAG,CAAA;AACvB,IAAA,IAAI,QAAQ,MAAW,EAAA;AACrB,MAAM,MAAA,OAAA,GAAU,MAAM,GAAG,CAAA;AACzB,MAAA,IAAI,CAAC,OAAS,EAAA,MAAM,IAAI,KAAM,CAAA,CAAA,iBAAA,EAAoB,GAAG,CAAE,CAAA,CAAA;AACvD,MAAI,IAAA,GAAA,KAAQ,QAAQ,GAAQ,KAAA,MAAA,SAAe,OAAQ,CAAA,OAAA,CAAQ,QAAQ,CAAA;AACnE,MAAA,IAAI,QAAQ,KAAO,EAAA,OAAO,OAAQ,CAAA,OAAA,CAAQ,WAAgB,CAAA;AAE1D,MAAA,OAAO,OAAQ,EAAA;AAAA;AAIjB,IAAA,IAAI,YAAc,EAAA;AAChB,MAAM,MAAA,EAAA,GAAK,QAAQ,YAAY,CAAA;AAC/B,MAAM,MAAA,OAAA,GAAU,MAAM,EAAE,CAAA;AACxB,MAAI,IAAA,OAAA,EAAgB,OAAA,OAAA,CAAQ,OAAO,CAAA;AACnC,MAAA,IAAI,KAAM,CAAA,OAAA,EAAgB,OAAA,KAAA,CAAM,QAAQ,OAAO,CAAA;AAC/C,MAAA,MAAM,IAAI,KAAM,CAAA,CAAA,sCAAA,EAAyC,MAAO,CAAA,EAAE,CAAC,CAAE,CAAA,CAAA;AAAA;AAOvE,IAAA,KAAA,MAAW,OAAO,OAAS,EAAA;AACzB,MAAA,IAAI,QAAQ,SAAW,EAAA;AACvB,MAAA,IAAI,OAAO,KAAO,EAAA;AAChB,QAAM,MAAA,OAAA,GAAU,MAAM,GAAG,CAAA;AACzB,QAAA,IAAI,OAAS,EAAA;AACX,UAAO,OAAA,OAAO,YAAY,UACtB,GAAA,OAAA,CAAQ,QAAQ,GAAG,CAAC,IACpB,OAAQ,EAAA;AAAA;AACd;AACF;AAEF,IAAA,IAAI,KAAM,CAAA,OAAA,EAAgB,OAAA,KAAA,CAAM,OAAQ,EAAA;AAAA;AAG1C,EAAM,MAAA,IAAI,MAAM,iCAAiC,CAAA;AACnD;AAGC,UAAA,CAAmB,KAAQ,GAAA,KAAA","file":"match.cjs","sourcesContent":["import type { Option } from \"../option\";\nimport type { Result } from \"../result\";\n\n// Hidden discriminant tag — set by Ok/Err/Some/None instances for O(1) dispatch.\n// Same Symbol as the one declared in the variant classes via Symbol.for.\nconst TAG = Symbol.for(\"@consolidados/results.tag\");\n\n// Utility types for mixed primitive + object unions\ntype PrimitiveMembers<T> = Extract<T, PropertyKey>;\ntype ObjectKeys<T> = T extends object ? keyof T : never;\ntype ObjectPropertyType<T, K extends PropertyKey> = T extends object\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\n// Helper to determine if a key K is a primitive member or object key\ntype HandlerFor<T, K extends PropertyKey, R> = K extends PrimitiveMembers<T>\n ? () => R\n : K extends ObjectKeys<T>\n ? (value: ObjectPropertyType<T, K>) => R\n : never;\n\n// Build cases type with a single mapped type\ntype MatchCases<T, R, HasDefault extends boolean = false> = (HasDefault extends true\n ? Partial<{\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }>\n : {\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }) &\n (HasDefault extends true ? { default: () => R } : {});\n\n// Overload for Result type\nexport function match<T, E, ROk, RErr>(\n matcher: Result<T, E>,\n cases: {\n Ok: (value: T) => ROk;\n Err: (error: E) => RErr;\n },\n): ROk | RErr;\n\n// Overload for Option type\nexport function match<T, RSome, RNone>(\n matcher: Option<T>,\n cases: {\n Some: (value: T) => RSome;\n None: () => RNone;\n },\n): RSome | RNone;\n\n// Overload for mixed primitive + object unions WITH default (cases optional)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, true>,\n): R;\n\n// Overload for mixed primitive + object unions WITHOUT default (exhaustive)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, false>,\n): R;\n\n// Overload for discriminated unions with default case\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]?: (value: Extract<T, { [P in D]: K }>) => R } & {\n default: (value: T) => R;\n },\n discriminant: D,\n): R;\n\n// Overload for discriminated unions without default case (exhaustive)\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]: (value: Extract<T, { [P in D]: K }>) => R },\n discriminant: D,\n): R;\n\n// Overload for primitives with default case\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Partial<Record<T, () => R>> & { default: () => R },\n): R;\n\n// Overload for primitives without default case (exhaustive)\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Record<T, () => R>,\n): R;\n\n// Implementation\nexport function match<T, E, R>(\n matcher: Result<T, E> | Option<T> | any,\n cases: any,\n discriminant?: keyof any,\n): R {\n // 1) Primitives (string/number/symbol) — direct key lookup, O(1).\n const t = typeof matcher;\n if (t === \"string\" || t === \"number\" || t === \"symbol\") {\n const handler = cases[matcher];\n if (handler) return handler();\n if (cases.default) return cases.default();\n throw new Error(`No case found for value: ${String(matcher)}`);\n }\n\n if (matcher !== null && t === \"object\") {\n // 2) Tagged variant (Ok/Err/Some/None) single Symbol read + single lookup.\n // The Symbol property is invisible to `for...in`, `Object.keys`, and\n // `JSON.stringify`, so mixed unions with plain-object variants are\n // unaffected.\n const tag = matcher[TAG];\n if (tag !== undefined) {\n const handler = cases[tag];\n if (!handler) throw new Error(`Missing case for ${tag}`);\n if (tag === \"Ok\" || tag === \"Some\") return handler(matcher.unwrap());\n if (tag === \"Err\") return handler(matcher.unwrapErr() as E);\n // tag === \"None\"\n return handler();\n }\n\n // 3) Discriminated union via explicit `discriminant` arg O(1).\n if (discriminant) {\n const dv = matcher[discriminant];\n const handler = cases[dv];\n if (handler) return handler(matcher);\n if (cases.default) return cases.default(matcher);\n throw new Error(`No case found for discriminant value: ${String(dv)}`);\n }\n\n // 4) Mixed primitive + object union iterate matcher's own enumerable\n // keys (usually 1 for tagged variant objects like `{ Other: [...] }`)\n // and look up by key in cases. This flips the loop from O(cases)\n // to O(matcher-keys), which is effectively O(1) for tagged variants.\n for (const key in matcher) {\n if (key === \"default\") continue;\n if (key in cases) {\n const handler = cases[key];\n if (handler) {\n return typeof handler === \"function\"\n ? handler(matcher[key])\n : handler();\n }\n }\n }\n if (cases.default) return cases.default();\n }\n\n throw new Error(\"Invalid matcher or missing case\");\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n(globalThis as any).match = match;\n"]}
@@ -1,4 +1,4 @@
1
- import { R as Result, O as Option } from '../option-B_KKIecf.cjs';
1
+ import { R as Result, O as Option } from '../option-CYCiGxtw.cjs';
2
2
 
3
3
  type PrimitiveMembers<T> = Extract<T, PropertyKey>;
4
4
  type ObjectKeys<T> = T extends object ? keyof T : never;
@@ -1,4 +1,4 @@
1
- import { R as Result, O as Option } from '../option-B_KKIecf.js';
1
+ import { R as Result, O as Option } from '../option-CYCiGxtw.js';
2
2
 
3
3
  type PrimitiveMembers<T> = Extract<T, PropertyKey>;
4
4
  type ObjectKeys<T> = T extends object ? keyof T : never;
@@ -1,57 +1,39 @@
1
1
  // src/helpers/match.ts
2
+ var TAG = Symbol.for("@consolidados/results.tag");
2
3
  function match(matcher, cases, discriminant) {
3
- if (typeof matcher === "string" || typeof matcher === "number" || typeof matcher === "symbol") {
4
+ const t = typeof matcher;
5
+ if (t === "string" || t === "number" || t === "symbol") {
4
6
  const handler = cases[matcher];
5
- if (handler) {
7
+ if (handler) return handler();
8
+ if (cases.default) return cases.default();
9
+ throw new Error(`No case found for value: ${String(matcher)}`);
10
+ }
11
+ if (matcher !== null && t === "object") {
12
+ const tag = matcher[TAG];
13
+ if (tag !== void 0) {
14
+ const handler = cases[tag];
15
+ if (!handler) throw new Error(`Missing case for ${tag}`);
16
+ if (tag === "Ok" || tag === "Some") return handler(matcher.unwrap());
17
+ if (tag === "Err") return handler(matcher.unwrapErr());
6
18
  return handler();
7
19
  }
8
- if (cases.default) {
9
- return cases.default();
20
+ if (discriminant) {
21
+ const dv = matcher[discriminant];
22
+ const handler = cases[dv];
23
+ if (handler) return handler(matcher);
24
+ if (cases.default) return cases.default(matcher);
25
+ throw new Error(`No case found for discriminant value: ${String(dv)}`);
10
26
  }
11
- throw new Error(`No case found for value: ${String(matcher)}`);
12
- }
13
- if (typeof matcher === "object" && matcher !== null && !discriminant) {
14
- for (const key in cases) {
27
+ for (const key in matcher) {
15
28
  if (key === "default") continue;
16
- if (key in matcher) {
29
+ if (key in cases) {
17
30
  const handler = cases[key];
18
31
  if (handler) {
19
32
  return typeof handler === "function" ? handler(matcher[key]) : handler();
20
33
  }
21
34
  }
22
35
  }
23
- if (cases.default) {
24
- return cases.default();
25
- }
26
- }
27
- if (discriminant && typeof matcher === "object" && matcher !== null) {
28
- const discriminantValue = matcher[discriminant];
29
- const handler = cases[discriminantValue];
30
- if (handler) {
31
- return handler(matcher);
32
- }
33
- if (cases.default) {
34
- return cases.default(matcher);
35
- }
36
- throw new Error(
37
- `No case found for discriminant value: ${String(discriminantValue)}`
38
- );
39
- }
40
- if (typeof matcher === "object" && matcher !== null && "isOk" in matcher && matcher.isOk()) {
41
- if (!cases.Ok) throw new Error("Missing case for Ok");
42
- return cases.Ok(matcher.unwrap());
43
- }
44
- if (typeof matcher === "object" && matcher !== null && "isErr" in matcher && matcher.isErr()) {
45
- if (!cases.Err) throw new Error("Missing case for Err");
46
- return cases.Err(matcher.unwrapErr());
47
- }
48
- if (typeof matcher === "object" && matcher !== null && "isSome" in matcher && matcher.isSome()) {
49
- if (!cases.Some) throw new Error("Missing case for Some");
50
- return cases.Some(matcher.unwrap());
51
- }
52
- if (typeof matcher === "object" && matcher !== null && "isNone" in matcher && matcher.isNone()) {
53
- if (!cases.None) throw new Error("Missing case for None");
54
- return cases.None();
36
+ if (cases.default) return cases.default();
55
37
  }
56
38
  throw new Error("Invalid matcher or missing case");
57
39
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers/match.ts"],"names":[],"mappings":"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","file":"match.js","sourcesContent":["import type { Option } from \"../option\";\nimport type { Result } from \"../result\";\n\n// Utility types for mixed primitive + object unions\ntype PrimitiveMembers<T> = Extract<T, PropertyKey>;\ntype ObjectKeys<T> = T extends object ? keyof T : never;\ntype ObjectPropertyType<T, K extends PropertyKey> = T extends object\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\n// Helper to determine if a key K is a primitive member or object key\ntype HandlerFor<T, K extends PropertyKey, R> = K extends PrimitiveMembers<T>\n ? () => R\n : K extends ObjectKeys<T>\n ? (value: ObjectPropertyType<T, K>) => R\n : never;\n\n// Build cases type with a single mapped type\ntype MatchCases<T, R, HasDefault extends boolean = false> = (HasDefault extends true\n ? Partial<{\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }>\n : {\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }) &\n (HasDefault extends true ? { default: () => R } : {});\n\n// Overload for Result type\nexport function match<T, E, ROk, RErr>(\n matcher: Result<T, E>,\n cases: {\n Ok: (value: T) => ROk;\n Err: (error: E) => RErr;\n },\n): ROk | RErr;\n\n// Overload for Option type\nexport function match<T, RSome, RNone>(\n matcher: Option<T>,\n cases: {\n Some: (value: T) => RSome;\n None: () => RNone;\n },\n): RSome | RNone;\n\n// Overload for mixed primitive + object unions WITH default (cases optional)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, true>,\n): R;\n\n// Overload for mixed primitive + object unions WITHOUT default (exhaustive)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, false>,\n): R;\n\n// Overload for discriminated unions with default case\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]?: (value: Extract<T, { [P in D]: K }>) => R } & {\n default: (value: T) => R;\n },\n discriminant: D,\n): R;\n\n// Overload for discriminated unions without default case (exhaustive)\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]: (value: Extract<T, { [P in D]: K }>) => R },\n discriminant: D,\n): R;\n\n// Overload for primitives with default case\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Partial<Record<T, () => R>> & { default: () => R },\n): R;\n\n// Overload for primitives without default case (exhaustive)\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Record<T, () => R>,\n): R;\n\n// Implementation\nexport function match<T, E, R>(\n matcher: Result<T, E> | Option<T> | any,\n cases: any,\n discriminant?: keyof any,\n): R {\n // Handle primitives (string, number, symbol) FIRST\n if (\n typeof matcher === \"string\" ||\n typeof matcher === \"number\" ||\n typeof matcher === \"symbol\"\n ) {\n const handler = cases[matcher];\n\n if (handler) {\n return handler();\n }\n\n if (cases.default) {\n return cases.default();\n }\n\n throw new Error(`No case found for value: ${String(matcher)}`);\n }\n\n // NEW: Handle objects with specific property keys (like { Other: [...] })\n // This must come BEFORE discriminated union check to handle mixed unions\n if (typeof matcher === \"object\" && matcher !== null && !discriminant) {\n // Check if any case key matches a property in the matcher object\n for (const key in cases) {\n if (key === \"default\") continue;\n\n if (key in matcher) {\n const handler = cases[key];\n if (handler) {\n return typeof handler === \"function\"\n ? handler(matcher[key])\n : handler();\n }\n }\n }\n\n // If no match found and there's a default, use it\n if (cases.default) {\n return cases.default();\n }\n }\n\n // Handle discriminated unions\n if (discriminant && typeof matcher === \"object\" && matcher !== null) {\n const discriminantValue = matcher[discriminant];\n const handler = cases[discriminantValue];\n\n if (handler) {\n return handler(matcher);\n }\n\n if (cases.default) {\n return cases.default(matcher);\n }\n\n throw new Error(\n `No case found for discriminant value: ${String(discriminantValue)}`,\n );\n }\n\n // Early return for Result.Ok\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isOk\" in matcher &&\n matcher.isOk()\n ) {\n if (!cases.Ok) throw new Error(\"Missing case for Ok\");\n return cases.Ok(matcher.unwrap());\n }\n\n // Early return for Result.Err\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isErr\" in matcher &&\n matcher.isErr()\n ) {\n if (!cases.Err) throw new Error(\"Missing case for Err\");\n return cases.Err(matcher.unwrapErr() as E);\n }\n\n // Early return for Option.Some\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isSome\" in matcher &&\n matcher.isSome()\n ) {\n if (!cases.Some) throw new Error(\"Missing case for Some\");\n return cases.Some(matcher.unwrap());\n }\n\n // Early return for Option.None\n if (\n typeof matcher === \"object\" &&\n matcher !== null &&\n \"isNone\" in matcher &&\n matcher.isNone()\n ) {\n if (!cases.None) throw new Error(\"Missing case for None\");\n return cases.None();\n }\n\n throw new Error(\"Invalid matcher or missing case\");\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n(globalThis as any).match = match;\n"]}
1
+ {"version":3,"sources":["../../src/helpers/match.ts"],"names":[],"mappings":";AAKA,IAAM,GAAA,GAAM,MAAO,CAAA,GAAA,CAAI,2BAA2B,CAAA;AA+F3C,SAAS,KAAA,CACd,OACA,EAAA,KAAA,EACA,YACG,EAAA;AAEH,EAAA,MAAM,IAAI,OAAO,OAAA;AACjB,EAAA,IAAI,CAAM,KAAA,QAAA,IAAY,CAAM,KAAA,QAAA,IAAY,MAAM,QAAU,EAAA;AACtD,IAAM,MAAA,OAAA,GAAU,MAAM,OAAO,CAAA;AAC7B,IAAI,IAAA,OAAA,SAAgB,OAAQ,EAAA;AAC5B,IAAA,IAAI,KAAM,CAAA,OAAA,EAAgB,OAAA,KAAA,CAAM,OAAQ,EAAA;AACxC,IAAA,MAAM,IAAI,KAAM,CAAA,CAAA,yBAAA,EAA4B,MAAO,CAAA,OAAO,CAAC,CAAE,CAAA,CAAA;AAAA;AAG/D,EAAI,IAAA,OAAA,KAAY,IAAQ,IAAA,CAAA,KAAM,QAAU,EAAA;AAKtC,IAAM,MAAA,GAAA,GAAM,QAAQ,GAAG,CAAA;AACvB,IAAA,IAAI,QAAQ,MAAW,EAAA;AACrB,MAAM,MAAA,OAAA,GAAU,MAAM,GAAG,CAAA;AACzB,MAAA,IAAI,CAAC,OAAS,EAAA,MAAM,IAAI,KAAM,CAAA,CAAA,iBAAA,EAAoB,GAAG,CAAE,CAAA,CAAA;AACvD,MAAI,IAAA,GAAA,KAAQ,QAAQ,GAAQ,KAAA,MAAA,SAAe,OAAQ,CAAA,OAAA,CAAQ,QAAQ,CAAA;AACnE,MAAA,IAAI,QAAQ,KAAO,EAAA,OAAO,OAAQ,CAAA,OAAA,CAAQ,WAAgB,CAAA;AAE1D,MAAA,OAAO,OAAQ,EAAA;AAAA;AAIjB,IAAA,IAAI,YAAc,EAAA;AAChB,MAAM,MAAA,EAAA,GAAK,QAAQ,YAAY,CAAA;AAC/B,MAAM,MAAA,OAAA,GAAU,MAAM,EAAE,CAAA;AACxB,MAAI,IAAA,OAAA,EAAgB,OAAA,OAAA,CAAQ,OAAO,CAAA;AACnC,MAAA,IAAI,KAAM,CAAA,OAAA,EAAgB,OAAA,KAAA,CAAM,QAAQ,OAAO,CAAA;AAC/C,MAAA,MAAM,IAAI,KAAM,CAAA,CAAA,sCAAA,EAAyC,MAAO,CAAA,EAAE,CAAC,CAAE,CAAA,CAAA;AAAA;AAOvE,IAAA,KAAA,MAAW,OAAO,OAAS,EAAA;AACzB,MAAA,IAAI,QAAQ,SAAW,EAAA;AACvB,MAAA,IAAI,OAAO,KAAO,EAAA;AAChB,QAAM,MAAA,OAAA,GAAU,MAAM,GAAG,CAAA;AACzB,QAAA,IAAI,OAAS,EAAA;AACX,UAAO,OAAA,OAAO,YAAY,UACtB,GAAA,OAAA,CAAQ,QAAQ,GAAG,CAAC,IACpB,OAAQ,EAAA;AAAA;AACd;AACF;AAEF,IAAA,IAAI,KAAM,CAAA,OAAA,EAAgB,OAAA,KAAA,CAAM,OAAQ,EAAA;AAAA;AAG1C,EAAM,MAAA,IAAI,MAAM,iCAAiC,CAAA;AACnD;AAGC,UAAA,CAAmB,KAAQ,GAAA,KAAA","file":"match.js","sourcesContent":["import type { Option } from \"../option\";\nimport type { Result } from \"../result\";\n\n// Hidden discriminant tag — set by Ok/Err/Some/None instances for O(1) dispatch.\n// Same Symbol as the one declared in the variant classes via Symbol.for.\nconst TAG = Symbol.for(\"@consolidados/results.tag\");\n\n// Utility types for mixed primitive + object unions\ntype PrimitiveMembers<T> = Extract<T, PropertyKey>;\ntype ObjectKeys<T> = T extends object ? keyof T : never;\ntype ObjectPropertyType<T, K extends PropertyKey> = T extends object\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\n// Helper to determine if a key K is a primitive member or object key\ntype HandlerFor<T, K extends PropertyKey, R> = K extends PrimitiveMembers<T>\n ? () => R\n : K extends ObjectKeys<T>\n ? (value: ObjectPropertyType<T, K>) => R\n : never;\n\n// Build cases type with a single mapped type\ntype MatchCases<T, R, HasDefault extends boolean = false> = (HasDefault extends true\n ? Partial<{\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }>\n : {\n [K in PrimitiveMembers<T> | ObjectKeys<T>]: HandlerFor<T, K, R>;\n }) &\n (HasDefault extends true ? { default: () => R } : {});\n\n// Overload for Result type\nexport function match<T, E, ROk, RErr>(\n matcher: Result<T, E>,\n cases: {\n Ok: (value: T) => ROk;\n Err: (error: E) => RErr;\n },\n): ROk | RErr;\n\n// Overload for Option type\nexport function match<T, RSome, RNone>(\n matcher: Option<T>,\n cases: {\n Some: (value: T) => RSome;\n None: () => RNone;\n },\n): RSome | RNone;\n\n// Overload for mixed primitive + object unions WITH default (cases optional)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, true>,\n): R;\n\n// Overload for mixed primitive + object unions WITHOUT default (exhaustive)\nexport function match<T extends PropertyKey | object, R>(\n matcher: T,\n cases: MatchCases<T, R, false>,\n): R;\n\n// Overload for discriminated unions with default case\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]?: (value: Extract<T, { [P in D]: K }>) => R } & {\n default: (value: T) => R;\n },\n discriminant: D,\n): R;\n\n// Overload for discriminated unions without default case (exhaustive)\nexport function match<\n T extends { [K in D]: string | number | symbol },\n D extends keyof T,\n R,\n>(\n matcher: T,\n cases: { [K in T[D]]: (value: Extract<T, { [P in D]: K }>) => R },\n discriminant: D,\n): R;\n\n// Overload for primitives with default case\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Partial<Record<T, () => R>> & { default: () => R },\n): R;\n\n// Overload for primitives without default case (exhaustive)\nexport function match<T extends PropertyKey, R>(\n matcher: T,\n cases: Record<T, () => R>,\n): R;\n\n// Implementation\nexport function match<T, E, R>(\n matcher: Result<T, E> | Option<T> | any,\n cases: any,\n discriminant?: keyof any,\n): R {\n // 1) Primitives (string/number/symbol) — direct key lookup, O(1).\n const t = typeof matcher;\n if (t === \"string\" || t === \"number\" || t === \"symbol\") {\n const handler = cases[matcher];\n if (handler) return handler();\n if (cases.default) return cases.default();\n throw new Error(`No case found for value: ${String(matcher)}`);\n }\n\n if (matcher !== null && t === \"object\") {\n // 2) Tagged variant (Ok/Err/Some/None) single Symbol read + single lookup.\n // The Symbol property is invisible to `for...in`, `Object.keys`, and\n // `JSON.stringify`, so mixed unions with plain-object variants are\n // unaffected.\n const tag = matcher[TAG];\n if (tag !== undefined) {\n const handler = cases[tag];\n if (!handler) throw new Error(`Missing case for ${tag}`);\n if (tag === \"Ok\" || tag === \"Some\") return handler(matcher.unwrap());\n if (tag === \"Err\") return handler(matcher.unwrapErr() as E);\n // tag === \"None\"\n return handler();\n }\n\n // 3) Discriminated union via explicit `discriminant` arg O(1).\n if (discriminant) {\n const dv = matcher[discriminant];\n const handler = cases[dv];\n if (handler) return handler(matcher);\n if (cases.default) return cases.default(matcher);\n throw new Error(`No case found for discriminant value: ${String(dv)}`);\n }\n\n // 4) Mixed primitive + object union iterate matcher's own enumerable\n // keys (usually 1 for tagged variant objects like `{ Other: [...] }`)\n // and look up by key in cases. This flips the loop from O(cases)\n // to O(matcher-keys), which is effectively O(1) for tagged variants.\n for (const key in matcher) {\n if (key === \"default\") continue;\n if (key in cases) {\n const handler = cases[key];\n if (handler) {\n return typeof handler === \"function\"\n ? handler(matcher[key])\n : handler();\n }\n }\n }\n if (cases.default) return cases.default();\n }\n\n throw new Error(\"Invalid matcher or missing case\");\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\n(globalThis as any).match = match;\n"]}
package/dist/index.cjs CHANGED
@@ -1,66 +1,51 @@
1
1
  'use strict';
2
2
 
3
3
  // src/helpers/match.ts
4
+ var TAG = Symbol.for("@consolidados/results.tag");
4
5
  function match(matcher, cases, discriminant) {
5
- if (typeof matcher === "string" || typeof matcher === "number" || typeof matcher === "symbol") {
6
+ const t = typeof matcher;
7
+ if (t === "string" || t === "number" || t === "symbol") {
6
8
  const handler = cases[matcher];
7
- if (handler) {
9
+ if (handler) return handler();
10
+ if (cases.default) return cases.default();
11
+ throw new Error(`No case found for value: ${String(matcher)}`);
12
+ }
13
+ if (matcher !== null && t === "object") {
14
+ const tag = matcher[TAG];
15
+ if (tag !== void 0) {
16
+ const handler = cases[tag];
17
+ if (!handler) throw new Error(`Missing case for ${tag}`);
18
+ if (tag === "Ok" || tag === "Some") return handler(matcher.unwrap());
19
+ if (tag === "Err") return handler(matcher.unwrapErr());
8
20
  return handler();
9
21
  }
10
- if (cases.default) {
11
- return cases.default();
22
+ if (discriminant) {
23
+ const dv = matcher[discriminant];
24
+ const handler = cases[dv];
25
+ if (handler) return handler(matcher);
26
+ if (cases.default) return cases.default(matcher);
27
+ throw new Error(`No case found for discriminant value: ${String(dv)}`);
12
28
  }
13
- throw new Error(`No case found for value: ${String(matcher)}`);
14
- }
15
- if (typeof matcher === "object" && matcher !== null && !discriminant) {
16
- for (const key in cases) {
29
+ for (const key in matcher) {
17
30
  if (key === "default") continue;
18
- if (key in matcher) {
31
+ if (key in cases) {
19
32
  const handler = cases[key];
20
33
  if (handler) {
21
34
  return typeof handler === "function" ? handler(matcher[key]) : handler();
22
35
  }
23
36
  }
24
37
  }
25
- if (cases.default) {
26
- return cases.default();
27
- }
28
- }
29
- if (discriminant && typeof matcher === "object" && matcher !== null) {
30
- const discriminantValue = matcher[discriminant];
31
- const handler = cases[discriminantValue];
32
- if (handler) {
33
- return handler(matcher);
34
- }
35
- if (cases.default) {
36
- return cases.default(matcher);
37
- }
38
- throw new Error(
39
- `No case found for discriminant value: ${String(discriminantValue)}`
40
- );
41
- }
42
- if (typeof matcher === "object" && matcher !== null && "isOk" in matcher && matcher.isOk()) {
43
- if (!cases.Ok) throw new Error("Missing case for Ok");
44
- return cases.Ok(matcher.unwrap());
45
- }
46
- if (typeof matcher === "object" && matcher !== null && "isErr" in matcher && matcher.isErr()) {
47
- if (!cases.Err) throw new Error("Missing case for Err");
48
- return cases.Err(matcher.unwrapErr());
49
- }
50
- if (typeof matcher === "object" && matcher !== null && "isSome" in matcher && matcher.isSome()) {
51
- if (!cases.Some) throw new Error("Missing case for Some");
52
- return cases.Some(matcher.unwrap());
53
- }
54
- if (typeof matcher === "object" && matcher !== null && "isNone" in matcher && matcher.isNone()) {
55
- if (!cases.None) throw new Error("Missing case for None");
56
- return cases.None();
38
+ if (cases.default) return cases.default();
57
39
  }
58
40
  throw new Error("Invalid matcher or missing case");
59
41
  }
60
42
  globalThis.match = match;
61
43
 
62
44
  // src/result/__internal__/return-types/err.ts
45
+ var TAG2 = Symbol.for("@consolidados/results.tag");
63
46
  var Err = class _Err {
47
+ /** Hidden tag — read by `match()` for O(1) dispatch. */
48
+ [TAG2] = "Err";
64
49
  error;
65
50
  /**
66
51
  * Creates a new `Err` instance with the given error value.
@@ -171,6 +156,7 @@ var Err = class _Err {
171
156
  };
172
157
 
173
158
  // src/result/__internal__/return-types/ok.ts
159
+ var TAG3 = Symbol.for("@consolidados/results.tag");
174
160
  var Ok = class _Ok {
175
161
  /**
176
162
  * Creates a new `Ok` instance with the given value.
@@ -179,6 +165,9 @@ var Ok = class _Ok {
179
165
  constructor(_value) {
180
166
  this._value = _value;
181
167
  }
168
+ /** Hidden tag — read by `match()` for O(1) dispatch. Symbol-keyed so it
169
+ * doesn't appear in `for...in`, `Object.keys`, or `JSON.stringify`. */
170
+ [TAG3] = "Ok";
182
171
  /**
183
172
  * Checks if this result is an `Ok`.
184
173
  * @returns `true` because this is an `Ok`.
@@ -290,6 +279,7 @@ globalThis.Ok = Ok2;
290
279
  globalThis.Err = Err2;
291
280
 
292
281
  // src/option/__internal__/return-types/some.ts
282
+ var TAG4 = Symbol.for("@consolidados/results.tag");
293
283
  var Some2 = class _Some {
294
284
  /**
295
285
  * Creates a new `Some` option with the given value.
@@ -298,6 +288,8 @@ var Some2 = class _Some {
298
288
  constructor(_value) {
299
289
  this._value = _value;
300
290
  }
291
+ /** Hidden tag — read by `match()` for O(1) dispatch. */
292
+ [TAG4] = "Some";
301
293
  /**
302
294
  * Checks if this option is a `Some`.
303
295
  * @returns `true` if this option is a `Some`, otherwise `false`.
@@ -382,7 +374,10 @@ var Some2 = class _Some {
382
374
  };
383
375
 
384
376
  // src/option/__internal__/return-types/none.ts
377
+ var TAG5 = Symbol.for("@consolidados/results.tag");
385
378
  var None3 = class {
379
+ /** Hidden tag — read by `match()` for O(1) dispatch. */
380
+ [TAG5] = "None";
386
381
  /**
387
382
  * Checks if this option is a `Some`.
388
383
  * @returns `false` because this is a `None`.