@nicolastoulemont/std 0.8.2 → 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.
Files changed (206) hide show
  1. package/README.md +391 -40
  2. package/dist/brand/index.d.mts +1 -1
  3. package/dist/brand/index.mjs +1 -1
  4. package/dist/{brand-DZgGDrAe.mjs → brand-DP-C92GS.mjs} +2 -2
  5. package/dist/{brand-DZgGDrAe.mjs.map → brand-DP-C92GS.mjs.map} +1 -1
  6. package/dist/{brand.types-B3NDX1vo.d.mts → brand.types-C_7QgCA4.d.mts} +1 -1
  7. package/dist/{brand.types-B3NDX1vo.d.mts.map → brand.types-C_7QgCA4.d.mts.map} +1 -1
  8. package/dist/context/index.d.mts +1 -1
  9. package/dist/context/index.mjs +1 -1
  10. package/dist/{context-0xDbwtpx.mjs → context-7oKePrBY.mjs} +2 -2
  11. package/dist/{context-0xDbwtpx.mjs.map → context-7oKePrBY.mjs.map} +1 -1
  12. package/dist/{context-B2dWloPl.d.mts → context-B9oWzbwF.d.mts} +2 -2
  13. package/dist/{context-B2dWloPl.d.mts.map → context-B9oWzbwF.d.mts.map} +1 -1
  14. package/dist/data/index.d.mts +1 -1
  15. package/dist/data/index.mjs +1 -1
  16. package/dist/data-W10ldR5l.mjs +2 -0
  17. package/dist/data-W10ldR5l.mjs.map +1 -0
  18. package/dist/{dual-fN6OUwN_.mjs → dual-CZhzZslG.mjs} +1 -1
  19. package/dist/{dual-fN6OUwN_.mjs.map → dual-CZhzZslG.mjs.map} +1 -1
  20. package/dist/duration/index.d.mts +1 -1
  21. package/dist/duration/index.mjs +1 -1
  22. package/dist/{duration-CYoDHcOR.mjs → duration-Dwtjy95Z.mjs} +2 -2
  23. package/dist/{duration-CYoDHcOR.mjs.map → duration-Dwtjy95Z.mjs.map} +1 -1
  24. package/dist/either/index.d.mts +1 -1
  25. package/dist/either/index.mjs +1 -1
  26. package/dist/{either-G7uOu4Ar.mjs → either-B2TvVY_j.mjs} +2 -2
  27. package/dist/{either-G7uOu4Ar.mjs.map → either-B2TvVY_j.mjs.map} +1 -1
  28. package/dist/exit-DOdhmr81.d.mts +67 -0
  29. package/dist/exit-DOdhmr81.d.mts.map +1 -0
  30. package/dist/fiber/index.d.mts +2 -0
  31. package/dist/fiber/index.mjs +1 -0
  32. package/dist/fiber-CZsyrDdd.mjs +2 -0
  33. package/dist/fiber-CZsyrDdd.mjs.map +1 -0
  34. package/dist/{flow-CNyLsPGb.mjs → flow-D8_tllWl.mjs} +1 -1
  35. package/dist/{flow-CNyLsPGb.mjs.map → flow-D8_tllWl.mjs.map} +1 -1
  36. package/dist/functions/index.mjs +1 -1
  37. package/dist/functions-DmOZ7O4j.mjs +2 -0
  38. package/dist/{functions-ByAk682_.mjs.map → functions-DmOZ7O4j.mjs.map} +1 -1
  39. package/dist/fx/index.d.mts +1 -1
  40. package/dist/fx/index.mjs +1 -1
  41. package/dist/fx-DXBw4iYX.mjs +2 -0
  42. package/dist/fx-DXBw4iYX.mjs.map +1 -0
  43. package/dist/fx.runtime-B2_rL7h_.mjs +2 -0
  44. package/dist/fx.runtime-B2_rL7h_.mjs.map +1 -0
  45. package/dist/fx.runtime-BuIElLpZ.d.mts +16 -0
  46. package/dist/fx.runtime-BuIElLpZ.d.mts.map +1 -0
  47. package/dist/{fx.types-DyQVgTS8.mjs → fx.types-Bg-Mmdm5.mjs} +1 -1
  48. package/dist/{fx.types-DyQVgTS8.mjs.map → fx.types-Bg-Mmdm5.mjs.map} +1 -1
  49. package/dist/{fx.types-BdN1EWxr.d.mts → fx.types-CpFKa-Jj.d.mts} +1 -1
  50. package/dist/{fx.types-BdN1EWxr.d.mts.map → fx.types-CpFKa-Jj.d.mts.map} +1 -1
  51. package/dist/{index-DCUGtEcj.d.mts → index-5QkUtJ-4.d.mts} +4 -4
  52. package/dist/{index-DCUGtEcj.d.mts.map → index-5QkUtJ-4.d.mts.map} +1 -1
  53. package/dist/{index-C4DOLLaU.d.mts → index-B3xia3Jl.d.mts} +82 -58
  54. package/dist/index-B3xia3Jl.d.mts.map +1 -0
  55. package/dist/{index-CIvNgjsx.d.mts → index-B4rHoUK4.d.mts} +2 -2
  56. package/dist/{index-CIvNgjsx.d.mts.map → index-B4rHoUK4.d.mts.map} +1 -1
  57. package/dist/{index-BA0EsFxS.d.mts → index-BDUhDs4D.d.mts} +3 -3
  58. package/dist/{index-BA0EsFxS.d.mts.map → index-BDUhDs4D.d.mts.map} +1 -1
  59. package/dist/{index-CNTYbcY9.d.mts → index-BZ1-IrU_.d.mts} +1 -1
  60. package/dist/{index-CNTYbcY9.d.mts.map → index-BZ1-IrU_.d.mts.map} +1 -1
  61. package/dist/{index-uE3S3Krx.d.mts → index-BZP6t2h9.d.mts} +5 -5
  62. package/dist/{index-uE3S3Krx.d.mts.map → index-BZP6t2h9.d.mts.map} +1 -1
  63. package/dist/{index-D8rDE60Y.d.mts → index-Bu-z5Xoq.d.mts} +1 -1
  64. package/dist/index-Bu-z5Xoq.d.mts.map +1 -0
  65. package/dist/index-C8KMi_I9.d.mts +226 -0
  66. package/dist/index-C8KMi_I9.d.mts.map +1 -0
  67. package/dist/{index-dCRymj_g.d.mts → index-CfXGmPMY.d.mts} +5 -5
  68. package/dist/{index-dCRymj_g.d.mts.map → index-CfXGmPMY.d.mts.map} +1 -1
  69. package/dist/index-Cv48HmyO.d.mts +59 -0
  70. package/dist/index-Cv48HmyO.d.mts.map +1 -0
  71. package/dist/{index-B2Z7-XGR.d.mts → index-D-KxgnwF.d.mts} +59 -34
  72. package/dist/index-D-KxgnwF.d.mts.map +1 -0
  73. package/dist/{index-DR7hzXU4.d.mts → index-DLkMqvw4.d.mts} +137 -29
  74. package/dist/index-DLkMqvw4.d.mts.map +1 -0
  75. package/dist/index-DlWm_PwP.d.mts +436 -0
  76. package/dist/index-DlWm_PwP.d.mts.map +1 -0
  77. package/dist/{index-B0flvtFB.d.mts → index-DogEz6WQ.d.mts} +2 -2
  78. package/dist/{index-B0flvtFB.d.mts.map → index-DogEz6WQ.d.mts.map} +1 -1
  79. package/dist/{index-crtzMG48.d.mts → index-XxPUUAGQ.d.mts} +41 -6
  80. package/dist/index-XxPUUAGQ.d.mts.map +1 -0
  81. package/dist/{index-BqJ1GWAF.d.mts → index-pC80zLHb.d.mts} +2 -2
  82. package/dist/{index-BqJ1GWAF.d.mts.map → index-pC80zLHb.d.mts.map} +1 -1
  83. package/dist/index.d.mts +23 -20
  84. package/dist/index.mjs +1 -1
  85. package/dist/layer/index.d.mts +1 -1
  86. package/dist/layer/index.mjs +1 -1
  87. package/dist/layer-BmrPWBkT.mjs +2 -0
  88. package/dist/layer-BmrPWBkT.mjs.map +1 -0
  89. package/dist/{layer.types-BB0MrvLg.d.mts → layer.types-DsCTjICW.d.mts} +4 -4
  90. package/dist/{layer.types-BB0MrvLg.d.mts.map → layer.types-DsCTjICW.d.mts.map} +1 -1
  91. package/dist/log/index.d.mts +2 -0
  92. package/dist/log/index.mjs +1 -0
  93. package/dist/log-Bh8G5umo.mjs +2 -0
  94. package/dist/log-Bh8G5umo.mjs.map +1 -0
  95. package/dist/multithread/index.d.mts +1 -1
  96. package/dist/multithread/index.mjs +1 -1
  97. package/dist/multithread-CovZ2ioL.mjs +21 -0
  98. package/dist/multithread-CovZ2ioL.mjs.map +1 -0
  99. package/dist/option/index.d.mts +1 -1
  100. package/dist/option/index.mjs +1 -1
  101. package/dist/{option-C2iCxAuJ.mjs → option-BlyP5LA2.mjs} +2 -2
  102. package/dist/{option-C2iCxAuJ.mjs.map → option-BlyP5LA2.mjs.map} +1 -1
  103. package/dist/{option.types-D9hrKcfa.d.mts → option.types-DLp3QpFE.d.mts} +3 -3
  104. package/dist/{option.types-D9hrKcfa.d.mts.map → option.types-DLp3QpFE.d.mts.map} +1 -1
  105. package/dist/{option.types-CbY_swma.mjs → option.types-bFFSErJ-.mjs} +1 -1
  106. package/dist/{option.types-CbY_swma.mjs.map → option.types-bFFSErJ-.mjs.map} +1 -1
  107. package/dist/order/index.d.mts +1 -1
  108. package/dist/order/index.mjs +1 -1
  109. package/dist/{order-BXOBEKvB.mjs → order-VTXpppmI.mjs} +2 -2
  110. package/dist/{order-BXOBEKvB.mjs.map → order-VTXpppmI.mjs.map} +1 -1
  111. package/dist/{pipeable-BIrevC0D.d.mts → pipeable-BY9yPsNK.d.mts} +1 -1
  112. package/dist/{pipeable-BIrevC0D.d.mts.map → pipeable-BY9yPsNK.d.mts.map} +1 -1
  113. package/dist/pipeable-COGyGMUV.mjs +2 -0
  114. package/dist/{pipeable-Dp1_23zH.mjs.map → pipeable-COGyGMUV.mjs.map} +1 -1
  115. package/dist/predicate/index.d.mts +1 -1
  116. package/dist/predicate/index.mjs +1 -1
  117. package/dist/{predicate-D_1SsIi4.mjs → predicate-8hY-0Ocv.mjs} +2 -2
  118. package/dist/{predicate-D_1SsIi4.mjs.map → predicate-8hY-0Ocv.mjs.map} +1 -1
  119. package/dist/provide/index.d.mts +1 -1
  120. package/dist/provide/index.mjs +1 -1
  121. package/dist/provide-K-6oXtLm.mjs +2 -0
  122. package/dist/provide-K-6oXtLm.mjs.map +1 -0
  123. package/dist/queue/index.d.mts +1 -1
  124. package/dist/queue/index.mjs +1 -1
  125. package/dist/{queue-apiEOlRD.mjs → queue-CeEIUHcY.mjs} +2 -2
  126. package/dist/{queue-apiEOlRD.mjs.map → queue-CeEIUHcY.mjs.map} +1 -1
  127. package/dist/result/index.d.mts +1 -1
  128. package/dist/result/index.mjs +1 -1
  129. package/dist/{result-D3VY0qBG.mjs → result-C74pRN2x.mjs} +2 -2
  130. package/dist/{result-D3VY0qBG.mjs.map → result-C74pRN2x.mjs.map} +1 -1
  131. package/dist/{result.types-BKzChyWY.d.mts → result.types-CnhiVFEV.d.mts} +3 -3
  132. package/dist/{result.types-BKzChyWY.d.mts.map → result.types-CnhiVFEV.d.mts.map} +1 -1
  133. package/dist/schedule/index.d.mts +1 -1
  134. package/dist/schedule/index.mjs +1 -1
  135. package/dist/{schedule-C6iN3oMt.mjs → schedule-ChcIgvd5.mjs} +2 -2
  136. package/dist/{schedule-C6iN3oMt.mjs.map → schedule-ChcIgvd5.mjs.map} +1 -1
  137. package/dist/{schedule-D2651VJY.d.mts → schedule-DiidMLcl.d.mts} +3 -3
  138. package/dist/{schedule-D2651VJY.d.mts.map → schedule-DiidMLcl.d.mts.map} +1 -1
  139. package/dist/schema/index.d.mts +1 -1
  140. package/dist/schema/index.mjs +1 -1
  141. package/dist/schema-CT_wO7tN.mjs +2 -0
  142. package/dist/schema-CT_wO7tN.mjs.map +1 -0
  143. package/dist/scope/index.d.mts +1 -1
  144. package/dist/scope/index.mjs +1 -1
  145. package/dist/{scope-CuM3CzwG.d.mts → scope-7bLTmdRX.d.mts} +4 -4
  146. package/dist/scope-7bLTmdRX.d.mts.map +1 -0
  147. package/dist/scope-D2AqJy7j.mjs +2 -0
  148. package/dist/scope-D2AqJy7j.mjs.map +1 -0
  149. package/dist/service/index.d.mts +1 -1
  150. package/dist/service/index.mjs +1 -1
  151. package/dist/{service-D8mr0wwg.d.mts → service-C4xUfS_M.d.mts} +2 -2
  152. package/dist/{service-D8mr0wwg.d.mts.map → service-C4xUfS_M.d.mts.map} +1 -1
  153. package/dist/{service-CWAIEH46.mjs → service-DHkeorS3.mjs} +2 -2
  154. package/dist/{service-CWAIEH46.mjs.map → service-DHkeorS3.mjs.map} +1 -1
  155. package/dist/trace/index.d.mts +2 -0
  156. package/dist/trace/index.mjs +1 -0
  157. package/dist/trace-ByjppUes.mjs +2 -0
  158. package/dist/trace-ByjppUes.mjs.map +1 -0
  159. package/dist/trace-D_7sjH22.d.mts +375 -0
  160. package/dist/trace-D_7sjH22.d.mts.map +1 -0
  161. package/package.json +13 -5
  162. package/dist/adt/index.d.mts +0 -2
  163. package/dist/adt/index.mjs +0 -1
  164. package/dist/adt-CPG_sa8q.mjs +0 -2
  165. package/dist/adt-CPG_sa8q.mjs.map +0 -1
  166. package/dist/data-BHYPdqWZ.mjs +0 -2
  167. package/dist/data-BHYPdqWZ.mjs.map +0 -1
  168. package/dist/discriminator.types-C-ygT2S1.d.mts +0 -7
  169. package/dist/discriminator.types-C-ygT2S1.d.mts.map +0 -1
  170. package/dist/equality-BX6BUidG.mjs +0 -2
  171. package/dist/equality-BX6BUidG.mjs.map +0 -1
  172. package/dist/functions-ByAk682_.mjs +0 -2
  173. package/dist/fx-DUXDxwsU.mjs +0 -2
  174. package/dist/fx-DUXDxwsU.mjs.map +0 -1
  175. package/dist/fx.runtime-jQxh77s3.mjs +0 -2
  176. package/dist/fx.runtime-jQxh77s3.mjs.map +0 -1
  177. package/dist/index-B2Z7-XGR.d.mts.map +0 -1
  178. package/dist/index-B41_sFR6.d.mts +0 -64
  179. package/dist/index-B41_sFR6.d.mts.map +0 -1
  180. package/dist/index-C4DOLLaU.d.mts.map +0 -1
  181. package/dist/index-C6W3_n_Q.d.mts +0 -458
  182. package/dist/index-C6W3_n_Q.d.mts.map +0 -1
  183. package/dist/index-D8rDE60Y.d.mts.map +0 -1
  184. package/dist/index-DR7hzXU4.d.mts.map +0 -1
  185. package/dist/index-crtzMG48.d.mts.map +0 -1
  186. package/dist/layer-CKtH7TRL.mjs +0 -2
  187. package/dist/layer-CKtH7TRL.mjs.map +0 -1
  188. package/dist/multithread-Cyc8Bz45.mjs +0 -19
  189. package/dist/multithread-Cyc8Bz45.mjs.map +0 -1
  190. package/dist/pipeable-Dp1_23zH.mjs +0 -2
  191. package/dist/provide--yZE8x-n.mjs +0 -2
  192. package/dist/provide--yZE8x-n.mjs.map +0 -1
  193. package/dist/schema-DstB1_VK.mjs +0 -2
  194. package/dist/schema-DstB1_VK.mjs.map +0 -1
  195. package/dist/schema.shared-Bjyroa6b.mjs +0 -2
  196. package/dist/schema.shared-Bjyroa6b.mjs.map +0 -1
  197. package/dist/schema.types-E1pjcc0Y.d.mts +0 -62
  198. package/dist/schema.types-E1pjcc0Y.d.mts.map +0 -1
  199. package/dist/scope-CuM3CzwG.d.mts.map +0 -1
  200. package/dist/scope-gVt4PESc.mjs +0 -2
  201. package/dist/scope-gVt4PESc.mjs.map +0 -1
  202. package/dist/service-resolution-BefYr4nR.mjs +0 -2
  203. package/dist/service-resolution-BefYr4nR.mjs.map +0 -1
  204. /package/dist/{chunk-oQKkju2G.mjs → chunk-6rpU2rUb.mjs} +0 -0
  205. /package/dist/{option-CXXiA1w-.mjs → option-BqAUkJ8e.mjs} +0 -0
  206. /package/dist/{result-xFLfwriM.mjs → result-B5WbPg8C.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"context-0xDbwtpx.mjs","names":["service","impl","ctx"],"sources":["../src/context/context.ts"],"sourcesContent":["/**\n * Immutable service context map used by `Fx`, `Layer`, and `Provide`.\n *\n * **Mental model**\n * - A `Context` is a typed map from service key to implementation.\n * - Use it as the runtime carrier for dependency injection.\n *\n * **Common tasks**\n * - Start with `Context.empty` or `Context.make`.\n * - Combine contexts with `Context.add` and `Context.merge`.\n * - Resolve implementations with `Context.get`.\n *\n * **Gotchas**\n * - `Context.get` throws when a service is missing.\n * - Context values are immutable snapshots.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * const ctx = Context.empty()\n * // => { _tag: \"Context\", _services: Map(0) }\n * ```\n *\n * @module\n */\nimport type { ServiceClass } from \"../service/service\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Context uses phantom service-type markers and overloaded accessors that require narrowed assertions. */\n\n// ============================================================================\n// Context Type\n// ============================================================================\n\n/**\n * Context<Services> is an immutable map storing service implementations.\n * The Services type parameter tracks which services are available.\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * type Example = typeof Context\n * ```\n */\nexport type Context<Services = never> = {\n readonly _tag: \"Context\"\n readonly _services: ReadonlyMap<string, unknown>\n // Phantom type for tracking available services\n readonly _Services: Services\n}\n\n// ============================================================================\n// Context Constructors\n// ============================================================================\n\n/**\n * Create an empty context with no services.\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * const ctx = Context.empty()\n * // => { _tag: \"Context\", _services: Map(0) }\n * ```\n */\nexport const empty = (): Context => ({\n _tag: \"Context\",\n _services: new Map(),\n _Services: undefined as never,\n})\n\n/**\n * Create a context with a single service.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A context containing the service\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const ctx = Context.make(Logger, { log: (message) => console.log(message) })\n * // => context containing Logger\n * ```\n */\nexport const make = <S>(service: ServiceClass<S>, impl: S): Context<S> => ({\n _tag: \"Context\",\n _services: new Map([[service.key, impl]]),\n _Services: undefined as unknown as S,\n})\n\n// ============================================================================\n// Context Operations\n// ============================================================================\n\n/**\n * Add a service to an existing context (returns new context).\n * Curried for use with pipe.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A function that takes a context and returns a new context with the service added\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const Clock = Service.tag<{ now: () => number }>(\"Clock\")\n * const base = Context.make(Logger, { log: () => undefined })\n * const extended = Context.add(Clock, { now: () => 123 })(base)\n * // => context with Logger and Clock\n * ```\n */\nexport const add =\n <S>(service: ServiceClass<S>, impl: S) =>\n <Existing>(ctx: Context<Existing>): Context<Existing | S> => ({\n _tag: \"Context\",\n _services: new Map([...ctx._services, [service.key, impl]]),\n _Services: undefined as unknown as Existing | S,\n })\n\n/**\n * Merge two contexts together.\n * If both contexts have the same service, the second context's implementation wins.\n *\n * @param a - First context\n * @param b - Second context\n * @returns A new context with services from both\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const Clock = Service.tag<{ now: () => number }>(\"Clock\")\n * const a = Context.make(Logger, { log: () => undefined })\n * const b = Context.make(Clock, { now: () => 123 })\n * const merged = Context.merge(a, b)\n * // => context with both services\n * ```\n */\nexport const merge = <A, B>(a: Context<A>, b: Context<B>): Context<A | B> => ({\n _tag: \"Context\",\n _services: new Map([...a._services, ...b._services]),\n _Services: undefined as unknown as A | B,\n})\n\n/**\n * Get a service from a context.\n * Throws if the service is not found.\n *\n * @param service - The service class (tag)\n * @returns The service implementation\n * @throws Error if service not found\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const port = Context.get(ctx, Port)\n * // => 3000\n * ```\n */\n// Use overload to handle both curried and uncurried calls\nexport function get<S>(ctx: Context<S>, service: ServiceClass<S>): S\nexport function get<S>(service: ServiceClass<S>): (ctx: Context<S>) => S\nexport function get<S>(\n ctxOrService: Context<S> | ServiceClass<S>,\n maybeService?: ServiceClass<S>,\n): S | ((ctx: Context<S>) => S) {\n // Curried form: get(service)(ctx)\n if (maybeService === undefined) {\n const service = ctxOrService as ServiceClass<S>\n return (ctx: Context<S>): S => {\n const impl = ctx._services.get(service.key)\n if (impl === undefined) {\n throw new Error(\n `Service \"${service.key}\" not found in context. Available services: [${[...ctx._services.keys()].join(\", \")}]`,\n )\n }\n return impl as S\n }\n }\n\n // Uncurried form: get(ctx, service)\n const ctx = ctxOrService as Context<S>\n const service = maybeService\n const impl = ctx._services.get(service.key)\n if (impl === undefined) {\n throw new Error(\n `Service \"${service.key}\" not found in context. Available services: [${[...ctx._services.keys()].join(\", \")}]`,\n )\n }\n return impl as S\n}\n\n/**\n * Check if a context contains a specific service.\n *\n * @param ctx - The context to check\n * @param service - The service class (tag)\n * @returns true if the service is in the context\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const present = Context.has(ctx, Port)\n * // => true\n * ```\n */\nexport const has = <S>(ctx: Context<unknown>, service: ServiceClass<S>): boolean => ctx._services.has(service.key)\n\n/**\n * Get the size (number of services) in a context.\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const ctx = Context.add(Logger, { log: () => undefined })(Context.make(Port, 3000))\n * const count = Context.size(ctx)\n * // => 2\n * ```\n */\nexport const size = (ctx: Context<unknown>): number => ctx._services.size\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"gIAqEA,MAAa,OAAwB,CACnC,KAAM,UACN,UAAW,IAAI,IACf,UAAW,IAAA,GACZ,EAoBY,GAAW,EAA0B,KAAyB,CACzE,KAAM,UACN,UAAW,IAAI,IAAI,CAAC,CAAC,EAAQ,IAAK,EAAK,CAAC,CAAC,CACzC,UAAW,IAAA,GACZ,EA2BY,GACP,EAA0B,IACnB,IAAmD,CAC5D,KAAM,UACN,UAAW,IAAI,IAAI,CAAC,GAAG,EAAI,UAAW,CAAC,EAAQ,IAAK,EAAK,CAAC,CAAC,CAC3D,UAAW,IAAA,GACZ,EAwBU,GAAe,EAAe,KAAmC,CAC5E,KAAM,UACN,UAAW,IAAI,IAAI,CAAC,GAAG,EAAE,UAAW,GAAG,EAAE,UAAU,CAAC,CACpD,UAAW,IAAA,GACZ,EAyBD,SAAgB,EACd,EACA,EAC8B,CAE9B,GAAI,IAAiB,IAAA,GAAW,CAC9B,IAAMA,EAAU,EAChB,MAAQ,IAAuB,CAC7B,IAAMC,EAAOC,EAAI,UAAU,IAAIF,EAAQ,IAAI,CAC3C,GAAIC,IAAS,IAAA,GACX,MAAU,MACR,YAAYD,EAAQ,IAAI,+CAA+C,CAAC,GAAGE,EAAI,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,GAC7G,CAEH,OAAOD,GAKX,IAAM,EAAM,EACN,EAAU,EACV,EAAO,EAAI,UAAU,IAAI,EAAQ,IAAI,CAC3C,GAAI,IAAS,IAAA,GACX,MAAU,MACR,YAAY,EAAQ,IAAI,+CAA+C,CAAC,GAAG,EAAI,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,GAC7G,CAEH,OAAO,EAsBT,MAAa,GAAU,EAAuB,IAAsC,EAAI,UAAU,IAAI,EAAQ,IAAI,CAkBrG,EAAQ,GAAkC,EAAI,UAAU"}
1
+ {"version":3,"file":"context-7oKePrBY.mjs","names":["service","impl","ctx"],"sources":["../src/context/context.ts"],"sourcesContent":["/**\n * Immutable service context map used by `Fx`, `Layer`, and `Provide`.\n *\n * **Mental model**\n * - A `Context` is a typed map from service key to implementation.\n * - Use it as the runtime carrier for dependency injection.\n *\n * **Common tasks**\n * - Start with `Context.empty` or `Context.make`.\n * - Combine contexts with `Context.add` and `Context.merge`.\n * - Resolve implementations with `Context.get`.\n *\n * **Gotchas**\n * - `Context.get` throws when a service is missing.\n * - Context values are immutable snapshots.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * const ctx = Context.empty()\n * // => { _tag: \"Context\", _services: Map(0) }\n * ```\n *\n * @module\n */\nimport type { ServiceClass } from \"../service/service\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Context uses phantom service-type markers and overloaded accessors that require narrowed assertions. */\n\n// ============================================================================\n// Context Type\n// ============================================================================\n\n/**\n * Context<Services> is an immutable map storing service implementations.\n * The Services type parameter tracks which services are available.\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * type Example = typeof Context\n * ```\n */\nexport type Context<Services = never> = {\n readonly _tag: \"Context\"\n readonly _services: ReadonlyMap<string, unknown>\n // Phantom type for tracking available services\n readonly _Services: Services\n}\n\n// ============================================================================\n// Context Constructors\n// ============================================================================\n\n/**\n * Create an empty context with no services.\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * const ctx = Context.empty()\n * // => { _tag: \"Context\", _services: Map(0) }\n * ```\n */\nexport const empty = (): Context => ({\n _tag: \"Context\",\n _services: new Map(),\n _Services: undefined as never,\n})\n\n/**\n * Create a context with a single service.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A context containing the service\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const ctx = Context.make(Logger, { log: (message) => console.log(message) })\n * // => context containing Logger\n * ```\n */\nexport const make = <S>(service: ServiceClass<S>, impl: S): Context<S> => ({\n _tag: \"Context\",\n _services: new Map([[service.key, impl]]),\n _Services: undefined as unknown as S,\n})\n\n// ============================================================================\n// Context Operations\n// ============================================================================\n\n/**\n * Add a service to an existing context (returns new context).\n * Curried for use with pipe.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A function that takes a context and returns a new context with the service added\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const Clock = Service.tag<{ now: () => number }>(\"Clock\")\n * const base = Context.make(Logger, { log: () => undefined })\n * const extended = Context.add(Clock, { now: () => 123 })(base)\n * // => context with Logger and Clock\n * ```\n */\nexport const add =\n <S>(service: ServiceClass<S>, impl: S) =>\n <Existing>(ctx: Context<Existing>): Context<Existing | S> => ({\n _tag: \"Context\",\n _services: new Map([...ctx._services, [service.key, impl]]),\n _Services: undefined as unknown as Existing | S,\n })\n\n/**\n * Merge two contexts together.\n * If both contexts have the same service, the second context's implementation wins.\n *\n * @param a - First context\n * @param b - Second context\n * @returns A new context with services from both\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const Clock = Service.tag<{ now: () => number }>(\"Clock\")\n * const a = Context.make(Logger, { log: () => undefined })\n * const b = Context.make(Clock, { now: () => 123 })\n * const merged = Context.merge(a, b)\n * // => context with both services\n * ```\n */\nexport const merge = <A, B>(a: Context<A>, b: Context<B>): Context<A | B> => ({\n _tag: \"Context\",\n _services: new Map([...a._services, ...b._services]),\n _Services: undefined as unknown as A | B,\n})\n\n/**\n * Get a service from a context.\n * Throws if the service is not found.\n *\n * @param service - The service class (tag)\n * @returns The service implementation\n * @throws Error if service not found\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const port = Context.get(ctx, Port)\n * // => 3000\n * ```\n */\n// Use overload to handle both curried and uncurried calls\nexport function get<S>(ctx: Context<S>, service: ServiceClass<S>): S\nexport function get<S>(service: ServiceClass<S>): (ctx: Context<S>) => S\nexport function get<S>(\n ctxOrService: Context<S> | ServiceClass<S>,\n maybeService?: ServiceClass<S>,\n): S | ((ctx: Context<S>) => S) {\n // Curried form: get(service)(ctx)\n if (maybeService === undefined) {\n const service = ctxOrService as ServiceClass<S>\n return (ctx: Context<S>): S => {\n const impl = ctx._services.get(service.key)\n if (impl === undefined) {\n throw new Error(\n `Service \"${service.key}\" not found in context. Available services: [${[...ctx._services.keys()].join(\", \")}]`,\n )\n }\n return impl as S\n }\n }\n\n // Uncurried form: get(ctx, service)\n const ctx = ctxOrService as Context<S>\n const service = maybeService\n const impl = ctx._services.get(service.key)\n if (impl === undefined) {\n throw new Error(\n `Service \"${service.key}\" not found in context. Available services: [${[...ctx._services.keys()].join(\", \")}]`,\n )\n }\n return impl as S\n}\n\n/**\n * Check if a context contains a specific service.\n *\n * @param ctx - The context to check\n * @param service - The service class (tag)\n * @returns true if the service is in the context\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const present = Context.has(ctx, Port)\n * // => true\n * ```\n */\nexport const has = <S>(ctx: Context<unknown>, service: ServiceClass<S>): boolean => ctx._services.has(service.key)\n\n/**\n * Get the size (number of services) in a context.\n *\n * @example\n * ```ts\n * import { Context } from \"@nicolastoulemont/std\"\n *\n * import { Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const Logger = Service.tag<{ log: (message: string) => void }>(\"Logger\")\n * const ctx = Context.add(Logger, { log: () => undefined })(Context.make(Port, 3000))\n * const count = Context.size(ctx)\n * // => 2\n * ```\n */\nexport const size = (ctx: Context<unknown>): number => ctx._services.size\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"gIAqEA,MAAa,OAAwB,CACnC,KAAM,UACN,UAAW,IAAI,IACf,UAAW,IAAA,GACZ,EAoBY,GAAW,EAA0B,KAAyB,CACzE,KAAM,UACN,UAAW,IAAI,IAAI,CAAC,CAAC,EAAQ,IAAK,EAAK,CAAC,CAAC,CACzC,UAAW,IAAA,GACZ,EA2BY,GACP,EAA0B,IACnB,IAAmD,CAC5D,KAAM,UACN,UAAW,IAAI,IAAI,CAAC,GAAG,EAAI,UAAW,CAAC,EAAQ,IAAK,EAAK,CAAC,CAAC,CAC3D,UAAW,IAAA,GACZ,EAwBU,GAAe,EAAe,KAAmC,CAC5E,KAAM,UACN,UAAW,IAAI,IAAI,CAAC,GAAG,EAAE,UAAW,GAAG,EAAE,UAAU,CAAC,CACpD,UAAW,IAAA,GACZ,EAyBD,SAAgB,EACd,EACA,EAC8B,CAE9B,GAAI,IAAiB,IAAA,GAAW,CAC9B,IAAMA,EAAU,EAChB,MAAQ,IAAuB,CAC7B,IAAMC,EAAOC,EAAI,UAAU,IAAIF,EAAQ,IAAI,CAC3C,GAAIC,IAAS,IAAA,GACX,MAAU,MACR,YAAYD,EAAQ,IAAI,+CAA+C,CAAC,GAAGE,EAAI,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,GAC7G,CAEH,OAAOD,GAKX,IAAM,EAAM,EACN,EAAU,EACV,EAAO,EAAI,UAAU,IAAI,EAAQ,IAAI,CAC3C,GAAI,IAAS,IAAA,GACX,MAAU,MACR,YAAY,EAAQ,IAAI,+CAA+C,CAAC,GAAG,EAAI,UAAU,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,GAC7G,CAEH,OAAO,EAsBT,MAAa,GAAU,EAAuB,IAAsC,EAAI,UAAU,IAAI,EAAQ,IAAI,CAkBrG,EAAQ,GAAkC,EAAI,UAAU"}
@@ -1,4 +1,4 @@
1
- import { t as ServiceClass } from "./service-D8mr0wwg.mjs";
1
+ import { t as ServiceClass } from "./service-C4xUfS_M.mjs";
2
2
 
3
3
  //#region src/context/context.d.ts
4
4
  declare namespace context_d_exports {
@@ -157,4 +157,4 @@ declare const has: <S>(ctx: Context<unknown>, service: ServiceClass<S>) => boole
157
157
  declare const size: (ctx: Context<unknown>) => number;
158
158
  //#endregion
159
159
  export { context_d_exports as n, Context as t };
160
- //# sourceMappingURL=context-B2dWloPl.d.mts.map
160
+ //# sourceMappingURL=context-B9oWzbwF.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-B2dWloPl.d.mts","names":[],"sources":["../src/context/context.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AA0JA;;;;;;;AAA2D,KA3G/C,OA2G+C,CAAA,WAAA,KAAA,CAAA,GAAA;EAAO,SAAA,IAAA,EAAA,SAAA;EA2BlD,SAAG,SAAA,EApIG,WAoIH,CAAA,MAAA,EAAA,OAAA,CAAA;EAAiB,SAAA,SAAA,EAlId,QAkIc;CAAR;;;;;AAC5B;;;;;;;AAkDa,cAnKA,KAmKqG,EAAA,GAAA,GAnKzF,OAmKyF;;;;;AAkBlH;;;;;;;;;;;;;;cA7Ja,mBAAoB,aAAa,UAAU,MAAI,QAAQ;;;;;;;;;;;;;;;;;;;;;;cA+BvD,kBACE,aAAa,UAAU,sBACpB,QAAQ,cAAY,QAAQ,WAAW;;;;;;;;;;;;;;;;;;;;;;;cA4B5C,iBAAkB,QAAQ,OAAO,QAAQ,OAAK,QAAQ,IAAI;;;;;;;;;;;;;;;;;;;;;iBA2BvD,YAAY,QAAQ,aAAa,aAAa,KAAK;iBACnD,gBAAgB,aAAa,WAAW,QAAQ,OAAO;;;;;;;;;;;;;;;;;;;;cAkD1D,cAAe,2BAA2B,aAAa;;;;;;;;;;;;;;;;;cAkBvD,YAAa"}
1
+ {"version":3,"file":"context-B9oWzbwF.d.mts","names":[],"sources":["../src/context/context.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AA0JA;;;;;;;AAA2D,KA3G/C,OA2G+C,CAAA,WAAA,KAAA,CAAA,GAAA;EAAO,SAAA,IAAA,EAAA,SAAA;EA2BlD,SAAG,SAAA,EApIG,WAoIH,CAAA,MAAA,EAAA,OAAA,CAAA;EAAiB,SAAA,SAAA,EAlId,QAkIc;CAAR;;;;;AAC5B;;;;;;;AAkDa,cAnKA,KAmKqG,EAAA,GAAA,GAnKzF,OAmKyF;;;;;AAkBlH;;;;;;;;;;;;;;cA7Ja,mBAAoB,aAAa,UAAU,MAAI,QAAQ;;;;;;;;;;;;;;;;;;;;;;cA+BvD,kBACE,aAAa,UAAU,sBACpB,QAAQ,cAAY,QAAQ,WAAW;;;;;;;;;;;;;;;;;;;;;;;cA4B5C,iBAAkB,QAAQ,OAAO,QAAQ,OAAK,QAAQ,IAAI;;;;;;;;;;;;;;;;;;;;;iBA2BvD,YAAY,QAAQ,aAAa,aAAa,KAAK;iBACnD,gBAAgB,aAAa,WAAW,QAAQ,OAAO;;;;;;;;;;;;;;;;;;;;cAkD1D,cAAe,2BAA2B,aAAa;;;;;;;;;;;;;;;;;cAkBvD,YAAa"}
@@ -1,2 +1,2 @@
1
- import { t as data_d_exports } from "../index-B2Z7-XGR.mjs";
1
+ import { t as data_d_exports } from "../index-D-KxgnwF.mjs";
2
2
  export { data_d_exports as Data };
@@ -1 +1 @@
1
- import{n as e}from"../data-BHYPdqWZ.mjs";export{e as Data};
1
+ import{n as e}from"../data-W10ldR5l.mjs";export{e as Data};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{t}from"./fx.types-Bg-Mmdm5.mjs";const n=16777619,r=()=>({hashes:new WeakMap,inProgress:new WeakSet,objectIds:new WeakMap,nextObjectId:1}),i=(e,t)=>{let n=e.objectIds.get(t);if(n!==void 0)return n;let r=e.nextObjectId;return e.objectIds.set(t,r),e.nextObjectId++,r},a=(e,t)=>{let r=2166136261;if(e===null)return r^1853189228;if(e===void 0)return r^1970168933;switch(typeof e){case`boolean`:return r^(e?1:0);case`number`:return Number.isNaN(e)?r^5136718:Number.isFinite(e)?r^(e|0)^(e*1e6|0):r^(e>0?4812390:759787110);case`string`:for(let t=0;t<e.length;t++)r^=e.codePointAt(t),r=Math.imul(r,n);return r>>>0;case`object`:{let o=e,s=t.hashes.get(o);if(s!==void 0)return s;if(t.inProgress.has(o))return(r^1668899692^i(t,o))>>>0;if(e instanceof Date)return r^a(e.getTime(),t);if(t.inProgress.add(o),i(t,o),Array.isArray(e)){r^=23389;for(let i=0;i<e.length;i++)r^=a(e[i],t),r=Math.imul(r,n);let i=r>>>0;return t.inProgress.delete(o),t.hashes.set(o,i),i}r^=31613;let c=e,l=Object.keys(c).toSorted();for(let e of l)r^=a(e,t),r=Math.imul(r,n),r^=a(c[e],t),r=Math.imul(r,n);let u=r>>>0;return t.inProgress.delete(o),t.hashes.set(o,u),u}default:return r}};function o(e){return a(e,r())}const s=(e,t,n)=>{let r=e.get(t);return r?.has(n)===!0?!0:r===void 0?(e.set(t,new WeakSet([n])),!1):(r.add(n),!1)},c=(e,t,n)=>{if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||typeof t!=`object`)return!1;if(s(n,e,t))return!0;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length?e.every((e,r)=>c(e,t[r],n)):!1;if(Array.isArray(e)!==Array.isArray(t))return!1;let r=e,i=t,a=Object.keys(r),o=Object.keys(i);return a.length===o.length?a.every(e=>c(r[e],i[e],n)):!1};function l(e,t){return c(e,t,new WeakMap)}function u(e){return(t,n)=>t===n?!0:t._tag!==e||n._tag!==e?!1:l(t,n)}function d(e){return t=>t._tag===e?o(t):0}function f(e){return(t,n)=>t===n?!0:t._tag!==n._tag||!e.includes(t._tag)?!1:l(t,n)}function p(e){return t=>e.includes(t._tag)?o(t):0}function m(e){let t=[...e];Object.defineProperty(t,`equals`,{value:e=>l(t,e),enumerable:!1,writable:!1,configurable:!1}),Object.defineProperty(t,`hash`,{value:()=>o(t),enumerable:!1,writable:!1,configurable:!1});let n=t.map.bind(t);Object.defineProperty(t,`map`,{value:e=>m(n(e)),enumerable:!1,writable:!1,configurable:!1});let r=t.filter.bind(t);Object.defineProperty(t,`filter`,{value:e=>m(r(e)),enumerable:!1,writable:!1,configurable:!1});let i=t.slice.bind(t);Object.defineProperty(t,`slice`,{value:(e,t)=>m(i(e,t)),enumerable:!1,writable:!1,configurable:!1});let a=t.concat.bind(t);return Object.defineProperty(t,`concat`,{value:(...e)=>m(a(...e)),enumerable:!1,writable:!1,configurable:!1}),Object.freeze(t)}function h(e,t){let n=t[e._tag];return n(e)}function g(e){let t={...e};return Object.defineProperty(t,`equals`,{value:e=>l(t,e),enumerable:!1,writable:!1,configurable:!1}),Object.defineProperty(t,`hash`,{value:()=>o(t),enumerable:!1,writable:!1,configurable:!1}),Object.freeze(t)}function _(e){let t=t=>Object.freeze({...t,_tag:e});return t.is=t=>typeof t==`object`&&!!t&&`_tag`in t&&t._tag===e,t.equals=u(e),t.hash=d(e),t._tag=e,t}function v(e){return class extends Error{static _tag=e;_tag=e;[t]={_A:()=>void 0,_E:()=>this,_R:()=>void 0};constructor(...t){super(e),this.name=e;let n=t[0];n&&Object.assign(this,n),Object.setPrototypeOf(this,new.target.prototype)}*[Symbol.iterator](){throw yield this,Error(`Unreachable: Fx.gen should short-circuit on error`)}}}function y(...e){let t=[...e];return Object.defineProperty(t,`equals`,{value:e=>l(t,e),enumerable:!1,writable:!1,configurable:!1}),Object.defineProperty(t,`hash`,{value:()=>o(t),enumerable:!1,writable:!1,configurable:!1}),Object.freeze(t)}var b=e({TaggedError:()=>S,array:()=>E,match:()=>w,struct:()=>C,tagged:()=>x,tuple:()=>T});const x=_,S=v,C=g,w=h,T=y,E=m;export{p as a,f as i,b as n,u as o,g as r,d as s,S as t};
2
+ //# sourceMappingURL=data-W10ldR5l.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-W10ldR5l.mjs","names":["result","array","match","struct","tagged","TaggedError","tuple","taggedImpl","TaggedErrorImpl","structImpl","matchImpl","tupleImpl","arrayImpl"],"sources":["../src/equality/equality.ts","../src/data/data.array.ts","../src/data/data.match.ts","../src/data/data.struct.ts","../src/data/data.tagged.ts","../src/data/data.tagged-error.ts","../src/data/data.tuple.ts","../src/data/data.ts"],"sourcesContent":["import type { Discriminator } from \"../shared/discriminator.types\"\n\n// ============================================================================\n// Hashing (FNV-1a inspired algorithm)\n// ============================================================================\n\nconst FNV_OFFSET = 2166136261\nconst FNV_PRIME = 16777619\n// \"cycl\"\nconst CYCLE_MARKER = 0x6379636c\n\ntype HashState = {\n readonly hashes: WeakMap<object, number>\n readonly inProgress: WeakSet<object>\n readonly objectIds: WeakMap<object, number>\n nextObjectId: number\n}\n\nconst createHashState = (): HashState => ({\n hashes: new WeakMap<object, number>(),\n inProgress: new WeakSet<object>(),\n objectIds: new WeakMap<object, number>(),\n nextObjectId: 1,\n})\n\nconst getObjectId = (state: HashState, value: object): number => {\n const existing = state.objectIds.get(value)\n if (existing !== undefined) return existing\n const id = state.nextObjectId\n state.objectIds.set(value, id)\n state.nextObjectId++\n return id\n}\n\nconst deepHashInternal = (value: unknown, state: HashState): number => {\n let hash = FNV_OFFSET\n\n // \"null\" as hex\n if (value === null) return hash ^ 0x6e756c6c\n // \"unde\" as hex\n if (value === undefined) return hash ^ 0x756e6465\n\n /* oxlint-disable unicorn/prefer-math-trunc, no-case-declarations, switch-exhaustiveness-check -- Bitwise ops are intentional for FNV-1a hash: | 0 truncates to signed 32-bit, >>> 0 converts to unsigned 32-bit (Math.trunc cannot do this). Default case handles function, symbol, bigint. */\n switch (typeof value) {\n case \"boolean\":\n return hash ^ (value ? 1 : 0)\n\n case \"number\": {\n // Handle special cases: \"NaN\" as hex\n if (Number.isNaN(value)) return hash ^ 0x4e614e\n if (!Number.isFinite(value)) return hash ^ (value > 0 ? 0x496e66 : 0x2d496e66)\n // Mix the number bits into hash\n return hash ^ (value | 0) ^ ((value * 1000000) | 0)\n }\n\n case \"string\":\n for (let i = 0; i < value.length; i++) {\n hash ^= value.codePointAt(i)!\n hash = Math.imul(hash, FNV_PRIME)\n }\n // Convert to unsigned 32-bit\n return hash >>> 0\n\n case \"object\": {\n const objectValue = value\n\n const existingHash = state.hashes.get(objectValue)\n if (existingHash !== undefined) return existingHash\n\n if (state.inProgress.has(objectValue)) {\n return (hash ^ CYCLE_MARKER ^ getObjectId(state, objectValue)) >>> 0\n }\n\n if (value instanceof Date) {\n return hash ^ deepHashInternal(value.getTime(), state)\n }\n\n state.inProgress.add(objectValue)\n getObjectId(state, objectValue)\n\n if (Array.isArray(value)) {\n // \"[]\" as hex\n hash ^= 0x5b5d\n for (let i = 0; i < value.length; i++) {\n hash ^= deepHashInternal(value[i], state)\n hash = Math.imul(hash, FNV_PRIME)\n }\n const result = hash >>> 0\n state.inProgress.delete(objectValue)\n state.hashes.set(objectValue, result)\n return result\n }\n\n // Plain object: \"{}\" as hex\n hash ^= 0x7b7d\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for object iteration\n const obj = value as Record<string, unknown>\n // Sort keys for consistency\n const keys = Object.keys(obj).toSorted()\n for (const key of keys) {\n hash ^= deepHashInternal(key, state)\n hash = Math.imul(hash, FNV_PRIME)\n hash ^= deepHashInternal(obj[key], state)\n hash = Math.imul(hash, FNV_PRIME)\n }\n const result = hash >>> 0\n state.inProgress.delete(objectValue)\n state.hashes.set(objectValue, result)\n return result\n }\n\n default:\n // Handles: function, symbol, bigint\n return hash\n }\n /* oxlint-enable unicorn/prefer-math-trunc, no-case-declarations */\n}\n\n/**\n * Compute a 32-bit hash code for any value using an FNV-1a inspired algorithm.\n *\n * Handles: primitives, null, undefined, Date, arrays, plain objects, and cyclic structures.\n * Object keys are sorted for deterministic hashing regardless of insertion order.\n *\n * @param value - The value to hash (any type)\n * @returns A 32-bit unsigned integer hash code\n *\n * @example\n * ```ts\n * deepHash({ a: 1, b: 2 }) // deterministic number\n * deepHash({ b: 2, a: 1 }) // same number (keys sorted)\n * deepHash([1, 2, 3]) === deepHash([1, 2, 3]) // true\n * ```\n */\nexport function deepHash(value: unknown): number {\n return deepHashInternal(value, createHashState())\n}\n\ntype EqualsState = WeakMap<object, WeakSet<object>>\n\nconst markComparedPair = (state: EqualsState, a: object, b: object): boolean => {\n const compared = state.get(a)\n if (compared?.has(b) === true) return true\n if (compared === undefined) {\n state.set(a, new WeakSet<object>([b]))\n return false\n }\n compared.add(b)\n return false\n}\n\nconst deepEqualsInternal = (a: unknown, b: unknown, state: EqualsState): boolean => {\n // Same reference or both null/undefined\n if (a === b) return true\n\n // Different types\n if (typeof a !== typeof b) return false\n\n // Handle null\n if (a === null || b === null) return false\n\n // Primitives (already checked === above)\n if (typeof a !== \"object\") return false\n if (typeof b !== \"object\") return false\n\n const aObjRef = a\n const bObjRef = b\n\n if (markComparedPair(state, aObjRef, bObjRef)) return true\n\n // Date comparison\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n // Array comparison\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((item, index) => deepEqualsInternal(item, b[index], state))\n }\n\n // Plain object comparison\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for object comparison\n const aObj = a as Record<string, unknown>\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for object comparison\n const bObj = b as Record<string, unknown>\n\n const aKeys = Object.keys(aObj)\n const bKeys = Object.keys(bObj)\n\n if (aKeys.length !== bKeys.length) return false\n\n return aKeys.every((key) => deepEqualsInternal(aObj[key], bObj[key], state))\n}\n\n// ============================================================================\n// Equality\n// ============================================================================\n\n/**\n * Deep structural equality comparison for two values.\n *\n * Compares by value rather than reference. Handles:\n * - Primitives (===)\n * - null and undefined\n * - Date objects (by timestamp)\n * - Arrays (element-wise, same length required)\n * - Plain objects (key-value pairs, same keys required)\n * - Cyclic/self-referential object graphs\n *\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are structurally equal\n *\n * @example\n * ```ts\n * deepEquals({ x: 1 }, { x: 1 }) // true\n * deepEquals([1, 2], [1, 2]) // true\n * deepEquals(new Date(0), new Date(0)) // true\n * deepEquals({ a: 1 }, { a: 1, b: 2 }) // false (different keys)\n * ```\n */\nexport function deepEquals(a: unknown, b: unknown): boolean {\n return deepEqualsInternal(a, b, new WeakMap<object, WeakSet<object>>())\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create an equals method for a specific record type.\n *\n * Returns a function that compares two values of the same record type.\n * Returns false if either value doesn't have the expected _tag.\n *\n * @template Tag - The discriminator string literal type\n * @template T - The record's data type (excluding _tag)\n * @param _tag - The expected _tag discriminator value\n * @returns A binary equality function for the record type\n *\n * @example\n * ```ts\n * const equalsPoint = createEqualsMethod<'Point', { x: number; y: number }>('Point')\n * equalsPoint(\n * { _tag: 'Point', x: 1, y: 2 },\n * { _tag: 'Point', x: 1, y: 2 }\n * ) // true\n * ```\n */\nexport function createEqualsMethod<Tag extends string, T>(\n _tag: Tag,\n): (a: T & Discriminator<Tag>, b: T & Discriminator<Tag>) => boolean {\n return (a, b) => {\n if (a === b) return true\n if (a._tag !== _tag || b._tag !== _tag) return false\n return deepEquals(a, b)\n }\n}\n\n/**\n * Create a hash method for a specific record type.\n *\n * Returns a function that computes a hash code for values of the record type.\n * Returns 0 if the value doesn't have the expected _tag.\n *\n * @template Tag - The discriminator string literal type\n * @template T - The record's data type (excluding _tag)\n * @param _tag - The expected _tag discriminator value\n * @returns A unary hash function for the record type\n *\n * @example\n * ```ts\n * const hashPoint = createHashMethod<'Point', { x: number; y: number }>('Point')\n * hashPoint({ _tag: 'Point', x: 1, y: 2 }) // number\n * ```\n */\nexport function createHashMethod<Tag extends string, T>(_tag: Tag): (value: T & Discriminator<Tag>) => number {\n return (value) => {\n if (value._tag !== _tag) return 0\n return deepHash(value)\n }\n}\n\n/**\n * Create an equals method for an ADT (any variant).\n *\n * Returns a function that compares two ADT values for structural equality.\n * Values must have the same _tag and be a known variant.\n *\n * @template T - The ADT type (union of all variants with _tag)\n * @param tags - Array of valid _tag values for this ADT\n * @returns A binary equality function for any variant of the ADT\n *\n * @example\n * ```ts\n * const equalsShape = createADTEqualsMethod<Circle | Square>(['Circle', 'Square'])\n * equalsShape(circle1, circle2) // true if structurally equal\n * equalsShape(circle, square) // false (different _tag)\n * ```\n */\nexport function createADTEqualsMethod<T extends { readonly _tag: string }>(tags: string[]): (a: T, b: T) => boolean {\n return (a, b) => {\n if (a === b) return true\n if (a._tag !== b._tag) return false\n if (!tags.includes(a._tag)) return false\n return deepEquals(a, b)\n }\n}\n\n/**\n * Create a hash method for an ADT (any variant).\n *\n * Returns a function that computes a hash code for any variant of the ADT.\n * Returns 0 if the value's _tag is not a known variant.\n *\n * @template T - The ADT type (union of all variants with _tag)\n * @param tags - Array of valid _tag values for this ADT\n * @returns A unary hash function for any variant of the ADT\n *\n * @example\n * ```ts\n * const hashShape = createADTHashMethod<Circle | Square>(['Circle', 'Square'])\n * hashShape(circle) // number\n * hashShape(square) // number\n * ```\n */\nexport function createADTHashMethod<T extends { readonly _tag: string }>(tags: string[]): (value: T) => number {\n return (value) => {\n if (!tags.includes(value._tag)) return 0\n return deepHash(value)\n }\n}\n","import { deepEquals, deepHash } from \"../equality/equality\"\nimport type { ArrayValue } from \"./data.types\"\n\n/**\n * Create an array with structural equality.\n *\n * The returned array is frozen (immutable) and has non-enumerable\n * equals() and hash() methods for structural comparison.\n *\n * The map() and filter() methods are overridden to return ArrayValue,\n * enabling method chaining with preserved equality semantics.\n *\n * @template T - The element type of the array\n * @param items - The array elements\n * @returns A frozen array with equals(), hash(), map(), and filter()\n *\n * @see {@link tuple} for fixed-length typed tuples\n * @see {@link struct} for struct value types\n *\n * @example\n * ```ts\n * const arr1 = array([1, 2, 3])\n * const arr2 = array([1, 2, 3])\n *\n * arr1.equals(arr2) // true\n * arr1.hash() // number\n *\n * // Chainable operations return ArrayValue\n * arr1.map(x => x * 2) // ArrayValue<number>\n * arr1.filter(x => x > 1) // ArrayValue<number>\n *\n * // Chained equality check\n * arr1.map(x => x * 2).equals(array([2, 4, 6])) // true\n *\n * // Array is frozen\n * arr1[0] = 5 // TypeError\n * arr1.push(4) // TypeError\n * ```\n */\nexport function array<T>(items: readonly T[]): ArrayValue<T> {\n const value = [...items]\n\n // Add equals method (non-enumerable)\n Object.defineProperty(value, \"equals\", {\n value: (other: readonly T[]) => deepEquals(value, other),\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // Add hash method (non-enumerable)\n Object.defineProperty(value, \"hash\", {\n value: () => deepHash(value),\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // Override map to return ArrayValue\n const originalMap = value.map.bind(value)\n Object.defineProperty(value, \"map\", {\n value: <U>(fn: (item: T, index: number, arr: readonly T[]) => U): ArrayValue<U> => {\n return array(originalMap(fn))\n },\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // Override filter to return ArrayValue\n const originalFilter = value.filter.bind(value)\n Object.defineProperty(value, \"filter\", {\n value: (fn: (item: T, index: number, arr: readonly T[]) => boolean): ArrayValue<T> => {\n return array(originalFilter(fn))\n },\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // Override slice to return ArrayValue\n const originalSlice = value.slice.bind(value)\n Object.defineProperty(value, \"slice\", {\n value: (start?: number, end?: number): ArrayValue<T> => {\n return array(originalSlice(start, end))\n },\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // Override concat to return ArrayValue\n const originalConcat = value.concat.bind(value)\n Object.defineProperty(value, \"concat\", {\n value: (...args: readonly (T | readonly T[])[]): ArrayValue<T> => {\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for concat argument spread\n return array(originalConcat(...(args as T[][])))\n },\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for generic array return type\n return Object.freeze(value) as unknown as ArrayValue<T>\n}\n","/**\n * Handler functions for each variant in a discriminated union.\n * Each key maps to a function that receives the variant value and returns TResult.\n *\n * @template T - The discriminated union type (must have readonly _tag)\n * @template TResult - The return type of all handlers\n */\ntype MatchHandlers<T extends { readonly _tag: string }, TResult> = {\n [K in T[\"_tag\"]]: (value: Extract<T, { readonly _tag: K }>) => TResult\n}\n\n/**\n * Exhaustive pattern matching for discriminated unions.\n *\n * TypeScript will error if any variant is missing from handlers,\n * ensuring exhaustive handling of all cases.\n *\n * @template T - The discriminated union type (must have readonly _tag)\n * @template TResult - The return type of all handlers\n * @template Handlers - The handler object type (inferred)\n * @param value - A discriminated union value with _tag\n * @param handlers - An object with a handler function for each variant\n * @returns The result of calling the matching handler\n *\n */\nexport function match<\n T extends { readonly _tag: string },\n TResult,\n Handlers extends MatchHandlers<T, TResult> = MatchHandlers<T, TResult>,\n>(value: T, handlers: Handlers): TResult {\n const tag = value._tag as keyof Handlers\n const handler = handlers[tag]\n // oxlint-disable-next-line no-explicit-any, no-unsafe-argument, no-unsafe-type-assertion -- Required for variant dispatch\n return handler(value as any)\n}\n","import { deepEquals, deepHash } from \"../equality/equality\"\nimport type { StructValue } from \"./data.types\"\n\n/**\n * Create a frozen struct value with structural equality.\n *\n * Unlike tagged(), struct() does not add a _tag discriminator.\n * Use this for simple value objects that don't need discrimination.\n *\n * The returned object is frozen (immutable) and has non-enumerable\n * equals() and hash() methods for structural comparison.\n */\nexport function struct<T extends Record<string, unknown>>(input: T): StructValue<T> {\n const value = { ...input }\n\n Object.defineProperty(value, \"equals\", {\n value: (other: T) => deepEquals(value, other),\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n Object.defineProperty(value, \"hash\", {\n value: () => deepHash(value),\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for generic struct return type\n return Object.freeze(value) as StructValue<T>\n}\n","import { createEqualsMethod, createHashMethod } from \"../equality/equality\"\nimport type { Discriminator } from \"../shared/discriminator.types\"\nimport type { TaggedConstructor, TaggedValue } from \"./data.types\"\n\n/**\n * Create a tagged value constructor without schema validation.\n *\n * Unlike tagged(), this creates values directly without validation.\n * Values are frozen and have structural equality via equals() and hash() methods.\n *\n * @template T - The data shape type (excluding _tag)\n * @param tag - The _tag discriminator value\n * @returns A constructor function with is(), equals(), and hash() methods\n *\n * @see {@link variant} for validated variant with schema support\n * @see {@link struct} for struct value objects\n *\n * @example\n * ```ts\n * const Person = tagged<{ name: string; age: number }>(\"Person\")\n *\n * const alice = Person({ name: \"Alice\", age: 30 })\n * // => { _tag: \"Person\", name: \"Alice\", age: 30 }\n *\n * Person.equals(alice, Person({ name: \"Alice\", age: 30 })) // true\n * Person.is(alice) // true\n *\n * // Type guard usage\n * if (Person.is(unknownValue)) {\n * console.log(unknownValue.name) // TypeScript knows it's a Person\n * }\n *\n * // Values are frozen (immutable)\n * alice.name = \"Bob\" // TypeError\n * ```\n */\nexport function tagged<T extends Record<string, unknown>>(tag: string): TaggedConstructor<typeof tag, T> {\n type Output = TaggedValue<typeof tag, T>\n\n // Constructor function\n const constructor = (input: T): Output => {\n return Object.freeze({ ...input, _tag: tag }) as Output\n }\n\n // Type guard\n constructor.is = (value: unknown): value is Output => {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n // oxlint-disable-next-line no-unsafe-type-assertion -- Already checked with 'in' operator\n (value as Discriminator)._tag === tag\n )\n }\n\n // Equality (static method on constructor)\n constructor.equals = createEqualsMethod<typeof tag, T>(tag)\n\n // Hashing (static method on constructor)\n constructor.hash = createHashMethod<typeof tag, T>(tag)\n\n // Store tag for reflection\n constructor._tag = tag\n\n return constructor as TaggedConstructor<typeof tag, T>\n}\n","import { FxTypeId } from \"../fx/fx.types\"\nimport type { TaggedErrorFactory } from \"./data.tagged-error.types\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Tagged error factories intentionally cast to preserve ergonomic constructor signatures and Fx marker channels. */\n\n/**\n * Create a class-based tagged error type (Effect-style syntax).\n * Returns a class that can be extended to create custom error types.\n * Errors are native Error objects with proper stack traces and instanceof support.\n * Implements Yieldable protocol so errors can be directly yielded in Fx.gen computations.\n *\n * @template Tag - The error tag (discriminator string)\n * @param tag - The error tag\n * @returns A class that can be extended with custom data\n *\n * @example\n * ```ts\n * // Error with data\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{ id: string }> {}\n * const err = new NotFoundError({ id: \"123\" })\n * err.id // \"123\"\n * err._tag // \"NotFoundError\"\n * err.stack // Error stack trace\n *\n * // Error without data\n * class UnauthorizedError extends TaggedError(\"UnauthorizedError\") {}\n * const err2 = new UnauthorizedError()\n *\n * // Direct yielding in Fx.gen computation\n * const program = Fx.gen(function* () {\n * yield* new NotFoundError({ id: \"123\" }) // Short-circuits with error\n * })\n *\n * // instanceof checks work\n * if (err instanceof NotFoundError) {\n * console.log(err.id)\n * }\n * ```\n */\nexport function TaggedError<Tag extends string>(tag: Tag): TaggedErrorFactory<Tag> {\n return class TaggedErrorImpl<Data extends object = object> extends Error {\n static readonly _tag: Tag = tag\n readonly _tag: Tag = tag\n\n readonly [FxTypeId] = {\n _A: () => undefined as never,\n _E: () => this as TaggedErrorImpl<Data>,\n _R: () => undefined as never,\n }\n\n constructor(...args: keyof Data extends never ? [] : [data: Data]) {\n super(tag)\n this.name = tag\n const data = args[0]\n if (data) Object.assign(this, data)\n Object.setPrototypeOf(this, new.target.prototype)\n }\n\n *[Symbol.iterator](): Generator<this, never, unknown> {\n yield this\n throw new Error(\"Unreachable: Fx.gen should short-circuit on error\")\n }\n } as unknown as TaggedErrorFactory<Tag>\n}\n\n/* oxlint-enable no-unsafe-type-assertion */\n","import { deepEquals, deepHash } from \"../equality/equality\"\nimport type { TupleValue } from \"./data.types\"\n\n/**\n * Create a tuple with structural equality.\n *\n * The returned tuple is frozen (immutable) and has non-enumerable\n * equals() and hash() methods for structural comparison.\n *\n * @template T - The tuple type as a readonly array of element types\n * @param args - The tuple elements\n * @returns A frozen tuple-like array with equals() and hash() methods\n *\n * @see {@link array} for variable-length arrays with equality\n * @see {@link struct} for struct value types\n *\n * @example\n * ```ts\n * const t1 = tuple(1, \"hello\", true)\n * const t2 = tuple(1, \"hello\", true)\n *\n * t1.equals(t2) // true\n * t1.hash() // number\n *\n * // Access elements (typed)\n * t1[0] // number\n * t1[1] // string\n * t1[2] // boolean\n *\n * // Tuple is frozen\n * t1[0] = 5 // TypeError\n * ```\n */\nexport function tuple<T extends readonly unknown[]>(...args: T): TupleValue<T> {\n const value = [...args]\n\n // Add equals method (non-enumerable)\n Object.defineProperty(value, \"equals\", {\n value: (other: readonly unknown[]) => deepEquals(value, other),\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // Add hash method (non-enumerable)\n Object.defineProperty(value, \"hash\", {\n value: () => deepHash(value),\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n // oxlint-disable-next-line no-unsafe-type-assertion -- Required for generic tuple return type\n return Object.freeze(value) as unknown as TupleValue<T>\n}\n","/**\n * Structural data constructors for tagged objects, structs, tuples, and arrays.\n *\n * **Mental model**\n * - `Data` helpers create immutable-friendly values with structural equality semantics.\n * - `Data.struct` creates immutable-friendly object values with structural equality semantics.\n * - Use `tagged` and `TaggedError` to model domain objects and errors.\n *\n * **Common tasks**\n * - Build tagged records via `Data.tagged`.\n * - Build struct values via `Data.struct`.\n * - Define typed tagged errors with `Data.TaggedError`.\n * - Create structural containers with `Data.struct`, `Data.tuple`, and `Data.array`.\n *\n * **Gotchas**\n * - `Data` helpers are value-level utilities, not validation schemas.\n * - Prefer explicit tagged names for debugging and pattern matching.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Data } from \"@nicolastoulemont/std\"\n *\n * const User = Data.tagged<{ id: string }>(\"User\")\n * const user = User({ id: \"u1\" })\n * // => { _tag: \"User\", id: \"u1\" }\n * ```\n *\n * @module\n */\nimport { array as arrayImpl } from \"./data.array\"\nimport { match as matchImpl } from \"./data.match\"\nimport { struct as structImpl } from \"./data.struct\"\nimport { tagged as taggedImpl } from \"./data.tagged\"\nimport { TaggedError as TaggedErrorImpl } from \"./data.tagged-error\"\nexport type {\n TaggedErrorClass,\n TaggedErrorCore,\n TaggedErrorFactory,\n TaggedErrorInstance,\n} from \"./data.tagged-error.types\"\nexport type { ArrayValue, StructValue, TaggedConstructor, TaggedValue, TupleValue } from \"./data.types\"\nimport { tuple as tupleImpl } from \"./data.tuple\"\n\n/**\n * Construct tagged data objects.\n *\n * @example\n * ```ts\n * import { Data } from \"@nicolastoulemont/std\"\n *\n * const User = Data.tagged<{ id: string }>(\"User\")\n * const user = User({ id: \"u1\" })\n * // => { _tag: \"User\", id: \"u1\" }\n * ```\n */\nexport const tagged = taggedImpl\n\n/**\n * Construct tagged error classes.\n *\n * @example\n * ```ts\n * import { Data } from \"@nicolastoulemont/std\"\n *\n * class NotFoundError extends Data.TaggedError(\"NotFoundError\")<{ id: string }> {}\n * const error = new NotFoundError({ id: \"u1\" })\n * // => { _tag: \"NotFoundError\", id: \"u1\" }\n * ```\n */\nexport const TaggedError = TaggedErrorImpl\n\n/**\n * Construct immutable-like structs with stable structural behavior.\n *\n * @example\n * ```ts\n * const point = Data.struct({ x: 1, y: 2 })\n * const same = point.equals({ x: 1, y: 2 })\n * // => true\n * ```\n */\nexport const struct = structImpl\n\n/**\n * Match over tagged data by discriminator tag.\n *\n * @example\n * ```ts\n * import { Data } from \"@nicolastoulemont/std\"\n *\n * const label = Data.match({ _tag: \"Circle\", radius: 2 } as const, {\n * Circle: (circle) => `r=${circle.radius}` ,\n * })\n * // => \"r=2\"\n * ```\n */\nexport const match = matchImpl\n\n/**\n * Construct immutable-like tuples with stable structural behavior.\n *\n * @example\n * ```ts\n * import { Data } from \"@nicolastoulemont/std\"\n *\n * const pair = Data.tuple(\"left\", 1)\n * const first = pair[0]\n * // => \"left\"\n * ```\n */\nexport const tuple = tupleImpl\n\n/**\n * Construct immutable-like arrays with stable structural behavior.\n *\n * @example\n * ```ts\n * import { Data } from \"@nicolastoulemont/std\"\n *\n * const ids = Data.array([\"a\", \"b\"])\n * const upper = ids.map((id) => id.toUpperCase())\n * // => [\"A\", \"B\"]\n * ```\n */\nexport const array = arrayImpl\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  const e=function(e,t){if(typeof e==`function`)return function(){return e(arguments)?t.apply(this,arguments):(e=>t(e,...arguments))};switch(e){case 0:return t;case 1:return function(e){return arguments.length>0?t.call(this,e):t.bind(this)};case 2:return function(e,n){return arguments.length>=2?t.call(this,e,n):n=>t(n,e)};case 3:return function(e,n,r){return arguments.length>=3?t.call(this,e,n,r):r=>t(r,e,n)};case 4:return function(e,n,r,i){return arguments.length>=4?t.call(this,e,n,r,i):i=>t(i,e,n,r)};case 5:return function(e,n,r,i,a){return arguments.length>=5?t.call(this,e,n,r,i,a):a=>t(a,e,n,r,i)};default:return function(){if(arguments.length>=e)return t.apply(this,arguments);let n=arguments;return e=>t(e,...n)}}};export{e as t};
2
- //# sourceMappingURL=dual-fN6OUwN_.mjs.map
2
+ //# sourceMappingURL=dual-CZhzZslG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"dual-fN6OUwN_.mjs","names":[],"sources":["../src/shared/dual.ts"],"sourcesContent":["/**\n * Dual function utility for creating functions that support both\n * data-first and data-last (curried) calling styles.\n *\n * This pattern is inspired by Effect's dual function implementation.\n * It enables better ergonomics by allowing direct function calls\n * without requiring pipe() for simple operations.\n *\n * @example\n * ```ts\n * // Define a dual function\n * const map = dual<\n * <T, U>(self: Option<T>, fn: (value: T) => U) => Option<U>,\n * <T, U>(fn: (value: T) => U) => (self: Option<T>) => Option<U>\n * >(2, (self, fn) => self.some ? some(fn(self.value)) : none())\n *\n * // Use data-first (direct call)\n * map(some(5), x => x * 2) // Option<10>\n *\n * // Use data-last (curried for pipe)\n * pipe(some(5), map(x => x * 2)) // Option<10>\n * ```\n */\n\n/**\n * Creates a function that can be called with all arguments (data-first)\n * or partially applied (data-last) for use in pipe chains.\n *\n * @param arity - The number of arguments in the data-first version (including self)\n * @param body - The implementation function that receives all arguments\n * @returns A function that supports both calling styles\n *\n * @remarks\n * The arity parameter is used to determine whether the function is being\n * called in data-first mode (all arguments provided) or data-last mode\n * (partial application for piping).\n *\n * TypeScript 5.4+ NoInfer is used where appropriate in consuming code\n * to prevent inference from fallback positions.\n */\n/* oxlint-disable no-explicit-any, ban-types, no-unsafe-function-type, no-unsafe-assignment, no-unsafe-return, no-unsafe-call, no-unsafe-type-assertion -- Required for highly polymorphic dual implementation that relies on runtime arity dispatch */\nexport const dual: {\n <DataFirst extends (...args: any) => any, DataLast extends (...args: any) => any>(\n arity: Parameters<DataFirst>[\"length\"],\n body: DataFirst,\n ): DataFirst & DataLast\n <DataFirst extends (...args: any) => any, DataLast extends (...args: any) => any>(\n isDataFirst: (args: IArguments) => boolean,\n body: DataFirst,\n ): DataFirst & DataLast\n} = function (arityOrIsDataFirst: number | ((args: IArguments) => boolean), body: Function) {\n if (typeof arityOrIsDataFirst === \"function\") {\n return function (this: unknown) {\n // oxlint-disable-next-line prefer-rest-params\n if (arityOrIsDataFirst(arguments)) {\n // oxlint-disable-next-line prefer-rest-params\n return body.apply(this, arguments)\n }\n // oxlint-disable-next-line prefer-rest-params\n return ((self: unknown) => body(self, ...arguments)) as unknown\n }\n }\n switch (arityOrIsDataFirst) {\n case 0:\n return body\n case 1:\n return function (this: unknown, a: unknown) {\n if (arguments.length > 0) {\n return body.call(this, a)\n }\n return body.bind(this)\n }\n case 2:\n return function (this: unknown, a: unknown, b: unknown) {\n if (arguments.length >= 2) {\n return body.call(this, a, b)\n }\n return (self: unknown) => body(self, a)\n }\n case 3:\n return function (this: unknown, a: unknown, b: unknown, c: unknown) {\n if (arguments.length >= 3) {\n return body.call(this, a, b, c)\n }\n return (self: unknown) => body(self, a, b)\n }\n case 4:\n return function (this: unknown, a: unknown, b: unknown, c: unknown, d: unknown) {\n if (arguments.length >= 4) {\n return body.call(this, a, b, c, d)\n }\n return (self: unknown) => body(self, a, b, c)\n }\n case 5:\n return function (this: unknown, a: unknown, b: unknown, c: unknown, d: unknown, e: unknown) {\n if (arguments.length >= 5) {\n return body.call(this, a, b, c, d, e)\n }\n return (self: unknown) => body(self, a, b, c, d)\n }\n default:\n return function (this: unknown) {\n // oxlint-disable-next-line prefer-rest-params\n if (arguments.length >= arityOrIsDataFirst) {\n // oxlint-disable-next-line prefer-rest-params\n return body.apply(this, arguments)\n }\n const args = arguments\n return (self: unknown) => body(self, ...args)\n }\n }\n} as any\n/* oxlint-enable no-explicit-any, ban-types, no-unsafe-function-type, no-unsafe-assignment, no-unsafe-return, no-unsafe-call, no-unsafe-type-assertion */\n"],"mappings":"AAyCA,MAAa,EAST,SAAU,EAA8D,EAAgB,CAC1F,GAAI,OAAO,GAAuB,WAChC,OAAO,UAAyB,CAO9B,OALI,EAAmB,UAAU,CAExB,EAAK,MAAM,KAAM,UAAU,EAG3B,GAAkB,EAAK,EAAM,GAAG,UAAU,GAGvD,OAAQ,EAAR,CACE,IAAK,GACH,OAAO,EACT,IAAK,GACH,OAAO,SAAyB,EAAY,CAI1C,OAHI,UAAU,OAAS,EACd,EAAK,KAAK,KAAM,EAAE,CAEpB,EAAK,KAAK,KAAK,EAE1B,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,CAItD,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAE,CAEtB,GAAkB,EAAK,EAAM,EAAE,EAE3C,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,EAAY,CAIlE,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAG,EAAE,CAEzB,GAAkB,EAAK,EAAM,EAAG,EAAE,EAE9C,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,EAAY,EAAY,CAI9E,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAG,EAAG,EAAE,CAE5B,GAAkB,EAAK,EAAM,EAAG,EAAG,EAAE,EAEjD,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,EAAY,EAAY,EAAY,CAI1F,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAG,EAAG,EAAG,EAAE,CAE/B,GAAkB,EAAK,EAAM,EAAG,EAAG,EAAG,EAAE,EAEpD,QACE,OAAO,UAAyB,CAE9B,GAAI,UAAU,QAAU,EAEtB,OAAO,EAAK,MAAM,KAAM,UAAU,CAEpC,IAAM,EAAO,UACb,MAAQ,IAAkB,EAAK,EAAM,GAAG,EAAK"}
1
+ {"version":3,"file":"dual-CZhzZslG.mjs","names":[],"sources":["../src/shared/dual.ts"],"sourcesContent":["/**\n * Dual function utility for creating functions that support both\n * data-first and data-last (curried) calling styles.\n *\n * This pattern is inspired by Effect's dual function implementation.\n * It enables better ergonomics by allowing direct function calls\n * without requiring pipe() for simple operations.\n *\n * @example\n * ```ts\n * // Define a dual function\n * const map = dual<\n * <T, U>(self: Option<T>, fn: (value: T) => U) => Option<U>,\n * <T, U>(fn: (value: T) => U) => (self: Option<T>) => Option<U>\n * >(2, (self, fn) => self.some ? some(fn(self.value)) : none())\n *\n * // Use data-first (direct call)\n * map(some(5), x => x * 2) // Option<10>\n *\n * // Use data-last (curried for pipe)\n * pipe(some(5), map(x => x * 2)) // Option<10>\n * ```\n */\n\n/**\n * Creates a function that can be called with all arguments (data-first)\n * or partially applied (data-last) for use in pipe chains.\n *\n * @param arity - The number of arguments in the data-first version (including self)\n * @param body - The implementation function that receives all arguments\n * @returns A function that supports both calling styles\n *\n * @remarks\n * The arity parameter is used to determine whether the function is being\n * called in data-first mode (all arguments provided) or data-last mode\n * (partial application for piping).\n *\n * TypeScript 5.4+ NoInfer is used where appropriate in consuming code\n * to prevent inference from fallback positions.\n */\n/* oxlint-disable no-explicit-any, ban-types, no-unsafe-function-type, no-unsafe-assignment, no-unsafe-return, no-unsafe-call, no-unsafe-type-assertion -- Required for highly polymorphic dual implementation that relies on runtime arity dispatch */\nexport const dual: {\n <DataFirst extends (...args: any) => any, DataLast extends (...args: any) => any>(\n arity: Parameters<DataFirst>[\"length\"],\n body: DataFirst,\n ): DataFirst & DataLast\n <DataFirst extends (...args: any) => any, DataLast extends (...args: any) => any>(\n isDataFirst: (args: IArguments) => boolean,\n body: DataFirst,\n ): DataFirst & DataLast\n} = function (arityOrIsDataFirst: number | ((args: IArguments) => boolean), body: Function) {\n if (typeof arityOrIsDataFirst === \"function\") {\n return function (this: unknown) {\n // oxlint-disable-next-line prefer-rest-params\n if (arityOrIsDataFirst(arguments)) {\n // oxlint-disable-next-line prefer-rest-params\n return body.apply(this, arguments)\n }\n // oxlint-disable-next-line prefer-rest-params\n return ((self: unknown) => body(self, ...arguments)) as unknown\n }\n }\n switch (arityOrIsDataFirst) {\n case 0:\n return body\n case 1:\n return function (this: unknown, a: unknown) {\n if (arguments.length > 0) {\n return body.call(this, a)\n }\n return body.bind(this)\n }\n case 2:\n return function (this: unknown, a: unknown, b: unknown) {\n if (arguments.length >= 2) {\n return body.call(this, a, b)\n }\n return (self: unknown) => body(self, a)\n }\n case 3:\n return function (this: unknown, a: unknown, b: unknown, c: unknown) {\n if (arguments.length >= 3) {\n return body.call(this, a, b, c)\n }\n return (self: unknown) => body(self, a, b)\n }\n case 4:\n return function (this: unknown, a: unknown, b: unknown, c: unknown, d: unknown) {\n if (arguments.length >= 4) {\n return body.call(this, a, b, c, d)\n }\n return (self: unknown) => body(self, a, b, c)\n }\n case 5:\n return function (this: unknown, a: unknown, b: unknown, c: unknown, d: unknown, e: unknown) {\n if (arguments.length >= 5) {\n return body.call(this, a, b, c, d, e)\n }\n return (self: unknown) => body(self, a, b, c, d)\n }\n default:\n return function (this: unknown) {\n // oxlint-disable-next-line prefer-rest-params\n if (arguments.length >= arityOrIsDataFirst) {\n // oxlint-disable-next-line prefer-rest-params\n return body.apply(this, arguments)\n }\n const args = arguments\n return (self: unknown) => body(self, ...args)\n }\n }\n} as any\n/* oxlint-enable no-explicit-any, ban-types, no-unsafe-function-type, no-unsafe-assignment, no-unsafe-return, no-unsafe-call, no-unsafe-type-assertion */\n"],"mappings":"AAyCA,MAAa,EAST,SAAU,EAA8D,EAAgB,CAC1F,GAAI,OAAO,GAAuB,WAChC,OAAO,UAAyB,CAO9B,OALI,EAAmB,UAAU,CAExB,EAAK,MAAM,KAAM,UAAU,EAG3B,GAAkB,EAAK,EAAM,GAAG,UAAU,GAGvD,OAAQ,EAAR,CACE,IAAK,GACH,OAAO,EACT,IAAK,GACH,OAAO,SAAyB,EAAY,CAI1C,OAHI,UAAU,OAAS,EACd,EAAK,KAAK,KAAM,EAAE,CAEpB,EAAK,KAAK,KAAK,EAE1B,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,CAItD,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAE,CAEtB,GAAkB,EAAK,EAAM,EAAE,EAE3C,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,EAAY,CAIlE,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAG,EAAE,CAEzB,GAAkB,EAAK,EAAM,EAAG,EAAE,EAE9C,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,EAAY,EAAY,CAI9E,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAG,EAAG,EAAE,CAE5B,GAAkB,EAAK,EAAM,EAAG,EAAG,EAAE,EAEjD,IAAK,GACH,OAAO,SAAyB,EAAY,EAAY,EAAY,EAAY,EAAY,CAI1F,OAHI,UAAU,QAAU,EACf,EAAK,KAAK,KAAM,EAAG,EAAG,EAAG,EAAG,EAAE,CAE/B,GAAkB,EAAK,EAAM,EAAG,EAAG,EAAG,EAAE,EAEpD,QACE,OAAO,UAAyB,CAE9B,GAAI,UAAU,QAAU,EAEtB,OAAO,EAAK,MAAM,KAAM,UAAU,CAEpC,IAAM,EAAO,UACb,MAAQ,IAAkB,EAAK,EAAM,GAAG,EAAK"}
@@ -1,2 +1,2 @@
1
- import { r as duration_d_exports } from "../index-DCUGtEcj.mjs";
1
+ import { r as duration_d_exports } from "../index-5QkUtJ-4.mjs";
2
2
  export { duration_d_exports as Duration };
@@ -1 +1 @@
1
- import{t as e}from"../duration-CYoDHcOR.mjs";export{e as Duration};
1
+ import{t as e}from"../duration-Dwtjy95Z.mjs";export{e as Duration};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./chunk-oQKkju2G.mjs";import{i as t,t as n}from"./result-D3VY0qBG.mjs";import{n as r}from"./brand-DZgGDrAe.mjs";import{t as i}from"./data-BHYPdqWZ.mjs";var a=e({DurationInvalidInputError:()=>c,DurationInvalidValueError:()=>s,DurationParseError:()=>o,days:()=>v,from:()=>C,hours:()=>_,millis:()=>m,minutes:()=>g,parse:()=>S,seconds:()=>h,toMillis:()=>b,weeks:()=>y}),o=class extends i(`DurationParseError`){},s=class extends i(`DurationInvalidValueError`){},c=class extends i(`DurationInvalidInputError`){};const l=/^\s*(-?\d+(?:\.\d+)?)\s+(milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks)\s*$/i,u=e=>`Duration value must be a finite number, received: ${String(e)}`,d=e=>`Invalid duration input: ${String(e)}`,f=e=>`Invalid duration string: ${e}. Expected "{number} {milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks}".`,p=e=>{if(!Number.isFinite(e))throw new s({input:e,message:u(e)});return r(e)},m=e=>p(e),h=e=>m(e*1e3),g=e=>m(e*6e4),_=e=>m(e*36e5),v=e=>m(e*864e5),y=e=>m(e*6048e5),b=e=>e,x=(e,t,n)=>{switch(n.toLowerCase()){case`milli`:case`millis`:return m(t);case`second`:case`seconds`:return h(t);case`minute`:case`minutes`:return g(t);case`hour`:case`hours`:return _(t);case`day`:case`days`:return v(t);case`week`:case`weeks`:return y(t);default:throw new o({input:e,message:f(e)})}},S=e=>{let r=l.exec(e);if(!r)return n(new o({input:e,message:f(e)}));let i=Number(r[1]),a=r[2];try{return t(x(e,i,a))}catch(t){if(t instanceof s||t instanceof o)return n(new o({input:e,message:f(e)}));throw t}},C=e=>{if(typeof e==`number`)try{return t(m(e))}catch(e){if(e instanceof s)return n(e);throw e}return typeof e==`string`?S(e):n(new c({input:e,message:d(e)}))};export{C as n,b as r,a as t};
2
- //# sourceMappingURL=duration-CYoDHcOR.mjs.map
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{i as t,t as n}from"./result-C74pRN2x.mjs";import{n as r}from"./brand-DP-C92GS.mjs";import{t as i}from"./data-W10ldR5l.mjs";var a=e({DurationInvalidInputError:()=>c,DurationInvalidValueError:()=>s,DurationParseError:()=>o,days:()=>v,from:()=>C,hours:()=>_,millis:()=>m,minutes:()=>g,parse:()=>S,seconds:()=>h,toMillis:()=>b,weeks:()=>y}),o=class extends i(`DurationParseError`){},s=class extends i(`DurationInvalidValueError`){},c=class extends i(`DurationInvalidInputError`){};const l=/^\s*(-?\d+(?:\.\d+)?)\s+(milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks)\s*$/i,u=e=>`Duration value must be a finite number, received: ${String(e)}`,d=e=>`Invalid duration input: ${String(e)}`,f=e=>`Invalid duration string: ${e}. Expected "{number} {milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks}".`,p=e=>{if(!Number.isFinite(e))throw new s({input:e,message:u(e)});return r(e)},m=e=>p(e),h=e=>m(e*1e3),g=e=>m(e*6e4),_=e=>m(e*36e5),v=e=>m(e*864e5),y=e=>m(e*6048e5),b=e=>e,x=(e,t,n)=>{switch(n.toLowerCase()){case`milli`:case`millis`:return m(t);case`second`:case`seconds`:return h(t);case`minute`:case`minutes`:return g(t);case`hour`:case`hours`:return _(t);case`day`:case`days`:return v(t);case`week`:case`weeks`:return y(t);default:throw new o({input:e,message:f(e)})}},S=e=>{let r=l.exec(e);if(!r)return n(new o({input:e,message:f(e)}));let i=Number(r[1]),a=r[2];try{return t(x(e,i,a))}catch(t){if(t instanceof s||t instanceof o)return n(new o({input:e,message:f(e)}));throw t}},C=e=>{if(typeof e==`number`)try{return t(m(e))}catch(e){if(e instanceof s)return n(e);throw e}return typeof e==`string`?S(e):n(new c({input:e,message:d(e)}))};export{C as n,b as r,a as t};
2
+ //# sourceMappingURL=duration-Dwtjy95Z.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"duration-CYoDHcOR.mjs","names":["Data.TaggedError","Brand.make","Result.err","Result.ok"],"sources":["../src/duration/duration.ts"],"sourcesContent":["/**\n * Fixed-size duration helpers backed by branded millisecond numbers.\n *\n * **Mental model**\n * - `Duration` is a finite JavaScript `number` interpreted as milliseconds.\n * - Use constructors for direct code and `parse` / `from` for ergonomic input handling.\n *\n * **Common tasks**\n * - Build durations with `Duration.seconds(5)` or `Duration.minutes(2)`.\n * - Parse config-like strings with `Duration.parse(\"5 minutes\")`.\n * - Normalize mixed inputs with `Duration.from(...)`.\n *\n * **Gotchas**\n * - Only fixed-size units are supported.\n * - Months, years, micros, and nanos are intentionally not supported.\n * - Invalid values use tagged errors instead of plain `RangeError`.\n *\n * @module\n */\n/* oxlint-disable eslint/max-classes-per-file -- TaggedError classes are part of the public API surface for this small module. */\nimport { Brand } from \"../brand\"\nimport type { Branded } from \"../brand/brand.types\"\nimport { Data } from \"../data\"\nimport { Result } from \"../result\"\n\n/**\n * Millisecond-backed branded duration type.\n */\nexport type Duration = Branded<number, \"Duration\">\n\n/**\n * Supported textual duration units.\n */\nexport type Unit =\n | \"milli\"\n | \"millis\"\n | \"second\"\n | \"seconds\"\n | \"minute\"\n | \"minutes\"\n | \"hour\"\n | \"hours\"\n | \"day\"\n | \"days\"\n | \"week\"\n | \"weeks\"\n\n/**\n * String input for durations.\n */\nexport type StringInput = `${number} ${Unit}`\n\n/**\n * Accepted duration input shapes.\n */\nexport type Input = Duration | number | StringInput\n\n/**\n * Tagged parse error for invalid duration strings.\n */\nexport class DurationParseError extends Data.TaggedError(\"DurationParseError\")<{\n input: string\n message: string\n}> {}\n\n/**\n * Tagged error for invalid numeric duration values.\n */\nexport class DurationInvalidValueError extends Data.TaggedError(\"DurationInvalidValueError\")<{\n input: number\n message: string\n}> {}\n\n/**\n * Tagged error for invalid duration input values outside supported shapes.\n */\nexport class DurationInvalidInputError extends Data.TaggedError(\"DurationInvalidInputError\")<{\n input: Input\n message: string\n cause?: DurationParseError | DurationInvalidValueError\n}> {}\n\n/**\n * Re-exported parse error type.\n */\nexport type ParseError = DurationParseError\n\n/**\n * Re-exported duration input error union.\n */\nexport type InputError = DurationInvalidInputError | DurationParseError | DurationInvalidValueError\n\nconst DURATION_REGEXP =\n /^\\s*(-?\\d+(?:\\.\\d+)?)\\s+(milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks)\\s*$/i\n\nconst invalidValueMessage = (value: number) => `Duration value must be a finite number, received: ${String(value)}`\nconst invalidInputMessage = (input: Input) => `Invalid duration input: ${String(input)}`\nconst invalidStringMessage = (input: string) =>\n `Invalid duration string: ${input}. Expected \"{number} {milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks}\".`\n\nconst validateFinite = (value: number): Duration => {\n if (!Number.isFinite(value)) {\n throw new DurationInvalidValueError({\n input: value,\n message: invalidValueMessage(value),\n })\n }\n\n return Brand.make<Branded<number, \"Duration\">>(value)\n}\n\n/**\n * Create a duration from milliseconds.\n */\nexport const millis = (value: number): Duration => validateFinite(value)\n\n/**\n * Create a duration from seconds.\n */\nexport const seconds = (value: number): Duration => millis(value * 1_000)\n\n/**\n * Create a duration from minutes.\n */\nexport const minutes = (value: number): Duration => millis(value * 60_000)\n\n/**\n * Create a duration from hours.\n */\nexport const hours = (value: number): Duration => millis(value * 3_600_000)\n\n/**\n * Create a duration from days.\n */\nexport const days = (value: number): Duration => millis(value * 86_400_000)\n\n/**\n * Create a duration from weeks.\n */\nexport const weeks = (value: number): Duration => millis(value * 604_800_000)\n\n/**\n * Convert a duration to raw milliseconds.\n */\nexport const toMillis = (duration: Duration): number => duration\n\nconst parseUnit = (input: string, value: number, unit: string): Duration => {\n switch (unit.toLowerCase()) {\n case \"milli\":\n case \"millis\":\n return millis(value)\n case \"second\":\n case \"seconds\":\n return seconds(value)\n case \"minute\":\n case \"minutes\":\n return minutes(value)\n case \"hour\":\n case \"hours\":\n return hours(value)\n case \"day\":\n case \"days\":\n return days(value)\n case \"week\":\n case \"weeks\":\n return weeks(value)\n default:\n throw new DurationParseError({\n input,\n message: invalidStringMessage(input),\n })\n }\n}\n\n/**\n * Parse a duration string.\n */\nexport const parse = (input: string): Result.Result<Duration, DurationParseError> => {\n const match = DURATION_REGEXP.exec(input)\n if (!match) {\n return Result.err(\n new DurationParseError({\n input,\n message: invalidStringMessage(input),\n }),\n )\n }\n\n const value = Number(match[1])\n const unit = match[2]!\n\n try {\n return Result.ok(parseUnit(input, value, unit))\n } catch (error) {\n if (error instanceof DurationInvalidValueError || error instanceof DurationParseError) {\n return Result.err(\n new DurationParseError({\n input,\n message: invalidStringMessage(input),\n }),\n )\n }\n throw error\n }\n}\n\n/**\n * Normalize supported duration inputs to a branded duration.\n */\nexport const from = (input: Input): Result.Result<Duration, InputError> => {\n if (typeof input === \"number\") {\n try {\n return Result.ok(millis(input))\n } catch (error) {\n if (error instanceof DurationInvalidValueError) {\n return Result.err(error)\n }\n throw error\n }\n }\n\n if (typeof input === \"string\") {\n return parse(input)\n }\n\n return Result.err(\n new DurationInvalidInputError({\n input,\n message: invalidInputMessage(input),\n }),\n )\n}\n"],"mappings":"iYA4Da,EAAb,cAAwCA,EAAiB,qBAAqB,AAG3E,GAKU,EAAb,cAA+CA,EAAiB,4BAA4B,AAGzF,GAKU,EAAb,cAA+CA,EAAiB,4BAA4B,AAIzF,GAYH,MAAM,EACJ,2GAEI,EAAuB,GAAkB,qDAAqD,OAAO,EAAM,GAC3G,EAAuB,GAAiB,2BAA2B,OAAO,EAAM,GAChF,EAAwB,GAC5B,4BAA4B,EAAM,oGAE9B,EAAkB,GAA4B,CAClD,GAAI,CAAC,OAAO,SAAS,EAAM,CACzB,MAAM,IAAI,EAA0B,CAClC,MAAO,EACP,QAAS,EAAoB,EAAM,CACpC,CAAC,CAGJ,OAAOC,EAAwC,EAAM,EAM1C,EAAU,GAA4B,EAAe,EAAM,CAK3D,EAAW,GAA4B,EAAO,EAAQ,IAAM,CAK5D,EAAW,GAA4B,EAAO,EAAQ,IAAO,CAK7D,EAAS,GAA4B,EAAO,EAAQ,KAAU,CAK9D,EAAQ,GAA4B,EAAO,EAAQ,MAAW,CAK9D,EAAS,GAA4B,EAAO,EAAQ,OAAY,CAKhE,EAAY,GAA+B,EAElD,GAAa,EAAe,EAAe,IAA2B,CAC1E,OAAQ,EAAK,aAAa,CAA1B,CACE,IAAK,QACL,IAAK,SACH,OAAO,EAAO,EAAM,CACtB,IAAK,SACL,IAAK,UACH,OAAO,EAAQ,EAAM,CACvB,IAAK,SACL,IAAK,UACH,OAAO,EAAQ,EAAM,CACvB,IAAK,OACL,IAAK,QACH,OAAO,EAAM,EAAM,CACrB,IAAK,MACL,IAAK,OACH,OAAO,EAAK,EAAM,CACpB,IAAK,OACL,IAAK,QACH,OAAO,EAAM,EAAM,CACrB,QACE,MAAM,IAAI,EAAmB,CAC3B,QACA,QAAS,EAAqB,EAAM,CACrC,CAAC,GAOK,EAAS,GAA+D,CACnF,IAAM,EAAQ,EAAgB,KAAK,EAAM,CACzC,GAAI,CAAC,EACH,OAAOC,EACL,IAAI,EAAmB,CACrB,QACA,QAAS,EAAqB,EAAM,CACrC,CAAC,CACH,CAGH,IAAM,EAAQ,OAAO,EAAM,GAAG,CACxB,EAAO,EAAM,GAEnB,GAAI,CACF,OAAOC,EAAU,EAAU,EAAO,EAAO,EAAK,CAAC,OACxC,EAAO,CACd,GAAI,aAAiB,GAA6B,aAAiB,EACjE,OAAOD,EACL,IAAI,EAAmB,CACrB,QACA,QAAS,EAAqB,EAAM,CACrC,CAAC,CACH,CAEH,MAAM,IAOG,EAAQ,GAAsD,CACzE,GAAI,OAAO,GAAU,SACnB,GAAI,CACF,OAAOC,EAAU,EAAO,EAAM,CAAC,OACxB,EAAO,CACd,GAAI,aAAiB,EACnB,OAAOD,EAAW,EAAM,CAE1B,MAAM,EAQV,OAJI,OAAO,GAAU,SACZ,EAAM,EAAM,CAGdA,EACL,IAAI,EAA0B,CAC5B,QACA,QAAS,EAAoB,EAAM,CACpC,CAAC,CACH"}
1
+ {"version":3,"file":"duration-Dwtjy95Z.mjs","names":["Data.TaggedError","Brand.make","Result.err","Result.ok"],"sources":["../src/duration/duration.ts"],"sourcesContent":["/**\n * Fixed-size duration helpers backed by branded millisecond numbers.\n *\n * **Mental model**\n * - `Duration` is a finite JavaScript `number` interpreted as milliseconds.\n * - Use constructors for direct code and `parse` / `from` for ergonomic input handling.\n *\n * **Common tasks**\n * - Build durations with `Duration.seconds(5)` or `Duration.minutes(2)`.\n * - Parse config-like strings with `Duration.parse(\"5 minutes\")`.\n * - Normalize mixed inputs with `Duration.from(...)`.\n *\n * **Gotchas**\n * - Only fixed-size units are supported.\n * - Months, years, micros, and nanos are intentionally not supported.\n * - Invalid values use tagged errors instead of plain `RangeError`.\n *\n * @module\n */\n/* oxlint-disable eslint/max-classes-per-file -- TaggedError classes are part of the public API surface for this small module. */\nimport { Brand } from \"../brand\"\nimport type { Branded } from \"../brand/brand.types\"\nimport { Data } from \"../data\"\nimport { Result } from \"../result\"\n\n/**\n * Millisecond-backed branded duration type.\n */\nexport type Duration = Branded<number, \"Duration\">\n\n/**\n * Supported textual duration units.\n */\nexport type Unit =\n | \"milli\"\n | \"millis\"\n | \"second\"\n | \"seconds\"\n | \"minute\"\n | \"minutes\"\n | \"hour\"\n | \"hours\"\n | \"day\"\n | \"days\"\n | \"week\"\n | \"weeks\"\n\n/**\n * String input for durations.\n */\nexport type StringInput = `${number} ${Unit}`\n\n/**\n * Accepted duration input shapes.\n */\nexport type Input = Duration | number | StringInput\n\n/**\n * Tagged parse error for invalid duration strings.\n */\nexport class DurationParseError extends Data.TaggedError(\"DurationParseError\")<{\n input: string\n message: string\n}> {}\n\n/**\n * Tagged error for invalid numeric duration values.\n */\nexport class DurationInvalidValueError extends Data.TaggedError(\"DurationInvalidValueError\")<{\n input: number\n message: string\n}> {}\n\n/**\n * Tagged error for invalid duration input values outside supported shapes.\n */\nexport class DurationInvalidInputError extends Data.TaggedError(\"DurationInvalidInputError\")<{\n input: Input\n message: string\n cause?: DurationParseError | DurationInvalidValueError\n}> {}\n\n/**\n * Re-exported parse error type.\n */\nexport type ParseError = DurationParseError\n\n/**\n * Re-exported duration input error union.\n */\nexport type InputError = DurationInvalidInputError | DurationParseError | DurationInvalidValueError\n\nconst DURATION_REGEXP =\n /^\\s*(-?\\d+(?:\\.\\d+)?)\\s+(milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks)\\s*$/i\n\nconst invalidValueMessage = (value: number) => `Duration value must be a finite number, received: ${String(value)}`\nconst invalidInputMessage = (input: Input) => `Invalid duration input: ${String(input)}`\nconst invalidStringMessage = (input: string) =>\n `Invalid duration string: ${input}. Expected \"{number} {milli|millis|second|seconds|minute|minutes|hour|hours|day|days|week|weeks}\".`\n\nconst validateFinite = (value: number): Duration => {\n if (!Number.isFinite(value)) {\n throw new DurationInvalidValueError({\n input: value,\n message: invalidValueMessage(value),\n })\n }\n\n return Brand.make<Branded<number, \"Duration\">>(value)\n}\n\n/**\n * Create a duration from milliseconds.\n */\nexport const millis = (value: number): Duration => validateFinite(value)\n\n/**\n * Create a duration from seconds.\n */\nexport const seconds = (value: number): Duration => millis(value * 1_000)\n\n/**\n * Create a duration from minutes.\n */\nexport const minutes = (value: number): Duration => millis(value * 60_000)\n\n/**\n * Create a duration from hours.\n */\nexport const hours = (value: number): Duration => millis(value * 3_600_000)\n\n/**\n * Create a duration from days.\n */\nexport const days = (value: number): Duration => millis(value * 86_400_000)\n\n/**\n * Create a duration from weeks.\n */\nexport const weeks = (value: number): Duration => millis(value * 604_800_000)\n\n/**\n * Convert a duration to raw milliseconds.\n */\nexport const toMillis = (duration: Duration): number => duration\n\nconst parseUnit = (input: string, value: number, unit: string): Duration => {\n switch (unit.toLowerCase()) {\n case \"milli\":\n case \"millis\":\n return millis(value)\n case \"second\":\n case \"seconds\":\n return seconds(value)\n case \"minute\":\n case \"minutes\":\n return minutes(value)\n case \"hour\":\n case \"hours\":\n return hours(value)\n case \"day\":\n case \"days\":\n return days(value)\n case \"week\":\n case \"weeks\":\n return weeks(value)\n default:\n throw new DurationParseError({\n input,\n message: invalidStringMessage(input),\n })\n }\n}\n\n/**\n * Parse a duration string.\n */\nexport const parse = (input: string): Result.Result<Duration, DurationParseError> => {\n const match = DURATION_REGEXP.exec(input)\n if (!match) {\n return Result.err(\n new DurationParseError({\n input,\n message: invalidStringMessage(input),\n }),\n )\n }\n\n const value = Number(match[1])\n const unit = match[2]!\n\n try {\n return Result.ok(parseUnit(input, value, unit))\n } catch (error) {\n if (error instanceof DurationInvalidValueError || error instanceof DurationParseError) {\n return Result.err(\n new DurationParseError({\n input,\n message: invalidStringMessage(input),\n }),\n )\n }\n throw error\n }\n}\n\n/**\n * Normalize supported duration inputs to a branded duration.\n */\nexport const from = (input: Input): Result.Result<Duration, InputError> => {\n if (typeof input === \"number\") {\n try {\n return Result.ok(millis(input))\n } catch (error) {\n if (error instanceof DurationInvalidValueError) {\n return Result.err(error)\n }\n throw error\n }\n }\n\n if (typeof input === \"string\") {\n return parse(input)\n }\n\n return Result.err(\n new DurationInvalidInputError({\n input,\n message: invalidInputMessage(input),\n }),\n )\n}\n"],"mappings":"iYA4Da,EAAb,cAAwCA,EAAiB,qBAAqB,AAG3E,GAKU,EAAb,cAA+CA,EAAiB,4BAA4B,AAGzF,GAKU,EAAb,cAA+CA,EAAiB,4BAA4B,AAIzF,GAYH,MAAM,EACJ,2GAEI,EAAuB,GAAkB,qDAAqD,OAAO,EAAM,GAC3G,EAAuB,GAAiB,2BAA2B,OAAO,EAAM,GAChF,EAAwB,GAC5B,4BAA4B,EAAM,oGAE9B,EAAkB,GAA4B,CAClD,GAAI,CAAC,OAAO,SAAS,EAAM,CACzB,MAAM,IAAI,EAA0B,CAClC,MAAO,EACP,QAAS,EAAoB,EAAM,CACpC,CAAC,CAGJ,OAAOC,EAAwC,EAAM,EAM1C,EAAU,GAA4B,EAAe,EAAM,CAK3D,EAAW,GAA4B,EAAO,EAAQ,IAAM,CAK5D,EAAW,GAA4B,EAAO,EAAQ,IAAO,CAK7D,EAAS,GAA4B,EAAO,EAAQ,KAAU,CAK9D,EAAQ,GAA4B,EAAO,EAAQ,MAAW,CAK9D,EAAS,GAA4B,EAAO,EAAQ,OAAY,CAKhE,EAAY,GAA+B,EAElD,GAAa,EAAe,EAAe,IAA2B,CAC1E,OAAQ,EAAK,aAAa,CAA1B,CACE,IAAK,QACL,IAAK,SACH,OAAO,EAAO,EAAM,CACtB,IAAK,SACL,IAAK,UACH,OAAO,EAAQ,EAAM,CACvB,IAAK,SACL,IAAK,UACH,OAAO,EAAQ,EAAM,CACvB,IAAK,OACL,IAAK,QACH,OAAO,EAAM,EAAM,CACrB,IAAK,MACL,IAAK,OACH,OAAO,EAAK,EAAM,CACpB,IAAK,OACL,IAAK,QACH,OAAO,EAAM,EAAM,CACrB,QACE,MAAM,IAAI,EAAmB,CAC3B,QACA,QAAS,EAAqB,EAAM,CACrC,CAAC,GAOK,EAAS,GAA+D,CACnF,IAAM,EAAQ,EAAgB,KAAK,EAAM,CACzC,GAAI,CAAC,EACH,OAAOC,EACL,IAAI,EAAmB,CACrB,QACA,QAAS,EAAqB,EAAM,CACrC,CAAC,CACH,CAGH,IAAM,EAAQ,OAAO,EAAM,GAAG,CACxB,EAAO,EAAM,GAEnB,GAAI,CACF,OAAOC,EAAU,EAAU,EAAO,EAAO,EAAK,CAAC,OACxC,EAAO,CACd,GAAI,aAAiB,GAA6B,aAAiB,EACjE,OAAOD,EACL,IAAI,EAAmB,CACrB,QACA,QAAS,EAAqB,EAAM,CACrC,CAAC,CACH,CAEH,MAAM,IAOG,EAAQ,GAAsD,CACzE,GAAI,OAAO,GAAU,SACnB,GAAI,CACF,OAAOC,EAAU,EAAO,EAAM,CAAC,OACxB,EAAO,CACd,GAAI,aAAiB,EACnB,OAAOD,EAAW,EAAM,CAE1B,MAAM,EAQV,OAJI,OAAO,GAAU,SACZ,EAAM,EAAM,CAGdA,EACL,IAAI,EAA0B,CAC5B,QACA,QAAS,EAAoB,EAAM,CACpC,CAAC,CACH"}
@@ -1,2 +1,2 @@
1
- import { t as either_d_exports } from "../index-dCRymj_g.mjs";
1
+ import { t as either_d_exports } from "../index-CfXGmPMY.mjs";
2
2
  export { either_d_exports as Either };
@@ -1 +1 @@
1
- import{t as e}from"../either-G7uOu4Ar.mjs";export{e as Either};
1
+ import{t as e}from"../either-B2TvVY_j.mjs";export{e as Either};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./fx.types-DyQVgTS8.mjs";import{t as n}from"./dual-fN6OUwN_.mjs";import{n as r}from"./flow-CNyLsPGb.mjs";import{t as i}from"./pipeable-Dp1_23zH.mjs";import{i as a,t as o}from"./result-D3VY0qBG.mjs";import{i as s,n as c}from"./option-C2iCxAuJ.mjs";var l=e({all:()=>C,bimap:()=>g,filter:()=>S,flatMap:()=>_,fromNullable:()=>j,fromOption:()=>k,fromPredicate:()=>M,fromResult:()=>D,isLeft:()=>p,isRight:()=>f,left:()=>d,map:()=>m,mapLeft:()=>h,match:()=>E,orElse:()=>b,right:()=>u,swap:()=>x,tap:()=>v,tapLeft:()=>y,toOption:()=>A,toResult:()=>O,unwrapOr:()=>w,unwrapOrElse:()=>T});const u=e=>({_tag:`Right`,value:e,[t]:{_A:()=>e,_E:()=>void 0,_R:()=>void 0},pipe:i,*[Symbol.iterator](){return e}}),d=e=>({_tag:`Left`,value:e,[t]:{_A:()=>e,_E:()=>void 0,_R:()=>void 0},pipe:i,*[Symbol.iterator](){return e}}),f=e=>e._tag===`Right`,p=e=>e._tag===`Left`,m=n(2,(e,t)=>{if(e._tag===`Left`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(u):u(n)}),h=n(2,(e,t)=>{if(e._tag===`Right`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(d):d(n)}),g=n(3,(e,t,n)=>{if(e._tag===`Right`){let t=n(e.value);return r(t)?Promise.resolve(t).then(u):u(t)}let i=t(e.value);return r(i)?Promise.resolve(i).then(d):d(i)}),_=n(2,(e,t)=>e._tag===`Left`?e:t(e.value)),v=n(2,(e,t)=>{if(e._tag===`Left`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(()=>e):e}),y=n(2,(e,t)=>{if(e._tag===`Right`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(()=>e):e}),b=n(2,(e,t)=>e._tag===`Right`?e:t(e.value)),x=()=>e=>e._tag===`Left`?u(e.value):d(e.value),S=n(3,(e,t,n)=>e._tag===`Left`||t(e.value)?e:d(n(e.value))),C=e=>{if(Array.isArray(e)){let t=[];for(let n of e){if(n._tag===`Left`)return n;t.push(n.value)}return u(t)}let t={};for(let n in e){let r=e[n];if(r._tag===`Left`)return r;t[n]=r.value}return u(t)},w=n(2,(e,t)=>e._tag===`Right`?e.value:t),T=n(2,(e,t)=>e._tag===`Right`?e.value:t(e.value)),E=n(2,(e,t)=>e._tag===`Right`?t.Right(e.value):t.Left(e.value)),D=e=>e._tag===`Ok`?u(e.value):d(e.error),O=e=>e._tag===`Right`?a(e.value):o(e.value),k=(e,t)=>e._tag===`Some`?u(e.value):d(t()),A=e=>e._tag===`Right`?s(e.value):c(),j=(e,t)=>e==null?d(t()):u(e),M=(e,t,n)=>t(e)?u(e):d(n(e));export{l as t};
2
- //# sourceMappingURL=either-G7uOu4Ar.mjs.map
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{t}from"./fx.types-Bg-Mmdm5.mjs";import{t as n}from"./dual-CZhzZslG.mjs";import{n as r}from"./flow-D8_tllWl.mjs";import{t as i}from"./pipeable-COGyGMUV.mjs";import{i as a,t as o}from"./result-C74pRN2x.mjs";import{i as s,n as c}from"./option-BlyP5LA2.mjs";var l=e({all:()=>C,bimap:()=>g,filter:()=>S,flatMap:()=>_,fromNullable:()=>j,fromOption:()=>k,fromPredicate:()=>M,fromResult:()=>D,isLeft:()=>p,isRight:()=>f,left:()=>d,map:()=>m,mapLeft:()=>h,match:()=>E,orElse:()=>b,right:()=>u,swap:()=>x,tap:()=>v,tapLeft:()=>y,toOption:()=>A,toResult:()=>O,unwrapOr:()=>w,unwrapOrElse:()=>T});const u=e=>({_tag:`Right`,value:e,[t]:{_A:()=>e,_E:()=>void 0,_R:()=>void 0},pipe:i,*[Symbol.iterator](){return e}}),d=e=>({_tag:`Left`,value:e,[t]:{_A:()=>e,_E:()=>void 0,_R:()=>void 0},pipe:i,*[Symbol.iterator](){return e}}),f=e=>e._tag===`Right`,p=e=>e._tag===`Left`,m=n(2,(e,t)=>{if(e._tag===`Left`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(u):u(n)}),h=n(2,(e,t)=>{if(e._tag===`Right`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(d):d(n)}),g=n(3,(e,t,n)=>{if(e._tag===`Right`){let t=n(e.value);return r(t)?Promise.resolve(t).then(u):u(t)}let i=t(e.value);return r(i)?Promise.resolve(i).then(d):d(i)}),_=n(2,(e,t)=>e._tag===`Left`?e:t(e.value)),v=n(2,(e,t)=>{if(e._tag===`Left`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(()=>e):e}),y=n(2,(e,t)=>{if(e._tag===`Right`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(()=>e):e}),b=n(2,(e,t)=>e._tag===`Right`?e:t(e.value)),x=()=>e=>e._tag===`Left`?u(e.value):d(e.value),S=n(3,(e,t,n)=>e._tag===`Left`||t(e.value)?e:d(n(e.value))),C=e=>{if(Array.isArray(e)){let t=[];for(let n of e){if(n._tag===`Left`)return n;t.push(n.value)}return u(t)}let t={};for(let n in e){let r=e[n];if(r._tag===`Left`)return r;t[n]=r.value}return u(t)},w=n(2,(e,t)=>e._tag===`Right`?e.value:t),T=n(2,(e,t)=>e._tag===`Right`?e.value:t(e.value)),E=n(2,(e,t)=>e._tag===`Right`?t.Right(e.value):t.Left(e.value)),D=e=>e._tag===`Ok`?u(e.value):d(e.error),O=e=>e._tag===`Right`?a(e.value):o(e.value),k=(e,t)=>e._tag===`Some`?u(e.value):d(t()),A=e=>e._tag===`Right`?s(e.value):c(),j=(e,t)=>e==null?d(t()):u(e),M=(e,t,n)=>t(e)?u(e):d(n(e));export{l as t};
2
+ //# sourceMappingURL=either-B2TvVY_j.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"either-G7uOu4Ar.mjs","names":["mapped","Result.ok","Result.err","Option.some","Option.none"],"sources":["../src/either/either.ts"],"sourcesContent":["/**\n * Biased disjoint union primitives for modeling two valid branches (`Left` / `Right`).\n *\n * **Mental model**\n * - `Either<L, R>` represents two meaningful outcomes.\n * - This module is right-biased for `map` / `flatMap`.\n *\n * **Common tasks**\n * - Construct with `Either.left` and `Either.right`.\n * - Transform with `Either.map`, `Either.mapLeft`, `Either.bimap`.\n * - Handle with `Either.match`, `Either.unwrapOr`, and conversions.\n *\n * **Gotchas**\n * - `Either.left` does not short-circuit in `Fx.gen`.\n * - Use `Result` when the left side should model failure semantics.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.right(2)\n * const next = Either.map(value, (n) => n + 1)\n * ```\n *\n * @module\n */\nimport { FxTypeId } from \"../fx/fx.types\"\nimport { Option } from \"../option\"\nimport type { Option as OptionType } from \"../option/option.types\"\nimport { Result } from \"../result\"\nimport type { Result as ResultType } from \"../result/result.types\"\nimport { dual } from \"../shared/dual\"\nimport { isPromise } from \"../shared/is-promise\"\nimport { pipeable } from \"../shared/pipeable\"\nimport type {\n Either as EitherType,\n EitherAll,\n EitherBimap,\n EitherFilter,\n EitherFlatMap,\n EitherMap,\n EitherMapLeft,\n EitherMatch,\n EitherOrElse,\n EitherTap,\n EitherTapLeft,\n EitherUnwrapOr,\n EitherUnwrapOrElse,\n} from \"./either.types\"\n\n/**\n * Re-exported `Either` type.\n *\n * @example\n * ```ts\n * import type { Either } from \"@nicolastoulemont/std\"\n *\n * type Example = Either.Either<unknown, unknown>\n * ```\n */\nexport type Either<L, R> = EitherType<L, R>\n\n/* oxlint-disable no-unsafe-type-assertion -- Either constructors encode Fx marker channels and left/right union normalization through intentional assertions. */\n\n// ============================================================================\n// Constructors\n// ============================================================================\n\n/**\n * Create a right Either value (success/preferred path).\n *\n * By convention, right represents the correct/preferred outcome.\n * In Fx.gen(), this returns the value without short-circuiting.\n *\n * @param value - The right value\n * @returns An Either in the right state\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.right(42)\n * // => { _tag: \"Right\", value: 42 }\n * ```\n */\nexport const right = <R, L = never>(value: R): EitherType<L, R> => ({\n _tag: \"Right\",\n value,\n [FxTypeId]: {\n _A: () => value as L | R,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n pipe: pipeable,\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, R, unknown> {\n return value\n },\n})\n\n/**\n * Create a left Either value (alternative path).\n *\n * By convention, left represents the alternative outcome.\n * Unlike Result's err(), left doesn't imply an error - it's a valid value.\n *\n * In Fx.gen(), left returns its value without short-circuiting.\n * This is the key difference from Result.err() which short-circuits.\n *\n * @param value - The left value\n * @returns An Either in the left state\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.left(\"missing\")\n * // => { _tag: \"Left\", value: \"missing\" }\n * ```\n */\nexport const left = <L, R = never>(value: L): EitherType<L, R> => ({\n _tag: \"Left\",\n value,\n [FxTypeId]: {\n _A: () => value as L | R,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n pipe: pipeable,\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, L, unknown> {\n return value\n },\n})\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard to check if an Either is in the right state.\n *\n * @param either - The Either to check\n * @returns True if right, false if left (with type narrowing)\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const isRight = Either.isRight(Either.right(1))\n * // => true\n * ```\n */\nexport const isRight = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Right\" }> =>\n either._tag === \"Right\"\n\n/**\n * isLeft utility.\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const isLeft = Either.isLeft(Either.left(\"missing\"))\n * // => true\n * ```\n */\nexport const isLeft = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Left\" }> =>\n either._tag === \"Left\"\n\n// ============================================================================\n// Right-biased Transformations\n// ============================================================================\n\n/**\n * Transform the right value of an Either.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `map(either, fn)`\n * - Data-last: `pipe(either, map(fn))`\n *\n * Supports both sync and async callbacks.\n *\n * @param fn - Transformation function for right values\n * @returns The mapped Either in data-first form, or a function that maps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2)\n * const dataFirst = Either.map(input, (n) => n + 1)\n * // => { _tag: \"Right\", value: 3 }\n *\n * const dataLast = Either.map((n: number) => n + 1)(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const map: EitherMap = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const mapped = fn(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(right) as any\n }\n return right(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Transform the left value of an Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `mapLeft(either, fn)`\n * - Data-last: `pipe(either, mapLeft(fn))`\n *\n * Supports both sync and async callbacks.\n *\n * @param fn - Transformation function for left values\n * @returns The mapped Either in data-first form, or a function that maps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.mapLeft(input, (msg) => msg.toUpperCase())\n * // => { _tag: \"Left\", value: \"MISSING\" }\n *\n * const dataLast = Either.mapLeft((msg: string) => msg.toUpperCase())(input)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const mapLeft: EitherMapLeft = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const mapped = fn(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(left) as any\n }\n return left(mapped) as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Transform both sides of an Either simultaneously.\n * Unique to Either - not available in Result/Option.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `bimap(either, fnLeft, fnRight)`\n * - Data-last: `pipe(either, bimap(fnLeft, fnRight))`\n *\n * Supports both sync and async callbacks.\n *\n * @param fnLeft - Transformation function for left values\n * @param fnRight - Transformation function for right values\n * @returns The mapped Either in data-first form, or a function that bimaps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.bimap(input, (left) => left.toUpperCase(), (right: number) => right + 1)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n *\n * const dataLast = Either.bimap((left: string) => left.toUpperCase(), (right: number) => right + 1)(input)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const bimap: EitherBimap = dual(\n 3,\n (either: EitherType<unknown, unknown>, fnLeft: (value: unknown) => unknown, fnRight: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") {\n const mapped = fnRight(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(right) as any\n }\n return right(mapped) as any\n }\n const mapped = fnLeft(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(left) as any\n }\n return left(mapped) as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Chain operations that return Either.\n * Left values short-circuit the chain.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `flatMap(either, fn)`\n * - Data-last: `pipe(either, flatMap(fn))`\n *\n * Supports both sync and async callbacks. Combines left error unions.\n *\n * @param fn - Function that returns an Either\n * @returns The resulting Either in data-first form, or a function that flatMaps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2)\n * const dataFirst = Either.flatMap(input, (n) => Either.right(n + 1))\n * // => { _tag: \"Right\", value: 3 }\n *\n * const dataLast = Either.flatMap((n: number) => Either.right(n + 1))(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const flatMap: EitherFlatMap = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const result = fn(either.value)\n return result as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Execute a side effect on right values without modifying the Either.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tap(either, fn)`\n * - Data-last: `pipe(either, tap(fn))`\n *\n * Supports both sync and async side effects.\n *\n * @param fn - Side effect function for right values\n * @returns The original Either in data-first form, or a function that taps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * let seen = 0\n * const input = Either.right(2)\n * const dataFirst = Either.tap(input, (n) => {\n * seen = n\n * })\n * // => { _tag: \"Right\", value: 2 }\n *\n * const dataLast = Either.tap((n: number) => {\n * seen = n\n * })(input)\n * // => { _tag: \"Right\", value: 2 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tap: EitherTap = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const result = fn(either.value)\n if (isPromise(result)) {\n return Promise.resolve(result).then(() => either) as any\n }\n return either as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Execute a side effect on left values without modifying the Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tapLeft(either, fn)`\n * - Data-last: `pipe(either, tapLeft(fn))`\n *\n * Supports both sync and async side effects.\n *\n * @param fn - Side effect function for left values\n * @returns The original Either in data-first form, or a function that taps left values in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * let seen = \"\"\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.tapLeft(input, (msg) => {\n * seen = msg\n * })\n * // => { _tag: \"Left\", value: \"missing\" }\n *\n * const dataLast = Either.tapLeft((msg: string) => {\n * seen = msg\n * })(input)\n * // => { _tag: \"Left\", value: \"missing\" }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tapLeft: EitherTapLeft = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const result = fn(either.value)\n if (isPromise(result)) {\n return Promise.resolve(result).then(() => either) as any\n }\n return either as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n// ============================================================================\n// Recovery/Fallback\n// ============================================================================\n\n/**\n * Recover from a left value by providing an alternative Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `orElse(either, fn)`\n * - Data-last: `pipe(either, orElse(fn))`\n *\n * Supports both sync and async fallback functions. Combines right value unions.\n *\n * @param fn - Function that returns an alternative Either\n * @returns The original or fallback Either in data-first form, or a function that recovers from left in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.orElse(input, () => Either.right(0))\n * // => { _tag: \"Right\", value: 0 }\n *\n * const dataLast = Either.orElse(() => Either.right(0))(input)\n * // => { _tag: \"Right\", value: 0 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const orElse: EitherOrElse = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const result = fn(either.value)\n return result as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Swap left and right values.\n * Unique to Either - not available in Result/Option.\n *\n * Curried for use with pipe().\n *\n * @returns A curried function that swaps left and right\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const swap = Either.swap<string, number>()\n * const value = swap(Either.left(\"missing\"))\n * // => { _tag: \"Right\", value: \"missing\" }\n * ```\n */\nexport const swap =\n <L, R>() =>\n (either: EitherType<L, R>): EitherType<R, L> =>\n either._tag === \"Left\" ? right(either.value) : left(either.value)\n\n// ============================================================================\n// Filtering\n// ============================================================================\n\n/**\n * Filter right values based on a predicate.\n * Failed predicates convert to left with onFail callback.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `filter(either, predicate, onFail)`\n * - Data-last: `pipe(either, filter(predicate, onFail))`\n *\n * @param predicate - Function to test right values\n * @param onFail - Function to produce left value on failure\n * @returns The filtered Either in data-first form, or a function that filters an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(3)\n * const dataFirst = Either.filter(input, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Right\", value: 3 }\n *\n * const dataLast = Either.filter((n: number) => n > 0, (n) => `${n} must be positive`)(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const filter: EitherFilter = dual(\n 3,\n (\n either: EitherType<unknown, unknown>,\n predicate: (value: unknown) => boolean,\n onFail: (value: unknown) => unknown,\n ) => {\n if (either._tag === \"Left\") return either as any\n return predicate(either.value) ? (either as any) : left(onFail(either.value))\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n// ============================================================================\n// Combinators\n// ============================================================================\n\n/**\n * Combine multiple Eithers into a single Either.\n * Short-circuits on the first left value.\n *\n * Supports both array and object inputs with full type preservation.\n * For arrays of 1-6 elements, tuple types are inferred automatically.\n * For longer arrays, use `as const` to preserve tuple structure.\n *\n * @param eithers - Array or object of Eithers to combine\n * @returns Either with all right values or first left\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const combined = Either.all([Either.right(1), Either.right(2)] as const)\n * // => { _tag: \"Right\", value: [1, 2] }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-assignment -- Required for handling union types in overloaded function */\nexport const all: EitherAll = (eithers: any): any => {\n // Array case\n if (Array.isArray(eithers)) {\n const values: unknown[] = []\n for (const either of eithers) {\n if (either._tag === \"Left\") return either\n values.push(either.value)\n }\n return right(values)\n }\n\n // Object case\n const result: Record<string, unknown> = {}\n for (const key in eithers) {\n const either = eithers[key]\n if (either._tag === \"Left\") return either\n result[key] = either.value\n }\n return right(result)\n}\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-assignment */\n// ============================================================================\n// Extraction\n// ============================================================================\n\n/**\n * Extract the right value or return a default.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOr(either, defaultValue)`\n * - Data-last: `pipe(either, unwrapOr(defaultValue))`\n *\n * Uses NoInfer to prevent type inference from the default value.\n *\n * @param defaultValue - Value to return if Either is left\n * @returns The unwrapped value in data-first form, or a function that unwraps an Either with a default in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\") as Either.Either<string, number>\n * const dataFirst = Either.unwrapOr(input, 0)\n * // => 0\n *\n * const dataLast = Either.unwrapOr(0)(input)\n * // => 0\n * ```\n */\nexport const unwrapOr: EitherUnwrapOr = dual(\n 2,\n <L, R>(either: EitherType<L, R>, defaultValue: NoInfer<R>): R =>\n either._tag === \"Right\" ? either.value : defaultValue,\n)\n\n/**\n * Extract the right value or compute one from the left value.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOrElse(either, fn)`\n * - Data-last: `pipe(either, unwrapOrElse(fn))`\n *\n * @param fn - Function to compute default from left value\n * @returns The unwrapped value in data-first form, or a function that unwraps an Either lazily in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\") as Either.Either<string, number>\n * const dataFirst = Either.unwrapOrElse(input, () => 0)\n * // => 0\n *\n * const dataLast = Either.unwrapOrElse(() => 0)(input)\n * // => 0\n * ```\n */\nexport const unwrapOrElse: EitherUnwrapOrElse = dual(\n 2,\n <L, R>(either: EitherType<L, R>, fn: (left: L) => R): R =>\n either._tag === \"Right\" ? either.value : fn(either.value),\n)\n\n/**\n * Pattern match on an Either with handlers for both cases.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `match(either, { Left: ..., Right: ... })`\n * - Data-last: `pipe(either, match({ Left: ..., Right: ... }))`\n *\n * @param handlers - Object with left and right handler functions\n * @returns The handler result in data-first form, or a function that matches an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2) as Either.Either<string, number>\n * const dataFirst = Either.match(input, {\n * Left: (left) => `error:${left}` ,\n * Right: (right) => `ok:${right}` ,\n * })\n * // => \"ok:2\"\n *\n * const dataLast = Either.match({\n * Left: (left: string) => `error:${left}` ,\n * Right: (right: number) => `ok:${right}` ,\n * })(input)\n * // => \"ok:2\"\n * ```\n */\nexport const match: EitherMatch = dual(\n 2,\n <L, R, U>(either: EitherType<L, R>, handlers: { Left: (value: L) => U; Right: (value: R) => U }): U =>\n either._tag === \"Right\" ? handlers.Right(either.value) : handlers.Left(either.value),\n)\n\n// ============================================================================\n// Conversions\n// ============================================================================\n\n/**\n * Convert a Result to an Either.\n * Result's ok becomes right, err becomes left.\n *\n * @param result - The Result to convert\n * @returns An Either with the same semantics\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromResult(Result.ok(1))\n * // => { _tag: \"Right\", value: 1 }\n * ```\n */\nexport const fromResult = <R, E>(result: ResultType<R, E>): EitherType<E, R> =>\n result._tag === \"Ok\" ? right(result.value) : left(result.error)\n\n/**\n * Convert an Either to a Result.\n * Either's right becomes ok, left becomes err.\n *\n * Curried for use with pipe().\n *\n * @param either - The Either to convert\n * @returns A Result with error semantics\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.toResult(Either.left(\"missing\"))\n * // => { _tag: \"Err\", error: \"missing\" }\n * ```\n */\nexport const toResult = <L, R>(either: EitherType<L, R>): ResultType<R, L> =>\n either._tag === \"Right\" ? Result.ok(either.value) : Result.err(either.value)\n\n/**\n * Convert an Option to an Either.\n * Option's some becomes right, none becomes left with onNone callback.\n *\n * @param option - The Option to convert\n * @param onNone - Function to produce left value for none\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * import { Option } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromOption(Option.some(1), () => \"missing\")\n * // => { _tag: \"Right\", value: 1 }\n * ```\n */\nexport const fromOption = <R, L>(option: OptionType<R>, onNone: () => L): EitherType<L, R> =>\n option._tag === \"Some\" ? right(option.value) : left(onNone())\n\n/**\n * Convert an Either to an Option.\n * Either's right becomes some, left is discarded.\n *\n * Curried for use with pipe().\n *\n * @param either - The Either to convert\n * @returns An Option (left value is discarded)\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.toOption(Either.left(\"missing\"))\n * // => { _tag: \"None\" }\n * ```\n */\nexport const toOption = <L, R>(either: EitherType<L, R>): OptionType<R> =>\n either._tag === \"Right\" ? Option.some(either.value) : Option.none<R>()\n\n/**\n * Convert a nullable value to an Either.\n * null/undefined becomes left with onNull callback, otherwise right.\n *\n * @param value - The nullable value\n * @param onNull - Function to produce left value for null/undefined\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromNullable(\"Ada\", () => \"missing\")\n * // => { _tag: \"Right\", value: \"Ada\" }\n * ```\n */\nexport const fromNullable = <R, L>(value: R | null | undefined, onNull: () => L): EitherType<L, R> =>\n value === null || value === undefined ? left(onNull()) : right(value)\n\n/**\n * Create an Either from a predicate.\n * Predicate success becomes right, failure becomes left with onFail callback.\n *\n * @param value - The value to test\n * @param predicate - Function to test the value\n * @param onFail - Function to produce left value on failure\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromPredicate(3, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\nexport const fromPredicate = <R, L>(\n value: R,\n predicate: (value: R) => boolean,\n onFail: (value: R) => L,\n): EitherType<L, R> => (predicate(value) ? right(value) : left(onFail(value)))\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
1
+ {"version":3,"file":"either-B2TvVY_j.mjs","names":["mapped","Result.ok","Result.err","Option.some","Option.none"],"sources":["../src/either/either.ts"],"sourcesContent":["/**\n * Biased disjoint union primitives for modeling two valid branches (`Left` / `Right`).\n *\n * **Mental model**\n * - `Either<L, R>` represents two meaningful outcomes.\n * - This module is right-biased for `map` / `flatMap`.\n *\n * **Common tasks**\n * - Construct with `Either.left` and `Either.right`.\n * - Transform with `Either.map`, `Either.mapLeft`, `Either.bimap`.\n * - Handle with `Either.match`, `Either.unwrapOr`, and conversions.\n *\n * **Gotchas**\n * - `Either.left` does not short-circuit in `Fx.gen`.\n * - Use `Result` when the left side should model failure semantics.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.right(2)\n * const next = Either.map(value, (n) => n + 1)\n * ```\n *\n * @module\n */\nimport { FxTypeId } from \"../fx/fx.types\"\nimport { Option } from \"../option\"\nimport type { Option as OptionType } from \"../option/option.types\"\nimport { Result } from \"../result\"\nimport type { Result as ResultType } from \"../result/result.types\"\nimport { dual } from \"../shared/dual\"\nimport { isPromise } from \"../shared/is-promise\"\nimport { pipeable } from \"../shared/pipeable\"\nimport type {\n Either as EitherType,\n EitherAll,\n EitherBimap,\n EitherFilter,\n EitherFlatMap,\n EitherMap,\n EitherMapLeft,\n EitherMatch,\n EitherOrElse,\n EitherTap,\n EitherTapLeft,\n EitherUnwrapOr,\n EitherUnwrapOrElse,\n} from \"./either.types\"\n\n/**\n * Re-exported `Either` type.\n *\n * @example\n * ```ts\n * import type { Either } from \"@nicolastoulemont/std\"\n *\n * type Example = Either.Either<unknown, unknown>\n * ```\n */\nexport type Either<L, R> = EitherType<L, R>\n\n/* oxlint-disable no-unsafe-type-assertion -- Either constructors encode Fx marker channels and left/right union normalization through intentional assertions. */\n\n// ============================================================================\n// Constructors\n// ============================================================================\n\n/**\n * Create a right Either value (success/preferred path).\n *\n * By convention, right represents the correct/preferred outcome.\n * In Fx.gen(), this returns the value without short-circuiting.\n *\n * @param value - The right value\n * @returns An Either in the right state\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.right(42)\n * // => { _tag: \"Right\", value: 42 }\n * ```\n */\nexport const right = <R, L = never>(value: R): EitherType<L, R> => ({\n _tag: \"Right\",\n value,\n [FxTypeId]: {\n _A: () => value as L | R,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n pipe: pipeable,\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, R, unknown> {\n return value\n },\n})\n\n/**\n * Create a left Either value (alternative path).\n *\n * By convention, left represents the alternative outcome.\n * Unlike Result's err(), left doesn't imply an error - it's a valid value.\n *\n * In Fx.gen(), left returns its value without short-circuiting.\n * This is the key difference from Result.err() which short-circuits.\n *\n * @param value - The left value\n * @returns An Either in the left state\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.left(\"missing\")\n * // => { _tag: \"Left\", value: \"missing\" }\n * ```\n */\nexport const left = <L, R = never>(value: L): EitherType<L, R> => ({\n _tag: \"Left\",\n value,\n [FxTypeId]: {\n _A: () => value as L | R,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n pipe: pipeable,\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, L, unknown> {\n return value\n },\n})\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard to check if an Either is in the right state.\n *\n * @param either - The Either to check\n * @returns True if right, false if left (with type narrowing)\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const isRight = Either.isRight(Either.right(1))\n * // => true\n * ```\n */\nexport const isRight = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Right\" }> =>\n either._tag === \"Right\"\n\n/**\n * isLeft utility.\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const isLeft = Either.isLeft(Either.left(\"missing\"))\n * // => true\n * ```\n */\nexport const isLeft = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Left\" }> =>\n either._tag === \"Left\"\n\n// ============================================================================\n// Right-biased Transformations\n// ============================================================================\n\n/**\n * Transform the right value of an Either.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `map(either, fn)`\n * - Data-last: `pipe(either, map(fn))`\n *\n * Supports both sync and async callbacks.\n *\n * @param fn - Transformation function for right values\n * @returns The mapped Either in data-first form, or a function that maps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2)\n * const dataFirst = Either.map(input, (n) => n + 1)\n * // => { _tag: \"Right\", value: 3 }\n *\n * const dataLast = Either.map((n: number) => n + 1)(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const map: EitherMap = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const mapped = fn(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(right) as any\n }\n return right(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Transform the left value of an Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `mapLeft(either, fn)`\n * - Data-last: `pipe(either, mapLeft(fn))`\n *\n * Supports both sync and async callbacks.\n *\n * @param fn - Transformation function for left values\n * @returns The mapped Either in data-first form, or a function that maps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.mapLeft(input, (msg) => msg.toUpperCase())\n * // => { _tag: \"Left\", value: \"MISSING\" }\n *\n * const dataLast = Either.mapLeft((msg: string) => msg.toUpperCase())(input)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const mapLeft: EitherMapLeft = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const mapped = fn(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(left) as any\n }\n return left(mapped) as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Transform both sides of an Either simultaneously.\n * Unique to Either - not available in Result/Option.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `bimap(either, fnLeft, fnRight)`\n * - Data-last: `pipe(either, bimap(fnLeft, fnRight))`\n *\n * Supports both sync and async callbacks.\n *\n * @param fnLeft - Transformation function for left values\n * @param fnRight - Transformation function for right values\n * @returns The mapped Either in data-first form, or a function that bimaps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.bimap(input, (left) => left.toUpperCase(), (right: number) => right + 1)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n *\n * const dataLast = Either.bimap((left: string) => left.toUpperCase(), (right: number) => right + 1)(input)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const bimap: EitherBimap = dual(\n 3,\n (either: EitherType<unknown, unknown>, fnLeft: (value: unknown) => unknown, fnRight: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") {\n const mapped = fnRight(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(right) as any\n }\n return right(mapped) as any\n }\n const mapped = fnLeft(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(left) as any\n }\n return left(mapped) as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Chain operations that return Either.\n * Left values short-circuit the chain.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `flatMap(either, fn)`\n * - Data-last: `pipe(either, flatMap(fn))`\n *\n * Supports both sync and async callbacks. Combines left error unions.\n *\n * @param fn - Function that returns an Either\n * @returns The resulting Either in data-first form, or a function that flatMaps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2)\n * const dataFirst = Either.flatMap(input, (n) => Either.right(n + 1))\n * // => { _tag: \"Right\", value: 3 }\n *\n * const dataLast = Either.flatMap((n: number) => Either.right(n + 1))(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const flatMap: EitherFlatMap = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const result = fn(either.value)\n return result as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Execute a side effect on right values without modifying the Either.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tap(either, fn)`\n * - Data-last: `pipe(either, tap(fn))`\n *\n * Supports both sync and async side effects.\n *\n * @param fn - Side effect function for right values\n * @returns The original Either in data-first form, or a function that taps an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * let seen = 0\n * const input = Either.right(2)\n * const dataFirst = Either.tap(input, (n) => {\n * seen = n\n * })\n * // => { _tag: \"Right\", value: 2 }\n *\n * const dataLast = Either.tap((n: number) => {\n * seen = n\n * })(input)\n * // => { _tag: \"Right\", value: 2 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tap: EitherTap = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const result = fn(either.value)\n if (isPromise(result)) {\n return Promise.resolve(result).then(() => either) as any\n }\n return either as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Execute a side effect on left values without modifying the Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tapLeft(either, fn)`\n * - Data-last: `pipe(either, tapLeft(fn))`\n *\n * Supports both sync and async side effects.\n *\n * @param fn - Side effect function for left values\n * @returns The original Either in data-first form, or a function that taps left values in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * let seen = \"\"\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.tapLeft(input, (msg) => {\n * seen = msg\n * })\n * // => { _tag: \"Left\", value: \"missing\" }\n *\n * const dataLast = Either.tapLeft((msg: string) => {\n * seen = msg\n * })(input)\n * // => { _tag: \"Left\", value: \"missing\" }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tapLeft: EitherTapLeft = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const result = fn(either.value)\n if (isPromise(result)) {\n return Promise.resolve(result).then(() => either) as any\n }\n return either as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n// ============================================================================\n// Recovery/Fallback\n// ============================================================================\n\n/**\n * Recover from a left value by providing an alternative Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `orElse(either, fn)`\n * - Data-last: `pipe(either, orElse(fn))`\n *\n * Supports both sync and async fallback functions. Combines right value unions.\n *\n * @param fn - Function that returns an alternative Either\n * @returns The original or fallback Either in data-first form, or a function that recovers from left in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.orElse(input, () => Either.right(0))\n * // => { _tag: \"Right\", value: 0 }\n *\n * const dataLast = Either.orElse(() => Either.right(0))(input)\n * // => { _tag: \"Right\", value: 0 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const orElse: EitherOrElse = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const result = fn(either.value)\n return result as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Swap left and right values.\n * Unique to Either - not available in Result/Option.\n *\n * Curried for use with pipe().\n *\n * @returns A curried function that swaps left and right\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const swap = Either.swap<string, number>()\n * const value = swap(Either.left(\"missing\"))\n * // => { _tag: \"Right\", value: \"missing\" }\n * ```\n */\nexport const swap =\n <L, R>() =>\n (either: EitherType<L, R>): EitherType<R, L> =>\n either._tag === \"Left\" ? right(either.value) : left(either.value)\n\n// ============================================================================\n// Filtering\n// ============================================================================\n\n/**\n * Filter right values based on a predicate.\n * Failed predicates convert to left with onFail callback.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `filter(either, predicate, onFail)`\n * - Data-last: `pipe(either, filter(predicate, onFail))`\n *\n * @param predicate - Function to test right values\n * @param onFail - Function to produce left value on failure\n * @returns The filtered Either in data-first form, or a function that filters an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(3)\n * const dataFirst = Either.filter(input, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Right\", value: 3 }\n *\n * const dataLast = Either.filter((n: number) => n > 0, (n) => `${n} must be positive`)(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const filter: EitherFilter = dual(\n 3,\n (\n either: EitherType<unknown, unknown>,\n predicate: (value: unknown) => boolean,\n onFail: (value: unknown) => unknown,\n ) => {\n if (either._tag === \"Left\") return either as any\n return predicate(either.value) ? (either as any) : left(onFail(either.value))\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n// ============================================================================\n// Combinators\n// ============================================================================\n\n/**\n * Combine multiple Eithers into a single Either.\n * Short-circuits on the first left value.\n *\n * Supports both array and object inputs with full type preservation.\n * For arrays of 1-6 elements, tuple types are inferred automatically.\n * For longer arrays, use `as const` to preserve tuple structure.\n *\n * @param eithers - Array or object of Eithers to combine\n * @returns Either with all right values or first left\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const combined = Either.all([Either.right(1), Either.right(2)] as const)\n * // => { _tag: \"Right\", value: [1, 2] }\n * ```\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-assignment -- Required for handling union types in overloaded function */\nexport const all: EitherAll = (eithers: any): any => {\n // Array case\n if (Array.isArray(eithers)) {\n const values: unknown[] = []\n for (const either of eithers) {\n if (either._tag === \"Left\") return either\n values.push(either.value)\n }\n return right(values)\n }\n\n // Object case\n const result: Record<string, unknown> = {}\n for (const key in eithers) {\n const either = eithers[key]\n if (either._tag === \"Left\") return either\n result[key] = either.value\n }\n return right(result)\n}\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-assignment */\n// ============================================================================\n// Extraction\n// ============================================================================\n\n/**\n * Extract the right value or return a default.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOr(either, defaultValue)`\n * - Data-last: `pipe(either, unwrapOr(defaultValue))`\n *\n * Uses NoInfer to prevent type inference from the default value.\n *\n * @param defaultValue - Value to return if Either is left\n * @returns The unwrapped value in data-first form, or a function that unwraps an Either with a default in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\") as Either.Either<string, number>\n * const dataFirst = Either.unwrapOr(input, 0)\n * // => 0\n *\n * const dataLast = Either.unwrapOr(0)(input)\n * // => 0\n * ```\n */\nexport const unwrapOr: EitherUnwrapOr = dual(\n 2,\n <L, R>(either: EitherType<L, R>, defaultValue: NoInfer<R>): R =>\n either._tag === \"Right\" ? either.value : defaultValue,\n)\n\n/**\n * Extract the right value or compute one from the left value.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOrElse(either, fn)`\n * - Data-last: `pipe(either, unwrapOrElse(fn))`\n *\n * @param fn - Function to compute default from left value\n * @returns The unwrapped value in data-first form, or a function that unwraps an Either lazily in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\") as Either.Either<string, number>\n * const dataFirst = Either.unwrapOrElse(input, () => 0)\n * // => 0\n *\n * const dataLast = Either.unwrapOrElse(() => 0)(input)\n * // => 0\n * ```\n */\nexport const unwrapOrElse: EitherUnwrapOrElse = dual(\n 2,\n <L, R>(either: EitherType<L, R>, fn: (left: L) => R): R =>\n either._tag === \"Right\" ? either.value : fn(either.value),\n)\n\n/**\n * Pattern match on an Either with handlers for both cases.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `match(either, { Left: ..., Right: ... })`\n * - Data-last: `pipe(either, match({ Left: ..., Right: ... }))`\n *\n * @param handlers - Object with left and right handler functions\n * @returns The handler result in data-first form, or a function that matches an Either in data-last form\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2) as Either.Either<string, number>\n * const dataFirst = Either.match(input, {\n * Left: (left) => `error:${left}` ,\n * Right: (right) => `ok:${right}` ,\n * })\n * // => \"ok:2\"\n *\n * const dataLast = Either.match({\n * Left: (left: string) => `error:${left}` ,\n * Right: (right: number) => `ok:${right}` ,\n * })(input)\n * // => \"ok:2\"\n * ```\n */\nexport const match: EitherMatch = dual(\n 2,\n <L, R, U>(either: EitherType<L, R>, handlers: { Left: (value: L) => U; Right: (value: R) => U }): U =>\n either._tag === \"Right\" ? handlers.Right(either.value) : handlers.Left(either.value),\n)\n\n// ============================================================================\n// Conversions\n// ============================================================================\n\n/**\n * Convert a Result to an Either.\n * Result's ok becomes right, err becomes left.\n *\n * @param result - The Result to convert\n * @returns An Either with the same semantics\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromResult(Result.ok(1))\n * // => { _tag: \"Right\", value: 1 }\n * ```\n */\nexport const fromResult = <R, E>(result: ResultType<R, E>): EitherType<E, R> =>\n result._tag === \"Ok\" ? right(result.value) : left(result.error)\n\n/**\n * Convert an Either to a Result.\n * Either's right becomes ok, left becomes err.\n *\n * Curried for use with pipe().\n *\n * @param either - The Either to convert\n * @returns A Result with error semantics\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.toResult(Either.left(\"missing\"))\n * // => { _tag: \"Err\", error: \"missing\" }\n * ```\n */\nexport const toResult = <L, R>(either: EitherType<L, R>): ResultType<R, L> =>\n either._tag === \"Right\" ? Result.ok(either.value) : Result.err(either.value)\n\n/**\n * Convert an Option to an Either.\n * Option's some becomes right, none becomes left with onNone callback.\n *\n * @param option - The Option to convert\n * @param onNone - Function to produce left value for none\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * import { Option } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromOption(Option.some(1), () => \"missing\")\n * // => { _tag: \"Right\", value: 1 }\n * ```\n */\nexport const fromOption = <R, L>(option: OptionType<R>, onNone: () => L): EitherType<L, R> =>\n option._tag === \"Some\" ? right(option.value) : left(onNone())\n\n/**\n * Convert an Either to an Option.\n * Either's right becomes some, left is discarded.\n *\n * Curried for use with pipe().\n *\n * @param either - The Either to convert\n * @returns An Option (left value is discarded)\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.toOption(Either.left(\"missing\"))\n * // => { _tag: \"None\" }\n * ```\n */\nexport const toOption = <L, R>(either: EitherType<L, R>): OptionType<R> =>\n either._tag === \"Right\" ? Option.some(either.value) : Option.none<R>()\n\n/**\n * Convert a nullable value to an Either.\n * null/undefined becomes left with onNull callback, otherwise right.\n *\n * @param value - The nullable value\n * @param onNull - Function to produce left value for null/undefined\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromNullable(\"Ada\", () => \"missing\")\n * // => { _tag: \"Right\", value: \"Ada\" }\n * ```\n */\nexport const fromNullable = <R, L>(value: R | null | undefined, onNull: () => L): EitherType<L, R> =>\n value === null || value === undefined ? left(onNull()) : right(value)\n\n/**\n * Create an Either from a predicate.\n * Predicate success becomes right, failure becomes left with onFail callback.\n *\n * @param value - The value to test\n * @param predicate - Function to test the value\n * @param onFail - Function to produce left value on failure\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromPredicate(3, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n */\nexport const fromPredicate = <R, L>(\n value: R,\n predicate: (value: R) => boolean,\n onFail: (value: R) => L,\n): EitherType<L, R> => (predicate(value) ? right(value) : left(onFail(value)))\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { m as Ok, p as Err } from "./result.types-CnhiVFEV.mjs";
2
+
3
+ //#region src/fx/exit.d.ts
4
+
5
+ /**
6
+ * Represents an unexpected thrown exception (defect) caught during Fx execution.
7
+ */
8
+ type Defect = {
9
+ readonly _tag: "Defect";
10
+ readonly defect: unknown;
11
+ };
12
+ /**
13
+ * Represents cooperative fiber interruption.
14
+ */
15
+ type Interrupted = {
16
+ readonly _tag: "Interrupted";
17
+ readonly fiberId: number;
18
+ };
19
+ /**
20
+ * Exit represents the outcome of an Fx computation.
21
+ * A flat discriminated union that cleanly separates:
22
+ * - `Ok<A>`: successful result with value of type A
23
+ * - `Err<E>`: typed failure with error of type E
24
+ * - `Defect`: unexpected thrown exception (defect)
25
+ * - `Interrupted`: cooperative fiber interruption
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const exit = Fx.run(computation)
30
+ * switch (exit._tag) {
31
+ * case "Ok": exit.value // A
32
+ * case "Err": exit.error // E (clean!)
33
+ * case "Defect": exit.defect // unknown
34
+ * }
35
+ * ```
36
+ */
37
+ type Exit<A, E> = Ok<A> | Err<E> | Defect | Interrupted;
38
+ /**
39
+ * Handler functions for Exit.match.
40
+ */
41
+ type ExitMatch<A, E, R> = {
42
+ readonly Ok: (value: A) => R;
43
+ readonly Err: (error: E) => R;
44
+ readonly Defect: (defect: unknown) => R;
45
+ readonly Interrupted?: (fiberId: number) => R;
46
+ };
47
+ /**
48
+ * Exit namespace containing all Exit utilities.
49
+ */
50
+ declare const Exit: {
51
+ readonly ok: <A>(value: A) => Ok<A>;
52
+ readonly err: <E>(error: E) => Err<E>;
53
+ readonly defect: (thrown: unknown) => Defect;
54
+ readonly interrupted: (fiberId: number) => Interrupted;
55
+ readonly isOk: <A, E>(exit: Exit<A, E>) => exit is Ok<A>;
56
+ readonly isErr: <A, E>(exit: Exit<A, E>) => exit is Err<E>;
57
+ readonly isDefect: <A, E>(exit: Exit<A, E>) => exit is Defect;
58
+ readonly isInterrupted: <A, E>(exit: Exit<A, E>) => exit is Interrupted;
59
+ readonly match: {
60
+ <A, E, R>(exit: Exit<A, E>, handlers: ExitMatch<A, E, R>): R;
61
+ <A, E, R>(handlers: ExitMatch<A, E, R>): (exit: Exit<A, E>) => R;
62
+ };
63
+ readonly getOrThrow: <A, E>(exit: Exit<A, E>) => A;
64
+ };
65
+ //#endregion
66
+ export { Exit as t };
67
+ //# sourceMappingURL=exit-DOdhmr81.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-DOdhmr81.d.mts","names":[],"sources":["../src/fx/exit.ts"],"sourcesContent":[],"mappings":";;;;;;AACyD;AAS9C,KAAN,MAAA,GAQA;EAuBO,SAAI,IAAA,EAAA,QAAA;EAAY,SAAA,MAAA,EAAA,OAAA;CAAH;;;;KAvBpB,WAAA,GAuB8C;EAAW,SAAA,IAAA,EAAA,aAAA;EAyDzD,SAAA,OAAS,EAAA,MAAA;CACS;;;;;;;AA4EvB;;;;;;;;;;;;AArGkD,KAjCtC,IAiCsC,CAAA,CAAA,EAAA,CAAA,CAAA,GAjCzB,EAiCyB,CAjCtB,CAiCsB,CAAA,GAjCjB,GAiCiB,CAjCb,CAiCa,CAAA,GAjCR,MAiCQ,GAjCC,WAiCD;;;;KAwB7C,SA4BmD,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,GAAA;EAAhB,SAAA,EAAA,EAAA,CAAA,KAAA,EA3BjB,CA2BiB,EAAA,GA3BX,CA2BW;EAAqB,SAAA,GAAA,EAAA,CAAA,KAAA,EA1BrC,CA0BqC,EAAA,GA1B/B,CA0B+B;EAC7B,SAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,GA1BQ,CA0BR;EAAG,SAAA,WAAA,CAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAzBW,CAyBX;CAAG;;;;AAAY,cAgDrC,IAhDqC,EAAA;EAAe,SAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EA7EpC,CA6EoC,EAAA,GA7EhC,EA6EgC,CA7E7B,CA6E6B,CAAA;EA2B5B,SAAA,GAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAnGP,CAmGO,EAAA,GAnGH,GAmGG,CAnGC,CAmGD,CAAA;EAAG,SAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,GA9FC,MA8FD;EAAR,SAAA,WAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAzFc,WAyFd;EAAa,SAAA,IAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,IAAA,EAhFnB,IAgFmB,CAhFd,CAgFc,EAhFX,CAgFW,CAAA,EAAA,GAAA,IAAA,IAhFE,EAgFF,CAhFK,CAgFL,CAAA;EAAC,SAAA,KAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,IAAA,EA3EnB,IA2EmB,CA3Ed,CA2Ec,EA3EX,CA2EW,CAAA,EAAA,GAAA,IAAA,IA3EE,GA2EF,CA3EM,CA2EN,CAAA;kCAtEhB,KAAK,GAAG,eAAa;uCAKhB,KAAK,GAAG,eAAa;;oBAqCtC,KAAK,GAAG,cAAc,UAAU,GAAG,GAAG,KAAK;wBACvC,UAAU,GAAG,GAAG,YAAY,KAAK,GAAG,OAAO;;oCA2BjC,KAAK,GAAG,OAAK"}
@@ -0,0 +1,2 @@
1
+ import { t as fiber_d_exports } from "../index-Cv48HmyO.mjs";
2
+ export { fiber_d_exports as Fiber };
@@ -0,0 +1 @@
1
+ import{t as e}from"../fiber-CZsyrDdd.mjs";export{e as Fiber};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{a as t,c as n,r,t as i}from"./fx.runtime-B2_rL7h_.mjs";var a=e({await:()=>o,await_:()=>o,interrupt:()=>c,join:()=>s,status:()=>l});const o=e=>i(e),s=e=>n(e),c=e=>t(e),l=e=>r(e);export{a as t};
2
+ //# sourceMappingURL=fiber-CZsyrDdd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiber-CZsyrDdd.mjs","names":[],"sources":["../src/fiber/fiber.ts"],"sourcesContent":["import type { Exit } from \"../fx/exit\"\nimport { awaitFiber, getFiberStatus, interruptFiber, joinFiber } from \"../fx/fx.runtime\"\nimport type { FiberStatus, RuntimeFiber } from \"../fx/fx.runtime\"\nimport type { AsyncFx, SyncFx } from \"../fx/fx.types\"\n\n/**\n * Public handle for a running Fx fiber.\n */\nexport type Fiber<A, E> = RuntimeFiber<A, E>\n\n/**\n * Fiber lifecycle status.\n */\nexport type Status = FiberStatus\n\n/**\n * Await a fiber and return its full Exit.\n *\n * @example\n * ```ts\n * const exit = yield* Fiber.await(fiber)\n * // => Fx.Exit<A, E>\n * ```\n */\nexport const await_ = <A, E>(fiber: Fiber<A, E>): AsyncFx<Exit<A, E>> => awaitFiber(fiber)\n\n/**\n * Join a fiber and resume with its success value.\n *\n * @example\n * ```ts\n * const value = yield* Fiber.join(fiber)\n * // => A\n * ```\n */\nexport const join = <A, E>(fiber: Fiber<A, E>): AsyncFx<A, E> => joinFiber(fiber)\n\n/**\n * Request cooperative interruption and wait for fiber completion.\n *\n * @example\n * ```ts\n * const exit = yield* Fiber.interrupt(fiber)\n * // => Fx.Exit<A, E>\n * ```\n */\nexport const interrupt = <A, E>(fiber: Fiber<A, E>): AsyncFx<Exit<A, E>> => interruptFiber(fiber)\n\n/**\n * Read the current fiber status.\n *\n * @example\n * ```ts\n * const status = yield* Fiber.status(fiber)\n * // => \"Running\" | \"Done\" | \"Interrupted\"\n * ```\n */\nexport const status = (fiber: Fiber<unknown, unknown>): SyncFx<Status> => getFiberStatus(fiber)\n\nexport { await_ as await }\n"],"mappings":"mLAwBA,MAAa,EAAgB,GAA4C,EAAW,EAAM,CAW7E,EAAc,GAAsC,EAAU,EAAM,CAWpE,EAAmB,GAA4C,EAAe,EAAM,CAWpF,EAAU,GAAmD,EAAe,EAAM"}
@@ -1,2 +1,2 @@
1
1
  function e(e){return e===null||typeof e!=`object`&&typeof e!=`function`?!1:typeof e.then==`function`}function t(...t){return((...r)=>{let i=r;for(let r=0;r<t.length;r++){let[a]=i=[t[r]?.(...i)];if(e(a))return n(a,t.slice(r+1))}return i[0]})}const n=async(e,t)=>{for(let n of t)e=n(await e);return await e};export{e as n,t};
2
- //# sourceMappingURL=flow-CNyLsPGb.mjs.map
2
+ //# sourceMappingURL=flow-D8_tllWl.mjs.map