@nicolastoulemont/std 0.5.0 → 0.6.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 (126) hide show
  1. package/README.md +341 -0
  2. package/dist/adt/index.d.mts +2 -2
  3. package/dist/adt/index.mjs +1 -1
  4. package/dist/adt-CkRcY_GA.mjs +2 -0
  5. package/dist/adt-CkRcY_GA.mjs.map +1 -0
  6. package/dist/{apply-fn.types-CMgY6WQe.d.mts → apply-fn.types-0g_9eXRy.d.mts} +1 -1
  7. package/dist/{apply-fn.types-CMgY6WQe.d.mts.map → apply-fn.types-0g_9eXRy.d.mts.map} +1 -1
  8. package/dist/brand/index.d.mts +1 -1
  9. package/dist/brand/index.mjs +1 -1
  10. package/dist/{brand-BUqMmkzC.mjs → brand-Gy0kW6-n.mjs} +2 -2
  11. package/dist/brand-Gy0kW6-n.mjs.map +1 -0
  12. package/dist/chunk-DAexk1S7.mjs +1 -0
  13. package/dist/data/index.d.mts +2 -2
  14. package/dist/data/index.mjs +1 -1
  15. package/dist/data-C0_3MGwm.mjs +2 -0
  16. package/dist/data-C0_3MGwm.mjs.map +1 -0
  17. package/dist/{discriminator.types-DkThfvNE.d.mts → discriminator.types-9PxvrZki.d.mts} +1 -1
  18. package/dist/discriminator.types-9PxvrZki.d.mts.map +1 -0
  19. package/dist/either/index.d.mts +1 -1
  20. package/dist/either/index.mjs +1 -1
  21. package/dist/either-CPzK-s8W.mjs +2 -0
  22. package/dist/either-CPzK-s8W.mjs.map +1 -0
  23. package/dist/equality-CD4_A1Op.mjs +2 -0
  24. package/dist/equality-CD4_A1Op.mjs.map +1 -0
  25. package/dist/err/index.d.mts +1 -1
  26. package/dist/err/index.mjs +1 -1
  27. package/dist/err-3KpQ4pj9.mjs +2 -0
  28. package/dist/err-3KpQ4pj9.mjs.map +1 -0
  29. package/dist/flow/index.d.mts +1 -1
  30. package/dist/flow/index.mjs +1 -1
  31. package/dist/flow-CYjiodlC.mjs +2 -0
  32. package/dist/flow-CYjiodlC.mjs.map +1 -0
  33. package/dist/fx/index.d.mts +3 -3
  34. package/dist/fx/index.mjs +1 -1
  35. package/dist/fx-vqywVJhV.mjs +2 -0
  36. package/dist/fx-vqywVJhV.mjs.map +1 -0
  37. package/dist/{fx.types-DO-8yG4c.d.mts → fx.types-B34asVRX.d.mts} +2 -7
  38. package/dist/{fx.types-DO-8yG4c.d.mts.map → fx.types-B34asVRX.d.mts.map} +1 -1
  39. package/dist/{fx.types-CXTwEa1G.mjs → fx.types-CDVjDn_3.mjs} +1 -1
  40. package/dist/{fx.types-CXTwEa1G.mjs.map → fx.types-CDVjDn_3.mjs.map} +1 -1
  41. package/dist/{index-78LWwTds.d.mts → index-8Ne4GdOG.d.mts} +2 -2
  42. package/dist/{index-78LWwTds.d.mts.map → index-8Ne4GdOG.d.mts.map} +1 -1
  43. package/dist/{index-BuLJRX1e.d.mts → index-B2l8_CiD.d.mts} +42 -52
  44. package/dist/index-B2l8_CiD.d.mts.map +1 -0
  45. package/dist/{index-BahMvQpA.d.mts → index-BOrJQBPO.d.mts} +2 -2
  46. package/dist/{index-BahMvQpA.d.mts.map → index-BOrJQBPO.d.mts.map} +1 -1
  47. package/dist/{index-CDio8mJY.d.mts → index-BsXtpnw-.d.mts} +7 -7
  48. package/dist/index-BsXtpnw-.d.mts.map +1 -0
  49. package/dist/{index-DtAPrec7.d.mts → index-BzYtgdX0.d.mts} +70 -62
  50. package/dist/index-BzYtgdX0.d.mts.map +1 -0
  51. package/dist/index-C4v_3f3-.d.mts +396 -0
  52. package/dist/index-C4v_3f3-.d.mts.map +1 -0
  53. package/dist/{index-BQ5wVDSP.d.mts → index-CjZ95Dsv.d.mts} +35 -47
  54. package/dist/index-CjZ95Dsv.d.mts.map +1 -0
  55. package/dist/{index-Bs5TTFlK.d.mts → index-CklRfom5.d.mts} +10 -10
  56. package/dist/index-CklRfom5.d.mts.map +1 -0
  57. package/dist/{index-IdejL485.d.mts → index-DZdmFtjA.d.mts} +2 -2
  58. package/dist/{index-IdejL485.d.mts.map → index-DZdmFtjA.d.mts.map} +1 -1
  59. package/dist/{index-DQoTXLSm.d.mts → index-a4MEBZZ1.d.mts} +25 -21
  60. package/dist/index-a4MEBZZ1.d.mts.map +1 -0
  61. package/dist/{index-DjjJIDaA.d.mts → index-jeC5jyRh.d.mts} +8 -8
  62. package/dist/index-jeC5jyRh.d.mts.map +1 -0
  63. package/dist/index.d.mts +16 -16
  64. package/dist/index.mjs +1 -1
  65. package/dist/option/index.d.mts +3 -3
  66. package/dist/option/index.mjs +1 -1
  67. package/dist/option-DawZC1cE.mjs +2 -0
  68. package/dist/option-DawZC1cE.mjs.map +1 -0
  69. package/dist/{option.types-Cluybn30.d.mts → option.types-ClJiBTdg.d.mts} +6 -11
  70. package/dist/option.types-ClJiBTdg.d.mts.map +1 -0
  71. package/dist/pipe/index.d.mts +1 -1
  72. package/dist/pipe/index.mjs +1 -1
  73. package/dist/pipe-BPpJyZf7.mjs +2 -0
  74. package/dist/{pipe-BROILDeC.mjs.map → pipe-BPpJyZf7.mjs.map} +1 -1
  75. package/dist/{pipeable-KHu4D8ol.d.mts → pipeable-B4YJA56p.d.mts} +1 -1
  76. package/dist/{pipeable-KHu4D8ol.d.mts.map → pipeable-B4YJA56p.d.mts.map} +1 -1
  77. package/dist/{pipeable-rQvolRqh.mjs → pipeable-BA0mXhs4.mjs} +2 -2
  78. package/dist/pipeable-BA0mXhs4.mjs.map +1 -0
  79. package/dist/predicate/index.d.mts +1 -1
  80. package/dist/predicate/index.mjs +1 -1
  81. package/dist/{predicate-DvXnfmeJ.mjs → predicate-Cy_oHA1Q.mjs} +1 -1
  82. package/dist/{predicate-DvXnfmeJ.mjs.map → predicate-Cy_oHA1Q.mjs.map} +1 -1
  83. package/dist/result/index.d.mts +2 -2
  84. package/dist/result/index.mjs +1 -1
  85. package/dist/result-CgGYLp0L.mjs +2 -0
  86. package/dist/result-CgGYLp0L.mjs.map +1 -0
  87. package/dist/result-fiJhwVGz.mjs +1 -0
  88. package/dist/{result.types-fIbuBwVQ.d.mts → result.types-HHDzgSTV.d.mts} +31 -17
  89. package/dist/result.types-HHDzgSTV.d.mts.map +1 -0
  90. package/package.json +3 -2
  91. package/dist/adt-DZmVJG4P.mjs +0 -2
  92. package/dist/adt-DZmVJG4P.mjs.map +0 -1
  93. package/dist/brand-BUqMmkzC.mjs.map +0 -1
  94. package/dist/data-DzqKBCQg.mjs +0 -2
  95. package/dist/data-DzqKBCQg.mjs.map +0 -1
  96. package/dist/discriminator.types-DkThfvNE.d.mts.map +0 -1
  97. package/dist/either-BDY9T5oz.mjs +0 -2
  98. package/dist/either-BDY9T5oz.mjs.map +0 -1
  99. package/dist/equality-D2EJvZm4.mjs +0 -2
  100. package/dist/equality-D2EJvZm4.mjs.map +0 -1
  101. package/dist/err-CYs4b1RV.mjs +0 -2
  102. package/dist/err-CYs4b1RV.mjs.map +0 -1
  103. package/dist/flow-CxKQ5yac.mjs +0 -2
  104. package/dist/flow-CxKQ5yac.mjs.map +0 -1
  105. package/dist/fx-C4UuWCqP.mjs +0 -2
  106. package/dist/fx-C4UuWCqP.mjs.map +0 -1
  107. package/dist/index-BQ5wVDSP.d.mts.map +0 -1
  108. package/dist/index-Bs5TTFlK.d.mts.map +0 -1
  109. package/dist/index-BuLJRX1e.d.mts.map +0 -1
  110. package/dist/index-CDio8mJY.d.mts.map +0 -1
  111. package/dist/index-DLlx9jiG.d.mts +0 -389
  112. package/dist/index-DLlx9jiG.d.mts.map +0 -1
  113. package/dist/index-DQoTXLSm.d.mts.map +0 -1
  114. package/dist/index-DjjJIDaA.d.mts.map +0 -1
  115. package/dist/index-DtAPrec7.d.mts.map +0 -1
  116. package/dist/option-Qiv7Ls7L.mjs +0 -2
  117. package/dist/option-Qiv7Ls7L.mjs.map +0 -1
  118. package/dist/option.types-By5UOfC2.mjs +0 -2
  119. package/dist/option.types-By5UOfC2.mjs.map +0 -1
  120. package/dist/option.types-Cluybn30.d.mts.map +0 -1
  121. package/dist/pipe-BROILDeC.mjs +0 -2
  122. package/dist/pipeable-rQvolRqh.mjs.map +0 -1
  123. package/dist/result-B68pxC7l.mjs +0 -2
  124. package/dist/result-B68pxC7l.mjs.map +0 -1
  125. package/dist/result.types-fIbuBwVQ.d.mts.map +0 -1
  126. /package/dist/{result-uRORQlAQ.mjs → option-Bb-taghv.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"either-CPzK-s8W.mjs","names":["mapped","Option.some","Option.none"],"sources":["../src/either/either.ts"],"sourcesContent":["import { 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 { pipeMethod } 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/* 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 * const result = right(42)\n * // => { _tag: \"Right\", value: 42 }\n *\n * // In Fx.gen() - never short-circuits\n * const fx = Fx.gen(function* () {\n * const a = yield* Either.right(10) // Returns 10\n * return a * 2 // Executes, returns 20\n * })\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: pipeMethod,\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 * const cached = left({ source: \"cache\", data: cachedValue })\n * // => { _tag: \"Left\", value: { source: \"cache\", data: cachedValue } }\n *\n * // In Fx.gen() - never short-circuits (unlike Result.err)\n * const fx = Fx.gen(function* () {\n * const a = yield* Either.left(\"cached\") // Returns \"cached\"\n * return a.toUpperCase() // Executes, returns \"CACHED\"\n * })\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: pipeMethod,\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 * const either = right(42)\n * if (isRight(either)) {\n * console.log(either.value) // Type: number\n * }\n * ```\n */\nexport const isRight = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Right\" }> =>\n either._tag === \"Right\"\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 async functions.\n *\n * @param fn - Transformation function for right values\n * @returns A curried function that transforms an Either\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * map(right(5), x => x * 2) // => right(10)\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(5),\n * map(x => x * 2)\n * ) // => right(10)\n *\n * pipe(\n * left(\"error\"),\n * map(x => x * 2)\n * ) // => left(\"error\")\n *\n * // Async usage\n * await pipe(\n * right(userId),\n * map(async id => await fetchUser(id))\n * ) // => Promise<Either<L, User>>\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 async functions.\n *\n * @param fn - Transformation function for left values\n * @returns A curried function that transforms an Either\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * mapLeft(left(\"error\"), e => e.toUpperCase()) // => left(\"ERROR\")\n *\n * // Data-last (curried for pipe)\n * pipe(\n * left(\"error\"),\n * mapLeft(e => e.toUpperCase())\n * ) // => left(\"ERROR\")\n *\n * pipe(\n * right(42),\n * mapLeft(e => e.toUpperCase())\n * ) // => right(42)\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 async functions.\n *\n * @param fnLeft - Transformation function for left values\n * @param fnRight - Transformation function for right values\n * @returns A curried function that transforms an Either\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * bimap(right(5), e => e.toUpperCase(), x => x * 2) // => right(10)\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(5),\n * bimap(\n * e => e.toUpperCase(),\n * x => x * 2\n * )\n * ) // => right(10)\n *\n * pipe(\n * left(\"error\"),\n * bimap(\n * e => e.toUpperCase(),\n * x => x * 2\n * )\n * ) // => left(\"ERROR\")\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 async functions. Combines left error unions.\n *\n * @param fn - Function that returns an Either\n * @returns A curried function that chains Eithers\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * flatMap(right(5), x => right(x * 2)) // => right(10)\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(5),\n * flatMap(x => right(x * 2)),\n * flatMap(x => right(x + 1))\n * ) // => right(11)\n *\n * pipe(\n * right(5),\n * flatMap(x => left(\"error\")),\n * flatMap(x => right(x + 1)) // Not executed\n * ) // => left(\"error\")\n *\n * // Async usage\n * await pipe(\n * right(userId),\n * flatMap(async id => right(await fetchUser(id))),\n * flatMap(async user => right(await enrichProfile(user)))\n * ) // => Promise<Either<L, EnrichedUser>>\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 async functions.\n *\n * @param fn - Side effect function for right values\n * @returns A curried function that executes side effects\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * tap(right(42), x => console.log(x)) // Logs: 42, returns right(42)\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(42),\n * tap(x => console.log(x)), // Logs: 42\n * map(x => x * 2)\n * ) // => right(84)\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 async functions.\n *\n * @param fn - Side effect function for left values\n * @returns A curried function that executes side effects\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * tapLeft(left(\"error\"), e => console.error(e)) // Logs: error, returns left(\"error\")\n *\n * // Data-last (curried for pipe)\n * pipe(\n * left(\"error\"),\n * tapLeft(e => console.error(e)), // Logs: error\n * mapLeft(e => e.toUpperCase())\n * ) // => left(\"ERROR\")\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 async functions. Combines right value unions.\n *\n * @param fn - Function that returns an alternative Either\n * @returns A curried function that recovers from left\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * orElse(left(\"error\"), () => right(42)) // => right(42)\n *\n * // Data-last (curried for pipe)\n * pipe(\n * left(\"error\"),\n * orElse(() => right(42))\n * ) // => right(42)\n *\n * pipe(\n * right(10),\n * orElse(() => right(42))\n * ) // => right(10)\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 * pipe(\n * left(\"error\"),\n * swap()\n * ) // => right(\"error\")\n *\n * pipe(\n * right(42),\n * swap()\n * ) // => left(42)\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 A curried function that filters an Either\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * filter(right(5), x => x > 3, x => `${x} is too small`) // => right(5)\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(5),\n * filter(x => x > 3, x => `${x} is too small`)\n * ) // => right(5)\n *\n * pipe(\n * right(2),\n * filter(x => x > 3, x => `${x} is too small`)\n * ) // => left(\"2 is too small\")\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 * // Array form - tuple types inferred automatically for up to 6 elements\n * all([right(1), right(\"hello\")])\n * // => right([1, \"hello\"])\n *\n * all([right(1), left(\"error\"), right(3)])\n * // => left(\"error\")\n *\n * // Object form\n * all({ a: right(1), b: right(\"hello\") })\n * // => right({ a: 1, b: \"hello\" })\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 A curried function that extracts the value\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * unwrapOr(right(42), 0) // => 42\n * unwrapOr(left(\"error\"), 0) // => 0\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(42),\n * unwrapOr(0)\n * ) // => 42\n *\n * pipe(\n * left(\"error\"),\n * unwrapOr(0)\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 A curried function that extracts the value\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * unwrapOrElse(right(42), () => 0) // => 42\n * unwrapOrElse(left(\"error\"), e => e.length) // => 5\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(42),\n * unwrapOrElse(() => 0)\n * ) // => 42\n *\n * pipe(\n * left(\"error\"),\n * unwrapOrElse(e => e.length)\n * ) // => 5\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 A curried function that pattern matches\n *\n * @example\n * ```ts\n * // Data-first (direct call)\n * match(right(42), {\n * Left: e => `Error: ${e}`,\n * Right: x => `Success: ${x}`\n * }) // => \"Success: 42\"\n *\n * // Data-last (curried for pipe)\n * pipe(\n * right(42),\n * match({\n * Left: e => `Error: ${e}`,\n * Right: x => `Success: ${x}`\n * })\n * ) // => \"Success: 42\"\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 * fromResult(Result.ok(42)) // => right(42)\n * fromResult(Result.err(\"error\")) // => left(\"error\")\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 * pipe(\n * right(42),\n * toResult\n * ) // => Result.ok(42)\n *\n * pipe(\n * left(\"error\"),\n * toResult\n * ) // => Result.err(\"error\")\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 * fromOption(Option.some(42), () => \"not found\") // => right(42)\n * fromOption(Option.none(), () => \"not found\") // => left(\"not found\")\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 * pipe(\n * right(42),\n * toOption\n * ) // => Option.some(42)\n *\n * pipe(\n * left(\"error\"),\n * toOption\n * ) // => Option.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 * fromNullable(42, () => \"not found\") // => right(42)\n * fromNullable(null, () => \"not found\") // => left(\"not found\")\n * fromNullable(undefined, () => \"not found\") // => left(\"not found\")\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 * fromPredicate(5, x => x > 3, x => `${x} is too small`)\n * // => right(5)\n *\n * fromPredicate(2, x => x > 3, x => `${x} is too small`)\n * // => left(\"2 is too small\")\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// ============================================================================\n// Namespace Export\n// ============================================================================\n\n/**\n * Either namespace containing all utility functions for working with Either types.\n *\n * Either represents a value that can be one of two types: Left<L> or Right<R>.\n * By convention, Right is the \"success\" or preferred path, while Left represents\n * an alternative outcome (not necessarily an error, unlike Result).\n *\n * Use Either when both outcomes are valid and meaningful, not just success/failure.\n * For error handling, prefer Result instead.\n *\n * @see {@link Result} for success/error semantics\n * @see {@link Option} for presence/absence semantics\n *\n * @example\n * ```ts\n * import { Either, pipe } from '@nicolastoulemont/std'\n * import type { Either as EitherType } from '@nicolastoulemont/std'\n *\n * // Either for branching logic (cache vs fresh data)\n * const fetchOrCache = (id: number): EitherType<CachedData, FreshData> =>\n * cache.has(id) ? Either.left(cache.get(id)) : Either.right(fetch(id))\n *\n * const result = pipe(\n * fetchOrCache(1),\n * Either.map(data => data.value),\n * Either.unwrapOr(defaultValue)\n * )\n *\n * // Async example\n * const processed = await pipe(\n * Either.right(userId),\n * Either.map(async id => await fetchUser(id)),\n * Either.flatMap(async user => Either.right(await enrichUser(user)))\n * )\n * ```\n */\nexport const Either = {\n // Constructors\n left,\n right,\n\n // Type guards\n isLeft,\n isRight,\n\n // Transformations\n map,\n mapLeft,\n bimap,\n flatMap,\n tap,\n tapLeft,\n\n // Recovery\n orElse,\n swap,\n\n // Filtering\n filter,\n\n // Combinators\n all,\n\n // Extraction\n unwrapOr,\n unwrapOrElse,\n match,\n\n // Conversions\n fromResult,\n toResult,\n fromOption,\n toOption,\n fromNullable,\n fromPredicate,\n} as const\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=16777619,t=()=>({hashes:new WeakMap,inProgress:new WeakSet,objectIds:new WeakMap,nextObjectId:1}),n=(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},r=(t,i)=>{let a=2166136261;if(t===null)return a^1853189228;if(t===void 0)return a^1970168933;switch(typeof t){case`boolean`:return a^(t?1:0);case`number`:return Number.isNaN(t)?a^5136718:Number.isFinite(t)?a^(t|0)^(t*1e6|0):a^(t>0?4812390:759787110);case`string`:for(let n=0;n<t.length;n++)a^=t.codePointAt(n),a=Math.imul(a,e);return a>>>0;case`object`:{let o=t,s=i.hashes.get(o);if(s!==void 0)return s;if(i.inProgress.has(o))return(a^1668899692^n(i,o))>>>0;if(t instanceof Date)return a^r(t.getTime(),i);if(i.inProgress.add(o),n(i,o),Array.isArray(t)){a^=23389;for(let n=0;n<t.length;n++)a^=r(t[n],i),a=Math.imul(a,e);let n=a>>>0;return i.inProgress.delete(o),i.hashes.set(o,n),n}a^=31613;let c=t,l=Object.keys(c).toSorted();for(let t of l)a^=r(t,i),a=Math.imul(a,e),a^=r(c[t],i),a=Math.imul(a,e);let u=a>>>0;return i.inProgress.delete(o),i.hashes.set(o,u),u}default:return a}};function i(e){return r(e,t())}const a=(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)},o=(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(a(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)=>o(e,t[r],n)):!1;if(Array.isArray(e)!==Array.isArray(t))return!1;let r=e,i=t,s=Object.keys(r),c=Object.keys(i);return s.length===c.length?s.every(e=>o(r[e],i[e],n)):!1};function s(e,t){return o(e,t,new WeakMap)}function c(e){return(t,n)=>t===n?!0:t._tag!==e||n._tag!==e?!1:s(t,n)}function l(e){return t=>t._tag===e?i(t):0}function u(e){return(t,n)=>t===n?!0:t._tag!==n._tag||!e.includes(t._tag)?!1:s(t,n)}function d(e){return t=>e.includes(t._tag)?i(t):0}export{s as a,l as i,d as n,i as o,c as r,u as t};
2
+ //# sourceMappingURL=equality-CD4_A1Op.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equality-CD4_A1Op.mjs","names":["result"],"sources":["../src/equality/equality.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"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as ErrorData, c as TaggedErrorFactory, i as tagged, l as TaggedErrorInstance, n as TaggedError, o as ErrorTag, r as is, s as TaggedError$1, t as Err } from "../index-CDio8mJY.mjs";
1
+ import { a as ErrorData, c as TaggedErrorFactory, i as tagged, l as TaggedErrorInstance, n as TaggedError, o as ErrorTag, r as is, s as TaggedError$1, t as Err } from "../index-BsXtpnw-.mjs";
2
2
  export { Err, ErrorData, ErrorTag, TaggedError, TaggedErrorFactory, TaggedErrorInstance, TaggedError$1 as TaggedErrorType, is, tagged };
@@ -1 +1 @@
1
- import{i as e,n as t,r as n,t as r}from"../err-CYs4b1RV.mjs";export{r as Err,t as TaggedError,n as is,e as tagged};
1
+ import{i as e,n as t,r as n,t as r}from"../err-3KpQ4pj9.mjs";export{r as Err,t as TaggedError,n as is,e as tagged};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./fx.types-CDVjDn_3.mjs";const t=e=>(t=>({_tag:e,...t}));function n(t){return class extends Error{static _tag=t;_tag=t;[e]={_A:()=>void 0,_E:()=>this,_R:()=>void 0};constructor(...e){super(t),this.name=t;let n=e[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`)}}}const r=e=>t=>typeof t==`object`&&!!t&&`_tag`in t&&t._tag===e,i={tagged:t,is:r};export{t as i,n,r,i as t};
2
+ //# sourceMappingURL=err-3KpQ4pj9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"err-3KpQ4pj9.mjs","names":[],"sources":["../src/err/err.ts"],"sourcesContent":["import { FxTypeId } from \"../fx/fx.types\"\nimport type { TaggedError, TaggedErrorFactory } from \"./err.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 * Helper type to extract data fields from a TaggedError (excluding _tag and Fx protocol)\n */\ntype DataOf<E extends TaggedError<string>> = Omit<E, \"_tag\" | typeof FxTypeId | typeof Symbol.iterator>\n\n/**\n * Helper type to check if data is empty (only has _tag)\n */\ntype IsEmptyData<Data> = keyof Data extends never ? true : false\n\n/**\n * Create a constructor function for a tagged error type.\n * If the error has no additional data, returns a function that takes no arguments.\n * If the error has data, returns a function that requires the data object.\n *\n * @template E - The tagged error type\n * @param tag - The error tag (must match E's _tag)\n * @returns A constructor function for the error type\n *\n * @example\n * ```ts\n * // Error with data\n * type NotFoundError = TaggedError<\"NotFoundError\", { resourceId: string }>\n * const NotFound = Err.tagged<NotFoundError>(\"NotFoundError\")\n * const err = NotFound({ resourceId: \"user-123\" })\n * // { _tag: \"NotFoundError\", resourceId: \"user-123\" }\n *\n * // Error without data\n * type UnauthorizedError = TaggedError<\"UnauthorizedError\">\n * const Unauthorized = Err.tagged<UnauthorizedError>(\"UnauthorizedError\")\n * const err = Unauthorized()\n * // { _tag: \"UnauthorizedError\" }\n * ```\n */\nexport const tagged: <E extends TaggedError<string>>(\n tag: E[\"_tag\"],\n) => IsEmptyData<DataOf<E>> extends true ? () => E : (data: DataOf<E>) => E = (tag) => {\n return ((data?: object) => ({ _tag: tag, ...data })) as never\n}\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/**\n * Create a type guard for a tagged error type.\n * Returns a curried function that checks if a value is the specified error type.\n *\n * @template E - The tagged error type to check for\n * @param tag - The error tag to match\n * @returns A type guard function\n *\n * @example\n * ```ts\n * type NotFoundError = TaggedError<\"NotFoundError\", { id: string }>\n *\n * const error: unknown = getError()\n *\n * if (Err.is<NotFoundError>(\"NotFoundError\")(error)) {\n * console.log(error.id) // TypeScript knows error is NotFoundError\n * }\n *\n * // Works with union error types\n * type AppError = NotFoundError | ValidationError | DbError\n *\n * function handleError(error: AppError) {\n * if (Err.is<NotFoundError>(\"NotFoundError\")(error)) {\n * // Handle not found\n * } else if (Err.is<ValidationError>(\"ValidationError\")(error)) {\n * // Handle validation error\n * }\n * }\n * ```\n */\nexport const is = <E extends TaggedError<string>>(tag: E[\"_tag\"]): ((error: unknown) => error is E) => {\n return (error: unknown): error is E =>\n typeof error === \"object\" && error !== null && \"_tag\" in error && error._tag === tag\n}\n\n/**\n * Err namespace containing utilities for creating and checking tagged errors.\n *\n * Tagged errors are plain objects with a `_tag` discriminator field,\n * making them serializable and easy to pattern match.\n *\n * @example\n * ```ts\n * import { Err, Result, Fx, pipe } from \"@nicolastoulemont/std\"\n * import type { TaggedError } from \"@nicolastoulemont/std\"\n *\n * // Define error types\n * type NotFoundError = TaggedError<\"NotFoundError\", { resourceId: string }>\n * type ValidationError = TaggedError<\"ValidationError\", { field: string; message: string }>\n *\n * // Create constructors\n * const NotFound = Err.tagged<NotFoundError>(\"NotFoundError\")\n * const Validation = Err.tagged<ValidationError>(\"ValidationError\")\n *\n * // Use with Result\n * function findUser(id: string): Result<User, NotFoundError> {\n * const user = db.find(id)\n * if (!user) return Result.err(NotFound({ resourceId: id }))\n * return Result.ok(user)\n * }\n *\n * // Use with Fx.gen computation\n * const program = Fx.gen(function* () {\n * const user = yield* findUser(\"123\")\n * return user\n * })\n *\n * // Pattern match on error types\n * pipe(\n * program.run(),\n * Result.match({\n * Ok: (user) => console.log(user),\n * Err: (error) => {\n * if (Err.is<NotFoundError>(\"NotFoundError\")(error)) {\n * console.log(`Not found: ${error.resourceId}`)\n * }\n * }\n * })\n * )\n * ```\n */\nexport const Err = {\n tagged,\n is,\n} as const\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"4CAuCA,MAAa,EAEkE,IACpE,IAAmB,CAAE,KAAM,EAAK,GAAG,EAAM,GAqCpD,SAAgB,EAAgC,EAAmC,CACjF,OAAO,cAA4D,KAAM,CACvE,OAAgB,KAAY,EAC5B,KAAqB,EAErB,CAAU,GAAY,CACpB,OAAU,IAAA,GACV,OAAU,KACV,OAAU,IAAA,GACX,CAED,YAAY,GAAG,EAAoD,CACjE,MAAM,EAAI,CACV,KAAK,KAAO,EACZ,IAAM,EAAO,EAAK,GACd,GAAM,OAAO,OAAO,KAAM,EAAK,CACnC,OAAO,eAAe,KAAM,IAAI,OAAO,UAAU,CAGnD,EAAE,OAAO,WAA6C,CAEpD,MADA,MAAM,KACI,MAAM,oDAAoD,GAmC1E,MAAa,EAAqC,GACxC,GACN,OAAO,GAAU,YAAY,GAAkB,SAAU,GAAS,EAAM,OAAS,EAiDxE,EAAM,CACjB,SACA,KACD"}
@@ -1,2 +1,2 @@
1
- import { t as flow } from "../index-BahMvQpA.mjs";
1
+ import { t as flow } from "../index-BOrJQBPO.mjs";
2
2
  export { flow };
@@ -1 +1 @@
1
- import{t as e}from"../flow-CxKQ5yac.mjs";export{e as flow};
1
+ import{t as e}from"../flow-CYjiodlC.mjs";export{e as flow};
@@ -0,0 +1,2 @@
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-CYjiodlC.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-CYjiodlC.mjs","names":[],"sources":["../src/shared/is-promise.ts","../src/flow/flow.ts"],"sourcesContent":["/**\n * Check if a value is a Promise.\n */\nexport function isPromise(value: unknown): value is PromiseLike<unknown> {\n if (value === null) return false\n if (typeof value !== \"object\" && typeof value !== \"function\") return false\n return typeof (value as { then?: unknown }).then === \"function\"\n}\n","import { isPromise } from \"../shared/is-promise\"\nimport type { λ } from \"../shared/lambda.types\"\nimport type { FlowdFun } from \"./flow.types\"\n\n/**\n * Given a list of functions returns a function that will execute the given\n * functions one after another, always passing the result of the previous\n * function as an argument to the next function.\n *\n * If one of the given functions returns a promise, the promise will be resolved\n * before being passed to the next function.\n *\n * Type inference: This function provides automatic type inference for chains of\n * 1-15 functions. Each function's parameter type is automatically inferred from\n * the previous function's return type. For chains longer than 15 functions,\n * types must be explicitly specified.\n *\n * Async support: Functions can return Promises. The runtime automatically awaits\n * Promises before passing values to subsequent functions, and parameter types\n * use `Awaited<T>` to reflect this behavior. The final return type will be\n * Promise<T> if any function returns a Promise.\n *\n * @see {@link pipe} for immediate execution with an initial value\n *\n * @example\n * ```typescript\n * const join = (...chars: string[]) => chars.join('')\n * flow(join, parseInt)('1', '2', '3') // -> 123\n *\n * const square = (n: number) => n ** 2\n *\n * // this is equivalent to: square(square(square(2)))\n * flow(square, square, square)(2) // -> 256\n *\n * // Type inference in action\n * const fn = flow(\n * (n: number) => n * 2, // First function must be typed\n * (n) => n + 1, // n: number (inferred!)\n * (n) => n.toString() // n: number (inferred!)\n * )\n *\n * // also works with promises:\n * // fetchNumber :: async () => Promise<number>\n * flow(fetchNumber, n => n.toString()) // async () => Promise<string>\n * ```\n */\n// 1 function\nexport function flow<A extends unknown[], B>(f1: (...args: A) => B): FlowdFun<[typeof f1]>\n// 2 functions\nexport function flow<A extends unknown[], B, C>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n): FlowdFun<[typeof f1, typeof f2]>\n// 3 functions\nexport function flow<A extends unknown[], B, C, D>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n): FlowdFun<[typeof f1, typeof f2, typeof f3]>\n// 4 functions\nexport function flow<A extends unknown[], B, C, D, E>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n): FlowdFun<[typeof f1, typeof f2, typeof f3, typeof f4]>\n// 5 functions\nexport function flow<A extends unknown[], B, C, D, E, F>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n): FlowdFun<[typeof f1, typeof f2, typeof f3, typeof f4, typeof f5]>\n// 6 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n): FlowdFun<[typeof f1, typeof f2, typeof f3, typeof f4, typeof f5, typeof f6]>\n// 7 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n): FlowdFun<[typeof f1, typeof f2, typeof f3, typeof f4, typeof f5, typeof f6, typeof f7]>\n// 8 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n): FlowdFun<[typeof f1, typeof f2, typeof f3, typeof f4, typeof f5, typeof f6, typeof f7, typeof f8]>\n// 9 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n): FlowdFun<[typeof f1, typeof f2, typeof f3, typeof f4, typeof f5, typeof f6, typeof f7, typeof f8, typeof f9]>\n// 10 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J, K>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n f10: (arg: Awaited<J>) => K,\n): FlowdFun<\n [typeof f1, typeof f2, typeof f3, typeof f4, typeof f5, typeof f6, typeof f7, typeof f8, typeof f9, typeof f10]\n>\n// 11 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J, K, L>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n f10: (arg: Awaited<J>) => K,\n f11: (arg: Awaited<K>) => L,\n): FlowdFun<\n [\n typeof f1,\n typeof f2,\n typeof f3,\n typeof f4,\n typeof f5,\n typeof f6,\n typeof f7,\n typeof f8,\n typeof f9,\n typeof f10,\n typeof f11,\n ]\n>\n// 12 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J, K, L, M>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n f10: (arg: Awaited<J>) => K,\n f11: (arg: Awaited<K>) => L,\n f12: (arg: Awaited<L>) => M,\n): FlowdFun<\n [\n typeof f1,\n typeof f2,\n typeof f3,\n typeof f4,\n typeof f5,\n typeof f6,\n typeof f7,\n typeof f8,\n typeof f9,\n typeof f10,\n typeof f11,\n typeof f12,\n ]\n>\n// 13 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J, K, L, M, N>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n f10: (arg: Awaited<J>) => K,\n f11: (arg: Awaited<K>) => L,\n f12: (arg: Awaited<L>) => M,\n f13: (arg: Awaited<M>) => N,\n): FlowdFun<\n [\n typeof f1,\n typeof f2,\n typeof f3,\n typeof f4,\n typeof f5,\n typeof f6,\n typeof f7,\n typeof f8,\n typeof f9,\n typeof f10,\n typeof f11,\n typeof f12,\n typeof f13,\n ]\n>\n// 14 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J, K, L, M, N, O>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n f10: (arg: Awaited<J>) => K,\n f11: (arg: Awaited<K>) => L,\n f12: (arg: Awaited<L>) => M,\n f13: (arg: Awaited<M>) => N,\n f14: (arg: Awaited<N>) => O,\n): FlowdFun<\n [\n typeof f1,\n typeof f2,\n typeof f3,\n typeof f4,\n typeof f5,\n typeof f6,\n typeof f7,\n typeof f8,\n typeof f9,\n typeof f10,\n typeof f11,\n typeof f12,\n typeof f13,\n typeof f14,\n ]\n>\n// 15 functions\nexport function flow<A extends unknown[], B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(\n f1: (...args: A) => B,\n f2: (arg: Awaited<B>) => C,\n f3: (arg: Awaited<C>) => D,\n f4: (arg: Awaited<D>) => E,\n f5: (arg: Awaited<E>) => F,\n f6: (arg: Awaited<F>) => G,\n f7: (arg: Awaited<G>) => H,\n f8: (arg: Awaited<H>) => I,\n f9: (arg: Awaited<I>) => J,\n f10: (arg: Awaited<J>) => K,\n f11: (arg: Awaited<K>) => L,\n f12: (arg: Awaited<L>) => M,\n f13: (arg: Awaited<M>) => N,\n f14: (arg: Awaited<N>) => O,\n f15: (arg: Awaited<O>) => P,\n): FlowdFun<\n [\n typeof f1,\n typeof f2,\n typeof f3,\n typeof f4,\n typeof f5,\n typeof f6,\n typeof f7,\n typeof f8,\n typeof f9,\n typeof f10,\n typeof f11,\n typeof f12,\n typeof f13,\n typeof f14,\n typeof f15,\n ]\n>\n// Implementation signature (fallback for 16+ functions)\nexport function flow<Fns extends [λ, ...λ[]]>(...fns: Fns): FlowdFun<Fns> {\n // oxlint-disable-next-line\n return ((...args) => {\n // oxlint-disable-next-line\n let nextArgs: unknown[] = args\n\n for (let i = 0; i < fns.length; i++) {\n // oxlint-disable-next-line\n const [result] = (nextArgs = [fns[i]?.(...nextArgs)])\n if (isPromise(result)) return resolveAsync(result, fns.slice(i + 1))\n }\n\n return nextArgs[0]\n }) as FlowdFun<Fns>\n}\n\nconst resolveAsync = async (result: unknown, funs: λ[]) => {\n // oxlint-disable-next-line\n for (const fun of funs) result = fun(await result)\n return await result\n}\n"],"mappings":"AAGA,SAAgB,EAAU,EAA+C,CAGvE,OAFI,IAAU,MACV,OAAO,GAAU,UAAY,OAAO,GAAU,WAAmB,GAC9D,OAAQ,EAA6B,MAAS,WC8RvD,SAAgB,EAA8B,GAAG,EAAyB,CAExE,QAAS,GAAG,IAAS,CAEnB,IAAI,EAAsB,EAE1B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAI,OAAQ,IAAK,CAEnC,GAAM,CAAC,GAAW,EAAW,CAAC,EAAI,KAAK,GAAG,EAAS,CAAC,CACpD,GAAI,EAAU,EAAO,CAAE,OAAO,EAAa,EAAQ,EAAI,MAAM,EAAI,EAAE,CAAC,CAGtE,OAAO,EAAS,KAIpB,MAAM,EAAe,MAAO,EAAiB,IAAc,CAEzD,IAAK,IAAM,KAAO,EAAM,EAAS,EAAI,MAAM,EAAO,CAClD,OAAO,MAAM"}
@@ -1,3 +1,3 @@
1
- import { a as FxError, c as FxSuccess, d as FxYield, f as FxYieldable, g as isServiceRequest, h as SyncFx, i as Fx$1, l as FxTypeId, m as ServiceRequest, n as AsyncFxGenerator, o as FxGenerator, p as RunnableFx, r as AsyncFxYieldable, s as FxRequirements, t as AsyncFx, u as FxValue } from "../fx.types-DO-8yG4c.mjs";
2
- import { A as gen, C as isServiceClass, D as err, E as TaggedMatch, M as run, N as Defect, O as fn, P as Exit, S as ServiceOf, T as Fx, _ as createScope, a as Layer$1, b as ServiceClass, c as LayerROut, d as UnprovidedDeps, f as MemoMap, g as ScopeTag, h as ScopeService, i as Layer, j as ok, k as fxMatch, l as MergeError, m as ExcludeScope, n as provideContext, o as LayerError, p as createMemoMap, r as provideService, s as LayerRIn, t as provide, u as MergeROut, v as Context, w as serviceTag, x as ServiceKey, y as Service } from "../index-DQoTXLSm.mjs";
3
- export { AsyncFx, AsyncFxGenerator, AsyncFxYieldable, Context, Context as ContextType, ExcludeScope, Exit, Exit as ExitType, Defect as ExitDefect, Fx, FxError, FxGenerator, Fx$1 as FxProtocol, Fx$1 as FxType, FxRequirements, FxSuccess, FxTypeId, FxValue, FxYield, FxYieldable, Layer, LayerError, LayerRIn, LayerROut, Layer$1 as LayerType, MemoMap, MergeError, MergeROut, RunnableFx, ScopeTag as Scope, ScopeService, Service, ServiceClass, ServiceKey, ServiceOf, ServiceRequest, SyncFx, TaggedMatch, UnprovidedDeps, createMemoMap, createScope, err, fn, gen, isServiceClass, isServiceRequest, fxMatch as match, ok, provide, provideContext, provideService, run, serviceTag };
1
+ import { a as FxError, c as FxTypeId, d as FxYieldable, f as RunnableFx, h as isServiceRequest, i as Fx$1, l as FxValue, m as SyncFx, n as AsyncFxGenerator, o as FxGenerator, p as ServiceRequest, r as AsyncFxYieldable, s as FxRequirements, t as AsyncFx, u as FxYield } from "../fx.types-B34asVRX.mjs";
2
+ import { A as gen, C as isServiceClass, D as err, E as TaggedMatch, M as run, N as Defect, O as fn, P as Exit, S as ServiceOf, T as Fx, _ as createScope, a as Layer$1, b as ServiceClass, c as LayerROut, d as UnprovidedDeps, f as MemoMap, g as ScopeTag, h as ScopeService, i as Layer, j as ok, k as fxMatch, l as MergeError, m as ExcludeScope, n as provideContext, o as LayerError, p as createMemoMap, r as provideService, s as LayerRIn, t as provide, u as MergeROut, v as Context, w as serviceTag, x as ServiceKey, y as Service } from "../index-a4MEBZZ1.mjs";
3
+ export { AsyncFx, AsyncFxGenerator, AsyncFxYieldable, Context, Context as ContextType, ExcludeScope, Exit, Exit as ExitType, Defect as ExitDefect, Fx, FxError, FxGenerator, Fx$1 as FxProtocol, Fx$1 as FxType, FxRequirements, FxTypeId, FxValue, FxYield, FxYieldable, Layer, LayerError, LayerRIn, LayerROut, Layer$1 as LayerType, MemoMap, MergeError, MergeROut, RunnableFx, ScopeTag as Scope, ScopeService, Service, ServiceClass, ServiceKey, ServiceOf, ServiceRequest, SyncFx, TaggedMatch, UnprovidedDeps, createMemoMap, createScope, err, fn, gen, isServiceClass, isServiceRequest, fxMatch as match, ok, provide, provideContext, provideService, run, serviceTag };
package/dist/fx/index.mjs CHANGED
@@ -1 +1 @@
1
- import{n as e,t}from"../fx.types-CXTwEa1G.mjs";import{_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as v,u as y,v as b,y as x}from"../fx-C4UuWCqP.mjs";export{d as Context,i as Exit,h as Fx,t as FxTypeId,a as Layer,u as MemoMap,m as Scope,y as Service,r as createMemoMap,_ as createScope,f as err,l as fn,n as gen,o as isServiceClass,e as isServiceRequest,c as match,b as ok,v as provide,p as provideContext,g as provideService,x as run,s as serviceTag};
1
+ import{n as e,t}from"../fx.types-CDVjDn_3.mjs";import{_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as v,u as y,v as b,y as x}from"../fx-vqywVJhV.mjs";export{d as Context,i as Exit,h as Fx,t as FxTypeId,a as Layer,u as MemoMap,m as Scope,y as Service,r as createMemoMap,_ as createScope,f as err,l as fn,n as gen,o as isServiceClass,e as isServiceRequest,c as match,b as ok,v as provide,p as provideContext,g as provideService,x as run,s as serviceTag};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./fx.types-CDVjDn_3.mjs";import{n as t}from"./pipeable-BA0mXhs4.mjs";import{f as n,o as r,r as i}from"./result-CgGYLp0L.mjs";import{a,t as o}from"./option-DawZC1cE.mjs";const s=e=>({_tag:`Ok`,value:e}),c=e=>({_tag:`Err`,error:e}),l=e=>({_tag:`Defect`,defect:e}),u={ok:s,err:c,defect:l,isOk:e=>e._tag===`Ok`,isErr:e=>e._tag===`Err`,isDefect:e=>e._tag===`Defect`,match:t(2,(e,t)=>{switch(e._tag){case`Ok`:return t.Ok(e.value);case`Err`:return t.Err(e.error);case`Defect`:return t.Defect(e.defect)}}),getOrThrow:e=>{switch(e._tag){case`Ok`:return e.value;case`Err`:throw e.error;case`Defect`:throw e.defect}}};function d(e){return typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Service`&&`key`in e&&typeof e.key==`string`}function f(e){return d(e)?e:void 0}function p(e,t){let n=f(t);if(n!==void 0)return e._services.get(n.key)}function m(e){return e._tag===`AsyncFx`?g(e):h(e)}function h(e){try{let t=e[Symbol.iterator]().next();if(t.done!==!0){let e=t.value,n=f(e);return n===void 0?e instanceof a?c(e):typeof e==`object`&&e&&`_tag`in e&&e._tag===`Err`?c(e.error):c(e):l(Error(`Service "${n.key}" not provided. Use provide() to inject services.`))}return s(t.value)}catch(e){return l(e)}}async function g(e){try{let t=await e[Symbol.asyncIterator]().next();if(t.done!==!0){let e=t.value,n=f(e);return n===void 0?e instanceof a?c(e):typeof e==`object`&&e&&`_tag`in e&&e._tag===`Err`?c(e.error):c(e):l(Error(`Service "${n.key}" not provided. Use provide() to inject services.`))}return s(t.value)}catch(e){return l(e)}}function _(t){if(t.length>0)return(...e)=>_(()=>t(...e));let n=t();return Symbol.asyncIterator in n?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=t(),n=await e.next();for(;n.done!==!0;){let t=yield n.value;n=await e.next(t)}return n.value}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=t(),n=e.next();for(;n.done!==!0;){let t=yield n.value;n=e.next(t)}return n.value}}}function v(e,t){let n=_(e);return m(t?t(n):n)}const y=n,b=i,x=r,S=o,C=t(2,(e,t)=>t[e._tag](e)),w=_,T=v,E=m,D=y,O=b,k={gen:_,fn:v,run:m,ok:y,err:b,match:C,try:x,option:S};function A(){return t=>{let n=class{static _tag=`Service`;static key=t;static _Self=void 0;static[e]={_A:()=>void 0,_E:()=>void 0,_R:()=>void 0};static*[Symbol.iterator](){return yield n}};return n}}function j(t){let n={_tag:`Service`,key:t,_Self:void 0,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){return yield n}};return n}const M=e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Service`,N=()=>({_tag:`Context`,_services:new Map,_Services:void 0}),P=(e,t)=>({_tag:`Context`,_services:new Map([[e.key,t]]),_Services:void 0}),F=(e,t)=>n=>({_tag:`Context`,_services:new Map([...n._services,[e.key,t]]),_Services:void 0}),I=(e,t)=>({_tag:`Context`,_services:new Map([...e._services,...t._services]),_Services:void 0});function L(e,t){if(t===void 0){let t=e;return e=>{let n=e._services.get(t.key);if(n===void 0)throw Error(`Service "${t.key}" not found in context. Available services: [${[...e._services.keys()].join(`, `)}]`);return n}}let n=e,r=t,i=n._services.get(r.key);if(i===void 0)throw Error(`Service "${r.key}" not found in context. Available services: [${[...n._services.keys()].join(`, `)}]`);return i}const R={empty:N,make:P,add:F,merge:I,get:L,unsafeGet:(e,t)=>e._services.get(t),has:(e,t)=>e._services.has(t.key),keys:e=>[...e._services.keys()],size:e=>e._services.size,isContext:e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Context`},z=(t,n)=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>({_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){return R.make(t,n)}})}),B=t=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>({_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>t,_R:()=>void 0},*[Symbol.iterator](){throw yield t,Error(`Unreachable`)}})});function V(t){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:()=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=n[Symbol.asyncIterator](),r=await e.next();for(;r.done!==!0;){let t=yield r.value;r=await e.next(t)}return R.make(t,r.value)}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=n[Symbol.iterator](),r=e.next();for(;r.done!==!0;){let t=yield r.value;r=e.next(t)}return R.make(t,r.value)}}})}function H(t){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(r,i)=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=n[Symbol.asyncIterator](),r=await e.next();for(;r.done!==!0;){let t=r.value;if(f(t)?.key===`@std/Scope`)r=await e.next(i);else{let n=yield t;r=await e.next(n)}}return R.make(t,r.value)}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=n[Symbol.iterator](),r=e.next();for(;r.done!==!0;){let t=r.value;if(f(t)?.key===`@std/Scope`)r=e.next(i);else{let n=yield t;r=e.next(n)}}return R.make(t,r.value)}}})}function U(t){return n=>({_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(r,i)=>{let a=t.build(r,i);return a._tag===`AsyncFx`?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=a[Symbol.asyncIterator](),t=await e.next();for(;t.done!==!0;){let n=yield t.value;t=await e.next(n)}let o=t.value,s=n.build(r,i);if(s._tag===`AsyncFx`){let e=s[Symbol.asyncIterator](),t=await e.next();for(;t.done!==!0;){let n=t.value,r=p(o,n);if(r!==void 0){t=await e.next(r);continue}let i=yield n;t=await e.next(i)}return R.merge(o,t.value)}let c=s[Symbol.iterator](),l=c.next();for(;l.done!==!0;){let e=l.value,t=p(o,e);if(t!==void 0){l=c.next(t);continue}let n=yield e;l=c.next(n)}return R.merge(o,l.value)}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=a[Symbol.iterator](),t=e.next();for(;t.done!==!0;){let n=yield t.value;t=e.next(n)}let o=t.value,s=n.build(r,i);if(s._tag===`SyncFx`){let e=s[Symbol.iterator](),t=e.next();for(;t.done!==!0;){let n=t.value,r=p(o,n);if(r!==void 0){t=e.next(r);continue}let i=yield n;t=e.next(i)}return R.merge(o,t.value)}throw Error(`Cannot use async layer in sync context`)}}}})}function W(...t){return{_tag:`Layer`,_ROut:void 0,_E:void 0,_RIn:void 0,_Sync:void 0,build:(n,r)=>t.some(e=>e.build(n,r)._tag===`AsyncFx`)?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=R.empty();for(let i of t){let t=i.build(n,r);if(t._tag===`AsyncFx`){let n=t[Symbol.asyncIterator](),r=await n.next();for(;r.done!==!0;){let t=r.value,i=p(e,t);if(i!==void 0){r=await n.next(i);continue}let a=yield t;r=await n.next(a)}e=R.merge(e,r.value)}else{let n=t[Symbol.iterator](),r=n.next();for(;r.done!==!0;){let t=r.value,i=p(e,t);if(i!==void 0){r=n.next(i);continue}let a=yield t;r=n.next(a)}e=R.merge(e,r.value)}}return e}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=R.empty();for(let i of t){let t=i.build(n,r);if(t._tag!==`SyncFx`)throw Error(`Expected sync layer in sync context`);let a=t[Symbol.iterator](),o=a.next();for(;o.done!==!0;){let t=o.value,n=p(e,t);if(n!==void 0){o=a.next(n);continue}let r=yield t;o=a.next(r)}e=R.merge(e,o.value)}return e}}}}const G={ok:z,err:B,fx:V,scoped:H,provide:U,merge:W};var K=class extends A()(`@std/Scope`){};function q(){let t=[],n=!1,r=[];return{addFinalizer(r){return{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){n||t.push(r)}}},close(i){return t.some(e=>e()._tag===`AsyncFx`)?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){if(n)return;n=!0;for(let e of[...r].toReversed()){let t=e.close(i);t._tag===`AsyncFx`?await g(t):h(t)}let e=[...t].toReversed();for(let t of e){let e=t();e._tag===`AsyncFx`?await g(e):h(e)}}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){if(n)return;n=!0;for(let e of[...r].toReversed())h(e.close(i));let e=[...t].toReversed();for(let t of e)h(t())}}},fork(){let e=q();return r.push(e),e}}}var J=class{cache=new Map;getOrBuild(t,r,i){let a=this.cache.get(t);if(a?.context)return{_tag:`SyncFx`,[e]:{_A:()=>a.context,_E:()=>void 0,_R:()=>void 0},run:()=>n(a.context),*[Symbol.iterator](){return a.context}};if(a?.promise)return{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:async()=>n(await a.promise),async*[Symbol.asyncIterator](){return await a.promise}};this.cache.set(t,{building:!0});let o=t.build(this,r),s=this.cache;if(o._tag===`AsyncFx`){let r=(async()=>{let e=o[Symbol.asyncIterator](),n=await e.next();for(;n.done!==!0;){let t=n.value,r=f(t);if(r===void 0)throw t;let a=i._services.get(r.key);if(a===void 0)throw Error(`Service "${r.key}" not found during layer build`);n=await e.next(a)}let r=n.value;return s.set(t,{context:r}),r})();return this.cache.set(t,{promise:r}),{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:async()=>{try{return n(await r)}catch(e){return{ok:!1,error:e,*[Symbol.iterator](){throw yield e,Error(`Unreachable`)}}}},async*[Symbol.asyncIterator](){try{return await r}catch(e){throw yield e,Error(`Unreachable`,{cause:e})}}}}return{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:()=>{let e=o[Symbol.iterator](),r=e.next();for(;r.done!==!0;){let t=r.value,n=f(t);if(n===void 0)return{ok:!1,error:t,*[Symbol.iterator](){throw yield t,Error(`Unreachable`)}};let a=i._services.get(n.key);if(a===void 0)throw Error(`Service "${n.key}" not found during layer build`);r=e.next(a)}let a=r.value;return s.set(t,{context:a}),n(a)},*[Symbol.iterator](){let e=o[Symbol.iterator](),n=e.next();for(;n.done!==!0;){let t=n.value,r=f(t);if(r===void 0)throw yield t,Error(`Unreachable`);let a=i._services.get(r.key);if(a===void 0)throw Error(`Service "${r.key}" not found during layer build`);n=e.next(a)}return s.set(t,{context:n.value}),n.value}}}clear(){this.cache.clear()}get size(){return this.cache.size}};const Y=()=>new J;function X(t){return r=>{let i=new J,a=q(),o=t.build(i,a);return o._tag===`AsyncFx`||r._tag===`AsyncFx`?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){try{let e;if(o._tag===`AsyncFx`){let t=o[Symbol.asyncIterator](),n=await t.next();for(;n.done!==!0;)yield n.value,n=await t.next(void 0);e=n.value}else{let t=o[Symbol.iterator](),n=t.next();for(;n.done!==!0;)yield n.value,n=t.next(void 0);e=n.value}if(r._tag===`AsyncFx`){let t=r[Symbol.asyncIterator](),n=await t.next();for(;n.done!==!0;){let r=n.value,i=p(e,r);if(i!==void 0){n=await t.next(i);continue}let a=yield r;n=await t.next(a)}return n.value}let t=r[Symbol.iterator](),n=t.next();for(;n.done!==!0;){let r=n.value,i=p(e,r);if(i!==void 0){n=t.next(i);continue}let a=yield r;n=t.next(a)}return n.value}finally{let e=a.close(n(void 0));e._tag===`AsyncFx`?await g(e):h(e)}}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){try{let e=o[Symbol.iterator](),t=e.next();for(;t.done!==!0;)yield t.value,t=e.next(void 0);let n=t.value,i=r[Symbol.iterator](),a=i.next();for(;a.done!==!0;){let e=a.value,t=p(n,e);if(t!==void 0){a=i.next(t);continue}let r=yield e;a=i.next(r)}return a.value}finally{h(a.close(n(void 0)))}}}}}const Z=t=>n=>n._tag===`AsyncFx`?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=n[Symbol.asyncIterator](),r=await e.next();for(;r.done!==!0;){let n=r.value,i=f(n);if(i===void 0){yield n,r=await e.next(void 0);continue}let a=t._services.get(i.key);if(a===void 0)throw Error(`Service "${i.key}" not found`);r=await e.next(a)}return r.value}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=n[Symbol.iterator](),r=e.next();for(;r.done!==!0;){let n=r.value,i=f(n);if(i===void 0){yield n,r=e.next(void 0);continue}let a=t._services.get(i.key);if(a===void 0)throw Error(`Service "${i.key}" not found`);r=e.next(a)}return r.value}},Q=(t,n)=>r=>r._tag===`AsyncFx`?{_tag:`AsyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let e=r[Symbol.asyncIterator](),i=await e.next();for(;i.done!==!0;){let r=i.value;if(f(r)?.key===t.key)i=await e.next(n);else{let t=yield r;i=await e.next(t)}}return i.value}}:{_tag:`SyncFx`,[e]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let e=r[Symbol.iterator](),i=e.next();for(;i.done!==!0;){let r=i.value;if(f(r)?.key===t.key)i=e.next(n);else{let t=yield r;i=e.next(t)}}return i.value}};export{w as _,Y as a,u as b,G as c,M as d,j as f,C as g,T as h,J as i,R as l,O as m,Z as n,K as o,k as p,Q as r,q as s,X as t,A as u,D as v,E as y};
2
+ //# sourceMappingURL=fx-vqywVJhV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-vqywVJhV.mjs","names":["ok","err","exitDefect","exitErr","exitOk","gen","resultOk","resultErr","resultTry","optionFromNullable","service","impl","ctx","gen","layerGen","layerResult","ok","gen","gen","fxGen","fxResult","ok"],"sources":["../src/fx/exit.ts","../src/fx/service-resolution.ts","../src/fx/fx.ts","../src/fx/service.ts","../src/fx/context.ts","../src/fx/layer.ts","../src/fx/scope.ts","../src/fx/memo-map.ts","../src/fx/provide.ts"],"sourcesContent":["import { dual } from \"../shared/dual\"\nimport type { Err, Ok } from \"../shared/type-utils.types\"\n\n// ============================================================================\n// Exit Types - Flat 3-variant discriminated union\n// ============================================================================\n\n/**\n * Represents an unexpected thrown exception (defect) caught during Fx execution.\n */\nexport type Defect = {\n readonly _tag: \"Defect\"\n readonly defect: unknown\n}\n\n/**\n * Exit represents the outcome of an Fx computation.\n * A flat 3-variant discriminated union that cleanly separates:\n * - `Ok<A>`: successful result with value of type A\n * - `Err<E>`: typed failure with error of type E\n * - `Defect`: unexpected thrown exception (defect)\n *\n * @example\n * ```ts\n * const exit = Fx.run(computation)\n * switch (exit._tag) {\n * case \"Ok\": exit.value // A\n * case \"Err\": exit.error // E (clean!)\n * case \"Defect\": exit.defect // unknown\n * }\n * ```\n */\nexport type Exit<A, E> = Ok<A> | Err<E> | Defect\n\n// ============================================================================\n// Constructors\n// ============================================================================\n\n/**\n * Create a successful Exit.\n */\nexport const ok = <A>(value: A): Ok<A> => ({ _tag: \"Ok\", value })\n\n/**\n * Create a typed failure Exit.\n */\nexport const err = <E>(error: E): Err<E> => ({ _tag: \"Err\", error })\n\n/**\n * Create a defect Exit from an unexpected thrown value.\n */\nexport const defect = (thrown: unknown): Defect => ({ _tag: \"Defect\", defect: thrown })\n\n// ============================================================================\n// Guards\n// ============================================================================\n\n/**\n * Check if an Exit is a successful result.\n */\nconst isOk = <A, E>(exit: Exit<A, E>): exit is Ok<A> => exit._tag === \"Ok\"\n\n/**\n * Check if an Exit is a typed failure.\n */\nconst isErr = <A, E>(exit: Exit<A, E>): exit is Err<E> => exit._tag === \"Err\"\n\n/**\n * Check if an Exit is an unexpected defect.\n */\nconst isDefect = <A, E>(exit: Exit<A, E>): exit is Defect => exit._tag === \"Defect\"\n\n// ============================================================================\n// Match\n// ============================================================================\n\n/**\n * Handler functions for Exit.match.\n */\ntype ExitMatch<A, E, R> = {\n readonly Ok: (value: A) => R\n readonly Err: (error: E) => R\n readonly Defect: (defect: unknown) => R\n}\n\n/**\n * Pattern match on an Exit value.\n *\n * @example\n * ```ts\n * // Data-first\n * Exit.match(exit, {\n * Ok: (value) => `Success: ${value}`,\n * Err: (error) => `Error: ${error}`,\n * Defect: (defect) => `Defect: ${defect}`,\n * })\n *\n * // Data-last (pipe)\n * pipe(exit, Exit.match({\n * Ok: (value) => `Success: ${value}`,\n * Err: (error) => `Error: ${error}`,\n * Defect: (defect) => `Defect: ${defect}`,\n * }))\n * ```\n */\nconst match: {\n <A, E, R>(exit: Exit<A, E>, handlers: ExitMatch<A, E, R>): R\n <A, E, R>(handlers: ExitMatch<A, E, R>): (exit: Exit<A, E>) => R\n} = dual(2, <A, E, R>(exit: Exit<A, E>, handlers: ExitMatch<A, E, R>): R => {\n switch (exit._tag) {\n case \"Ok\":\n return handlers.Ok(exit.value)\n case \"Err\":\n return handlers.Err(exit.error)\n case \"Defect\":\n return handlers.Defect(exit.defect)\n }\n})\n\n// ============================================================================\n// Utility\n// ============================================================================\n\n/**\n * Extract the value from an Ok exit, or throw.\n * Useful for tests and scripts where you expect success.\n *\n * @throws The error for Err exits, or the defect for Defect exits\n */\nconst getOrThrow = <A, E>(exit: Exit<A, E>): A => {\n switch (exit._tag) {\n case \"Ok\":\n return exit.value\n case \"Err\":\n // oxlint-disable-next-line only-throw-error -- E is intentionally generic and may be a non-Error domain value.\n throw exit.error\n case \"Defect\":\n throw exit.defect\n }\n}\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\n/**\n * Exit namespace containing all Exit utilities.\n */\nexport const Exit = {\n ok,\n err,\n defect,\n isOk,\n isErr,\n isDefect,\n match,\n getOrThrow,\n} as const\n","import type { Context } from \"./context\"\n\ntype ServiceRequest = {\n _tag: \"Service\"\n key: string\n}\n\n/**\n * Narrow an unknown yielded value to a service request.\n */\nfunction isServiceRequest(value: unknown): value is ServiceRequest {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n value._tag === \"Service\" &&\n \"key\" in value &&\n typeof value.key === \"string\"\n )\n}\n\nexport function asServiceRequest(value: unknown) {\n return isServiceRequest(value) ? value : undefined\n}\n\n/**\n * Resolve a yielded service request from a context.\n */\nexport function resolveService<R>(ctx: Context<R>, value: unknown) {\n const request = asServiceRequest(value)\n if (request === undefined) return undefined\n return ctx._services.get(request.key)\n}\n","import { fromNullable as optionFromNullable } from \"../option/option\"\nimport { NoSuchElementError } from \"../option/option.types\"\nimport { ok as resultOk, err as resultErr, fromTry as resultTry } from \"../result/result\"\nimport { dual } from \"../shared/dual\"\nimport { ok as exitOk, err as exitErr, defect as exitDefect } from \"./exit\"\nimport type { Exit } from \"./exit\"\nimport { FxTypeId } from \"./fx.types\"\nimport type {\n RunnableFx,\n SyncFx,\n AsyncFx,\n Fx as FxProtocol,\n FxError,\n FxRequirements,\n FxGenerator,\n AsyncFxGenerator,\n} from \"./fx.types\"\nimport { asServiceRequest } from \"./service-resolution\"\n\n/* oxlint-disable no-unsafe-type-assertion, no-unsafe-assignment, no-unsafe-call, no-unsafe-member-access, no-unsafe-return, no-unsafe-argument, no-unnecessary-type-assertion -- Fx runtime adapters intentionally traverse erased generator channels and rehydrate typed effects through controlled dynamic boundaries. */\n\n// ============================================================================\n// Fx.run - Execute computations\n// ============================================================================\n\n/**\n * Execute a sync Fx computation and return the Exit.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n * Only available when R = never (all dependencies provided).\n *\n * @param fx - The sync computation to execute\n * @returns Exit<A, E>\n */\nfunction fxRun<A, E>(fx: SyncFx<A, E>): Exit<A, E>\n\n/**\n * Execute an async Fx computation and return a Promise of the Exit.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n * Only available when R = never (all dependencies provided).\n *\n * @param fx - The async computation to execute\n * @returns Promise<Exit<A, E>>\n */\nfunction fxRun<A, E>(fx: AsyncFx<A, E>): Promise<Exit<A, E>>\n\n/**\n * Execute an Fx computation (union type).\n * Returns Exit for sync, Promise<Exit> for async.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n */\nfunction fxRun<A, E>(fx: RunnableFx<A, E>): Exit<A, E> | Promise<Exit<A, E>>\n\n/**\n * Implementation of Fx.run.\n * Detects sync vs async and executes appropriately.\n */\nfunction fxRun<A, E>(fx: RunnableFx<A, E>): Exit<A, E> | Promise<Exit<A, E>> {\n if (fx._tag === \"AsyncFx\") {\n return runAsync(fx)\n }\n return runSync(fx)\n}\n\n/**\n * Internal helper to run a sync Fx computation.\n * Wraps execution in try-catch to capture unexpected thrown exceptions as Defect.\n */\nfunction runSync<A, E>(fx: SyncFx<A, E>): Exit<A, E> {\n try {\n const gen = fx[Symbol.iterator]()\n const result = gen.next()\n\n if (result.done !== true) {\n const yielded = result.value as unknown\n // Check for ServiceClass (which is what gets yielded now)\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest !== undefined) {\n return exitDefect(new Error(`Service \"${serviceRequest.key}\" not provided. Use provide() to inject services.`))\n }\n // Check for NoSuchElementError (from Option.none())\n if (yielded instanceof NoSuchElementError) {\n return exitErr(yielded as E)\n }\n // Check for Result.err - extract the error field\n if (typeof yielded === \"object\" && yielded !== null && \"_tag\" in yielded && yielded._tag === \"Err\") {\n return exitErr((yielded as Record<string, unknown>)[\"error\"] as E)\n }\n // Otherwise it's a raw error (shouldn't happen with proper types, but handle for safety)\n return exitErr(yielded as E)\n }\n\n return exitOk(result.value)\n } catch (thrown) {\n return exitDefect(thrown)\n }\n}\n\n/**\n * Internal helper to run an async Fx computation.\n * Wraps execution in try-catch to capture unexpected thrown exceptions as Defect.\n */\nasync function runAsync<A, E>(fx: AsyncFx<A, E>): Promise<Exit<A, E>> {\n try {\n const gen = fx[Symbol.asyncIterator]()\n const result = await gen.next()\n\n if (result.done !== true) {\n const yielded = result.value as unknown\n // Check for ServiceClass (which is what gets yielded now)\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest !== undefined) {\n return exitDefect(new Error(`Service \"${serviceRequest.key}\" not provided. Use provide() to inject services.`))\n }\n // Check for NoSuchElementError (from Option.none())\n if (yielded instanceof NoSuchElementError) {\n return exitErr(yielded as E)\n }\n // Check for Result.err - extract the error field\n if (typeof yielded === \"object\" && yielded !== null && \"_tag\" in yielded && yielded._tag === \"Err\") {\n return exitErr((yielded as Record<string, unknown>)[\"error\"] as E)\n }\n // Otherwise it's a raw error (shouldn't happen with proper types, but handle for safety)\n return exitErr(yielded as E)\n }\n\n return exitOk(result.value)\n } catch (thrown) {\n return exitDefect(thrown)\n }\n}\n\n// ============================================================================\n// Fx.gen - Create composable computations\n// ============================================================================\n\n/**\n * Create a composable computation from a sync generator function.\n * Returns a SyncFx that can be stored, passed around, and executed later.\n *\n * @template Yielded - The type of values yielded by the generator (must implement Fx protocol)\n * @template A - The success value type\n * @param generatorFn - A function that returns a sync generator\n * @returns SyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n *\n * @example\n * ```ts\n * const getUser = (id: string) => Fx.gen(function* () {\n * const db = yield* Database\n * const logger = yield* Logger\n *\n * logger.info(`Fetching user ${id}`)\n * return yield* db.query<User>(`SELECT * FROM users WHERE id = '${id}'`)\n * })\n * // Type: SyncFx<User[], DatabaseError, Database | Logger>\n *\n * // Execute later with dependencies provided\n * const exit = pipe(getUser(\"123\"), provide(AppLayer)).run()\n * ```\n */\nfunction fxGen<Yielded extends FxProtocol<unknown, unknown, unknown>, A>(\n generatorFn: () => Generator<Yielded, A, unknown>,\n): SyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n\n/**\n * Create a composable computation from an async generator function.\n * Returns an AsyncFx that can be stored, passed around, and executed later.\n *\n * @template Yielded - The type of values yielded by the generator (must implement Fx protocol)\n * @template A - The success value type\n * @param generatorFn - A function that returns an async generator\n * @returns AsyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n *\n * @example\n * ```ts\n * const fetchData = (url: string) => Fx.gen(async function* () {\n * const logger = yield* Logger\n *\n * logger.info(`Fetching ${url}`)\n * const response = await fetch(url)\n * return yield* Result.try(async () => await response.json())\n * })\n * // Type: AsyncFx<unknown, Error, Logger>\n * ```\n */\nfunction fxGen<Yielded extends FxProtocol<unknown, unknown, unknown>, A>(\n generatorFn: () => AsyncGenerator<Yielded, A, unknown>,\n): AsyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n\n/**\n * Create a composable computation from a sync generator function that takes parameters.\n * Returns a factory function that, when called with parameters, produces a SyncFx.\n *\n * @template P - The parameter types (must be non-empty)\n * @template Yielded - The type of values yielded by the generator (must implement Fx protocol)\n * @template A - The success value type\n * @param generatorFn - A function that takes parameters and returns a sync generator\n * @returns A factory function that produces SyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n *\n * @example\n * ```ts\n * const getUser = Fx.gen(function* ({userId}: {userId: string}) {\n * const db = yield* Database\n * return yield* db.query(`SELECT * FROM users WHERE id = '${userId}'`)\n * })\n * // Type: (params: {userId: string}) => SyncFx<...>\n *\n * const exit = Fx.run(pipe(getUser({userId: \"123\"}), provide(DbLayer)))\n * ```\n */\nfunction fxGen<P extends [unknown, ...unknown[]], Yielded extends FxProtocol<unknown, unknown, unknown>, A>(\n generatorFn: (...params: P) => Generator<Yielded, A, unknown>,\n): (...params: P) => SyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n\n/**\n * Create a composable computation from an async generator function that takes parameters.\n * Returns a factory function that, when called with parameters, produces an AsyncFx.\n *\n * @template P - The parameter types (must be non-empty)\n * @template Yielded - The type of values yielded by the generator (must implement Fx protocol)\n * @template A - The success value type\n * @param generatorFn - A function that takes parameters and returns an async generator\n * @returns A factory function that produces AsyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n *\n * @example\n * ```ts\n * const fetchUser = Fx.gen(async function* ({url}: {url: string}) {\n * const response = await fetch(url)\n * return yield* Result.try(async () => await response.json())\n * })\n * // Type: (params: {url: string}) => AsyncFx<...>\n * ```\n */\nfunction fxGen<P extends [unknown, ...unknown[]], Yielded extends FxProtocol<unknown, unknown, unknown>, A>(\n generatorFn: (...params: P) => AsyncGenerator<Yielded, A, unknown>,\n): (...params: P) => AsyncFx<A, FxError<Yielded>, FxRequirements<Yielded>>\n\n/**\n * Implementation of unified Fx.gen function.\n * Detects sync vs async generator and returns appropriate computation type.\n * For parameterized generators (length > 0), returns a factory function.\n */\n// oxlint-disable-next-line no-explicit-any\nfunction fxGen(generatorFn: (...args: any[]) => any): any {\n if (generatorFn.length > 0) {\n return (...params: unknown[]) => fxGen(() => generatorFn(...params))\n }\n\n // Check if we're dealing with async generator\n const testGen = generatorFn()\n const isAsync = Symbol.asyncIterator in testGen\n\n if (isAsync) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined,\n _E: () => undefined,\n _R: () => undefined,\n },\n // oxlint-disable-next-line no-explicit-any\n async *[Symbol.asyncIterator](): AsyncGenerator<any, any, unknown> {\n const gen = generatorFn()\n let result = await gen.next()\n\n while (result.done !== true) {\n // Pass through yields (errors or services as Fx values)\n const injected = yield result.value\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(injected)\n }\n\n return result.value\n },\n }\n }\n\n // Sync generator\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined,\n _E: () => undefined,\n _R: () => undefined,\n },\n // oxlint-disable-next-line no-explicit-any\n *[Symbol.iterator](): Generator<any, any, unknown> {\n const gen = generatorFn()\n let result = gen.next()\n\n while (result.done !== true) {\n const injected = yield result.value\n result = gen.next(injected)\n }\n\n return result.value\n },\n }\n}\n\n// ============================================================================\n// Fx.fn - Execute computations immediately\n// ============================================================================\n\n/**\n * Execute a sync computation immediately and return the Exit.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n * For computations without service dependencies.\n *\n * @template A - The success value type\n * @template E - The error type\n * @param generatorFn - A function that returns a sync generator\n * @returns Exit<A, E>\n *\n * @example\n * ```ts\n * const exit = Fx.fn(function* () {\n * const a = yield* Result.ok(10)\n * const b = yield* Result.ok(20)\n * return a + b\n * })\n * // Type: Exit<number, never>\n * // exit = { _tag: \"Ok\", value: 30 }\n * ```\n */\nfunction fxFn<A, E>(generatorFn: () => FxGenerator<A, E, never>): Exit<A, E>\n\n/**\n * Execute an async computation immediately and return a Promise of the Exit.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n * For computations without service dependencies.\n *\n * @template A - The success value type\n * @template E - The error type\n * @param generatorFn - A function that returns an async generator\n * @returns Promise<Exit<A, E>>\n *\n * @example\n * ```ts\n * const exit = await Fx.fn(async function* () {\n * const response = await fetch(\"/api/users\")\n * const data = yield* Result.try(async () => await response.json())\n * return data\n * })\n * // Type: Promise<Exit<unknown, Error>>\n * ```\n */\nfunction fxFn<A, E>(generatorFn: () => AsyncFxGenerator<A, E, never>): Promise<Exit<A, E>>\n\n/**\n * Execute a sync computation with service dependencies immediately.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n * The second argument is required when the computation has service requirements (R ≠ never).\n *\n * @template A - The success value type\n * @template E - The error type from the computation\n * @template E2 - The error type from the provider (layer)\n * @template R - The required services type\n * @param generatorFn - A function that returns a sync generator with service requirements\n * @param provider - A function that provides the services (e.g., provide(AppLayer))\n * @returns Exit<A, E | E2>\n *\n * @example\n * ```ts\n * const exit = Fx.fn(function* () {\n * const config = yield* Config\n * const logger = yield* Logger\n * logger.info(`DB URL: ${config.dbUrl}`)\n * return config.dbUrl\n * }, provide(AppLayer))\n * // Type: Exit<string, never>\n * ```\n */\nfunction fxFn<A, E, E2, R>(\n generatorFn: () => FxGenerator<A, E, R>,\n provider: (fx: RunnableFx<A, E, R>) => RunnableFx<A, E | E2>,\n): Exit<A, E | E2>\n\n/**\n * Execute an async computation with service dependencies immediately.\n * Catches unexpected thrown exceptions and wraps them as Defect.\n * The second argument is required when the computation has service requirements (R ≠ never).\n *\n * @template A - The success value type\n * @template E - The error type from the computation\n * @template E2 - The error type from the provider (layer)\n * @template R - The required services type\n * @param generatorFn - A function that returns an async generator with service requirements\n * @param provider - A function that provides the services (e.g., provide(AppLayer))\n * @returns Promise<Exit<A, E | E2>>\n *\n * @example\n * ```ts\n * const exit = await Fx.fn(async function* () {\n * const config = yield* Config\n * await doAsyncWork()\n * return config.dbUrl\n * }, provide(AppLayer))\n * // Type: Promise<Exit<string, never>>\n * ```\n */\nfunction fxFn<A, E, E2, R>(\n generatorFn: () => AsyncFxGenerator<A, E, R>,\n provider: (fx: RunnableFx<A, E, R>) => RunnableFx<A, E | E2>,\n): Promise<Exit<A, E | E2>>\n\n/**\n * Implementation of Fx.fn.\n * Reuses fxGen() for Fx creation and fxRun() for execution to ensure consistent behavior.\n */\nfunction fxFn<A, E, E2, R>(\n generatorFn: () => FxGenerator<A, E, R> | AsyncFxGenerator<A, E, R>,\n provider?: (fx: RunnableFx<A, E, R>) => RunnableFx<A, E | E2>,\n): Exit<A, E | E2> | Promise<Exit<A, E | E2>> {\n // Create the Fx using fxGen (single source of truth for Fx creation)\n // Type cast needed because fxGen infers E/R from yielded Fx values,\n // while fxFn receives E/R as explicit type parameters\n // oxlint-disable-next-line no-explicit-any\n const fx = fxGen(generatorFn as any) as RunnableFx<A, E, R>\n\n if (provider) {\n // Apply provider and run\n const provided = provider(fx)\n return fxRun(provided as RunnableFx<A, E | E2>) as Exit<A, E | E2> | Promise<Exit<A, E | E2>>\n }\n\n // No provider - run directly (R must be never at the type level)\n return fxRun(fx as RunnableFx<A, E | E2>) as Exit<A, E | E2> | Promise<Exit<A, E | E2>>\n}\n\n// ============================================================================\n// Fx.ok / Fx.err / Fx.option - Convenience aliases\n// ============================================================================\n\n/**\n * Convenience alias for Result.ok.\n * Creates a successful Result that can be yielded in an Fx computation.\n *\n * @param value - The success value\n * @returns Result<T, never>\n *\n * @example\n * ```ts\n * const workflow = Fx.gen(function* () {\n * const value = yield* Fx.ok(42)\n * return value * 2\n * })\n * ```\n */\nconst fxOk = resultOk\n\n/**\n * Convenience alias for Result.err.\n * Creates an error Result that can be yielded in an Fx computation.\n *\n * @param error - The error value\n * @returns Result<never, E>\n *\n * @example\n * ```ts\n * const workflow = Fx.gen(function* () {\n * const config = yield* Config\n *\n * if (!config.dbUrl) {\n * return yield* Fx.err(new ValidationError({ field: \"dbUrl\" }))\n * }\n *\n * return config.dbUrl\n * })\n * ```\n */\nconst fxErr = resultErr\n\n/**\n * Convenience alias for Result.try.\n * Creates a Result that can be yielded in an Fx computation.\n *\n * @param fn - A function that returns a value or throws an error\n * @returns Result<T, E>\n *\n * @example\n * ```ts\n * const result = Fx.try(() => {\n * return 42\n * })\n *\n * const workflow = Fx.gen(function* () {\n * const result = yield* Fx.try(() => {\n * return 42\n * })\n * return result\n * })\n * ```\n */\nconst fxTry = resultTry\n\n/**\n * Convenience alias for Option.fromNullable.\n * Converts nullable values into an Option that can be yielded in an Fx computation.\n *\n * @param value - A possibly nullish value\n * @returns Option<NonNullable<T>>\n *\n * @example\n * ```ts\n * const workflow = Fx.gen(function* () {\n * const apiKey = yield* Fx.option(request.headers[\"x-api-key\"])\n * return apiKey\n * })\n * ```\n */\nconst fxOption = optionFromNullable\n\n// ============================================================================\n// Fx.match - Universal pattern matching\n// ============================================================================\n\n/**\n * Handler functions for matching on a tagged union by `_tag` discriminator.\n * Each handler receives the narrowed variant corresponding to its tag key.\n */\nexport type TaggedMatch<T extends { readonly _tag: string }, R> = {\n readonly [K in T[\"_tag\"]]: (variant: Extract<T, { readonly _tag: K }>) => R\n}\n\n/**\n * Generic pattern matcher for any `_tag`-based discriminated union.\n *\n * Works with Exit, tagged errors, or any type with a `readonly _tag` discriminator.\n * Each handler receives the full narrowed variant object for its tag.\n *\n * Supports both data-first and data-last (pipe) calling styles.\n *\n * @example\n * ```ts\n * // Match on Exit\n * Fx.match(exit, {\n * Ok: (ok) => ok.value,\n * Err: (err) =>\n * Fx.match(err.error, {\n * DatabaseError: (e) => e.message,\n * NotFoundError: (e) => e.resourceId,\n * }),\n * Defect: (d) => String(d.defect),\n * })\n *\n * // Data-last with pipe\n * pipe(exit, Fx.match({\n * Ok: (ok) => ok.value,\n * Err: (err) => \"error\",\n * Defect: (d) => \"defect\",\n * }))\n * ```\n */\nconst fxMatch: {\n <T extends { readonly _tag: string }, R>(value: T, handlers: TaggedMatch<T, R>): R\n <T extends { readonly _tag: string }, R>(handlers: TaggedMatch<T, R>): (value: T) => R\n} = dual(\n 2,\n // oxlint-disable-next-line no-explicit-any\n (value: any, handlers: any): any => handlers[value._tag](value),\n)\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n// Export individual functions\nexport const gen = fxGen\nexport const fn = fxFn\nexport const run = fxRun\nexport const ok = fxOk\nexport const err = fxErr\nexport { fxMatch as match }\n\n// Export internal helpers for use in other modules (provide, scope)\nexport { runSync, runAsync }\n\n/**\n * Fx namespace containing utilities for creating and running effectful computations.\n *\n * Fx provides a minimal API inspired by Effect.ts:\n * - `Fx.gen()` - Create composable computations with service dependencies\n * - `Fx.fn()` - Execute computations immediately\n * - `Fx.run()` - Execute a computation (when all dependencies are provided)\n * - `Fx.ok()` - Create successful results (alias for Result.ok)\n * - `Fx.err()` - Create error results (alias for Result.err)\n * - `Fx.try()` - Wrap throwing operations (alias for Result.try)\n * - `Fx.option()` - Convert nullish values to Option (alias for Option.fromNullable)\n *\n * @example\n * ```ts\n * import { Fx, Service, Layer, provide, pipe, Exit } from \"@nicolastoulemont/std\"\n *\n * // Define services\n * class Config extends Service<Config>()(\"Config\") {\n * readonly dbUrl!: string\n * }\n *\n * class Logger extends Service<Logger>()(\"Logger\") {\n * readonly info!: (msg: string) => void\n * }\n *\n * // Create layers\n * const ConfigLive = Layer.ok(Config, { dbUrl: \"postgres://...\" })\n * const LoggerLive = Layer.fx(Logger)(\n * Fx.gen(function* () {\n * const config = yield* Config\n * return { info: (msg) => console.log(`[${config.dbUrl}] ${msg}`) }\n * })\n * )\n *\n * // Create workflow\n * const myWorkflow = Fx.gen(function* () {\n * const logger = yield* Logger\n * logger.info(\"Hello from Fx!\")\n * return \"done\"\n * })\n *\n * // Compose and run\n * const AppLayer = pipe(ConfigLive, Layer.provide(LoggerLive))\n * const exit = Fx.run(pipe(myWorkflow, provide(AppLayer)))\n * // exit._tag === \"Ok\" | \"Err\" | \"Defect\"\n * ```\n */\nexport const Fx = {\n gen: fxGen,\n fn: fxFn,\n run: fxRun,\n ok: fxOk,\n err: fxErr,\n match: fxMatch,\n try: fxTry,\n option: fxOption,\n} as const\n\n/* oxlint-enable no-unsafe-type-assertion, no-unsafe-assignment, no-unsafe-call, no-unsafe-member-access, no-unsafe-return, no-unsafe-argument, no-unnecessary-type-assertion */\n","import { FxTypeId } from \"./fx.types\"\nimport type { Fx } from \"./fx.types\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Service tags carry phantom generic metadata at runtime and require explicit type assertions. */\n\n// ============================================================================\n// Service Class Types\n// ============================================================================\n\n/**\n * The interface returned by Service()().\n * Acts as both a type tag and a runtime lookup key.\n * Implements Fx protocol with E = never (no errors) and R = Self (requires itself).\n * When yielded, yields itself (as Fx) for proper type inference.\n */\nexport type ServiceClass<Self, Key extends string = string> = Fx<Self, never, Self> & {\n readonly _tag: \"Service\"\n readonly key: Key\n // Phantom type\n readonly _Self: Self\n\n /**\n * Yielding the service class in a gen computation\n * returns the service instance from context.\n * Yields the ServiceClass itself (which implements Fx) for type inference.\n */\n [Symbol.iterator](): Generator<ServiceClass<Self, Key>, Self, unknown>\n}\n\n/**\n * Extract the service type from a ServiceClass.\n */\nexport type ServiceOf<T> = T extends ServiceClass<infer S> ? S : never\n\n/**\n * Extract the key from a ServiceClass.\n */\nexport type ServiceKey<T> = T extends ServiceClass<unknown, infer K> ? K : never\n\n// ============================================================================\n// Service Factory\n// ============================================================================\n\n/**\n * Define a service with a unique key.\n * The returned class acts as both a type and a runtime tag for lookup.\n *\n * Usage follows a double-invocation pattern:\n * - First call provides the Self type parameter\n * - Second call provides the unique key\n *\n * @example\n * ```ts\n * class Config extends Service<Config>()(\"Config\") {\n * readonly dbUrl!: string\n * readonly logLevel!: \"debug\" | \"info\" | \"error\"\n * }\n *\n * class Logger extends Service<Logger>()(\"Logger\") {\n * readonly info!: (msg: string) => void\n * readonly error!: (msg: string) => void\n * }\n *\n * // Use in Fx.gen:\n * const workflow = Fx.gen(function* () {\n * const config = yield* Config\n * const logger = yield* Logger\n * logger.info(`DB URL: ${config.dbUrl}`)\n * })\n * ```\n */\nexport function Service<Self>(): <Key extends string>(key: Key) => ServiceClass<Self, Key> & (new () => Self) {\n return <Key extends string>(key: Key): ServiceClass<Self, Key> & (new () => Self) => {\n // Create the base class with proper prototype\n // oxlint-disable-next-line typescript/no-extraneous-class\n const ServiceBase = class {\n static readonly _tag = \"Service\" as const\n static readonly key: Key = key\n static readonly _Self: Self = undefined as unknown as Self\n\n static readonly [FxTypeId] = {\n _A: () => undefined as unknown as Self,\n _E: () => undefined as never,\n _R: () => undefined as unknown as Self,\n };\n\n /**\n * Yielding the class returns the class itself (for type inference).\n * The runtime intercepts this and provides the actual service instance.\n */\n static *[Symbol.iterator](): Generator<typeof ServiceBase, Self, Self> {\n // Yield the class itself - it implements Fx<Self, never, Self>\n // The runtime will recognize ServiceClass and inject the service\n const serviceInstance = yield ServiceBase\n return serviceInstance\n }\n }\n\n // Return with correct typing\n return ServiceBase as unknown as ServiceClass<Self, Key> & (new () => Self)\n }\n}\n\n/**\n * Create a service tag without class syntax.\n * Useful for simple services that don't need class inheritance.\n *\n * @example\n * ```ts\n * interface ConfigService {\n * readonly dbUrl: string\n * readonly logLevel: \"debug\" | \"info\" | \"error\"\n * }\n *\n * const Config = serviceTag<ConfigService>(\"Config\")\n *\n * // Use in Fx.gen:\n * const workflow = Fx.gen(function* () {\n * const config = yield* Config\n * console.log(config.dbUrl)\n * })\n * ```\n */\nexport function serviceTag<S>(key: string): ServiceClass<S> {\n const tag: ServiceClass<S> = {\n _tag: \"Service\",\n key,\n _Self: undefined as unknown as S,\n [FxTypeId]: {\n _A: () => undefined as unknown as S,\n _E: () => undefined as never,\n _R: () => undefined as unknown as S,\n },\n *[Symbol.iterator](): Generator<ServiceClass<S>, S, S> {\n // Yield the tag itself - it implements Fx<S, never, S>\n // The runtime will recognize ServiceClass and inject the service\n const serviceInstance = yield tag\n return serviceInstance\n },\n }\n return tag\n}\n\n/**\n * Check if a value is a ServiceClass.\n */\nexport const isServiceClass = (value: unknown): value is ServiceClass<unknown> =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Service\"\n\n/* oxlint-enable no-unsafe-type-assertion */\n","import type { ServiceClass } from \"./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 */\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 */\nconst 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 * const ctx = Context.make(Config, { dbUrl: \"postgres://...\", logLevel: \"info\" })\n * ```\n */\nconst 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 * const ctx = pipe(\n * Context.empty(),\n * Context.add(Config, configImpl),\n * Context.add(Logger, loggerImpl),\n * )\n * ```\n */\nconst 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 * const ctx = Context.merge(configContext, loggerContext)\n * ```\n */\nconst 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 * const config = Context.get(ctx, Config)\n * ```\n */\n// Use overload to handle both curried and uncurried calls\nfunction get<S>(ctx: Context<S>, service: ServiceClass<S>): S\nfunction get<S>(service: ServiceClass<S>): (ctx: Context<S>) => S\nfunction 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 * Unsafely get a service from a context by key string.\n * Used internally by the runtime when resolving ServiceRequests.\n * Returns undefined if not found (caller should handle).\n */\nconst unsafeGet = (ctx: Context<unknown>, key: string): unknown => ctx._services.get(key)\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 */\nconst has = <S>(ctx: Context<unknown>, service: ServiceClass<S>): boolean => ctx._services.has(service.key)\n\n/**\n * Get all service keys in a context.\n */\nconst keys = (ctx: Context<unknown>): string[] => [...ctx._services.keys()]\n\n/**\n * Get the size (number of services) in a context.\n */\nconst size = (ctx: Context<unknown>): number => ctx._services.size\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if a value is a Context.\n */\nconst isContext = (value: unknown): value is Context<unknown> =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Context\"\n\n// ============================================================================\n// Context Namespace\n// ============================================================================\n\n/**\n * Context namespace containing utilities for managing service contexts.\n *\n * A Context is an immutable map of services that can be provided to Fx computations.\n * Services are identified by their unique keys.\n *\n * @example\n * ```ts\n * import { Context, Service } from \"@nicolastoulemont/std\"\n *\n * class Config extends Service<Config>()(\"Config\") {\n * readonly dbUrl!: string\n * }\n *\n * class Logger extends Service<Logger>()(\"Logger\") {\n * readonly info!: (msg: string) => void\n * }\n *\n * // Create a context with services\n * const ctx = pipe(\n * Context.empty(),\n * Context.add(Config, { dbUrl: \"postgres://...\" }),\n * Context.add(Logger, { info: console.log }),\n * )\n *\n * // Or use make and merge\n * const configCtx = Context.make(Config, { dbUrl: \"postgres://...\" })\n * const loggerCtx = Context.make(Logger, { info: console.log })\n * const fullCtx = Context.merge(configCtx, loggerCtx)\n * ```\n */\nexport const Context = {\n empty,\n make,\n add,\n merge,\n get,\n unsafeGet,\n has,\n keys,\n size,\n isContext,\n} as const\n\n/* oxlint-enable no-unsafe-type-assertion */\n","import { Context } from \"./context\"\nimport { FxTypeId } from \"./fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"./fx.types\"\nimport type { Layer as LayerType, MergeROut, MergeError, UnprovidedDeps, AllSync } from \"./layer.types\"\nimport type { ScopeService, ExcludeScope } from \"./scope\"\nimport type { ServiceClass } from \"./service\"\nimport { asServiceRequest, resolveService } from \"./service-resolution\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Layer composition carries erased generic channels and phantom type slots that require assertion-based reconstruction. */\n\n/**\n * Create a layer from a synchronous value (no dependencies).\n */\nconst layerOk = <S>(service: ServiceClass<S>, impl: S): LayerType<S, never, never, true> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as never,\n _RIn: undefined as never,\n _Sync: undefined as unknown as true,\n build: (): SyncFx<Context<S>> => ({\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<S>,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, Context<S>, unknown> {\n return Context.make(service, impl)\n },\n }),\n})\n\n/**\n * Create a layer that always fails with an error.\n */\nconst layerErr = <E>(error: E): LayerType<never, E, never, true> => ({\n _tag: \"Layer\",\n _ROut: undefined as never,\n _E: undefined as unknown as E,\n _RIn: undefined as never,\n _Sync: undefined as unknown as true,\n build: (): SyncFx<Context, E> => ({\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as never,\n _E: () => error,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<E, never, unknown> {\n yield error\n throw new Error(\"Unreachable\")\n },\n }),\n})\n\n/**\n * Create a layer from an Fx computation (can have dependencies).\n * The Sync type parameter is inferred from the input fx:\n * - SyncFx input → Layer with Sync=true\n * - AsyncFx input → Layer with Sync=false\n */\nfunction layerFx<S>(service: ServiceClass<S>): {\n <E, R>(fx: SyncFx<S, E, R>): LayerType<S, E, R, true>\n <E, R>(fx: AsyncFx<S, E, R>): LayerType<S, E, R, false>\n <E, R>(fx: RunnableFx<S, E, R>): LayerType<S, E, R>\n}\nfunction layerFx<S>(service: ServiceClass<S>) {\n return <E, R>(fx: RunnableFx<S, E, R>): LayerType<S, E, R> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as unknown as E,\n _RIn: undefined as unknown as R,\n _Sync: undefined as unknown as boolean,\n build: (): RunnableFx<Context<S>, E, R> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as R,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, R>, Context<S>, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n while (result.done !== true) {\n const value = yield result.value\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n return Context.make(service, result.value)\n },\n } as AsyncFx<Context<S>, E, R>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as R,\n },\n *[Symbol.iterator](): Generator<FxYield<E, R>, Context<S>, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const value = yield result.value\n result = gen.next(value)\n }\n return Context.make(service, result.value)\n },\n } as SyncFx<Context<S>, E, R>\n },\n })\n}\n\n/**\n * Create a scoped layer (with resource cleanup).\n * The Sync type parameter is inferred from the input fx.\n */\nfunction layerScoped<S>(service: ServiceClass<S>): {\n <E, R>(fx: SyncFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>, true>\n <E, R>(fx: AsyncFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>, false>\n <E, R>(fx: RunnableFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>>\n}\nfunction layerScoped<S>(service: ServiceClass<S>) {\n return <E, R>(fx: RunnableFx<S, E, R | ScopeService>): LayerType<S, E, ExcludeScope<R>> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as S,\n _E: undefined as unknown as E,\n _RIn: undefined as unknown as ExcludeScope<R>,\n _Sync: undefined as unknown as boolean,\n build: (_memoMap, scope): RunnableFx<Context<S>, E, ExcludeScope<R>> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as ExcludeScope<R>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, ExcludeScope<R>>, Context<S>, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === \"@std/Scope\") {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(scope)\n } else {\n const value = yield yielded as FxYield<E, ExcludeScope<R>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n }\n return Context.make(service, result.value)\n },\n } as AsyncFx<Context<S>, E, ExcludeScope<R>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<S>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as ExcludeScope<R>,\n },\n *[Symbol.iterator](): Generator<FxYield<E, ExcludeScope<R>>, Context<S>, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === \"@std/Scope\") {\n result = gen.next(scope)\n } else {\n const value = yield yielded as FxYield<E, ExcludeScope<R>>\n result = gen.next(value)\n }\n }\n return Context.make(service, result.value)\n },\n } as SyncFx<Context<S>, E, ExcludeScope<R>>\n },\n })\n}\n\n// ============================================================================\n// Layer Composition\n// ============================================================================\n\n/**\n * Provide dependencies to a layer and merge outputs.\n * Sync is preserved only if both the deps layer and the consuming layer are sync.\n */\nfunction layerProvide<DepsROut, DepsE, DepsRIn, DepsSync extends boolean>(\n deps: LayerType<DepsROut, DepsE, DepsRIn, DepsSync>,\n): {\n <ROut, E, RIn extends DepsROut, LayerSync extends boolean>(\n layer: LayerType<ROut, E, RIn, LayerSync>,\n ): LayerType<ROut | DepsROut, E | DepsE, DepsRIn, LayerSync extends true ? DepsSync : false>\n}\nfunction layerProvide<DepsROut, DepsE, DepsRIn>(deps: LayerType<DepsROut, DepsE, DepsRIn>) {\n return <ROut, E, RIn extends DepsROut>(\n layer: LayerType<ROut, E, RIn>,\n ): LayerType<ROut | DepsROut, E | DepsE, DepsRIn> => ({\n _tag: \"Layer\",\n _ROut: undefined as unknown as ROut | DepsROut,\n _E: undefined as unknown as E | DepsE,\n _RIn: undefined as unknown as DepsRIn,\n _Sync: undefined as unknown as boolean,\n build: (memoMap, scope): RunnableFx<Context<ROut | DepsROut>, E | DepsE, DepsRIn> => {\n const depsBuildFx = deps.build(memoMap, scope)\n\n if (depsBuildFx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut | DepsROut>,\n _E: () => undefined as unknown as E | DepsE,\n _R: () => undefined as unknown as DepsRIn,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<\n FxYield<E | DepsE, DepsRIn>,\n Context<ROut | DepsROut>,\n unknown\n > {\n const depsGen = depsBuildFx[Symbol.asyncIterator]()\n let depsResult = await depsGen.next()\n while (depsResult.done !== true) {\n const value = yield depsResult.value\n // oxlint-disable-next-line no-await-in-loop\n depsResult = await depsGen.next(value)\n }\n const depsCtx = depsResult.value\n\n const layerBuildFx = layer.build(memoMap, scope)\n if (layerBuildFx._tag === \"AsyncFx\") {\n const layerGen = layerBuildFx[Symbol.asyncIterator]()\n let layerResult = await layerGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n layerResult = await layerGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n // oxlint-disable-next-line no-await-in-loop\n layerResult = await layerGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n }\n\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n layerResult = layerGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n layerResult = layerGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n },\n } as AsyncFx<Context<ROut | DepsROut>, E | DepsE, DepsRIn>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut | DepsROut>,\n _E: () => undefined as unknown as E | DepsE,\n _R: () => undefined as unknown as DepsRIn,\n },\n *[Symbol.iterator](): Generator<FxYield<E | DepsE, DepsRIn>, Context<ROut | DepsROut>, unknown> {\n const depsGen = depsBuildFx[Symbol.iterator]()\n let depsResult = depsGen.next()\n while (depsResult.done !== true) {\n const value = yield depsResult.value\n depsResult = depsGen.next(value)\n }\n const depsCtx = depsResult.value\n\n const layerBuildFx = layer.build(memoMap, scope)\n if (layerBuildFx._tag === \"SyncFx\") {\n const syncGen = layerBuildFx[Symbol.iterator]()\n let layerResult = syncGen.next()\n while (layerResult.done !== true) {\n const yielded = layerResult.value\n const service = resolveService(depsCtx, yielded)\n if (service !== undefined) {\n layerResult = syncGen.next(service)\n continue\n }\n const value = yield yielded as FxYield<E, DepsRIn>\n layerResult = syncGen.next(value)\n }\n return Context.merge(depsCtx, layerResult.value)\n }\n throw new Error(\"Cannot use async layer in sync context\")\n },\n } as SyncFx<Context<ROut | DepsROut>, E | DepsE, DepsRIn>\n },\n })\n}\n\n/**\n * Merge multiple layers with automatic dependency resolution.\n * The merged layer is sync only if ALL input layers are sync.\n */\nfunction layerMerge<L extends LayerType<unknown, unknown, unknown>[]>(\n ...layers: L\n): LayerType<MergeROut<L>, MergeError<L>, UnprovidedDeps<L>, AllSync<L>>\nfunction layerMerge<L extends LayerType<unknown, unknown, unknown>[]>(\n ...layers: L\n): LayerType<MergeROut<L>, MergeError<L>, UnprovidedDeps<L>> {\n return {\n _tag: \"Layer\",\n _ROut: undefined as unknown as MergeROut<L>,\n _E: undefined as unknown as MergeError<L>,\n _RIn: undefined as unknown as UnprovidedDeps<L>,\n _Sync: undefined as unknown as boolean,\n build: (memoMap, scope): RunnableFx<Context<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>> => {\n const hasAsync = layers.some((l) => l.build(memoMap, scope)._tag === \"AsyncFx\")\n\n if (hasAsync) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<MergeROut<L>>,\n _E: () => undefined as unknown as MergeError<L>,\n _R: () => undefined as unknown as UnprovidedDeps<L>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<\n FxYield<MergeError<L>, UnprovidedDeps<L>>,\n Context<MergeROut<L>>,\n unknown\n > {\n let ctx = Context.empty() as Context<unknown>\n for (const layer of layers) {\n const buildFx = layer.build(memoMap, scope)\n if (buildFx._tag === \"AsyncFx\") {\n const gen = buildFx[Symbol.asyncIterator]()\n // oxlint-disable-next-line no-await-in-loop\n let result = await gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n } else {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n result = gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n result = gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n }\n }\n return ctx as Context<MergeROut<L>>\n },\n } as AsyncFx<Context<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<MergeROut<L>>,\n _E: () => undefined as unknown as MergeError<L>,\n _R: () => undefined as unknown as UnprovidedDeps<L>,\n },\n *[Symbol.iterator](): Generator<FxYield<MergeError<L>, UnprovidedDeps<L>>, Context<MergeROut<L>>, unknown> {\n let ctx = Context.empty() as Context<unknown>\n for (const layer of layers) {\n const buildFx = layer.build(memoMap, scope)\n if (buildFx._tag !== \"SyncFx\") {\n throw new Error(\"Expected sync layer in sync context\")\n }\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n while (result.done !== true) {\n const yielded = result.value\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n result = gen.next(service)\n continue\n }\n const value = yield yielded as FxYield<MergeError<L>, UnprovidedDeps<L>>\n result = gen.next(value)\n }\n ctx = Context.merge(ctx, result.value)\n }\n return ctx as Context<MergeROut<L>>\n },\n } as SyncFx<Context<MergeROut<L>>, MergeError<L>, UnprovidedDeps<L>>\n },\n }\n}\n\n// ============================================================================\n// Layer Namespace\n// ============================================================================\n\nexport const Layer = {\n ok: layerOk,\n err: layerErr,\n fx: layerFx,\n scoped: layerScoped,\n provide: layerProvide,\n merge: layerMerge,\n} as const\n\n/* oxlint-enable no-unsafe-type-assertion */\n","import type { Result } from \"../result/result.types\"\nimport { runSync, runAsync } from \"./fx\"\nimport { FxTypeId } from \"./fx.types\"\nimport type { SyncFx, AsyncFx, FxYield } from \"./fx.types\"\nimport { Service } from \"./service\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Scope encodes Fx phantom type slots and sync/async branch narrowing via assertions. */\n\n// ============================================================================\n// Scope Service\n// ============================================================================\n\n/**\n * Scope manages resource lifecycles with finalizers.\n * Finalizers run in LIFO (Last In, First Out) order when the scope closes.\n *\n * @example\n * ```ts\n * const DatabaseLive = Layer.scoped(Database)(\n * Fx.gen(function* () {\n * const scope = yield* Scope\n *\n * const connection = createConnection()\n *\n * // Register cleanup - runs when scope closes\n * yield* scope.addFinalizer(() =>\n * Fx.gen(function* () {\n * connection.close()\n * })\n * )\n *\n * return { query: (sql) => connection.query(sql) }\n * })\n * )\n * ```\n */\nexport type ScopeService = {\n /**\n * Add a finalizer to be run when the scope closes.\n * Finalizers are run in LIFO order.\n *\n * @param finalizer - A function that returns an Fx to run on cleanup\n * @returns An Fx that completes when the finalizer is registered\n */\n addFinalizer(finalizer: () => SyncFx<void> | AsyncFx<void>): SyncFx<void>\n\n /**\n * Close the scope, running all finalizers in LIFO order.\n *\n * @param exit - The exit status of the computation\n * @returns An Fx that completes when all finalizers have run\n */\n close(exit: Result<unknown, unknown>): SyncFx<void> | AsyncFx<void>\n\n /**\n * Fork a child scope.\n * The child scope will be closed when the parent scope closes.\n *\n * @returns A new child scope\n */\n fork(): ScopeService\n}\n\n// Create the Scope service tag\nclass ScopeTag extends Service<ScopeService>()(\"@std/Scope\") {}\nexport { ScopeTag as Scope }\n\n// ============================================================================\n// Scope Implementation\n// ============================================================================\n\n/**\n * Create a new Scope instance.\n * This is the concrete implementation of the ScopeService interface.\n */\nexport function createScope(): ScopeService {\n type Finalizer = () => SyncFx<void> | AsyncFx<void>\n const finalizers: Finalizer[] = []\n let closed = false\n const children: ScopeService[] = []\n\n const scope: ScopeService = {\n addFinalizer(finalizer: Finalizer): SyncFx<void> {\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as void,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<never, never>, void, unknown> {\n if (!closed) {\n finalizers.push(finalizer)\n }\n },\n } as SyncFx<void>\n },\n\n close(exit: Result<unknown, unknown>): SyncFx<void> | AsyncFx<void> {\n // Check if any finalizer is async\n const hasAsyncFinalizer = finalizers.some((f) => {\n const fx = f()\n return fx._tag === \"AsyncFx\"\n })\n\n if (hasAsyncFinalizer) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as void,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<never, never>, void, unknown> {\n if (closed) return\n closed = true\n\n // Close children first\n for (const child of [...children].toReversed()) {\n const childClose = child.close(exit)\n if (childClose._tag === \"AsyncFx\") {\n // oxlint-disable-next-line no-await-in-loop\n await runAsync(childClose)\n } else {\n runSync(childClose)\n }\n }\n\n // Run finalizers in LIFO order\n const reversed = [...finalizers].toReversed()\n for (const finalizer of reversed) {\n const fx = finalizer()\n if (fx._tag === \"AsyncFx\") {\n // oxlint-disable-next-line no-await-in-loop\n await runAsync(fx)\n } else {\n runSync(fx)\n }\n }\n },\n } as AsyncFx<void>\n }\n\n // Sync version\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as void,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<never, never>, void, unknown> {\n if (closed) return\n closed = true\n\n // Close children first\n for (const child of [...children].toReversed()) {\n const childClose = child.close(exit)\n runSync(childClose as SyncFx<void>)\n }\n\n // Run finalizers in LIFO order\n const reversed = [...finalizers].toReversed()\n for (const finalizer of reversed) {\n const fx = finalizer()\n runSync(fx as SyncFx<void>)\n }\n },\n } as SyncFx<void>\n },\n\n fork(): ScopeService {\n const child = createScope()\n children.push(child)\n return child\n },\n }\n\n return scope\n}\n\n// ============================================================================\n// Helper Types\n// ============================================================================\n\n/**\n * Type utility to exclude Scope from requirements.\n * Used by Layer.scoped to auto-provide Scope.\n */\nexport type ExcludeScope<R> = Exclude<R, ScopeService>\n\n/* oxlint-enable no-unsafe-type-assertion */\n","import { ok } from \"../result/result\"\nimport type { Context } from \"./context\"\nimport { FxTypeId } from \"./fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"./fx.types\"\nimport type { Layer } from \"./layer.types\"\nimport type { ScopeService } from \"./scope\"\nimport { asServiceRequest } from \"./service-resolution\"\n\n/* oxlint-disable no-unsafe-type-assertion, only-throw-error -- MemoMap bridges erased generic Fx channels and re-emits typed domain errors from generator boundaries. */\n\n// ============================================================================\n// MemoMap\n// ============================================================================\n\ntype AnyLayer = Layer<unknown, unknown, unknown>\n\n/**\n * MemoMap caches built layers so each layer is only built once.\n * Multiple dependents share the same service instance.\n *\n * This implements the \"service singleton\" pattern where a service\n * is instantiated once and shared across all consumers.\n *\n * @example\n * ```ts\n * // Database is built once, shared by DocumentService and TeamService\n * const AppLayer = Layer.merge(\n * ConfigLive,\n * LoggerLive,\n * DatabaseLive, // Built once\n * DocumentServiceLive, // Uses shared Database\n * TeamServiceLive, // Uses same Database instance\n * )\n * ```\n */\nexport class MemoMap {\n private cache = new Map<\n AnyLayer,\n {\n promise?: Promise<Context<unknown>>\n context?: Context<unknown>\n building?: boolean\n }\n >()\n\n /**\n * Get a cached context or build the layer if not cached.\n *\n * @param layer - The layer to get or build\n * @param scope - The scope for resource management\n * @param deps - Context containing the layer's dependencies\n * @returns A RunnableFx producing the layer's context\n */\n getOrBuild<ROut, E, RIn>(\n layer: Layer<ROut, E, RIn>,\n scope: ScopeService,\n deps: Context<RIn>,\n ): RunnableFx<Context<ROut>, E> {\n const cached = this.cache.get(layer as AnyLayer)\n\n // Already built - return cached context\n if (cached?.context) {\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => cached.context as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: () => ok(cached.context as Context<ROut>),\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<E, never>, Context<ROut>, unknown> {\n return cached.context as Context<ROut>\n },\n } as SyncFx<Context<ROut>, E>\n }\n\n // Building in progress (async) - wait for it\n if (cached?.promise) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: async () => {\n const ctx = await cached.promise!\n return ok(ctx as Context<ROut>)\n },\n // oxlint-disable-next-line require-yield\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, Context<ROut>, unknown> {\n const ctx = await cached.promise!\n return ctx as Context<ROut>\n },\n } as AsyncFx<Context<ROut>, E>\n }\n\n // Need to build - mark as building\n this.cache.set(layer as AnyLayer, { building: true })\n\n // Build the layer with provided dependencies\n const buildFx = layer.build(this, scope)\n const cacheRef = this.cache\n\n // Determine if async\n if (buildFx._tag === \"AsyncFx\") {\n // Create a promise for the build\n const buildPromise = (async () => {\n const gen = buildFx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error - rethrow\n throw yielded\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n }\n\n const ctx = result.value\n cacheRef.set(layer as AnyLayer, { context: ctx })\n return ctx\n })()\n\n this.cache.set(layer as AnyLayer, { promise: buildPromise })\n\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: async () => {\n try {\n const ctx = await buildPromise\n return ok(ctx)\n } catch (e) {\n return {\n ok: false,\n error: e as E,\n *[Symbol.iterator]() {\n yield e as E\n throw new Error(\"Unreachable\")\n },\n }\n }\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, Context<ROut>, unknown> {\n try {\n const ctx = await buildPromise\n return ctx\n } catch (e) {\n yield e as E\n throw new Error(\"Unreachable\", { cause: e })\n }\n },\n } as AsyncFx<Context<ROut>, E>\n }\n\n // Sync build\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: () => {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error\n return {\n ok: false,\n error: yielded as E,\n *[Symbol.iterator]() {\n yield yielded as E\n throw new Error(\"Unreachable\")\n },\n }\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n result = gen.next(service)\n }\n\n const ctx = result.value\n cacheRef.set(layer as AnyLayer, { context: ctx })\n return ok(ctx)\n },\n *[Symbol.iterator](): Generator<FxYield<E, never>, Context<ROut>, unknown> {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error - yield it\n yield yielded as E\n throw new Error(\"Unreachable\")\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n result = gen.next(service)\n }\n\n cacheRef.set(layer as AnyLayer, { context: result.value })\n return result.value\n },\n } as SyncFx<Context<ROut>, E>\n }\n\n /**\n * Clear the cache.\n * Useful for testing.\n */\n clear(): void {\n this.cache.clear()\n }\n\n /**\n * Get the number of cached layers.\n */\n get size(): number {\n return this.cache.size\n }\n}\n\n/**\n * Create a new MemoMap instance.\n */\nexport const createMemoMap = (): MemoMap => new MemoMap()\n\n/* oxlint-enable no-unsafe-type-assertion, only-throw-error */\n","import { ok } from \"../result/result\"\nimport type { Context } from \"./context\"\nimport { runSync, runAsync } from \"./fx\"\nimport { FxTypeId } from \"./fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"./fx.types\"\nimport type { Layer } from \"./layer.types\"\nimport { MemoMap } from \"./memo-map\"\nimport { createScope } from \"./scope\"\nimport type { ServiceClass } from \"./service\"\nimport { asServiceRequest, resolveService } from \"./service-resolution\"\n\n/* oxlint-disable no-unsafe-type-assertion -- provide/provideService re-thread generic Fx channels through runtime service injection points. */\n\n// ============================================================================\n// Provide Layer\n// ============================================================================\n\n/**\n * Extract the value type from an Fx.\n */\ntype FxValueType<F> = F extends RunnableFx<infer A, unknown, unknown> ? A : never\n\n/**\n * Extract the error type from an Fx.\n */\ntype FxErrorType<F> = F extends RunnableFx<unknown, infer E, unknown> ? E : never\n\n/**\n * Type for the result of provide based on layer sync and fx type.\n * Uses infer to extract A and E from the actual Fx type.\n * - Sync layer + SyncFx → SyncFx\n * - Sync layer + AsyncFx → AsyncFx\n * - Async layer + any fx → AsyncFx\n * - Unknown sync layer + any fx → RunnableFx (fallback)\n */\ntype ProvideResult<\n E2,\n LayerSync extends boolean,\n Fx extends RunnableFx<unknown, unknown, unknown>,\n> = LayerSync extends true\n ? Fx[\"_tag\"] extends \"SyncFx\"\n ? SyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : LayerSync extends false\n ? AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : RunnableFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n\n/**\n * Provide a layer to an Fx computation, resolving all service requirements.\n * Creates a new scope for resource management.\n *\n * Type preservation:\n * - Sync layer + SyncFx → SyncFx\n * - Sync layer + AsyncFx → AsyncFx\n * - Async layer + any fx → AsyncFx\n * - Unknown sync layer + any fx → RunnableFx (fallback)\n *\n * @param layer - The layer providing services (must have no external requirements)\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * const result = Fx.run(pipe(\n * updateDocumentWorkflow(userId, docId, data),\n * provide(AppLayer)\n * ))\n * ```\n */\nexport function provide<ROut, E2, LayerSync extends boolean>(\n layer: Layer<ROut, E2, never, LayerSync>,\n): <Fx extends RunnableFx<unknown, unknown, ROut>>(fx: Fx) => ProvideResult<E2, LayerSync, Fx>\nexport function provide<ROut, E2>(layer: Layer<ROut, E2>) {\n return <A, E, R extends ROut>(fx: RunnableFx<A, E, R>): RunnableFx<A, E | E2> => {\n // Determine if the layer or fx is async\n const memoMap = new MemoMap()\n const scope = createScope()\n const layerBuildFx = layer.build(memoMap, scope)\n\n if (layerBuildFx._tag === \"AsyncFx\" || fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E | E2,\n _R: () => undefined as never,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E | E2, Exclude<R, ROut>>, A, unknown> {\n try {\n // Build the layer\n let ctx: Context<ROut>\n\n if (layerBuildFx._tag === \"AsyncFx\") {\n const gen = layerBuildFx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n yield result.value as E2\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(undefined)\n }\n ctx = result.value\n } else {\n const gen = layerBuildFx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n yield result.value as E2\n result = gen.next(undefined)\n }\n ctx = result.value\n }\n\n // Run the fx with the context\n if (fx._tag === \"AsyncFx\") {\n const fxGen = fx[Symbol.asyncIterator]()\n let fxResult = await fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n fxResult = await fxGen.next(service)\n continue\n }\n\n // Pass through (error or unsatisfied service)\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n // oxlint-disable-next-line no-await-in-loop\n fxResult = await fxGen.next(value)\n }\n\n return fxResult.value\n }\n\n // Sync fx\n const fxGen = fx[Symbol.iterator]()\n let fxResult = fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n fxResult = fxGen.next(service)\n continue\n }\n\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n fxResult = fxGen.next(value)\n }\n\n return fxResult.value\n } finally {\n const closeResult = scope.close(ok(undefined))\n if (closeResult._tag === \"AsyncFx\") {\n await runAsync(closeResult)\n } else {\n runSync(closeResult)\n }\n }\n },\n } as AsyncFx<A, E | E2>\n }\n\n // Both sync\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E | E2,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<FxYield<E | E2, Exclude<R, ROut>>, A, unknown> {\n try {\n // Build the layer\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n\n while (layerResult.done !== true) {\n yield layerResult.value as E2\n layerResult = layerGen.next(undefined)\n }\n\n const ctx = layerResult.value\n\n // Run the fx with the context\n const fxGen = fx[Symbol.iterator]()\n let fxResult = fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n fxResult = fxGen.next(service)\n continue\n }\n\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n fxResult = fxGen.next(value)\n }\n\n return fxResult.value\n } finally {\n const closeResult = scope.close(ok(undefined))\n // In sync-only branch, closeResult is always SyncFx\n runSync(closeResult as SyncFx<void>)\n }\n },\n } as SyncFx<A, E | E2>\n }\n}\n\n// ============================================================================\n// Provide Context\n// ============================================================================\n\n/**\n * Provide a context directly to an Fx computation.\n *\n * @param ctx - The context containing services\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * const ctx = Context.make(Config, configImpl)\n * const result = Fx.run(pipe(\n * myWorkflow,\n * provideContext(ctx)\n * ))\n * ```\n */\nexport const provideContext =\n <R>(ctx: Context<R>) =>\n <A, E>(fx: RunnableFx<A, E, R>): RunnableFx<A, E> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, A, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n yield yielded as E\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(undefined)\n continue\n }\n const service = ctx._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found`)\n }\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n }\n\n return result.value\n },\n } as AsyncFx<A, E>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<FxYield<E, never>, A, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n yield yielded as E\n result = gen.next(undefined)\n continue\n }\n const service = ctx._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found`)\n }\n result = gen.next(service)\n }\n\n return result.value\n },\n } as SyncFx<A, E>\n }\n\n// ============================================================================\n// Provide Service\n// ============================================================================\n\n/**\n * Provide a single service to an Fx computation.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A function that takes an Fx and returns an Fx with the service provided\n *\n * @example\n * ```ts\n * const result = Fx.run(pipe(\n * myWorkflow,\n * provideService(Config, configImpl),\n * provideService(Logger, loggerImpl),\n * ))\n * ```\n */\nexport const provideService =\n <S>(service: ServiceClass<S>, impl: S) =>\n <A, E, R>(fx: RunnableFx<A, E, R | S>): RunnableFx<A, E, Exclude<R, S>> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as Exclude<R, S>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, Exclude<R, S>>, A, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === service.key) {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(impl)\n } else {\n const value = yield yielded as FxYield<E, Exclude<R, S>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n }\n\n return result.value\n },\n } as AsyncFx<A, E, Exclude<R, S>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as Exclude<R, S>,\n },\n *[Symbol.iterator](): Generator<FxYield<E, Exclude<R, S>>, A, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === service.key) {\n result = gen.next(impl)\n } else {\n const value = yield yielded as FxYield<E, Exclude<R, S>>\n result = gen.next(value)\n }\n }\n\n return result.value\n },\n } as SyncFx<A, E, Exclude<R, S>>\n }\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
@@ -101,11 +101,6 @@ type AsyncFx<A, E = never, R = never> = Fx<A, E, R> & {
101
101
  * Use this for functions that execute effects like Fx.run().
102
102
  */
103
103
  type RunnableFx<A, E = never, R = never> = SyncFx<A, E, R> | AsyncFx<A, E, R>;
104
- /**
105
- * Extract the success type from an Fx.
106
- * @deprecated Use FxValue instead
107
- */
108
- type FxSuccess<T> = T extends Fx<infer A, unknown, unknown> ? A : never;
109
104
  /**
110
105
  * Sync generator type for Fx.gen.
111
106
  * Yields error Results or ServiceClasses, returns value of type A.
@@ -129,5 +124,5 @@ type AsyncFxYieldable<A, E = never, R = never> = Fx<A, E, R> & {
129
124
  [Symbol.asyncIterator](): AsyncGenerator<FxYield<E, R>, A, unknown>;
130
125
  };
131
126
  //#endregion
132
- export { FxError as a, FxSuccess as c, FxYield as d, FxYieldable as f, isServiceRequest as g, SyncFx as h, Fx as i, FxTypeId as l, ServiceRequest as m, AsyncFxGenerator as n, FxGenerator as o, RunnableFx as p, AsyncFxYieldable as r, FxRequirements as s, AsyncFx as t, FxValue as u };
133
- //# sourceMappingURL=fx.types-DO-8yG4c.d.mts.map
127
+ export { FxError as a, FxTypeId as c, FxYieldable as d, RunnableFx as f, isServiceRequest as h, Fx as i, FxValue as l, SyncFx as m, AsyncFxGenerator as n, FxGenerator as o, ServiceRequest as p, AsyncFxYieldable as r, FxRequirements as s, AsyncFx as t, FxYield as u };
128
+ //# sourceMappingURL=fx.types-B34asVRX.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fx.types-DO-8yG4c.d.mts","names":[],"sources":["../src/fx/fx.types.ts"],"sourcesContent":[],"mappings":";;AAOA;AACA;AAUY,cAXC,QAWC,EAAA,OAAA,MAAA;AAES,KAZX,QAAA,GAYW,OAZO,QAYP;;;;;AAWvB;;;;AAGqB,KAhBT,EAgBS,CAAA,KAAA,EAAA,QAAA,KAAA,EAAA,QAAA,KAAA,CAAA,GAAA;EAAC,UAfV,QAAA,CAeU,EAAA;IAOT,SAAA,EAAA,EAAA,GACsF,GAtB5E,CAsB4E;IAKvF,SAAO,EAAA,EAAA,GAAA,GA1BI,CA0BE;IAKb,SAAO,EAAA,EAAA,GAAA,GA9BI,CA8BE;EAKb,CAAA;AAeZ,CAAA;;;;;AAA+C;AAMrB,KA/Cd,cA+Cc,CAAA,CAAA,CAAA,GA/CM,EA+CN,CA/CS,CA+CT,EAAA,KAAA,EA/CmB,CA+CnB,CAAA,GAAA;EAAU,SAAA,IAAA,EAAA,gBAAA;EAAb;EAAE,SAAA,QAAA,EA5CJ,CA4CI;EAUb,SAAM,UAAA,EAAA,MAAA;CAA+B;;;;AAOR,cAtD5B,gBAsD4B,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,GAAA,KAAA,IAtDkB,cAsDlB,CAAA,OAAA,CAAA;;;;AAAlB,KAhDX,OAgDW,CAAA,CAAA,CAAA,GAhDE,CAgDF,SAhDY,EAgDZ,CAAA,KAAA,EAAA,EAAA,OAAA,EAAA,OAAA,CAAA,GAAA,CAAA,GAAA,KAAA;;AAWvB;;AAAqD,KAtDzC,OAsDyC,CAAA,CAAA,CAAA,GAtD5B,CAsD4B,SAtDlB,EAsDkB,CAAA,OAAA,EAAA,KAAA,EAAA,EAAA,OAAA,CAAA,GAAA,CAAA,GAAA,KAAA;;;;AAOC,KAxD1C,cAwD0C,CAAA,CAAA,CAAA,GAxDtB,CAwDsB,SAxDZ,EAwDY,CAAA,OAAA,EAAA,OAAA,EAAA,KAAA,EAAA,CAAA,GAAA,CAAA,GAAA,KAAA;;;;;AAOtD;;;;;AAA4E,KAhDhE,OAgDgE,CAAA,CAAA,EAAA,CAAA,CAAA,GAhDhD,CAgDgD,GAhD5C,YAgD4C,CAhD/B,CAgD+B,CAAA;;;;;AAU5E,KApDK,YAoDgB,CAAA,CAAA,CAAA,GApDE,EAoDF,CApDK,CAoDL,EAAA,KAAgB,EApDD,CAoDG,CAAA,GAAA;EAU3B,IAAA,EAAA,SAAW;EAA8B,GAAA,EAAA,MAAA;CAAG;;;;;AAMxD;;;;AAAsE,KA1D1D,MA0D0D,CAAA,CAAA,EAAA,IAAA,KAAA,EAAA,IAAA,KAAA,CAAA,GA1DxB,EA0DwB,CA1DrB,CA0DqB,EA1DlB,CA0DkB,EA1Df,CA0De,CAAA,GAAA;EAA9B,SAAA,IAAA,EAAA,QAAA;EAAc;AAStD;;;EAA4D,CAAA,MAAA,CAAA,QAAA,GAAA,EA5DrC,SA4DqC,CA5D3B,OA4D2B,CA5DnB,CA4DmB,EA5DhB,CA4DgB,CAAA,EA5DZ,CA4DY,EAAA,OAAA,CAAA;CAAT;;;;;;;AAOnD;;AAA8D,KAxDlD,OAwDkD,CAAA,CAAA,EAAA,IAAA,KAAA,EAAA,IAAA,KAAA,CAAA,GAxDf,EAwDe,CAxDZ,CAwDY,EAxDT,CAwDS,EAxDN,CAwDM,CAAA,GAAA;EAAG,SAAA,IAAA,EAAA,SAAA;EAAT;;;;EACE,CAAA,MAAA,CAAA,aAAA,GAAA,EAlD9B,cAkD8B,CAlDf,OAkDe,CAlDP,CAkDO,EAlDJ,CAkDI,CAAA,EAlDA,CAkDA,EAAA,OAAA,CAAA;CAA9B;;;;;KA3ChB,sCAAsC,OAAO,GAAG,GAAG,KAAK,QAAQ,GAAG,GAAG;;;;;KAUtE,eAAe,UAAU;;;;;KAUzB,uBAAuB,UAAU,QAAQ,GAAG,IAAI;;;;;KAMhD,4BAA4B,eAAe,QAAQ,GAAG,IAAI;;;;KAS1D,uCAAuC,GAAG,GAAG,GAAG;uBACrC,UAAU,QAAQ,GAAG,IAAI;;;;;KAMpC,4CAA4C,GAAG,GAAG,GAAG;4BACrC,eAAe,QAAQ,GAAG,IAAI"}
1
+ {"version":3,"file":"fx.types-B34asVRX.d.mts","names":[],"sources":["../src/fx/fx.types.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  const e=Symbol.for(`@repo/std/fx/FxTypeId`),t=e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`ServiceRequest`;export{t as n,e as t};
2
- //# sourceMappingURL=fx.types-CXTwEa1G.mjs.map
2
+ //# sourceMappingURL=fx.types-CDVjDn_3.mjs.map