@nicolastoulemont/std 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +388 -60
  2. package/dist/brand/index.d.mts +1 -1
  3. package/dist/brand/index.mjs +1 -1
  4. package/dist/{brand-DZgGDrAe.mjs → brand-DP-C92GS.mjs} +2 -2
  5. package/dist/{brand-DZgGDrAe.mjs.map → brand-DP-C92GS.mjs.map} +1 -1
  6. package/dist/{brand.types-B3NDX1vo.d.mts → brand.types-C_7QgCA4.d.mts} +1 -1
  7. package/dist/{brand.types-B3NDX1vo.d.mts.map → brand.types-C_7QgCA4.d.mts.map} +1 -1
  8. package/dist/context/index.d.mts +1 -1
  9. package/dist/context/index.mjs +1 -1
  10. package/dist/{context-0xDbwtpx.mjs → context-7oKePrBY.mjs} +2 -2
  11. package/dist/{context-0xDbwtpx.mjs.map → context-7oKePrBY.mjs.map} +1 -1
  12. package/dist/{context-B2dWloPl.d.mts → context-B9oWzbwF.d.mts} +2 -2
  13. package/dist/{context-B2dWloPl.d.mts.map → context-B9oWzbwF.d.mts.map} +1 -1
  14. package/dist/data/index.d.mts +1 -1
  15. package/dist/data/index.mjs +1 -1
  16. package/dist/data-W10ldR5l.mjs +2 -0
  17. package/dist/data-W10ldR5l.mjs.map +1 -0
  18. package/dist/{dual-fN6OUwN_.mjs → dual-CZhzZslG.mjs} +1 -1
  19. package/dist/{dual-fN6OUwN_.mjs.map → dual-CZhzZslG.mjs.map} +1 -1
  20. package/dist/duration/index.d.mts +1 -1
  21. package/dist/duration/index.mjs +1 -1
  22. package/dist/{duration-Bas3mi1N.mjs → duration-Dwtjy95Z.mjs} +2 -2
  23. package/dist/{duration-Bas3mi1N.mjs.map → duration-Dwtjy95Z.mjs.map} +1 -1
  24. package/dist/either/index.d.mts +1 -1
  25. package/dist/either/index.mjs +1 -1
  26. package/dist/{either-G7uOu4Ar.mjs → either-B2TvVY_j.mjs} +2 -2
  27. package/dist/{either-G7uOu4Ar.mjs.map → either-B2TvVY_j.mjs.map} +1 -1
  28. package/dist/exit-DOdhmr81.d.mts +67 -0
  29. package/dist/exit-DOdhmr81.d.mts.map +1 -0
  30. package/dist/fiber/index.d.mts +2 -0
  31. package/dist/fiber/index.mjs +1 -0
  32. package/dist/fiber-CZsyrDdd.mjs +2 -0
  33. package/dist/fiber-CZsyrDdd.mjs.map +1 -0
  34. package/dist/{flow-CNyLsPGb.mjs → flow-D8_tllWl.mjs} +1 -1
  35. package/dist/{flow-CNyLsPGb.mjs.map → flow-D8_tllWl.mjs.map} +1 -1
  36. package/dist/functions/index.mjs +1 -1
  37. package/dist/functions-DmOZ7O4j.mjs +2 -0
  38. package/dist/{functions-ByAk682_.mjs.map → functions-DmOZ7O4j.mjs.map} +1 -1
  39. package/dist/fx/index.d.mts +1 -1
  40. package/dist/fx/index.mjs +1 -1
  41. package/dist/fx-DXBw4iYX.mjs +2 -0
  42. package/dist/fx-DXBw4iYX.mjs.map +1 -0
  43. package/dist/fx.runtime-B2_rL7h_.mjs +2 -0
  44. package/dist/fx.runtime-B2_rL7h_.mjs.map +1 -0
  45. package/dist/fx.runtime-BuIElLpZ.d.mts +16 -0
  46. package/dist/fx.runtime-BuIElLpZ.d.mts.map +1 -0
  47. package/dist/{fx.types-DyQVgTS8.mjs → fx.types-Bg-Mmdm5.mjs} +1 -1
  48. package/dist/{fx.types-DyQVgTS8.mjs.map → fx.types-Bg-Mmdm5.mjs.map} +1 -1
  49. package/dist/{fx.types-BdN1EWxr.d.mts → fx.types-CpFKa-Jj.d.mts} +1 -1
  50. package/dist/{fx.types-BdN1EWxr.d.mts.map → fx.types-CpFKa-Jj.d.mts.map} +1 -1
  51. package/dist/{index-DfAqfnY0.d.mts → index-5QkUtJ-4.d.mts} +4 -4
  52. package/dist/{index-DfAqfnY0.d.mts.map → index-5QkUtJ-4.d.mts.map} +1 -1
  53. package/dist/{index-BD-els5J.d.mts → index-B3xia3Jl.d.mts} +82 -58
  54. package/dist/index-B3xia3Jl.d.mts.map +1 -0
  55. package/dist/{index-CIvNgjsx.d.mts → index-B4rHoUK4.d.mts} +2 -2
  56. package/dist/{index-CIvNgjsx.d.mts.map → index-B4rHoUK4.d.mts.map} +1 -1
  57. package/dist/{index-BA0EsFxS.d.mts → index-BDUhDs4D.d.mts} +3 -3
  58. package/dist/{index-BA0EsFxS.d.mts.map → index-BDUhDs4D.d.mts.map} +1 -1
  59. package/dist/{index-CNTYbcY9.d.mts → index-BZ1-IrU_.d.mts} +1 -1
  60. package/dist/{index-CNTYbcY9.d.mts.map → index-BZ1-IrU_.d.mts.map} +1 -1
  61. package/dist/{index-uE3S3Krx.d.mts → index-BZP6t2h9.d.mts} +5 -5
  62. package/dist/{index-uE3S3Krx.d.mts.map → index-BZP6t2h9.d.mts.map} +1 -1
  63. package/dist/{index-D8rDE60Y.d.mts → index-Bu-z5Xoq.d.mts} +1 -1
  64. package/dist/index-Bu-z5Xoq.d.mts.map +1 -0
  65. package/dist/index-C8KMi_I9.d.mts +226 -0
  66. package/dist/index-C8KMi_I9.d.mts.map +1 -0
  67. package/dist/{index-dCRymj_g.d.mts → index-CfXGmPMY.d.mts} +5 -5
  68. package/dist/{index-dCRymj_g.d.mts.map → index-CfXGmPMY.d.mts.map} +1 -1
  69. package/dist/index-Cv48HmyO.d.mts +59 -0
  70. package/dist/index-Cv48HmyO.d.mts.map +1 -0
  71. package/dist/{index-D6pjHqlK.d.mts → index-D-KxgnwF.d.mts} +49 -70
  72. package/dist/index-D-KxgnwF.d.mts.map +1 -0
  73. package/dist/{index-DR7hzXU4.d.mts → index-DLkMqvw4.d.mts} +137 -29
  74. package/dist/index-DLkMqvw4.d.mts.map +1 -0
  75. package/dist/index-DlWm_PwP.d.mts +436 -0
  76. package/dist/index-DlWm_PwP.d.mts.map +1 -0
  77. package/dist/{index-CVmgBpDt.d.mts → index-DogEz6WQ.d.mts} +2 -2
  78. package/dist/{index-CVmgBpDt.d.mts.map → index-DogEz6WQ.d.mts.map} +1 -1
  79. package/dist/{index-D8gcYvR9.d.mts → index-XxPUUAGQ.d.mts} +5 -5
  80. package/dist/{index-D8gcYvR9.d.mts.map → index-XxPUUAGQ.d.mts.map} +1 -1
  81. package/dist/{index-BqJ1GWAF.d.mts → index-pC80zLHb.d.mts} +2 -2
  82. package/dist/{index-BqJ1GWAF.d.mts.map → index-pC80zLHb.d.mts.map} +1 -1
  83. package/dist/index.d.mts +23 -20
  84. package/dist/index.mjs +1 -1
  85. package/dist/layer/index.d.mts +1 -1
  86. package/dist/layer/index.mjs +1 -1
  87. package/dist/layer-BmrPWBkT.mjs +2 -0
  88. package/dist/layer-BmrPWBkT.mjs.map +1 -0
  89. package/dist/{layer.types-BB0MrvLg.d.mts → layer.types-DsCTjICW.d.mts} +4 -4
  90. package/dist/{layer.types-BB0MrvLg.d.mts.map → layer.types-DsCTjICW.d.mts.map} +1 -1
  91. package/dist/log/index.d.mts +2 -0
  92. package/dist/log/index.mjs +1 -0
  93. package/dist/log-Bh8G5umo.mjs +2 -0
  94. package/dist/log-Bh8G5umo.mjs.map +1 -0
  95. package/dist/multithread/index.d.mts +1 -1
  96. package/dist/multithread/index.mjs +1 -1
  97. package/dist/multithread-CovZ2ioL.mjs +21 -0
  98. package/dist/multithread-CovZ2ioL.mjs.map +1 -0
  99. package/dist/option/index.d.mts +1 -1
  100. package/dist/option/index.mjs +1 -1
  101. package/dist/{option-C2iCxAuJ.mjs → option-BlyP5LA2.mjs} +2 -2
  102. package/dist/{option-C2iCxAuJ.mjs.map → option-BlyP5LA2.mjs.map} +1 -1
  103. package/dist/{option.types-D9hrKcfa.d.mts → option.types-DLp3QpFE.d.mts} +3 -3
  104. package/dist/{option.types-D9hrKcfa.d.mts.map → option.types-DLp3QpFE.d.mts.map} +1 -1
  105. package/dist/{option.types-CbY_swma.mjs → option.types-bFFSErJ-.mjs} +1 -1
  106. package/dist/{option.types-CbY_swma.mjs.map → option.types-bFFSErJ-.mjs.map} +1 -1
  107. package/dist/order/index.d.mts +1 -1
  108. package/dist/order/index.mjs +1 -1
  109. package/dist/{order-BXOBEKvB.mjs → order-VTXpppmI.mjs} +2 -2
  110. package/dist/{order-BXOBEKvB.mjs.map → order-VTXpppmI.mjs.map} +1 -1
  111. package/dist/{pipeable-BIrevC0D.d.mts → pipeable-BY9yPsNK.d.mts} +1 -1
  112. package/dist/{pipeable-BIrevC0D.d.mts.map → pipeable-BY9yPsNK.d.mts.map} +1 -1
  113. package/dist/pipeable-COGyGMUV.mjs +2 -0
  114. package/dist/{pipeable-Dp1_23zH.mjs.map → pipeable-COGyGMUV.mjs.map} +1 -1
  115. package/dist/predicate/index.d.mts +1 -1
  116. package/dist/predicate/index.mjs +1 -1
  117. package/dist/{predicate-D_1SsIi4.mjs → predicate-8hY-0Ocv.mjs} +2 -2
  118. package/dist/{predicate-D_1SsIi4.mjs.map → predicate-8hY-0Ocv.mjs.map} +1 -1
  119. package/dist/provide/index.d.mts +1 -1
  120. package/dist/provide/index.mjs +1 -1
  121. package/dist/provide-K-6oXtLm.mjs +2 -0
  122. package/dist/provide-K-6oXtLm.mjs.map +1 -0
  123. package/dist/queue/index.d.mts +1 -1
  124. package/dist/queue/index.mjs +1 -1
  125. package/dist/{queue-GYVrD39q.mjs → queue-CeEIUHcY.mjs} +2 -2
  126. package/dist/{queue-GYVrD39q.mjs.map → queue-CeEIUHcY.mjs.map} +1 -1
  127. package/dist/result/index.d.mts +1 -1
  128. package/dist/result/index.mjs +1 -1
  129. package/dist/{result-D3VY0qBG.mjs → result-C74pRN2x.mjs} +2 -2
  130. package/dist/{result-D3VY0qBG.mjs.map → result-C74pRN2x.mjs.map} +1 -1
  131. package/dist/{result.types-BKzChyWY.d.mts → result.types-CnhiVFEV.d.mts} +3 -3
  132. package/dist/{result.types-BKzChyWY.d.mts.map → result.types-CnhiVFEV.d.mts.map} +1 -1
  133. package/dist/schedule/index.d.mts +1 -1
  134. package/dist/schedule/index.mjs +1 -1
  135. package/dist/{schedule-B7qV60tO.mjs → schedule-ChcIgvd5.mjs} +2 -2
  136. package/dist/{schedule-B7qV60tO.mjs.map → schedule-ChcIgvd5.mjs.map} +1 -1
  137. package/dist/{schedule-BzPjvMXc.d.mts → schedule-DiidMLcl.d.mts} +3 -3
  138. package/dist/{schedule-BzPjvMXc.d.mts.map → schedule-DiidMLcl.d.mts.map} +1 -1
  139. package/dist/schema/index.d.mts +1 -1
  140. package/dist/schema/index.mjs +1 -1
  141. package/dist/schema-CT_wO7tN.mjs +2 -0
  142. package/dist/schema-CT_wO7tN.mjs.map +1 -0
  143. package/dist/scope/index.d.mts +1 -1
  144. package/dist/scope/index.mjs +1 -1
  145. package/dist/{scope-CuM3CzwG.d.mts → scope-7bLTmdRX.d.mts} +4 -4
  146. package/dist/scope-7bLTmdRX.d.mts.map +1 -0
  147. package/dist/scope-D2AqJy7j.mjs +2 -0
  148. package/dist/scope-D2AqJy7j.mjs.map +1 -0
  149. package/dist/service/index.d.mts +1 -1
  150. package/dist/service/index.mjs +1 -1
  151. package/dist/{service-D8mr0wwg.d.mts → service-C4xUfS_M.d.mts} +2 -2
  152. package/dist/{service-D8mr0wwg.d.mts.map → service-C4xUfS_M.d.mts.map} +1 -1
  153. package/dist/{service-CWAIEH46.mjs → service-DHkeorS3.mjs} +2 -2
  154. package/dist/{service-CWAIEH46.mjs.map → service-DHkeorS3.mjs.map} +1 -1
  155. package/dist/trace/index.d.mts +2 -0
  156. package/dist/trace/index.mjs +1 -0
  157. package/dist/trace-ByjppUes.mjs +2 -0
  158. package/dist/trace-ByjppUes.mjs.map +1 -0
  159. package/dist/trace-D_7sjH22.d.mts +375 -0
  160. package/dist/trace-D_7sjH22.d.mts.map +1 -0
  161. package/package.json +13 -5
  162. package/dist/adt/index.d.mts +0 -2
  163. package/dist/adt/index.mjs +0 -1
  164. package/dist/adt-CY8wLJJI.mjs +0 -2
  165. package/dist/adt-CY8wLJJI.mjs.map +0 -1
  166. package/dist/data-DqACNS_g.mjs +0 -2
  167. package/dist/data-DqACNS_g.mjs.map +0 -1
  168. package/dist/discriminator.types-C-ygT2S1.d.mts +0 -7
  169. package/dist/discriminator.types-C-ygT2S1.d.mts.map +0 -1
  170. package/dist/functions-ByAk682_.mjs +0 -2
  171. package/dist/fx-C_RTDEpv.mjs +0 -2
  172. package/dist/fx-C_RTDEpv.mjs.map +0 -1
  173. package/dist/fx.runtime-jQxh77s3.mjs +0 -2
  174. package/dist/fx.runtime-jQxh77s3.mjs.map +0 -1
  175. package/dist/index-BD-els5J.d.mts.map +0 -1
  176. package/dist/index-BaRJVkLo.d.mts +0 -458
  177. package/dist/index-BaRJVkLo.d.mts.map +0 -1
  178. package/dist/index-BipW0MC3.d.mts +0 -64
  179. package/dist/index-BipW0MC3.d.mts.map +0 -1
  180. package/dist/index-D6pjHqlK.d.mts.map +0 -1
  181. package/dist/index-D8rDE60Y.d.mts.map +0 -1
  182. package/dist/index-DR7hzXU4.d.mts.map +0 -1
  183. package/dist/is-plain-object-BoFjRafL.mjs +0 -2
  184. package/dist/is-plain-object-BoFjRafL.mjs.map +0 -1
  185. package/dist/layer-C5A-EM0h.mjs +0 -2
  186. package/dist/layer-C5A-EM0h.mjs.map +0 -1
  187. package/dist/multithread-Cyc8Bz45.mjs +0 -19
  188. package/dist/multithread-Cyc8Bz45.mjs.map +0 -1
  189. package/dist/pipeable-Dp1_23zH.mjs +0 -2
  190. package/dist/provide-CuccogWx.mjs +0 -2
  191. package/dist/provide-CuccogWx.mjs.map +0 -1
  192. package/dist/schema-DstB1_VK.mjs +0 -2
  193. package/dist/schema-DstB1_VK.mjs.map +0 -1
  194. package/dist/schema.shared-Bjyroa6b.mjs +0 -2
  195. package/dist/schema.shared-Bjyroa6b.mjs.map +0 -1
  196. package/dist/schema.types-w1WK4kGS.d.mts +0 -62
  197. package/dist/schema.types-w1WK4kGS.d.mts.map +0 -1
  198. package/dist/scope-CuM3CzwG.d.mts.map +0 -1
  199. package/dist/scope-gVt4PESc.mjs +0 -2
  200. package/dist/scope-gVt4PESc.mjs.map +0 -1
  201. package/dist/service-resolution-BefYr4nR.mjs +0 -2
  202. package/dist/service-resolution-BefYr4nR.mjs.map +0 -1
  203. /package/dist/{chunk-oQKkju2G.mjs → chunk-6rpU2rUb.mjs} +0 -0
  204. /package/dist/{option-CXXiA1w-.mjs → option-BqAUkJ8e.mjs} +0 -0
  205. /package/dist/{result-xFLfwriM.mjs → result-B5WbPg8C.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"option.types-CbY_swma.mjs","names":[],"sources":["../src/option/option.types.ts"],"sourcesContent":["import type { Fx } from \"../fx/fx.types\"\nimport type { Pipeable } from \"../shared/pipeable\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Option types expose Fx phantom channels through compile-time-only marker fields. */\n\n// ============================================================================\n// NoSuchElementError\n// ============================================================================\n\n/**\n * Error thrown when attempting to access a value from None.\n * Used as the error type when Option is yielded in Fx.gen().\n *\n * When you yield* Option.none() in Fx.gen(), the computation short-circuits\n * with this error, which becomes part of the error union type.\n *\n * This is the typed error channel for `Option.none()` in Fx computations.\n */\nexport class NoSuchElementError extends Error {\n readonly _tag = \"NoSuchElementError\"\n\n constructor() {\n super(\"Option is None - no element present\")\n this.name = \"NoSuchElementError\"\n }\n}\n\n// ============================================================================\n// Option Variant Types\n// ============================================================================\n\n/**\n * Represents an Option with a value.\n */\ntype Some<T> = {\n readonly _tag: \"Some\"\n readonly value: T\n}\n\n/**\n * Represents an Option with no value.\n */\ntype None = {\n readonly _tag: \"None\"\n}\n\n// ============================================================================\n// Option Type\n// ============================================================================\n\n/**\n * A discriminated union representing either a value (Some) or absence (None).\n * Uses _tag discriminator for unified API compatibility.\n * Compatible with ts-pattern for exhaustive matching.\n *\n * Implements Fx protocol: Option<T> is Fx<T, NoSuchElementError, never>\n * - Yielding Some in Fx.gen() returns the value\n * - Yielding None in Fx.gen() short-circuits with NoSuchElementError\n *\n * When yielded in a generator, yields NoSuchElementError\n * for proper type inference in both gen() and Fx.gen().\n */\nexport type Option<T> = (Some<T> | None) &\n Fx<T, NoSuchElementError> &\n Pipeable & {\n [Symbol.iterator](): Generator<NoSuchElementError, T, unknown>\n }\n\n/**\n * Compute the return type of `fromTry` based on whether fn returns a Promise.\n * - If fn returns Promise<T>, result is Promise<Option<T>>\n * - If fn returns T, result is Option<T>\n */\nexport type FromTryReturn<T> = T extends Promise<infer U> ? Promise<Option<U>> : Option<T>\n\n// ============================================================================\n// All/Combine types\n// ============================================================================\n\n/**\n * Extract the value type from an Option.\n * Uses structural matching to extract the value type from the Some branch.\n */\ntype OptionValue<O> = O extends { readonly _tag: \"Some\"; readonly value: infer T } ? T : never\n\n/**\n * Overloaded all() type with explicit tuple arities for better inference.\n * Provides tuple overloads for 1-6 elements so `as const` is not required.\n */\nexport type OptionAll = {\n // Tuple overloads (1-6 elements)\n <A>(options: readonly [Option<A>]): Option<[A]>\n <A, B>(options: readonly [Option<A>, Option<B>]): Option<[A, B]>\n <A, B, C>(options: readonly [Option<A>, Option<B>, Option<C>]): Option<[A, B, C]>\n <A, B, C, D>(options: readonly [Option<A>, Option<B>, Option<C>, Option<D>]): Option<[A, B, C, D]>\n <A, B, C, D, E>(options: readonly [Option<A>, Option<B>, Option<C>, Option<D>, Option<E>]): Option<[A, B, C, D, E]>\n <A, B, C, D, E, F>(\n options: readonly [Option<A>, Option<B>, Option<C>, Option<D>, Option<E>, Option<F>],\n ): Option<[A, B, C, D, E, F]>\n\n // Array fallback (longer tuples need `as const`)\n <T extends readonly Option<unknown>[]>(options: T): Option<{ -readonly [K in keyof T]: OptionValue<T[K]> }>\n\n // Object form\n <T extends Record<string, Option<unknown>>>(options: T): Option<{ -readonly [K in keyof T]: OptionValue<T[K]> }>\n}\n\n// ============================================================================\n// Function Interfaces for improved pipe inference\n// ============================================================================\n\n/**\n * Interface for flatMap - using method syntax improves generic inference in pipe chains.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Note: Async overload must come first for proper overload resolution.\n */\nexport type OptionFlatMap = {\n // Data-first overloads (async first)\n <A, B>(option: Option<A>, fn: (value: A) => Promise<Option<B>>): Promise<Option<B>>\n <A, B>(option: Option<A>, fn: (value: A) => Option<B>): Option<B>\n // Data-last overloads (curried for pipe)\n <A, B>(fn: (value: A) => Promise<Option<B>>): (option: Option<A>) => Promise<Option<B>>\n <A, B>(fn: (value: A) => Option<B>): (option: Option<A>) => Option<B>\n}\n\n/**\n * Interface for map function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Note: Async overload must come first for proper overload resolution.\n */\nexport type OptionMap = {\n // Data-first overloads (async first)\n <A, B>(option: Option<A>, fn: (value: A) => Promise<B>): Promise<Option<B>>\n <A, B>(option: Option<A>, fn: (value: A) => B): Option<B>\n // Data-last overloads (curried for pipe)\n <A, B>(fn: (value: A) => Promise<B>): (option: Option<A>) => Promise<Option<B>>\n <A, B>(fn: (value: A) => B): (option: Option<A>) => Option<B>\n}\n\n/* oxlint-enable no-unsafe-type-assertion */\n\n/**\n * Interface for tap function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionTap = {\n // Data-first overload\n <A, R>(option: Option<A>, fn: (value: A) => R): R extends Promise<unknown> ? Promise<Option<A>> : Option<A>\n // Data-last overload (curried for pipe)\n <A, R>(fn: (value: A) => R): (option: Option<A>) => R extends Promise<unknown> ? Promise<Option<A>> : Option<A>\n}\n\n/**\n * Interface for orElse function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Note: Async overload must come first for proper overload resolution.\n */\nexport type OptionOrElse = {\n // Data-first overloads (async first)\n <A, B>(option: Option<A>, fn: () => Promise<Option<B>>): Promise<Option<A | B>>\n <A, B>(option: Option<A>, fn: () => Option<B>): Option<A | B>\n // Data-last overloads (curried for pipe)\n <A, B>(fn: () => Promise<Option<B>>): (option: Option<A>) => Promise<Option<A | B>>\n <A, B>(fn: () => Option<B>): (option: Option<A>) => Option<A | B>\n}\n\n/**\n * Interface for filter function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionFilter = {\n // Data-first overload\n <A>(option: Option<A>, predicate: (value: A) => boolean): Option<A>\n // Data-last overload (curried for pipe)\n <A>(predicate: (value: A) => boolean): (option: Option<A>) => Option<A>\n}\n\n/**\n * Interface for unwrapOr function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Uses NoInfer to prevent type inference from the default value.\n */\nexport type OptionUnwrapOr = {\n // Data-first overload\n <T>(option: Option<T>, defaultValue: NoInfer<T>): T\n // Data-last overload (curried for pipe)\n <T>(defaultValue: NoInfer<T>): (option: Option<T>) => T\n}\n\n/**\n * Interface for unwrapOrElse function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionUnwrapOrElse = {\n // Data-first overload\n <T>(option: Option<T>, fn: () => T): T\n // Data-last overload (curried for pipe)\n <T>(fn: () => T): (option: Option<T>) => T\n}\n\n/**\n * Interface for match function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionMatch = {\n // Data-first overload\n <T, U>(option: Option<T>, handlers: { Some: (value: T) => U; None: () => U }): U\n // Data-last overload (curried for pipe)\n <T, U>(handlers: { Some: (value: T) => U; None: () => U }): (option: Option<T>) => U\n}\n"],"mappings":"AAkBA,IAAa,EAAb,cAAwC,KAAM,CAC5C,KAAgB,qBAEhB,aAAc,CACZ,MAAM,sCAAsC,CAC5C,KAAK,KAAO"}
1
+ {"version":3,"file":"option.types-bFFSErJ-.mjs","names":[],"sources":["../src/option/option.types.ts"],"sourcesContent":["import type { Fx } from \"../fx/fx.types\"\nimport type { Pipeable } from \"../shared/pipeable\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Option types expose Fx phantom channels through compile-time-only marker fields. */\n\n// ============================================================================\n// NoSuchElementError\n// ============================================================================\n\n/**\n * Error thrown when attempting to access a value from None.\n * Used as the error type when Option is yielded in Fx.gen().\n *\n * When you yield* Option.none() in Fx.gen(), the computation short-circuits\n * with this error, which becomes part of the error union type.\n *\n * This is the typed error channel for `Option.none()` in Fx computations.\n */\nexport class NoSuchElementError extends Error {\n readonly _tag = \"NoSuchElementError\"\n\n constructor() {\n super(\"Option is None - no element present\")\n this.name = \"NoSuchElementError\"\n }\n}\n\n// ============================================================================\n// Option Variant Types\n// ============================================================================\n\n/**\n * Represents an Option with a value.\n */\ntype Some<T> = {\n readonly _tag: \"Some\"\n readonly value: T\n}\n\n/**\n * Represents an Option with no value.\n */\ntype None = {\n readonly _tag: \"None\"\n}\n\n// ============================================================================\n// Option Type\n// ============================================================================\n\n/**\n * A discriminated union representing either a value (Some) or absence (None).\n * Uses _tag discriminator for unified API compatibility.\n * Compatible with ts-pattern for exhaustive matching.\n *\n * Implements Fx protocol: Option<T> is Fx<T, NoSuchElementError, never>\n * - Yielding Some in Fx.gen() returns the value\n * - Yielding None in Fx.gen() short-circuits with NoSuchElementError\n *\n * When yielded in a generator, yields NoSuchElementError\n * for proper type inference in both gen() and Fx.gen().\n */\nexport type Option<T> = (Some<T> | None) &\n Fx<T, NoSuchElementError> &\n Pipeable & {\n [Symbol.iterator](): Generator<NoSuchElementError, T, unknown>\n }\n\n/**\n * Compute the return type of `fromTry` based on whether fn returns a Promise.\n * - If fn returns Promise<T>, result is Promise<Option<T>>\n * - If fn returns T, result is Option<T>\n */\nexport type FromTryReturn<T> = T extends Promise<infer U> ? Promise<Option<U>> : Option<T>\n\n// ============================================================================\n// All/Combine types\n// ============================================================================\n\n/**\n * Extract the value type from an Option.\n * Uses structural matching to extract the value type from the Some branch.\n */\ntype OptionValue<O> = O extends { readonly _tag: \"Some\"; readonly value: infer T } ? T : never\n\n/**\n * Overloaded all() type with explicit tuple arities for better inference.\n * Provides tuple overloads for 1-6 elements so `as const` is not required.\n */\nexport type OptionAll = {\n // Tuple overloads (1-6 elements)\n <A>(options: readonly [Option<A>]): Option<[A]>\n <A, B>(options: readonly [Option<A>, Option<B>]): Option<[A, B]>\n <A, B, C>(options: readonly [Option<A>, Option<B>, Option<C>]): Option<[A, B, C]>\n <A, B, C, D>(options: readonly [Option<A>, Option<B>, Option<C>, Option<D>]): Option<[A, B, C, D]>\n <A, B, C, D, E>(options: readonly [Option<A>, Option<B>, Option<C>, Option<D>, Option<E>]): Option<[A, B, C, D, E]>\n <A, B, C, D, E, F>(\n options: readonly [Option<A>, Option<B>, Option<C>, Option<D>, Option<E>, Option<F>],\n ): Option<[A, B, C, D, E, F]>\n\n // Array fallback (longer tuples need `as const`)\n <T extends readonly Option<unknown>[]>(options: T): Option<{ -readonly [K in keyof T]: OptionValue<T[K]> }>\n\n // Object form\n <T extends Record<string, Option<unknown>>>(options: T): Option<{ -readonly [K in keyof T]: OptionValue<T[K]> }>\n}\n\n// ============================================================================\n// Function Interfaces for improved pipe inference\n// ============================================================================\n\n/**\n * Interface for flatMap - using method syntax improves generic inference in pipe chains.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Note: Async overload must come first for proper overload resolution.\n */\nexport type OptionFlatMap = {\n // Data-first overloads (async first)\n <A, B>(option: Option<A>, fn: (value: A) => Promise<Option<B>>): Promise<Option<B>>\n <A, B>(option: Option<A>, fn: (value: A) => Option<B>): Option<B>\n // Data-last overloads (curried for pipe)\n <A, B>(fn: (value: A) => Promise<Option<B>>): (option: Option<A>) => Promise<Option<B>>\n <A, B>(fn: (value: A) => Option<B>): (option: Option<A>) => Option<B>\n}\n\n/**\n * Interface for map function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Note: Async overload must come first for proper overload resolution.\n */\nexport type OptionMap = {\n // Data-first overloads (async first)\n <A, B>(option: Option<A>, fn: (value: A) => Promise<B>): Promise<Option<B>>\n <A, B>(option: Option<A>, fn: (value: A) => B): Option<B>\n // Data-last overloads (curried for pipe)\n <A, B>(fn: (value: A) => Promise<B>): (option: Option<A>) => Promise<Option<B>>\n <A, B>(fn: (value: A) => B): (option: Option<A>) => Option<B>\n}\n\n/* oxlint-enable no-unsafe-type-assertion */\n\n/**\n * Interface for tap function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionTap = {\n // Data-first overload\n <A, R>(option: Option<A>, fn: (value: A) => R): R extends Promise<unknown> ? Promise<Option<A>> : Option<A>\n // Data-last overload (curried for pipe)\n <A, R>(fn: (value: A) => R): (option: Option<A>) => R extends Promise<unknown> ? Promise<Option<A>> : Option<A>\n}\n\n/**\n * Interface for orElse function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Note: Async overload must come first for proper overload resolution.\n */\nexport type OptionOrElse = {\n // Data-first overloads (async first)\n <A, B>(option: Option<A>, fn: () => Promise<Option<B>>): Promise<Option<A | B>>\n <A, B>(option: Option<A>, fn: () => Option<B>): Option<A | B>\n // Data-last overloads (curried for pipe)\n <A, B>(fn: () => Promise<Option<B>>): (option: Option<A>) => Promise<Option<A | B>>\n <A, B>(fn: () => Option<B>): (option: Option<A>) => Option<A | B>\n}\n\n/**\n * Interface for filter function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionFilter = {\n // Data-first overload\n <A>(option: Option<A>, predicate: (value: A) => boolean): Option<A>\n // Data-last overload (curried for pipe)\n <A>(predicate: (value: A) => boolean): (option: Option<A>) => Option<A>\n}\n\n/**\n * Interface for unwrapOr function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n * Uses NoInfer to prevent type inference from the default value.\n */\nexport type OptionUnwrapOr = {\n // Data-first overload\n <T>(option: Option<T>, defaultValue: NoInfer<T>): T\n // Data-last overload (curried for pipe)\n <T>(defaultValue: NoInfer<T>): (option: Option<T>) => T\n}\n\n/**\n * Interface for unwrapOrElse function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionUnwrapOrElse = {\n // Data-first overload\n <T>(option: Option<T>, fn: () => T): T\n // Data-last overload (curried for pipe)\n <T>(fn: () => T): (option: Option<T>) => T\n}\n\n/**\n * Interface for match function.\n * Supports both data-first and data-last (curried) calling styles via dual().\n */\nexport type OptionMatch = {\n // Data-first overload\n <T, U>(option: Option<T>, handlers: { Some: (value: T) => U; None: () => U }): U\n // Data-last overload (curried for pipe)\n <T, U>(handlers: { Some: (value: T) => U; None: () => U }): (option: Option<T>) => U\n}\n"],"mappings":"AAkBA,IAAa,EAAb,cAAwC,KAAM,CAC5C,KAAgB,qBAEhB,aAAc,CACZ,MAAM,sCAAsC,CAC5C,KAAK,KAAO"}
@@ -1,2 +1,2 @@
1
- import { t as order_d_exports } from "../index-D8rDE60Y.mjs";
1
+ import { t as order_d_exports } from "../index-Bu-z5Xoq.mjs";
2
2
  export { order_d_exports as Order };
@@ -1 +1 @@
1
- import{t as e}from"../order-BXOBEKvB.mjs";export{e as Order};
1
+ import{t as e}from"../order-VTXpppmI.mjs";export{e as Order};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./dual-fN6OUwN_.mjs";var n=e({alwaysEqual:()=>u,array:()=>v,between:()=>D,bigint:()=>c,boolean:()=>s,by:()=>f,clamp:()=>E,collator:()=>a,date:()=>l,greaterThan:()=>S,greaterThanOrEqual:()=>C,lessThan:()=>b,lessThanOrEqual:()=>x,make:()=>r,max:()=>T,merge:()=>g,min:()=>w,number:()=>o,reverse:()=>d,sort:()=>O,sortBy:()=>A,sortWith:()=>k,string:()=>i,struct:()=>y,tuple:()=>_});function r(e){return(t,n)=>t===n?0:e(t,n)}const i=r((e,t)=>e<t?-1:1);function a(e){return r((t,n)=>{let r=e.compare(t,n);return r<0?-1:r>0?1:0})}const o=r((e,t)=>Number.isNaN(e)&&Number.isNaN(t)?0:Number.isNaN(e)?-1:Number.isNaN(t)?1:e<t?-1:1),s=r((e,t)=>e<t?-1:1),c=r((e,t)=>e<t?-1:1),l=r((e,t)=>o(e.getTime(),t.getTime()));function u(){return r(()=>0)}function d(e){return r((t,n)=>e(n,t))}const f=t(2,(e,t)=>r((n,r)=>e(t(n),t(r)))),p=(e,t)=>r((n,r)=>{let i=e(n,r);return i===0?t(n,r):i}),m=e=>{let t=Array.from(e);return t.length===0?u():t.length===1?t[0]:r((e,n)=>{for(let r of t){let t=r(e,n);if(t!==0)return t}return 0})};function h(e,t){if(t!==void 0){if(typeof e!=`function`)throw TypeError(`Order.merge(self, that) requires two order functions`);return p(e,t)}return typeof e==`function`?t=>p(t,e):m(e)}const g=h;function _(e){return r((t,n)=>{for(let r=0;r<e.length;r++){let i=e[r],a=i(t[r],n[r]);if(a!==0)return a}return 0})}function v(e){return r((t,n)=>{let r=Math.min(t.length,n.length);for(let i=0;i<r;i++){let r=e(t[i],n[i]);if(r!==0)return r}return o(t.length,n.length)})}function y(e){let t=Object.keys(e);return r((n,r)=>{for(let i of t){let t=e[i](n[i],r[i]);if(t!==0)return t}return 0})}const b=e=>t(2,(t,n)=>e(t,n)===-1),x=e=>t(2,(t,n)=>e(t,n)!==1),S=e=>t(2,(t,n)=>e(t,n)===1),C=e=>t(2,(t,n)=>e(t,n)!==-1),w=e=>t(2,(t,n)=>t===n||e(t,n)<1?t:n),T=e=>t(2,(t,n)=>t===n||e(t,n)>-1?t:n),E=e=>t(2,(t,n)=>w(e)(n.maximum,T(e)(n.minimum,t))),D=e=>t(2,(t,n)=>!b(e)(t,n.minimum)&&!S(e)(t,n.maximum)),O=t(2,(e,t)=>{let n=Array.from(e);return n.sort((e,n)=>t(e,n)),n}),k=t(3,(e,t,n)=>{let r=Array.from(e,e=>[e,t(e)]);return r.sort(([,e],[,t])=>n(e,t)),r.map(([e])=>e)}),A=(...e)=>{if(e.length===0)return e=>Array.from(e);let t=g(e);return e=>O(e,t)};export{n as t};
2
- //# sourceMappingURL=order-BXOBEKvB.mjs.map
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{t}from"./dual-CZhzZslG.mjs";var n=e({alwaysEqual:()=>u,array:()=>v,between:()=>D,bigint:()=>c,boolean:()=>s,by:()=>f,clamp:()=>E,collator:()=>a,date:()=>l,greaterThan:()=>S,greaterThanOrEqual:()=>C,lessThan:()=>b,lessThanOrEqual:()=>x,make:()=>r,max:()=>T,merge:()=>g,min:()=>w,number:()=>o,reverse:()=>d,sort:()=>O,sortBy:()=>A,sortWith:()=>k,string:()=>i,struct:()=>y,tuple:()=>_});function r(e){return(t,n)=>t===n?0:e(t,n)}const i=r((e,t)=>e<t?-1:1);function a(e){return r((t,n)=>{let r=e.compare(t,n);return r<0?-1:r>0?1:0})}const o=r((e,t)=>Number.isNaN(e)&&Number.isNaN(t)?0:Number.isNaN(e)?-1:Number.isNaN(t)?1:e<t?-1:1),s=r((e,t)=>e<t?-1:1),c=r((e,t)=>e<t?-1:1),l=r((e,t)=>o(e.getTime(),t.getTime()));function u(){return r(()=>0)}function d(e){return r((t,n)=>e(n,t))}const f=t(2,(e,t)=>r((n,r)=>e(t(n),t(r)))),p=(e,t)=>r((n,r)=>{let i=e(n,r);return i===0?t(n,r):i}),m=e=>{let t=Array.from(e);return t.length===0?u():t.length===1?t[0]:r((e,n)=>{for(let r of t){let t=r(e,n);if(t!==0)return t}return 0})};function h(e,t){if(t!==void 0){if(typeof e!=`function`)throw TypeError(`Order.merge(self, that) requires two order functions`);return p(e,t)}return typeof e==`function`?t=>p(t,e):m(e)}const g=h;function _(e){return r((t,n)=>{for(let r=0;r<e.length;r++){let i=e[r],a=i(t[r],n[r]);if(a!==0)return a}return 0})}function v(e){return r((t,n)=>{let r=Math.min(t.length,n.length);for(let i=0;i<r;i++){let r=e(t[i],n[i]);if(r!==0)return r}return o(t.length,n.length)})}function y(e){let t=Object.keys(e);return r((n,r)=>{for(let i of t){let t=e[i](n[i],r[i]);if(t!==0)return t}return 0})}const b=e=>t(2,(t,n)=>e(t,n)===-1),x=e=>t(2,(t,n)=>e(t,n)!==1),S=e=>t(2,(t,n)=>e(t,n)===1),C=e=>t(2,(t,n)=>e(t,n)!==-1),w=e=>t(2,(t,n)=>t===n||e(t,n)<1?t:n),T=e=>t(2,(t,n)=>t===n||e(t,n)>-1?t:n),E=e=>t(2,(t,n)=>w(e)(n.maximum,T(e)(n.minimum,t))),D=e=>t(2,(t,n)=>!b(e)(t,n.minimum)&&!S(e)(t,n.maximum)),O=t(2,(e,t)=>{let n=Array.from(e);return n.sort((e,n)=>t(e,n)),n}),k=t(3,(e,t,n)=>{let r=Array.from(e,e=>[e,t(e)]);return r.sort(([,e],[,t])=>n(e,t)),r.map(([e])=>e)}),A=(...e)=>{if(e.length===0)return e=>Array.from(e);let t=g(e);return e=>O(e,t)};export{n as t};
2
+ //# sourceMappingURL=order-VTXpppmI.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"order-BXOBEKvB.mjs","names":["collator"],"sources":["../src/order/order.ts"],"sourcesContent":["/**\n * Ordering combinators and instances for deterministic sorting and comparisons.\n *\n * **Mental model**\n * - `Order<A>` compares two values and returns `-1 | 0 | 1`.\n * - Compose reusable comparators with `by`, `merge`, and `reverse`.\n *\n * **Common tasks**\n * - Use built-ins like `Order.number`, `Order.string`, `Order.date`.\n * - Build custom orders with `Order.make`, `Order.by`, `Order.struct`.\n * - Sort with `Order.sort`, `Order.sortWith`, `Order.sortBy`.\n *\n * **Gotchas**\n * - Orders should be total and stable for predictable sorting.\n * - `Order.merge` uses lexicographic tie-breaking.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const byAge = Order.by(Order.number, (user: { age: number }) => user.age)\n * const sorted = Order.sort([{ age: 2 }, { age: 1 }], byAge)\n * ```\n *\n * @module\n */\nimport { dual } from \"../shared/dual\"\nimport type { Order as OrderType, OrderBounds, Ordering as OrderingType } from \"./order.types\"\n\n/**\n * Re-exported `Order` type.\n *\n * @example\n * ```ts\n * import type { Order } from \"@nicolastoulemont/std\"\n *\n * type Example = Order.Order<unknown>\n * ```\n */\nexport type Order<A> = OrderType<A>\n\n/**\n * Re-exported `Ordering` type.\n *\n * @example\n * ```ts\n * import type { Order } from \"@nicolastoulemont/std\"\n *\n * type Example = Order.Ordering\n * ```\n */\nexport type Ordering = OrderingType\n\n/**\n * Create an `Order` from a comparison function.\n *\n * The created order short-circuits identical references (`===`) to `0`.\n *\n * @param compare - Comparison function returning `-1 | 0 | 1`\n * @returns An order function\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const byLength = Order.make<string>((self, that) =>\n * self.length < that.length ? -1 : self.length > that.length ? 1 : 0,\n * )\n * const result = byLength(\"a\", \"bbb\")\n * // => -1\n * ```\n */\nexport function make<A>(compare: (self: A, that: A) => Ordering): OrderType<A> {\n return (self, that) => (self === that ? 0 : compare(self, that))\n}\n\n/**\n * `Order` instance for strings (lexicographic, case-sensitive).\n *\n * Use `Order.collator` for locale-aware human-facing ordering.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.string(\"a\", \"b\")\n * // => -1\n * ```\n */\nexport const string: OrderType<string> = make((self, that) => (self < that ? -1 : 1))\n\n/**\n * Create a locale-aware `Order` from an `Intl.Collator`.\n *\n * This is intended for human-facing sorting where locale rules matter.\n * Reuse a collator instance when sorting repeatedly.\n *\n * @param collator - Preconfigured collator controlling locale-sensitive ordering\n * @returns A string order normalized to `-1 | 0 | 1`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const collator = new Intl.Collator(\"en\", { numeric: true })\n * const result = Order.collator(collator)(\"2\", \"10\")\n * // => -1\n * ```\n */\nexport function collator(collator: Intl.Collator): OrderType<string> {\n return make((self, that) => {\n const result = collator.compare(self, that)\n return result < 0 ? -1 : result > 0 ? 1 : 0\n })\n}\n\n/**\n * `Order` instance for numbers.\n *\n * - `NaN` equals `NaN`\n * - `NaN` is less than any non-`NaN`\n * - `0` equals `-0`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.number(1, 2)\n * // => -1\n * ```\n */\nexport const number: OrderType<number> = make((self, that) => {\n if (Number.isNaN(self) && Number.isNaN(that)) return 0\n if (Number.isNaN(self)) return -1\n if (Number.isNaN(that)) return 1\n return self < that ? -1 : 1\n})\n\n/**\n * `Order` instance for booleans where `false < true`.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.boolean(false, true)\n * // => -1\n * ```\n */\nexport const boolean: OrderType<boolean> = make((self, that) => (self < that ? -1 : 1))\n\n/**\n * `Order` instance for bigints.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.bigint(1n, 2n)\n * // => -1\n * ```\n */\nexport const bigint: OrderType<bigint> = make((self, that) => (self < that ? -1 : 1))\n\n/**\n * `Order` instance for dates based on `getTime()`.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.date(new Date(\"2024-01-01\"), new Date(\"2024-01-02\"))\n * // => -1\n * ```\n */\nexport const date: OrderType<Date> = make((self, that) => number(self.getTime(), that.getTime()))\n\n/**\n * Create an order that treats all values as equal.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.alwaysEqual<number>()\n * const result = compare(1, 2)\n * // => 0\n * ```\n */\nexport function alwaysEqual<A>(): OrderType<A> {\n return make(() => 0)\n}\n\n/**\n * Reverse an existing order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const desc = Order.reverse(Order.number)\n * const result = desc(1, 2)\n * // => 1\n * ```\n */\nexport function reverse<A>(order: OrderType<A>): OrderType<A> {\n return make((self, that) => order(that, self))\n}\n\n/**\n * Map inputs before comparison.\n *\n * Supports data-first and data-last styles:\n * - `by(order, project)`\n * - `pipe(order, by(project))`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * type User = { age: number }\n * const dataFirst = Order.by(Order.number, (user: User) => user.age)\n * const compareFirst = dataFirst({ age: 1 }, { age: 2 })\n * // => -1\n *\n * const dataLast = Order.by((user: User) => user.age)(Order.number)\n * const compareLast = dataLast({ age: 1 }, { age: 2 })\n * // => -1\n * ```\n */\nexport const by: {\n <B, A>(project: (value: B) => A): (order: OrderType<A>) => OrderType<B>\n <A, B>(order: OrderType<A>, project: (value: B) => A): OrderType<B>\n} = dual(\n 2,\n <A, B>(order: OrderType<A>, project: (value: B) => A): OrderType<B> =>\n make((self, that) => order(project(self), project(that))),\n)\n\nconst mergeBinary = <A>(self: OrderType<A>, that: OrderType<A>): OrderType<A> =>\n make((a, b) => {\n const result = self(a, b)\n if (result !== 0) return result\n return that(a, b)\n })\n\nconst mergeAll = <A>(orders: Iterable<OrderType<A>>): OrderType<A> => {\n const all = Array.from(orders)\n if (all.length === 0) return alwaysEqual()\n if (all.length === 1) return all[0]!\n\n return make((a, b) => {\n for (const order of all) {\n const result = order(a, b)\n if (result !== 0) return result\n }\n return 0\n })\n}\n\nfunction mergeOverload<A>(that: OrderType<A>): (self: OrderType<A>) => OrderType<A>\nfunction mergeOverload<A>(self: OrderType<A>, that: OrderType<A>): OrderType<A>\nfunction mergeOverload<A>(orders: Iterable<OrderType<A>>): OrderType<A>\nfunction mergeOverload<A>(\n selfOrThatOrOrders: OrderType<A> | Iterable<OrderType<A>>,\n that?: OrderType<A>,\n): ((self: OrderType<A>) => OrderType<A>) | OrderType<A> {\n if (that !== undefined) {\n if (typeof selfOrThatOrOrders !== \"function\") {\n throw new TypeError(\"Order.merge(self, that) requires two order functions\")\n }\n return mergeBinary(selfOrThatOrOrders, that)\n }\n\n if (typeof selfOrThatOrOrders === \"function\") {\n return (self: OrderType<A>) => mergeBinary(self, selfOrThatOrOrders)\n }\n\n return mergeAll(selfOrThatOrOrders)\n}\n\n/**\n * Merge orders lexicographically.\n *\n * Supports three forms:\n * - `merge(self, that)`\n * - `merge(that)(self)`\n * - `merge([order1, order2, ...])`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * type User = { first: string; last: string }\n * const byLast = Order.by(Order.string, (user: User) => user.last)\n * const byFirst = Order.by(Order.string, (user: User) => user.first)\n * const compare = Order.merge([byLast, byFirst])({ first: \"Ada\", last: \"Lovelace\" }, { first: \"Alan\", last: \"Turing\" })\n * // => -1\n * ```\n */\nexport const merge: {\n <A>(that: OrderType<A>): (self: OrderType<A>) => OrderType<A>\n <A>(self: OrderType<A>, that: OrderType<A>): OrderType<A>\n <A>(orders: Iterable<OrderType<A>>): OrderType<A>\n} = mergeOverload\n\n/**\n * Create an order for tuples, compared left-to-right.\n */\ntype TupleOrders<Elements extends ReadonlyArray<unknown>> = {\n readonly [K in keyof Elements]: OrderType<Elements[K]>\n}\n\n/**\n * tuple utility.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.tuple([Order.string, Order.number] as const)([\"a\", 1], [\"a\", 2])\n * // => -1\n * ```\n */\nexport function tuple<const Elements extends ReadonlyArray<unknown>>(\n orders: TupleOrders<Elements>,\n): OrderType<Elements> {\n return make((self, that) => {\n for (let i = 0; i < orders.length; i++) {\n const order = orders[i]!\n const result = order(self[i], that[i])\n if (result !== 0) return result\n }\n return 0\n })\n}\n\n/**\n * Create an order for arrays.\n *\n * Arrays are compared element-by-element, then by length when all compared\n * elements are equal.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.array(Order.number)([1, 2], [1, 3])\n * // => -1\n * ```\n */\nexport function array<A>(order: OrderType<A>): OrderType<readonly A[]> {\n return make((self, that) => {\n const minLength = Math.min(self.length, that.length)\n for (let i = 0; i < minLength; i++) {\n const result = order(self[i]!, that[i]!)\n if (result !== 0) return result\n }\n return number(self.length, that.length)\n })\n}\n\n/**\n * Create an order for objects by key order in `fields`.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.struct<{ id: number; name: string }>({\n * id: Order.number,\n * name: Order.string,\n * })({ id: 1, name: \"a\" }, { id: 1, name: \"b\" })\n * // => -1\n * ```\n */\nexport function struct<const R extends Record<string, unknown>>(fields: {\n readonly [K in keyof R]: OrderType<R[K]>\n}): OrderType<R> {\n const keys = Object.keys(fields) as Array<keyof R>\n\n return make((self, that) => {\n for (const key of keys) {\n const result = fields[key](self[key], that[key])\n if (result !== 0) return result\n }\n return 0\n })\n}\n\n/**\n * Test strict less-than using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.lessThan(Order.number)(1, 2)\n * // => true\n * ```\n */\nexport const lessThan = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) === -1)\n\n/**\n * Test less-than-or-equal using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.lessThanOrEqual(Order.number)(2, 2)\n * // => true\n * ```\n */\nexport const lessThanOrEqual = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) !== 1)\n\n/**\n * Test strict greater-than using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.greaterThan(Order.number)(3, 2)\n * // => true\n * ```\n */\nexport const greaterThan = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) === 1)\n\n/**\n * Test greater-than-or-equal using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.greaterThanOrEqual(Order.number)(2, 2)\n * // => true\n * ```\n */\nexport const greaterThanOrEqual = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) !== -1)\n\n/**\n * Get the minimum of two values.\n *\n * If equal, returns the first argument.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const value = Order.min(Order.number)(3, 5)\n * // => 3\n * ```\n */\nexport const min = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => A\n (self: A, that: A): A\n} => dual(2, (self: A, that: A) => (self === that || order(self, that) < 1 ? self : that))\n\n/**\n * Get the maximum of two values.\n *\n * If equal, returns the first argument.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const value = Order.max(Order.number)(3, 5)\n * // => 5\n * ```\n */\nexport const max = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => A\n (self: A, that: A): A\n} => dual(2, (self: A, that: A) => (self === that || order(self, that) > -1 ? self : that))\n\n/**\n * Clamp a value to inclusive bounds.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const value = Order.clamp(Order.number)(7, { minimum: 0, maximum: 5 })\n * // => 5\n * ```\n */\nexport const clamp = <A>(\n order: OrderType<A>,\n): {\n (bounds: OrderBounds<A>): (self: A) => A\n (self: A, bounds: OrderBounds<A>): A\n} => dual(2, (self: A, bounds: OrderBounds<A>): A => min(order)(bounds.maximum, max(order)(bounds.minimum, self)))\n\n/**\n * Check whether a value is within inclusive bounds.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const isBetween = Order.between(Order.number)(3, { minimum: 0, maximum: 5 })\n * // => true\n * ```\n */\nexport const between = <A>(\n order: OrderType<A>,\n): {\n (bounds: OrderBounds<A>): (self: A) => boolean\n (self: A, bounds: OrderBounds<A>): boolean\n} =>\n dual(\n 2,\n (self: A, bounds: OrderBounds<A>): boolean =>\n !lessThan(order)(self, bounds.minimum) && !greaterThan(order)(self, bounds.maximum),\n )\n\n/**\n * Sort an iterable by an order, returning a new array.\n *\n * Supports data-first and data-last styles.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const values = [3, 1, 2]\n * const dataFirst = Order.sort(values, Order.number)\n * // => [1, 2, 3]\n *\n * const dataLast = Order.sort(Order.number)(values)\n * // => [1, 2, 3]\n * ```\n */\nexport const sort: {\n <B>(order: OrderType<B>): <A extends B>(input: Iterable<A>) => A[]\n <A extends B, B>(input: Iterable<A>, order: OrderType<B>): A[]\n} = dual(2, <A extends B, B>(input: Iterable<A>, order: OrderType<B>): A[] => {\n const output = Array.from(input)\n output.sort((self, that) => order(self, that))\n return output\n})\n\n/**\n * Sort an iterable by a projected value.\n *\n * Supports data-first and data-last styles.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const users = [{ age: 2 }, { age: 1 }]\n * const dataFirst = Order.sortWith(users, (user) => user.age, Order.number)\n * // => [{ age: 1 }, { age: 2 }]\n *\n * const dataLast = Order.sortWith((user: { age: number }) => user.age, Order.number)(users)\n * // => [{ age: 1 }, { age: 2 }]\n * ```\n */\nexport const sortWith: {\n <A, B>(project: (value: A) => B, order: OrderType<B>): (input: Iterable<A>) => A[]\n <A, B>(input: Iterable<A>, project: (value: A) => B, order: OrderType<B>): A[]\n} = dual(3, <A, B>(input: Iterable<A>, project: (value: A) => B, order: OrderType<B>): A[] => {\n const output = Array.from(input, (value) => [value, project(value)] as const)\n output.sort(([, a], [, b]) => order(a, b))\n return output.map(([value]) => value)\n})\n\n/**\n * Sort an iterable by multiple orders, in sequence.\n *\n * - first order has highest priority\n * - ties are broken by subsequent orders\n * - no orders returns a shallow copy preserving iteration order\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const users = [{ age: 2, name: \"b\" }, { age: 1, name: \"a\" }]\n * const sorted = Order.sortBy(Order.by(Order.number, (user: { age: number; name: string }) => user.age))(users)\n * // => [{ age: 1, name: \"a\" }, { age: 2, name: \"b\" }]\n * ```\n */\nexport const sortBy = <A>(...orders: readonly OrderType<A>[]) => {\n if (orders.length === 0) {\n return (input: Iterable<A>): A[] => Array.from(input)\n }\n\n const merged = merge(orders)\n return (input: Iterable<A>): A[] => sort(input, merged)\n}\n"],"mappings":"gbA0EA,SAAgB,EAAQ,EAAuD,CAC7E,OAAQ,EAAM,IAAU,IAAS,EAAO,EAAI,EAAQ,EAAM,EAAK,CAgBjE,MAAa,EAA4B,GAAM,EAAM,IAAU,EAAO,EAAO,GAAK,EAAG,CAoBrF,SAAgB,EAAS,EAA4C,CACnE,OAAO,GAAM,EAAM,IAAS,CAC1B,IAAM,EAASA,EAAS,QAAQ,EAAM,EAAK,CAC3C,OAAO,EAAS,EAAI,GAAK,EAAS,EAAI,EAAI,GAC1C,CAkBJ,MAAa,EAA4B,GAAM,EAAM,IAC/C,OAAO,MAAM,EAAK,EAAI,OAAO,MAAM,EAAK,CAAS,EACjD,OAAO,MAAM,EAAK,CAAS,GAC3B,OAAO,MAAM,EAAK,CAAS,EACxB,EAAO,EAAO,GAAK,EAC1B,CAaW,EAA8B,GAAM,EAAM,IAAU,EAAO,EAAO,GAAK,EAAG,CAa1E,EAA4B,GAAM,EAAM,IAAU,EAAO,EAAO,GAAK,EAAG,CAaxE,EAAwB,GAAM,EAAM,IAAS,EAAO,EAAK,SAAS,CAAE,EAAK,SAAS,CAAC,CAAC,CAcjG,SAAgB,GAA+B,CAC7C,OAAO,MAAW,EAAE,CAetB,SAAgB,EAAW,EAAmC,CAC5D,OAAO,GAAM,EAAM,IAAS,EAAM,EAAM,EAAK,CAAC,CAwBhD,MAAa,EAGT,EACF,GACO,EAAqB,IAC1B,GAAM,EAAM,IAAS,EAAM,EAAQ,EAAK,CAAE,EAAQ,EAAK,CAAC,CAAC,CAC5D,CAEK,GAAkB,EAAoB,IAC1C,GAAM,EAAG,IAAM,CACb,IAAM,EAAS,EAAK,EAAG,EAAE,CAEzB,OADI,IAAW,EACR,EAAK,EAAG,EAAE,CADQ,GAEzB,CAEE,EAAe,GAAiD,CACpE,IAAM,EAAM,MAAM,KAAK,EAAO,CAI9B,OAHI,EAAI,SAAW,EAAU,GAAa,CACtC,EAAI,SAAW,EAAU,EAAI,GAE1B,GAAM,EAAG,IAAM,CACpB,IAAK,IAAM,KAAS,EAAK,CACvB,IAAM,EAAS,EAAM,EAAG,EAAE,CAC1B,GAAI,IAAW,EAAG,OAAO,EAE3B,MAAO,IACP,EAMJ,SAAS,EACP,EACA,EACuD,CACvD,GAAI,IAAS,IAAA,GAAW,CACtB,GAAI,OAAO,GAAuB,WAChC,MAAU,UAAU,uDAAuD,CAE7E,OAAO,EAAY,EAAoB,EAAK,CAO9C,OAJI,OAAO,GAAuB,WACxB,GAAuB,EAAY,EAAM,EAAmB,CAG/D,EAAS,EAAmB,CAsBrC,MAAa,EAIT,EAoBJ,SAAgB,EACd,EACqB,CACrB,OAAO,GAAM,EAAM,IAAS,CAC1B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,OAAQ,IAAK,CACtC,IAAM,EAAQ,EAAO,GACf,EAAS,EAAM,EAAK,GAAI,EAAK,GAAG,CACtC,GAAI,IAAW,EAAG,OAAO,EAE3B,MAAO,IACP,CAiBJ,SAAgB,EAAS,EAA8C,CACrE,OAAO,GAAM,EAAM,IAAS,CAC1B,IAAM,EAAY,KAAK,IAAI,EAAK,OAAQ,EAAK,OAAO,CACpD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,IAAK,CAClC,IAAM,EAAS,EAAM,EAAK,GAAK,EAAK,GAAI,CACxC,GAAI,IAAW,EAAG,OAAO,EAE3B,OAAO,EAAO,EAAK,OAAQ,EAAK,OAAO,EACvC,CAiBJ,SAAgB,EAAgD,EAE/C,CACf,IAAM,EAAO,OAAO,KAAK,EAAO,CAEhC,OAAO,GAAM,EAAM,IAAS,CAC1B,IAAK,IAAM,KAAO,EAAM,CACtB,IAAM,EAAS,EAAO,GAAK,EAAK,GAAM,EAAK,GAAK,CAChD,GAAI,IAAW,EAAG,OAAO,EAE3B,MAAO,IACP,CAcJ,MAAa,EACX,GAIG,EAAK,GAAI,EAAS,IAAY,EAAM,EAAM,EAAK,GAAK,GAAG,CAa/C,EACX,GAIG,EAAK,GAAI,EAAS,IAAY,EAAM,EAAM,EAAK,GAAK,EAAE,CAa9C,EACX,GAIG,EAAK,GAAI,EAAS,IAAY,EAAM,EAAM,EAAK,GAAK,EAAE,CAa9C,EACX,GAIG,EAAK,GAAI,EAAS,IAAY,EAAM,EAAM,EAAK,GAAK,GAAG,CAe/C,EACX,GAIG,EAAK,GAAI,EAAS,IAAa,IAAS,GAAQ,EAAM,EAAM,EAAK,CAAG,EAAI,EAAO,EAAM,CAe7E,EACX,GAIG,EAAK,GAAI,EAAS,IAAa,IAAS,GAAQ,EAAM,EAAM,EAAK,CAAG,GAAK,EAAO,EAAM,CAa9E,EACX,GAIG,EAAK,GAAI,EAAS,IAA8B,EAAI,EAAM,CAAC,EAAO,QAAS,EAAI,EAAM,CAAC,EAAO,QAAS,EAAK,CAAC,CAAC,CAarG,EACX,GAKA,EACE,GACC,EAAS,IACR,CAAC,EAAS,EAAM,CAAC,EAAM,EAAO,QAAQ,EAAI,CAAC,EAAY,EAAM,CAAC,EAAM,EAAO,QAAQ,CACtF,CAmBU,EAGT,EAAK,GAAoB,EAAoB,IAA6B,CAC5E,IAAM,EAAS,MAAM,KAAK,EAAM,CAEhC,OADA,EAAO,MAAM,EAAM,IAAS,EAAM,EAAM,EAAK,CAAC,CACvC,GACP,CAmBW,EAGT,EAAK,GAAU,EAAoB,EAA0B,IAA6B,CAC5F,IAAM,EAAS,MAAM,KAAK,EAAQ,GAAU,CAAC,EAAO,EAAQ,EAAM,CAAC,CAAU,CAE7E,OADA,EAAO,MAAM,EAAG,GAAI,EAAG,KAAO,EAAM,EAAG,EAAE,CAAC,CACnC,EAAO,KAAK,CAAC,KAAW,EAAM,EACrC,CAkBW,GAAa,GAAG,IAAoC,CAC/D,GAAI,EAAO,SAAW,EACpB,MAAQ,IAA4B,MAAM,KAAK,EAAM,CAGvD,IAAM,EAAS,EAAM,EAAO,CAC5B,MAAQ,IAA4B,EAAK,EAAO,EAAO"}
1
+ {"version":3,"file":"order-VTXpppmI.mjs","names":["collator"],"sources":["../src/order/order.ts"],"sourcesContent":["/**\n * Ordering combinators and instances for deterministic sorting and comparisons.\n *\n * **Mental model**\n * - `Order<A>` compares two values and returns `-1 | 0 | 1`.\n * - Compose reusable comparators with `by`, `merge`, and `reverse`.\n *\n * **Common tasks**\n * - Use built-ins like `Order.number`, `Order.string`, `Order.date`.\n * - Build custom orders with `Order.make`, `Order.by`, `Order.struct`.\n * - Sort with `Order.sort`, `Order.sortWith`, `Order.sortBy`.\n *\n * **Gotchas**\n * - Orders should be total and stable for predictable sorting.\n * - `Order.merge` uses lexicographic tie-breaking.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const byAge = Order.by(Order.number, (user: { age: number }) => user.age)\n * const sorted = Order.sort([{ age: 2 }, { age: 1 }], byAge)\n * ```\n *\n * @module\n */\nimport { dual } from \"../shared/dual\"\nimport type { Order as OrderType, OrderBounds, Ordering as OrderingType } from \"./order.types\"\n\n/**\n * Re-exported `Order` type.\n *\n * @example\n * ```ts\n * import type { Order } from \"@nicolastoulemont/std\"\n *\n * type Example = Order.Order<unknown>\n * ```\n */\nexport type Order<A> = OrderType<A>\n\n/**\n * Re-exported `Ordering` type.\n *\n * @example\n * ```ts\n * import type { Order } from \"@nicolastoulemont/std\"\n *\n * type Example = Order.Ordering\n * ```\n */\nexport type Ordering = OrderingType\n\n/**\n * Create an `Order` from a comparison function.\n *\n * The created order short-circuits identical references (`===`) to `0`.\n *\n * @param compare - Comparison function returning `-1 | 0 | 1`\n * @returns An order function\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const byLength = Order.make<string>((self, that) =>\n * self.length < that.length ? -1 : self.length > that.length ? 1 : 0,\n * )\n * const result = byLength(\"a\", \"bbb\")\n * // => -1\n * ```\n */\nexport function make<A>(compare: (self: A, that: A) => Ordering): OrderType<A> {\n return (self, that) => (self === that ? 0 : compare(self, that))\n}\n\n/**\n * `Order` instance for strings (lexicographic, case-sensitive).\n *\n * Use `Order.collator` for locale-aware human-facing ordering.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.string(\"a\", \"b\")\n * // => -1\n * ```\n */\nexport const string: OrderType<string> = make((self, that) => (self < that ? -1 : 1))\n\n/**\n * Create a locale-aware `Order` from an `Intl.Collator`.\n *\n * This is intended for human-facing sorting where locale rules matter.\n * Reuse a collator instance when sorting repeatedly.\n *\n * @param collator - Preconfigured collator controlling locale-sensitive ordering\n * @returns A string order normalized to `-1 | 0 | 1`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const collator = new Intl.Collator(\"en\", { numeric: true })\n * const result = Order.collator(collator)(\"2\", \"10\")\n * // => -1\n * ```\n */\nexport function collator(collator: Intl.Collator): OrderType<string> {\n return make((self, that) => {\n const result = collator.compare(self, that)\n return result < 0 ? -1 : result > 0 ? 1 : 0\n })\n}\n\n/**\n * `Order` instance for numbers.\n *\n * - `NaN` equals `NaN`\n * - `NaN` is less than any non-`NaN`\n * - `0` equals `-0`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.number(1, 2)\n * // => -1\n * ```\n */\nexport const number: OrderType<number> = make((self, that) => {\n if (Number.isNaN(self) && Number.isNaN(that)) return 0\n if (Number.isNaN(self)) return -1\n if (Number.isNaN(that)) return 1\n return self < that ? -1 : 1\n})\n\n/**\n * `Order` instance for booleans where `false < true`.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.boolean(false, true)\n * // => -1\n * ```\n */\nexport const boolean: OrderType<boolean> = make((self, that) => (self < that ? -1 : 1))\n\n/**\n * `Order` instance for bigints.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.bigint(1n, 2n)\n * // => -1\n * ```\n */\nexport const bigint: OrderType<bigint> = make((self, that) => (self < that ? -1 : 1))\n\n/**\n * `Order` instance for dates based on `getTime()`.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.date(new Date(\"2024-01-01\"), new Date(\"2024-01-02\"))\n * // => -1\n * ```\n */\nexport const date: OrderType<Date> = make((self, that) => number(self.getTime(), that.getTime()))\n\n/**\n * Create an order that treats all values as equal.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.alwaysEqual<number>()\n * const result = compare(1, 2)\n * // => 0\n * ```\n */\nexport function alwaysEqual<A>(): OrderType<A> {\n return make(() => 0)\n}\n\n/**\n * Reverse an existing order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const desc = Order.reverse(Order.number)\n * const result = desc(1, 2)\n * // => 1\n * ```\n */\nexport function reverse<A>(order: OrderType<A>): OrderType<A> {\n return make((self, that) => order(that, self))\n}\n\n/**\n * Map inputs before comparison.\n *\n * Supports data-first and data-last styles:\n * - `by(order, project)`\n * - `pipe(order, by(project))`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * type User = { age: number }\n * const dataFirst = Order.by(Order.number, (user: User) => user.age)\n * const compareFirst = dataFirst({ age: 1 }, { age: 2 })\n * // => -1\n *\n * const dataLast = Order.by((user: User) => user.age)(Order.number)\n * const compareLast = dataLast({ age: 1 }, { age: 2 })\n * // => -1\n * ```\n */\nexport const by: {\n <B, A>(project: (value: B) => A): (order: OrderType<A>) => OrderType<B>\n <A, B>(order: OrderType<A>, project: (value: B) => A): OrderType<B>\n} = dual(\n 2,\n <A, B>(order: OrderType<A>, project: (value: B) => A): OrderType<B> =>\n make((self, that) => order(project(self), project(that))),\n)\n\nconst mergeBinary = <A>(self: OrderType<A>, that: OrderType<A>): OrderType<A> =>\n make((a, b) => {\n const result = self(a, b)\n if (result !== 0) return result\n return that(a, b)\n })\n\nconst mergeAll = <A>(orders: Iterable<OrderType<A>>): OrderType<A> => {\n const all = Array.from(orders)\n if (all.length === 0) return alwaysEqual()\n if (all.length === 1) return all[0]!\n\n return make((a, b) => {\n for (const order of all) {\n const result = order(a, b)\n if (result !== 0) return result\n }\n return 0\n })\n}\n\nfunction mergeOverload<A>(that: OrderType<A>): (self: OrderType<A>) => OrderType<A>\nfunction mergeOverload<A>(self: OrderType<A>, that: OrderType<A>): OrderType<A>\nfunction mergeOverload<A>(orders: Iterable<OrderType<A>>): OrderType<A>\nfunction mergeOverload<A>(\n selfOrThatOrOrders: OrderType<A> | Iterable<OrderType<A>>,\n that?: OrderType<A>,\n): ((self: OrderType<A>) => OrderType<A>) | OrderType<A> {\n if (that !== undefined) {\n if (typeof selfOrThatOrOrders !== \"function\") {\n throw new TypeError(\"Order.merge(self, that) requires two order functions\")\n }\n return mergeBinary(selfOrThatOrOrders, that)\n }\n\n if (typeof selfOrThatOrOrders === \"function\") {\n return (self: OrderType<A>) => mergeBinary(self, selfOrThatOrOrders)\n }\n\n return mergeAll(selfOrThatOrOrders)\n}\n\n/**\n * Merge orders lexicographically.\n *\n * Supports three forms:\n * - `merge(self, that)`\n * - `merge(that)(self)`\n * - `merge([order1, order2, ...])`\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * type User = { first: string; last: string }\n * const byLast = Order.by(Order.string, (user: User) => user.last)\n * const byFirst = Order.by(Order.string, (user: User) => user.first)\n * const compare = Order.merge([byLast, byFirst])({ first: \"Ada\", last: \"Lovelace\" }, { first: \"Alan\", last: \"Turing\" })\n * // => -1\n * ```\n */\nexport const merge: {\n <A>(that: OrderType<A>): (self: OrderType<A>) => OrderType<A>\n <A>(self: OrderType<A>, that: OrderType<A>): OrderType<A>\n <A>(orders: Iterable<OrderType<A>>): OrderType<A>\n} = mergeOverload\n\n/**\n * Create an order for tuples, compared left-to-right.\n */\ntype TupleOrders<Elements extends ReadonlyArray<unknown>> = {\n readonly [K in keyof Elements]: OrderType<Elements[K]>\n}\n\n/**\n * tuple utility.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.tuple([Order.string, Order.number] as const)([\"a\", 1], [\"a\", 2])\n * // => -1\n * ```\n */\nexport function tuple<const Elements extends ReadonlyArray<unknown>>(\n orders: TupleOrders<Elements>,\n): OrderType<Elements> {\n return make((self, that) => {\n for (let i = 0; i < orders.length; i++) {\n const order = orders[i]!\n const result = order(self[i], that[i])\n if (result !== 0) return result\n }\n return 0\n })\n}\n\n/**\n * Create an order for arrays.\n *\n * Arrays are compared element-by-element, then by length when all compared\n * elements are equal.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.array(Order.number)([1, 2], [1, 3])\n * // => -1\n * ```\n */\nexport function array<A>(order: OrderType<A>): OrderType<readonly A[]> {\n return make((self, that) => {\n const minLength = Math.min(self.length, that.length)\n for (let i = 0; i < minLength; i++) {\n const result = order(self[i]!, that[i]!)\n if (result !== 0) return result\n }\n return number(self.length, that.length)\n })\n}\n\n/**\n * Create an order for objects by key order in `fields`.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const compare = Order.struct<{ id: number; name: string }>({\n * id: Order.number,\n * name: Order.string,\n * })({ id: 1, name: \"a\" }, { id: 1, name: \"b\" })\n * // => -1\n * ```\n */\nexport function struct<const R extends Record<string, unknown>>(fields: {\n readonly [K in keyof R]: OrderType<R[K]>\n}): OrderType<R> {\n const keys = Object.keys(fields) as Array<keyof R>\n\n return make((self, that) => {\n for (const key of keys) {\n const result = fields[key](self[key], that[key])\n if (result !== 0) return result\n }\n return 0\n })\n}\n\n/**\n * Test strict less-than using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.lessThan(Order.number)(1, 2)\n * // => true\n * ```\n */\nexport const lessThan = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) === -1)\n\n/**\n * Test less-than-or-equal using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.lessThanOrEqual(Order.number)(2, 2)\n * // => true\n * ```\n */\nexport const lessThanOrEqual = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) !== 1)\n\n/**\n * Test strict greater-than using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.greaterThan(Order.number)(3, 2)\n * // => true\n * ```\n */\nexport const greaterThan = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) === 1)\n\n/**\n * Test greater-than-or-equal using an order.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const result = Order.greaterThanOrEqual(Order.number)(2, 2)\n * // => true\n * ```\n */\nexport const greaterThanOrEqual = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => boolean\n (self: A, that: A): boolean\n} => dual(2, (self: A, that: A) => order(self, that) !== -1)\n\n/**\n * Get the minimum of two values.\n *\n * If equal, returns the first argument.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const value = Order.min(Order.number)(3, 5)\n * // => 3\n * ```\n */\nexport const min = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => A\n (self: A, that: A): A\n} => dual(2, (self: A, that: A) => (self === that || order(self, that) < 1 ? self : that))\n\n/**\n * Get the maximum of two values.\n *\n * If equal, returns the first argument.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const value = Order.max(Order.number)(3, 5)\n * // => 5\n * ```\n */\nexport const max = <A>(\n order: OrderType<A>,\n): {\n (that: A): (self: A) => A\n (self: A, that: A): A\n} => dual(2, (self: A, that: A) => (self === that || order(self, that) > -1 ? self : that))\n\n/**\n * Clamp a value to inclusive bounds.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const value = Order.clamp(Order.number)(7, { minimum: 0, maximum: 5 })\n * // => 5\n * ```\n */\nexport const clamp = <A>(\n order: OrderType<A>,\n): {\n (bounds: OrderBounds<A>): (self: A) => A\n (self: A, bounds: OrderBounds<A>): A\n} => dual(2, (self: A, bounds: OrderBounds<A>): A => min(order)(bounds.maximum, max(order)(bounds.minimum, self)))\n\n/**\n * Check whether a value is within inclusive bounds.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const isBetween = Order.between(Order.number)(3, { minimum: 0, maximum: 5 })\n * // => true\n * ```\n */\nexport const between = <A>(\n order: OrderType<A>,\n): {\n (bounds: OrderBounds<A>): (self: A) => boolean\n (self: A, bounds: OrderBounds<A>): boolean\n} =>\n dual(\n 2,\n (self: A, bounds: OrderBounds<A>): boolean =>\n !lessThan(order)(self, bounds.minimum) && !greaterThan(order)(self, bounds.maximum),\n )\n\n/**\n * Sort an iterable by an order, returning a new array.\n *\n * Supports data-first and data-last styles.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const values = [3, 1, 2]\n * const dataFirst = Order.sort(values, Order.number)\n * // => [1, 2, 3]\n *\n * const dataLast = Order.sort(Order.number)(values)\n * // => [1, 2, 3]\n * ```\n */\nexport const sort: {\n <B>(order: OrderType<B>): <A extends B>(input: Iterable<A>) => A[]\n <A extends B, B>(input: Iterable<A>, order: OrderType<B>): A[]\n} = dual(2, <A extends B, B>(input: Iterable<A>, order: OrderType<B>): A[] => {\n const output = Array.from(input)\n output.sort((self, that) => order(self, that))\n return output\n})\n\n/**\n * Sort an iterable by a projected value.\n *\n * Supports data-first and data-last styles.\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const users = [{ age: 2 }, { age: 1 }]\n * const dataFirst = Order.sortWith(users, (user) => user.age, Order.number)\n * // => [{ age: 1 }, { age: 2 }]\n *\n * const dataLast = Order.sortWith((user: { age: number }) => user.age, Order.number)(users)\n * // => [{ age: 1 }, { age: 2 }]\n * ```\n */\nexport const sortWith: {\n <A, B>(project: (value: A) => B, order: OrderType<B>): (input: Iterable<A>) => A[]\n <A, B>(input: Iterable<A>, project: (value: A) => B, order: OrderType<B>): A[]\n} = dual(3, <A, B>(input: Iterable<A>, project: (value: A) => B, order: OrderType<B>): A[] => {\n const output = Array.from(input, (value) => [value, project(value)] as const)\n output.sort(([, a], [, b]) => order(a, b))\n return output.map(([value]) => value)\n})\n\n/**\n * Sort an iterable by multiple orders, in sequence.\n *\n * - first order has highest priority\n * - ties are broken by subsequent orders\n * - no orders returns a shallow copy preserving iteration order\n *\n * @example\n * ```ts\n * import { Order } from \"@nicolastoulemont/std\"\n *\n * const users = [{ age: 2, name: \"b\" }, { age: 1, name: \"a\" }]\n * const sorted = Order.sortBy(Order.by(Order.number, (user: { age: number; name: string }) => user.age))(users)\n * // => [{ age: 1, name: \"a\" }, { age: 2, name: \"b\" }]\n * ```\n */\nexport const sortBy = <A>(...orders: readonly OrderType<A>[]) => {\n if (orders.length === 0) {\n return (input: Iterable<A>): A[] => Array.from(input)\n }\n\n const merged = merge(orders)\n return (input: Iterable<A>): A[] => sort(input, merged)\n}\n"],"mappings":"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"}
@@ -17,4 +17,4 @@ type Pipeable = {
17
17
  };
18
18
  //#endregion
19
19
  export { Pipeable as t };
20
- //# sourceMappingURL=pipeable-BIrevC0D.d.mts.map
20
+ //# sourceMappingURL=pipeable-BY9yPsNK.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeable-BIrevC0D.d.mts","names":[],"sources":["../src/shared/pipeable.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"pipeable-BY9yPsNK.d.mts","names":[],"sources":["../src/shared/pipeable.ts"],"sourcesContent":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./flow-D8_tllWl.mjs";function t(...t){return t.length===0?this:e(...t)(this)}export{t};
2
+ //# sourceMappingURL=pipeable-COGyGMUV.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeable-Dp1_23zH.mjs","names":[],"sources":["../src/shared/pipeable.ts"],"sourcesContent":["import { flow } from \"../functions/flow\"\n\n/**\n * Pipeable interface for fluent method chaining.\n * Enables: value.pipe(fn1, fn2, fn3) as alternative to pipe(value, fn1, fn2, fn3)\n */\nexport type Pipeable = {\n pipe<A>(this: A): A\n pipe<A, B>(this: A, ab: (a: A) => B): B\n pipe<A, B, C>(this: A, ab: (a: A) => B, bc: (b: B) => C): C\n pipe<A, B, C, D>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D\n pipe<A, B, C, D, E>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E\n pipe<A, B, C, D, E, F>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n ): F\n pipe<A, B, C, D, E, F, G>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n ): G\n pipe<A, B, C, D, E, F, G, H>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n ): H\n pipe<A, B, C, D, E, F, G, H, I>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ): I\n pipe<A, B, C, D, E, F, G, H, I, J>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n ): J\n}\n\ntype UnaryFn = (arg: unknown) => unknown\n\n/**\n * Create a pipe method implementation.\n * Returns a function that pipes the value through provided functions.\n * This is designed to be used as an object method, so it uses `this` binding.\n */\n// oxlint-disable no-explicit-any, no-this-in-exported-function\nexport function pipeable<A>(this: A, ...fns: UnaryFn[]): any {\n if (fns.length === 0) return this\n // oxlint-disable-next-line no-unsafe-return, no-unsafe-call, no-unsafe-type-assertion\n return (flow as any)(...fns)(this)\n}\n// oxlint-enable no-explicit-any, no-this-in-exported-function\n"],"mappings":"wCAwEA,SAAgB,EAAqB,GAAG,EAAqB,CAG3D,OAFI,EAAI,SAAW,EAAU,KAErB,EAAa,GAAG,EAAI,CAAC,KAAK"}
1
+ {"version":3,"file":"pipeable-COGyGMUV.mjs","names":[],"sources":["../src/shared/pipeable.ts"],"sourcesContent":["import { flow } from \"../functions/flow\"\n\n/**\n * Pipeable interface for fluent method chaining.\n * Enables: value.pipe(fn1, fn2, fn3) as alternative to pipe(value, fn1, fn2, fn3)\n */\nexport type Pipeable = {\n pipe<A>(this: A): A\n pipe<A, B>(this: A, ab: (a: A) => B): B\n pipe<A, B, C>(this: A, ab: (a: A) => B, bc: (b: B) => C): C\n pipe<A, B, C, D>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D\n pipe<A, B, C, D, E>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E\n pipe<A, B, C, D, E, F>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n ): F\n pipe<A, B, C, D, E, F, G>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n ): G\n pipe<A, B, C, D, E, F, G, H>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n ): H\n pipe<A, B, C, D, E, F, G, H, I>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ): I\n pipe<A, B, C, D, E, F, G, H, I, J>(\n this: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n ): J\n}\n\ntype UnaryFn = (arg: unknown) => unknown\n\n/**\n * Create a pipe method implementation.\n * Returns a function that pipes the value through provided functions.\n * This is designed to be used as an object method, so it uses `this` binding.\n */\n// oxlint-disable no-explicit-any, no-this-in-exported-function\nexport function pipeable<A>(this: A, ...fns: UnaryFn[]): any {\n if (fns.length === 0) return this\n // oxlint-disable-next-line no-unsafe-return, no-unsafe-call, no-unsafe-type-assertion\n return (flow as any)(...fns)(this)\n}\n// oxlint-enable no-explicit-any, no-this-in-exported-function\n"],"mappings":"wCAwEA,SAAgB,EAAqB,GAAG,EAAqB,CAG3D,OAFI,EAAI,SAAW,EAAU,KAErB,EAAa,GAAG,EAAI,CAAC,KAAK"}
@@ -1,2 +1,2 @@
1
- import { t as predicate_d_exports } from "../index-CNTYbcY9.mjs";
1
+ import { t as predicate_d_exports } from "../index-BZ1-IrU_.mjs";
2
2
  export { predicate_d_exports as Predicate };
@@ -1 +1 @@
1
- import{t as e}from"../predicate-D_1SsIi4.mjs";export{e as Predicate};
1
+ import{t as e}from"../predicate-8hY-0Ocv.mjs";export{e as Predicate};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./chunk-oQKkju2G.mjs";var t=e({all:()=>a,and:()=>r,andRefinement:()=>c,constant:()=>u,equals:()=>d,none:()=>s,not:()=>n,or:()=>i,orRefinement:()=>l,some:()=>o});const n=e=>t=>!e(t),r=(...e)=>t=>{for(let n of e)if(!n(t))return!1;return!0},i=(...e)=>t=>{for(let n of e)if(n(t))return!0;return!1},a=e=>t=>t.every(e),o=e=>t=>t.some(e),s=e=>t=>!t.some(e),c=(...e)=>t=>{for(let n of e)if(!n(t))return!1;return!0},l=(...e)=>t=>{for(let n of e)if(n(t))return!0;return!1},u=e=>()=>e,d=e=>t=>t===e;export{t};
2
- //# sourceMappingURL=predicate-D_1SsIi4.mjs.map
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";var t=e({all:()=>a,and:()=>r,andRefinement:()=>c,constant:()=>u,equals:()=>d,none:()=>s,not:()=>n,or:()=>i,orRefinement:()=>l,some:()=>o});const n=e=>t=>!e(t),r=(...e)=>t=>{for(let n of e)if(!n(t))return!1;return!0},i=(...e)=>t=>{for(let n of e)if(n(t))return!0;return!1},a=e=>t=>t.every(e),o=e=>t=>t.some(e),s=e=>t=>!t.some(e),c=(...e)=>t=>{for(let n of e)if(!n(t))return!1;return!0},l=(...e)=>t=>{for(let n of e)if(n(t))return!0;return!1},u=e=>()=>e,d=e=>t=>t===e;export{t};
2
+ //# sourceMappingURL=predicate-8hY-0Ocv.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"predicate-D_1SsIi4.mjs","names":[],"sources":["../src/predicate/predicate.ts"],"sourcesContent":["import type { Predicate as PredicateType, Refinement } from \"./predicate.types\"\n\n/**\n * Negate a predicate.\n * Returns true when the original predicate returns false, and vice versa.\n *\n * @template T - The type being tested\n * @param predicate - The predicate to negate\n * @returns A new predicate that returns the opposite boolean\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isOdd = Predicate.not((n: number) => n % 2 === 0)\n * const result = isOdd(3)\n * // => true\n * ```\n */\nexport const not = <T>(predicate: PredicateType<T>): PredicateType<T> => {\n return (value: T): boolean => !predicate(value)\n}\n\n/**\n * Combine predicates with logical AND.\n * Returns true only when ALL predicates return true.\n * Short-circuits on first false (lazy evaluation).\n *\n * @template T - The type being tested\n * @param predicates - The predicates to combine\n * @returns A new predicate that returns true if all predicates pass\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isPositiveEven = Predicate.and<number>((n) => n > 0, (n) => n % 2 === 0)\n * const result = isPositiveEven(4)\n * // => true\n * ```\n */\nexport const and = <T>(...predicates: readonly PredicateType<T>[]): PredicateType<T> => {\n return (value: T): boolean => {\n for (const predicate of predicates) {\n if (!predicate(value)) return false\n }\n return true\n }\n}\n\n/**\n * Combine predicates with logical OR.\n * Returns true when ANY predicate returns true.\n * Short-circuits on first true (lazy evaluation).\n *\n * @template T - The type being tested\n * @param predicates - The predicates to combine\n * @returns A new predicate that returns true if any predicate passes\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isWeekend = Predicate.or<string>((day) => day === \"sat\", (day) => day === \"sun\")\n * const result = isWeekend(\"sun\")\n * // => true\n * ```\n */\nexport const or = <T>(...predicates: readonly PredicateType<T>[]): PredicateType<T> => {\n return (value: T): boolean => {\n for (const predicate of predicates) {\n if (predicate(value)) return true\n }\n return false\n }\n}\n\n/**\n * Create a predicate that tests if ALL elements in an array match.\n * Returns true for empty arrays (vacuous truth).\n *\n * @template T - The element type\n * @param predicate - The predicate to test each element\n * @returns A predicate that takes an array and returns true if all match\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const allPositive = Predicate.all((n: number) => n > 0)\n * const result = allPositive([1, 2, 3])\n * // => true\n * ```\n */\nexport const all = <T>(predicate: PredicateType<T>): PredicateType<readonly T[]> => {\n return (arr: readonly T[]): boolean => arr.every(predicate)\n}\n\n/**\n * Create a predicate that tests if ANY element in an array matches.\n * Returns false for empty arrays.\n *\n * @template T - The element type\n * @param predicate - The predicate to test each element\n * @returns A predicate that takes an array and returns true if any match\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const someNegative = Predicate.some((n: number) => n < 0)\n * const result = someNegative([1, -1, 3])\n * // => true\n * ```\n */\nexport const some = <T>(predicate: PredicateType<T>): PredicateType<readonly T[]> => {\n return (arr: readonly T[]): boolean => arr.some(predicate)\n}\n\n/**\n * Create a predicate that tests if NO elements in an array match.\n * Returns true for empty arrays (vacuous truth).\n * Equivalent to `not(some(predicate))`.\n *\n * @template T - The element type\n * @param predicate - The predicate that should NOT match any element\n * @returns A predicate that takes an array and returns true if none match\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const noneZero = Predicate.none((n: number) => n === 0)\n * const result = noneZero([1, 2, 3])\n * // => true\n * ```\n */\nexport const none = <T>(predicate: PredicateType<T>): PredicateType<readonly T[]> => {\n return (arr: readonly T[]): boolean => !arr.some(predicate)\n}\n\n/**\n * Combine refinements with logical AND, preserving type narrowing.\n * Use this instead of `and` when you need to preserve type guard behavior.\n *\n * @template T - The base type\n * @template U - The narrowed type (must extend T)\n * @param refinements - The refinements to combine\n * @returns A refinement that narrows to U if all refinements pass\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isString = (value: unknown): value is string => typeof value === \"string\"\n * const isNonEmpty = (value: unknown): value is string => typeof value === \"string\" && value.length > 0\n * const refine = Predicate.andRefinement(isString, isNonEmpty)\n * const result = refine(\"hello\")\n * // => true\n * ```\n */\nexport const andRefinement = <T, U extends T>(...refinements: readonly Refinement<T, U>[]): Refinement<T, U> => {\n return (value: T): value is U => {\n for (const refinement of refinements) {\n if (!refinement(value)) return false\n }\n return true\n }\n}\n\n/**\n * Combine refinements with logical OR, preserving type narrowing.\n * Use this instead of `or` when you need to preserve type guard behavior.\n *\n * @template T - The base type\n * @template U - The narrowed type (must extend T)\n * @param refinements - The refinements to combine\n * @returns A refinement that narrows to U if any refinement passes\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isGuest = (value: unknown): value is string => value === \"guest\"\n * const isAdmin = (value: unknown): value is string => value === \"admin\"\n * const refine = Predicate.orRefinement(isGuest, isAdmin)\n * const result = refine(\"admin\")\n * // => true\n * ```\n */\nexport const orRefinement = <T, U extends T>(...refinements: readonly Refinement<T, U>[]): Refinement<T, U> => {\n return (value: T): value is U => {\n for (const refinement of refinements) {\n if (refinement(value)) return true\n }\n return false\n }\n}\n\n/**\n * Create a predicate from a constant boolean value.\n * Useful for testing or as a placeholder.\n *\n * @template T - The type (can be anything)\n * @param value - The constant boolean to return\n * @returns A predicate that always returns the given value\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const always = Predicate.constant<number>(true)\n * const result = always(123)\n * // => true\n * ```\n */\nexport const constant = <T>(value: boolean): PredicateType<T> => {\n return (): boolean => value\n}\n\n/**\n * Create a predicate that checks strict equality.\n *\n * @template T - The type being compared\n * @param expected - The value to compare against\n * @returns A predicate that returns true if value === expected\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isReady = Predicate.equals(\"ready\")\n * const result = isReady(\"ready\")\n * // => true\n * ```\n */\nexport const equals = <T>(expected: T): PredicateType<T> => {\n return (value: T): boolean => value === expected\n}\n"],"mappings":"oLAmBA,MAAa,EAAU,GACb,GAAsB,CAAC,EAAU,EAAM,CAqBpC,GAAU,GAAG,IAChB,GAAsB,CAC5B,IAAK,IAAM,KAAa,EACtB,GAAI,CAAC,EAAU,EAAM,CAAE,MAAO,GAEhC,MAAO,IAsBE,GAAS,GAAG,IACf,GAAsB,CAC5B,IAAK,IAAM,KAAa,EACtB,GAAI,EAAU,EAAM,CAAE,MAAO,GAE/B,MAAO,IAqBE,EAAU,GACb,GAA+B,EAAI,MAAM,EAAU,CAoBhD,EAAW,GACd,GAA+B,EAAI,KAAK,EAAU,CAqB/C,EAAW,GACd,GAA+B,CAAC,EAAI,KAAK,EAAU,CAuBhD,GAAiC,GAAG,IACvC,GAAyB,CAC/B,IAAK,IAAM,KAAc,EACvB,GAAI,CAAC,EAAW,EAAM,CAAE,MAAO,GAEjC,MAAO,IAwBE,GAAgC,GAAG,IACtC,GAAyB,CAC/B,IAAK,IAAM,KAAc,EACvB,GAAI,EAAW,EAAM,CAAE,MAAO,GAEhC,MAAO,IAqBE,EAAe,OACJ,EAmBX,EAAa,GAChB,GAAsB,IAAU"}
1
+ {"version":3,"file":"predicate-8hY-0Ocv.mjs","names":[],"sources":["../src/predicate/predicate.ts"],"sourcesContent":["import type { Predicate as PredicateType, Refinement } from \"./predicate.types\"\n\n/**\n * Negate a predicate.\n * Returns true when the original predicate returns false, and vice versa.\n *\n * @template T - The type being tested\n * @param predicate - The predicate to negate\n * @returns A new predicate that returns the opposite boolean\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isOdd = Predicate.not((n: number) => n % 2 === 0)\n * const result = isOdd(3)\n * // => true\n * ```\n */\nexport const not = <T>(predicate: PredicateType<T>): PredicateType<T> => {\n return (value: T): boolean => !predicate(value)\n}\n\n/**\n * Combine predicates with logical AND.\n * Returns true only when ALL predicates return true.\n * Short-circuits on first false (lazy evaluation).\n *\n * @template T - The type being tested\n * @param predicates - The predicates to combine\n * @returns A new predicate that returns true if all predicates pass\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isPositiveEven = Predicate.and<number>((n) => n > 0, (n) => n % 2 === 0)\n * const result = isPositiveEven(4)\n * // => true\n * ```\n */\nexport const and = <T>(...predicates: readonly PredicateType<T>[]): PredicateType<T> => {\n return (value: T): boolean => {\n for (const predicate of predicates) {\n if (!predicate(value)) return false\n }\n return true\n }\n}\n\n/**\n * Combine predicates with logical OR.\n * Returns true when ANY predicate returns true.\n * Short-circuits on first true (lazy evaluation).\n *\n * @template T - The type being tested\n * @param predicates - The predicates to combine\n * @returns A new predicate that returns true if any predicate passes\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isWeekend = Predicate.or<string>((day) => day === \"sat\", (day) => day === \"sun\")\n * const result = isWeekend(\"sun\")\n * // => true\n * ```\n */\nexport const or = <T>(...predicates: readonly PredicateType<T>[]): PredicateType<T> => {\n return (value: T): boolean => {\n for (const predicate of predicates) {\n if (predicate(value)) return true\n }\n return false\n }\n}\n\n/**\n * Create a predicate that tests if ALL elements in an array match.\n * Returns true for empty arrays (vacuous truth).\n *\n * @template T - The element type\n * @param predicate - The predicate to test each element\n * @returns A predicate that takes an array and returns true if all match\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const allPositive = Predicate.all((n: number) => n > 0)\n * const result = allPositive([1, 2, 3])\n * // => true\n * ```\n */\nexport const all = <T>(predicate: PredicateType<T>): PredicateType<readonly T[]> => {\n return (arr: readonly T[]): boolean => arr.every(predicate)\n}\n\n/**\n * Create a predicate that tests if ANY element in an array matches.\n * Returns false for empty arrays.\n *\n * @template T - The element type\n * @param predicate - The predicate to test each element\n * @returns A predicate that takes an array and returns true if any match\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const someNegative = Predicate.some((n: number) => n < 0)\n * const result = someNegative([1, -1, 3])\n * // => true\n * ```\n */\nexport const some = <T>(predicate: PredicateType<T>): PredicateType<readonly T[]> => {\n return (arr: readonly T[]): boolean => arr.some(predicate)\n}\n\n/**\n * Create a predicate that tests if NO elements in an array match.\n * Returns true for empty arrays (vacuous truth).\n * Equivalent to `not(some(predicate))`.\n *\n * @template T - The element type\n * @param predicate - The predicate that should NOT match any element\n * @returns A predicate that takes an array and returns true if none match\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const noneZero = Predicate.none((n: number) => n === 0)\n * const result = noneZero([1, 2, 3])\n * // => true\n * ```\n */\nexport const none = <T>(predicate: PredicateType<T>): PredicateType<readonly T[]> => {\n return (arr: readonly T[]): boolean => !arr.some(predicate)\n}\n\n/**\n * Combine refinements with logical AND, preserving type narrowing.\n * Use this instead of `and` when you need to preserve type guard behavior.\n *\n * @template T - The base type\n * @template U - The narrowed type (must extend T)\n * @param refinements - The refinements to combine\n * @returns A refinement that narrows to U if all refinements pass\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isString = (value: unknown): value is string => typeof value === \"string\"\n * const isNonEmpty = (value: unknown): value is string => typeof value === \"string\" && value.length > 0\n * const refine = Predicate.andRefinement(isString, isNonEmpty)\n * const result = refine(\"hello\")\n * // => true\n * ```\n */\nexport const andRefinement = <T, U extends T>(...refinements: readonly Refinement<T, U>[]): Refinement<T, U> => {\n return (value: T): value is U => {\n for (const refinement of refinements) {\n if (!refinement(value)) return false\n }\n return true\n }\n}\n\n/**\n * Combine refinements with logical OR, preserving type narrowing.\n * Use this instead of `or` when you need to preserve type guard behavior.\n *\n * @template T - The base type\n * @template U - The narrowed type (must extend T)\n * @param refinements - The refinements to combine\n * @returns A refinement that narrows to U if any refinement passes\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isGuest = (value: unknown): value is string => value === \"guest\"\n * const isAdmin = (value: unknown): value is string => value === \"admin\"\n * const refine = Predicate.orRefinement(isGuest, isAdmin)\n * const result = refine(\"admin\")\n * // => true\n * ```\n */\nexport const orRefinement = <T, U extends T>(...refinements: readonly Refinement<T, U>[]): Refinement<T, U> => {\n return (value: T): value is U => {\n for (const refinement of refinements) {\n if (refinement(value)) return true\n }\n return false\n }\n}\n\n/**\n * Create a predicate from a constant boolean value.\n * Useful for testing or as a placeholder.\n *\n * @template T - The type (can be anything)\n * @param value - The constant boolean to return\n * @returns A predicate that always returns the given value\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const always = Predicate.constant<number>(true)\n * const result = always(123)\n * // => true\n * ```\n */\nexport const constant = <T>(value: boolean): PredicateType<T> => {\n return (): boolean => value\n}\n\n/**\n * Create a predicate that checks strict equality.\n *\n * @template T - The type being compared\n * @param expected - The value to compare against\n * @returns A predicate that returns true if value === expected\n *\n * @example\n * ```ts\n * import { Predicate } from \"@nicolastoulemont/std\"\n *\n * const isReady = Predicate.equals(\"ready\")\n * const result = isReady(\"ready\")\n * // => true\n * ```\n */\nexport const equals = <T>(expected: T): PredicateType<T> => {\n return (value: T): boolean => value === expected\n}\n"],"mappings":"oLAmBA,MAAa,EAAU,GACb,GAAsB,CAAC,EAAU,EAAM,CAqBpC,GAAU,GAAG,IAChB,GAAsB,CAC5B,IAAK,IAAM,KAAa,EACtB,GAAI,CAAC,EAAU,EAAM,CAAE,MAAO,GAEhC,MAAO,IAsBE,GAAS,GAAG,IACf,GAAsB,CAC5B,IAAK,IAAM,KAAa,EACtB,GAAI,EAAU,EAAM,CAAE,MAAO,GAE/B,MAAO,IAqBE,EAAU,GACb,GAA+B,EAAI,MAAM,EAAU,CAoBhD,EAAW,GACd,GAA+B,EAAI,KAAK,EAAU,CAqB/C,EAAW,GACd,GAA+B,CAAC,EAAI,KAAK,EAAU,CAuBhD,GAAiC,GAAG,IACvC,GAAyB,CAC/B,IAAK,IAAM,KAAc,EACvB,GAAI,CAAC,EAAW,EAAM,CAAE,MAAO,GAEjC,MAAO,IAwBE,GAAgC,GAAG,IACtC,GAAyB,CAC/B,IAAK,IAAM,KAAc,EACvB,GAAI,EAAW,EAAM,CAAE,MAAO,GAEhC,MAAO,IAqBE,EAAe,OACJ,EAmBX,EAAa,GAChB,GAAsB,IAAU"}
@@ -1,2 +1,2 @@
1
- import { t as provide_d_exports } from "../index-D8gcYvR9.mjs";
1
+ import { t as provide_d_exports } from "../index-XxPUUAGQ.mjs";
2
2
  export { provide_d_exports as Provide };
@@ -1 +1 @@
1
- import{t as e}from"../provide-CuccogWx.mjs";export{e as Provide};
1
+ import{t as e}from"../provide-K-6oXtLm.mjs";export{e as Provide};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{t}from"./fx.types-Bg-Mmdm5.mjs";import{i as n}from"./result-C74pRN2x.mjs";import{r}from"./context-7oKePrBY.mjs";import{b as i,h as a,l as o,x as s}from"./fx.runtime-B2_rL7h_.mjs";import{n as c}from"./layer-BmrPWBkT.mjs";import{t as l}from"./scope-D2AqJy7j.mjs";var u=class{cache=new Map;getOrBuild(e,r,a){let o=this.cache.get(e);if(o?.context)return{_tag:`SyncFx`,[t]:{_A:()=>o.context,_E:()=>void 0,_R:()=>void 0},run:()=>n(o.context),*[Symbol.iterator](){return o.context}};if(o?.promise)return{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:async()=>n(await o.promise),async*[Symbol.asyncIterator](){return await o.promise}};this.cache.set(e,{building:!0});let s=e.build(this,r),c=this.cache;if(s._tag===`AsyncFx`){let r=(async()=>{let t=s[Symbol.asyncIterator](),n=await t.next();for(;n.done!==!0;){let e=n.value,r=i(e);if(r===void 0)throw e;let o=a._services.get(r.key);if(o===void 0)throw Error(`Service "${r.key}" not found during layer build`);n=await t.next(o)}let r=n.value;return c.set(e,{context:r}),r})();return this.cache.set(e,{promise:r}),{_tag:`AsyncFx`,[t]:{_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`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},run:()=>{let t=s[Symbol.iterator](),r=t.next();for(;r.done!==!0;){let e=r.value,n=i(e);if(n===void 0)return{ok:!1,error:e,*[Symbol.iterator](){throw yield e,Error(`Unreachable`)}};let o=a._services.get(n.key);if(o===void 0)throw Error(`Service "${n.key}" not found during layer build`);r=t.next(o)}let o=r.value;return c.set(e,{context:o}),n(o)},*[Symbol.iterator](){let t=s[Symbol.iterator](),n=t.next();for(;n.done!==!0;){let e=n.value,r=i(e);if(r===void 0)throw yield e,Error(`Unreachable`);let o=a._services.get(r.key);if(o===void 0)throw Error(`Service "${r.key}" not found during layer build`);n=t.next(o)}return c.set(e,{context:n.value}),n.value}}}clear(){this.cache.clear()}get size(){return this.cache.size}},d=e({context:()=>m,layer:()=>f,layers:()=>p,service:()=>h});function f(e){return r=>{let i=e.build(new u,l())._tag,o=()=>{let t=new u,n=l();return{scope:n,layerBuildFx:e.build(t,n)}};return i===`AsyncFx`||r._tag===`AsyncFx`?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){let{scope:e,layerBuildFx:t}=o();try{let e;if(t._tag===`AsyncFx`){let n=t[Symbol.asyncIterator](),r=await n.next();for(;r.done!==!0;){let e=yield r.value;r=await n.next(e)}e=r.value}else{let n=t[Symbol.iterator](),r=n.next();for(;r.done!==!0;){let e=yield r.value;r=n.next(e)}e=r.value}if(r._tag===`AsyncFx`){let t=r[Symbol.asyncIterator](),n=await t.next();for(;n.done!==!0;){let r=n.value,i=s(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 n=r[Symbol.iterator](),i=n.next();for(;i.done!==!0;){let t=i.value,r=s(e,t);if(r!==void 0){i=n.next(r);continue}let a=yield t;i=n.next(a)}return i.value}finally{yield*a(e.close(n(void 0)),t=>({...t,scope:e}))}}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){let{scope:e,layerBuildFx:t}=o();if(t._tag===`AsyncFx`)throw Error(`Provide.layer sync execution encountered an async layer build. Ensure async layers are treated as async at composition time.`);try{let e=t[Symbol.iterator](),n=e.next();for(;n.done!==!0;){let t=yield n.value;n=e.next(t)}let i=n.value,a=r[Symbol.iterator](),o=a.next();for(;o.done!==!0;){let e=o.value,t=s(i,e);if(t!==void 0){o=a.next(t);continue}let n=yield e;o=a.next(n)}return o.value}finally{yield*a(e.close(n(void 0)),t=>({...t,scope:e}))}}}}}function p(...e){return f(c(...e))}const m=e=>t=>a(t,o(e)),h=(e,t)=>n=>a(n,o(r(e,t)));export{d as t};
2
+ //# sourceMappingURL=provide-K-6oXtLm.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provide-K-6oXtLm.mjs","names":["layer","service","layer","makeScope","fxGen","fxResult","service","layers","mergeLayers","Context.make"],"sources":["../src/provide/memo-map.ts","../src/provide/provide.ts"],"sourcesContent":["import type { Context } from \"../context/context\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { Layer } from \"../layer/layer.types\"\nimport { ok } from \"../result/result\"\nimport type { ScopeService } from \"../scope/scope\"\nimport { asServiceRequest } from \"../service/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/* oxlint-enable no-unsafe-type-assertion, only-throw-error */\n","import * as Context from \"../context/context\"\nimport type { Context as ContextType } from \"../context/context\"\nimport { mergeRuntimeServices, withRuntimeState } from \"../fx/fx.runtime\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport { merge as mergeLayers } from \"../layer/layer\"\nimport type { AllSync, Layer as LayerType, MergeError, MergeROut, UnprovidedDeps } from \"../layer/layer.types\"\nimport { ok } from \"../result/result\"\nimport { make as makeScope } from \"../scope/scope\"\nimport type { ServiceClass } from \"../service/service\"\nimport { resolveService } from \"../service/service-resolution\"\nimport { MemoMap } from \"./memo-map\"\n\n/* oxlint-disable no-unsafe-type-assertion -- layer/service 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\ntype LayerList = [LayerType<unknown, unknown, unknown>, ...LayerType<unknown, unknown, unknown>[]]\ntype CompleteLayers<L extends LayerList> = UnprovidedDeps<L> extends never ? L : never\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 * import { Fx, Layer, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.ok(Port, 3000)\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.layer(portLayer)(readPort)\n * const exit = Fx.run(provided)\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport function layer<ROut, E2, LayerSync extends boolean>(\n layer: LayerType<ROut, E2, never, LayerSync>,\n): <Fx extends RunnableFx<unknown, unknown, ROut>>(fx: Fx) => ProvideResult<E2, LayerSync, Fx>\nexport function layer<ROut, E2>(layer: LayerType<ROut, E2>) {\n return <A, E, R extends ROut>(fx: RunnableFx<A, E, R>): RunnableFx<A, E | E2> => {\n // Build mode selection should remain stable for this wrapper,\n // while actual layer state (scope + memoization) must be per-execution.\n const layerBuildTag = layer.build(new MemoMap(), makeScope())._tag\n\n const createRunLayerState = (): {\n readonly scope: ReturnType<typeof makeScope>\n readonly layerBuildFx: ReturnType<typeof layer.build>\n } => {\n const memoMap = new MemoMap()\n const scope = makeScope()\n return {\n scope,\n layerBuildFx: layer.build(memoMap, scope),\n }\n }\n\n if (layerBuildTag === \"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 const { scope, layerBuildFx } = createRunLayerState()\n\n try {\n // Build the layer\n let ctx: ContextType<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 const value = yield result.value\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\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 const value = yield result.value\n result = gen.next(value)\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 const closeFx = withRuntimeState(closeResult, (state) => ({ ...state, scope }))\n yield* closeFx\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 const { scope, layerBuildFx } = createRunLayerState()\n\n if (layerBuildFx._tag === \"AsyncFx\") {\n throw new Error(\n \"Provide.layer sync execution encountered an async layer build. Ensure async layers are treated as async at composition time.\",\n )\n }\n\n try {\n // Build the layer\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n\n while (layerResult.done !== true) {\n const value = yield layerResult.value\n layerResult = layerGen.next(value)\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 yield* withRuntimeState(closeResult as SyncFx<void>, (state) => ({ ...state, scope }))\n }\n },\n } as SyncFx<A, E | E2>\n }\n}\n\n/**\n * Provide multiple layers to an Fx computation.\n * Equivalent to `Provide.layer(Layer.merge(...layers))`, but keeps the call site flatter.\n *\n * @param layers - Layers whose combined external requirements are fully satisfied\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * import { Fx, Layer, Provide, Service, pipe } from \"@nicolastoulemont/std\"\n *\n * const Document = Service.tag<{ readonly getById: (id: string) => string }>(\"Document\")\n * const Team = Service.tag<{ readonly canRead: (id: string) => boolean }>(\"Team\")\n *\n * const program = Fx.gen(function* () {\n * const document = yield* Document\n * const team = yield* Team\n * return team.canRead(\"doc-1\") ? document.getById(\"doc-1\") : \"forbidden\"\n * })\n *\n * const exit = Fx.run(\n * pipe(\n * program,\n * Provide.layers(\n * Layer.ok(Document, { getById: (id) => id }),\n * Layer.ok(Team, { canRead: () => true }),\n * ),\n * ),\n * )\n * // => { _tag: \"Ok\", value: \"doc-1\" }\n * ```\n */\nexport function layers<L extends LayerList>(\n ...layers: CompleteLayers<L>\n): <Fx extends RunnableFx<unknown, unknown, MergeROut<L>>>(fx: Fx) => ProvideResult<MergeError<L>, AllSync<L>, Fx>\nexport function layers(...layers: LayerList) {\n return layer(mergeLayers(...layers))\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 * import { Context, Fx, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.context(ctx)(readPort)\n * const exit = Fx.run(provided)\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const context =\n <R>(ctx: ContextType<R>) =>\n <A, E>(fx: RunnableFx<A, E, R>): RunnableFx<A, E> => {\n return withRuntimeState(fx, mergeRuntimeServices(ctx))\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 * import { Fx, Provide, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.service(Port, 3000)(readPort)\n * const exit = Fx.run(provided)\n * // => { _tag: \"Ok\", value: 3000 }\n * ```\n */\nexport const service =\n <S>(service: ServiceClass<S>, impl: S) =>\n <A, E, R>(fx: RunnableFx<A, E, R | S>): RunnableFx<A, E, Exclude<R, S>> => {\n return withRuntimeState(fx, mergeRuntimeServices(Context.make(service, impl))) as RunnableFx<A, E, Exclude<R, S>>\n }\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { t as queue_d_exports } from "../index-CVmgBpDt.mjs";
1
+ import { t as queue_d_exports } from "../index-DogEz6WQ.mjs";
2
2
  export { queue_d_exports as Queue };
@@ -1 +1 @@
1
- import{a as e}from"../queue-GYVrD39q.mjs";export{e as Queue};
1
+ import{a as e}from"../queue-CeEIUHcY.mjs";export{e as Queue};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./data-DqACNS_g.mjs";var n=e({QueueAbortedError:()=>i,QueueClosedError:()=>r,QueueTaskAbortedError:()=>a,bounded:()=>h,is:()=>f,make:()=>m,unbounded:()=>g}),r=class extends t(`QueueClosedError`){},i=class extends t(`QueueAbortedError`){},a=class extends t(`QueueTaskAbortedError`){};const o=e=>{let t=e??`unbounded`;if(t===`unbounded`)return 1/0;if(!Number.isInteger(t)||t<=0)throw RangeError(`Queue concurrency must be a positive integer or "unbounded", received: ${String(t)}`);return t},s=e=>{if(e!==1/0&&(!Number.isInteger(e)||e<0))throw RangeError(`Queue maxSize must be an integer >= 0, received: ${String(e)}`)},c=e=>new a({reason:e.reason}),l=e=>new r({state:e}),u=e=>e instanceof Error?e:Error(`Queue rejection reason was not an Error`,{cause:e}),d=(e,t)=>{if(t===void 0)return e;if(t.aborted)return t;if(e.aborted)return e;let n=new AbortController,r=()=>{n.abort(e.reason),t.removeEventListener(`abort`,i)},i=()=>{n.abort(t.reason),e.removeEventListener(`abort`,r)};return e.addEventListener(`abort`,r,{once:!0}),t.addEventListener(`abort`,i,{once:!0}),n.signal.addEventListener(`abort`,()=>{e.removeEventListener(`abort`,r),t.removeEventListener(`abort`,i)},{once:!0}),n.signal},f=e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Queue`,p=(e,t)=>{s(e);let n=o(t?.concurrency),r=`open`,a,f=t?.autoStart===!1,p=0,m=!1,h=[],g=[],_=new Set,v=new AbortController,y,b,x=()=>{if(!(p!==0||h.length>0)){for(let e of _)e();_.clear(),(r===`draining`||r===`aborted`)&&(r=`closed`,y?.(),y=void 0)}},S=e=>{if(g.length===0)return;let t=g.splice(0);for(let n of t)n.reject(e)},C=()=>{if(!(!Number.isFinite(e)||g.length===0))for(;g.length>0&&h.length<e&&r===`open`;){let e=g.shift();e!==void 0&&e.resolve()}},w=e=>{if(h.length===0)return;let t=new i({reason:e}),n=h.splice(0);for(let e of n)e.reject(t)},T=t=>!Number.isFinite(e)||h.length<e?Promise.resolve():new Promise((e,n)=>{let r={resolve:()=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),e()},reject:e=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),n(e)},signal:t},i=t===void 0?void 0:()=>{let e=g.indexOf(r);e!==-1&&g.splice(e,1),n(c(t))};if(t!==void 0&&t.aborted){n(c(t));return}t!==void 0&&i!==void 0&&t.addEventListener(`abort`,i,{once:!0}),g.push(r)}),E=()=>{(r===`draining`||r===`aborted`)&&p===0&&h.length===0&&x()},D=e=>{p+=1;let t=d(v.signal,e.signal),n;if(t.aborted)n=Promise.reject(c(t));else try{n=Promise.resolve(e.task({signal:t}))}catch(e){n=Promise.reject(u(e))}n.then(t=>{e.resolve(t)},t=>{e.reject(u(t))}).finally(()=>{--p,C(),O(),x()})},O=()=>{if(!m){m=!0;try{if(r===`aborted`){E();return}for(;!f&&p<n&&h.length>0;){let e=h.shift();if(e===void 0)break;C(),D(e)}E()}finally{m=!1}}},k=()=>l(a===void 0?r===`aborted`?`aborted`:r===`draining`?`draining`:r===`closed`?a??`draining`:`draining`:a);return{_tag:`Queue`,get pending(){return p},get size(){return h.length},get isPaused(){return f},get isShutdown(){return r!==`open`},enqueue(t,n){let i=n?.signal;if(i!==void 0&&i.aborted)return Promise.reject(c(i));if(r!==`open`)return Promise.reject(k());let a=()=>new Promise((e,n)=>{let r={task:t,resolve:e,reject:n,signal:i};h.push(r),O()});return!Number.isFinite(e)||h.length<e?a():T(i).then(()=>{if(i!==void 0&&i.aborted)throw c(i);if(r!==`open`)throw k();return a()})},pause(){f=!0},resume(){f&&(f=!1,O())},awaitIdle(){return p===0&&h.length===0?Promise.resolve():new Promise(e=>{_.add(e)})},shutdown(e){let t=e?.mode??`drain`;return b!==void 0&&(r===`draining`||r===`aborted`||r===`closed`)?(t===`abort`&&a!==`aborted`&&(a=`aborted`,r=`aborted`,v.abort(e?.reason),w(e?.reason),S(l(`aborted`)),E()),b):(b??=new Promise(e=>{y=e}),t===`abort`?(a=`aborted`,r=`aborted`,f=!1,v.abort(e?.reason),w(e?.reason),S(l(`aborted`))):(a=`draining`,r===`open`&&(r=`draining`),f=!1,S(l(`draining`))),O(),x(),b)}}},m=e=>p(1/0,e),h=(e,t)=>p(e,t),g=e=>p(1/0,e);export{n as a,m as i,r as n,a as r,i as t};
2
- //# sourceMappingURL=queue-GYVrD39q.mjs.map
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{t}from"./data-W10ldR5l.mjs";var n=e({QueueAbortedError:()=>i,QueueClosedError:()=>r,QueueTaskAbortedError:()=>a,bounded:()=>h,is:()=>f,make:()=>m,unbounded:()=>g}),r=class extends t(`QueueClosedError`){},i=class extends t(`QueueAbortedError`){},a=class extends t(`QueueTaskAbortedError`){};const o=e=>{let t=e??`unbounded`;if(t===`unbounded`)return 1/0;if(!Number.isInteger(t)||t<=0)throw RangeError(`Queue concurrency must be a positive integer or "unbounded", received: ${String(t)}`);return t},s=e=>{if(e!==1/0&&(!Number.isInteger(e)||e<0))throw RangeError(`Queue maxSize must be an integer >= 0, received: ${String(e)}`)},c=e=>new a({reason:e.reason}),l=e=>new r({state:e}),u=e=>e instanceof Error?e:Error(`Queue rejection reason was not an Error`,{cause:e}),d=(e,t)=>{if(t===void 0)return e;if(t.aborted)return t;if(e.aborted)return e;let n=new AbortController,r=()=>{n.abort(e.reason),t.removeEventListener(`abort`,i)},i=()=>{n.abort(t.reason),e.removeEventListener(`abort`,r)};return e.addEventListener(`abort`,r,{once:!0}),t.addEventListener(`abort`,i,{once:!0}),n.signal.addEventListener(`abort`,()=>{e.removeEventListener(`abort`,r),t.removeEventListener(`abort`,i)},{once:!0}),n.signal},f=e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Queue`,p=(e,t)=>{s(e);let n=o(t?.concurrency),r=`open`,a,f=t?.autoStart===!1,p=0,m=!1,h=[],g=[],_=new Set,v=new AbortController,y,b,x=()=>{if(!(p!==0||h.length>0)){for(let e of _)e();_.clear(),(r===`draining`||r===`aborted`)&&(r=`closed`,y?.(),y=void 0)}},S=e=>{if(g.length===0)return;let t=g.splice(0);for(let n of t)n.reject(e)},C=()=>{if(!(!Number.isFinite(e)||g.length===0))for(;g.length>0&&h.length<e&&r===`open`;){let e=g.shift();e!==void 0&&e.resolve()}},w=e=>{if(h.length===0)return;let t=new i({reason:e}),n=h.splice(0);for(let e of n)e.reject(t)},T=t=>!Number.isFinite(e)||h.length<e?Promise.resolve():new Promise((e,n)=>{let r={resolve:()=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),e()},reject:e=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),n(e)},signal:t},i=t===void 0?void 0:()=>{let e=g.indexOf(r);e!==-1&&g.splice(e,1),n(c(t))};if(t!==void 0&&t.aborted){n(c(t));return}t!==void 0&&i!==void 0&&t.addEventListener(`abort`,i,{once:!0}),g.push(r)}),E=()=>{(r===`draining`||r===`aborted`)&&p===0&&h.length===0&&x()},D=e=>{p+=1;let t=d(v.signal,e.signal),n;if(t.aborted)n=Promise.reject(c(t));else try{n=Promise.resolve(e.task({signal:t}))}catch(e){n=Promise.reject(u(e))}n.then(t=>{e.resolve(t)},t=>{e.reject(u(t))}).finally(()=>{--p,C(),O(),x()})},O=()=>{if(!m){m=!0;try{if(r===`aborted`){E();return}for(;!f&&p<n&&h.length>0;){let e=h.shift();if(e===void 0)break;C(),D(e)}E()}finally{m=!1}}},k=()=>l(a===void 0?r===`aborted`?`aborted`:r===`draining`?`draining`:r===`closed`?a??`draining`:`draining`:a);return{_tag:`Queue`,get pending(){return p},get size(){return h.length},get isPaused(){return f},get isShutdown(){return r!==`open`},enqueue(t,n){let i=n?.signal;if(i!==void 0&&i.aborted)return Promise.reject(c(i));if(r!==`open`)return Promise.reject(k());let a=()=>new Promise((e,n)=>{let r={task:t,resolve:e,reject:n,signal:i};h.push(r),O()});return!Number.isFinite(e)||h.length<e?a():T(i).then(()=>{if(i!==void 0&&i.aborted)throw c(i);if(r!==`open`)throw k();return a()})},pause(){f=!0},resume(){f&&(f=!1,O())},awaitIdle(){return p===0&&h.length===0?Promise.resolve():new Promise(e=>{_.add(e)})},shutdown(e){let t=e?.mode??`drain`;return b!==void 0&&(r===`draining`||r===`aborted`||r===`closed`)?(t===`abort`&&a!==`aborted`&&(a=`aborted`,r=`aborted`,v.abort(e?.reason),w(e?.reason),S(l(`aborted`)),E()),b):(b??=new Promise(e=>{y=e}),t===`abort`?(a=`aborted`,r=`aborted`,f=!1,v.abort(e?.reason),w(e?.reason),S(l(`aborted`))):(a=`draining`,r===`open`&&(r=`draining`),f=!1,S(l(`draining`))),O(),x(),b)}}},m=e=>p(1/0,e),h=(e,t)=>p(e,t),g=e=>p(1/0,e);export{n as a,m as i,r as n,a as r,i as t};
2
+ //# sourceMappingURL=queue-CeEIUHcY.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue-GYVrD39q.mjs","names":["Data.TaggedError","options"],"sources":["../src/queue/queue.ts"],"sourcesContent":["/**\n * Promise-based work queue with bounded/unbounded capacity and shutdown modes.\n *\n * **Mental model**\n * - A queue coordinates concurrent task execution with backpressure.\n * - Enqueue returns a promise for each task result.\n *\n * **Common tasks**\n * - Create queues via `Queue.make`, `Queue.bounded`, or `Queue.unbounded`.\n * - Pause/resume processing and await idle state.\n * - Shutdown with drain or abort semantics.\n *\n * **Gotchas**\n * - Bounded queues can block enqueue when capacity is reached.\n * - Aborted queues reject queued and future tasks.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n *\n * @module\n */\nimport { Data } from \"../data\"\nimport type {\n Concurrency,\n Queue as QueueType,\n QueueBoundedOptions,\n QueueOptions,\n QueueShutdownMode,\n QueueShutdownOptions,\n QueueTask,\n} from \"./queue.types\"\n\n/* oxlint-disable max-classes-per-file -- Queue exports dedicated error classes for precise instanceof checks at call sites. */\n/**\n * Error raised when enqueueing into a non-open queue.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueClosedError({ state: \"draining\" })\n * // => { _tag: \"QueueClosedError\", state: \"draining\" }\n * ```\n */\nexport class QueueClosedError extends Data.TaggedError(\"QueueClosedError\")<{ state: \"draining\" | \"aborted\" }> {}\n/**\n * Error raised when queue processing is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueAbortedError({ reason: \"manual\" })\n * // => { _tag: \"QueueAbortedError\", reason: \"manual\" }\n * ```\n */\nexport class QueueAbortedError extends Data.TaggedError(\"QueueAbortedError\")<{ reason?: unknown }> {}\n/**\n * Error raised when a specific task is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueTaskAbortedError({ reason: \"signal\" })\n * // => { _tag: \"QueueTaskAbortedError\", reason: \"signal\" }\n * ```\n */\nexport class QueueTaskAbortedError extends Data.TaggedError(\"QueueTaskAbortedError\")<{ reason?: unknown }> {}\n\ntype QueueState = \"open\" | \"draining\" | \"aborted\" | \"closed\"\n\ntype TaskEntry<A> = {\n readonly task: QueueTask<A>\n resolve(value: A | PromiseLike<A>): void\n reject(reason: unknown): void\n readonly signal: AbortSignal | undefined\n}\n\ntype CapacityWaiter = {\n resolve(): void\n reject(reason: Error): void\n readonly signal: AbortSignal | undefined\n}\n\nconst asConcurrencyLimit = (concurrency: Concurrency | undefined): number => {\n const resolved = concurrency ?? \"unbounded\"\n if (resolved === \"unbounded\") {\n return Number.POSITIVE_INFINITY\n }\n\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new RangeError(`Queue concurrency must be a positive integer or \"unbounded\", received: ${String(resolved)}`)\n }\n\n return resolved\n}\n\nconst assertMaxSize = (maxSize: number) => {\n if (maxSize === Number.POSITIVE_INFINITY) {\n return\n }\n\n if (!Number.isInteger(maxSize) || maxSize < 0) {\n throw new RangeError(`Queue maxSize must be an integer >= 0, received: ${String(maxSize)}`)\n }\n}\n\nconst queueTaskAbortedError = (signal: AbortSignal): QueueTaskAbortedError =>\n new QueueTaskAbortedError({ reason: signal.reason })\n\nconst queueClosedError = (state: \"draining\" | \"aborted\"): QueueClosedError => new QueueClosedError({ state })\n\nconst toError = (reason: unknown): Error =>\n reason instanceof Error ? reason : new Error(\"Queue rejection reason was not an Error\", { cause: reason })\n\nconst composeSignals = (queueSignal: AbortSignal, taskSignal: AbortSignal | undefined): AbortSignal => {\n if (taskSignal === undefined) {\n return queueSignal\n }\n\n if (taskSignal.aborted) {\n return taskSignal\n }\n\n if (queueSignal.aborted) {\n return queueSignal\n }\n\n const composite = new AbortController()\n\n const onQueueAbort = () => {\n composite.abort(queueSignal.reason)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n }\n\n const onTaskAbort = () => {\n composite.abort(taskSignal.reason)\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n }\n\n queueSignal.addEventListener(\"abort\", onQueueAbort, { once: true })\n taskSignal.addEventListener(\"abort\", onTaskAbort, { once: true })\n\n composite.signal.addEventListener(\n \"abort\",\n () => {\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n },\n { once: true },\n )\n\n return composite.signal\n}\n\n/**\n * Check if a value is a `Queue`.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const isQueue = Queue.is(queue)\n * // => true\n * ```\n */\nexport const is = (value: unknown): value is QueueType =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Queue\"\n\nconst createQueue = (maxSize: number, options?: QueueOptions): QueueType => {\n assertMaxSize(maxSize)\n\n const concurrencyLimit = asConcurrencyLimit(options?.concurrency)\n let state: QueueState = \"open\"\n let closeState: \"draining\" | \"aborted\" | undefined\n let paused = options?.autoStart === false\n let pending = 0\n let draining = false\n\n const queuedTasks: TaskEntry<unknown>[] = []\n const capacityWaiters: CapacityWaiter[] = []\n const idleWaiters = new Set<() => void>()\n\n const queueAbortController = new AbortController()\n\n let shutdownResolver: (() => void) | undefined\n let shutdownPromise: Promise<void> | undefined\n\n const resolveIdleIfNeeded = () => {\n if (pending !== 0 || queuedTasks.length > 0) {\n return\n }\n\n for (const resolve of idleWaiters) {\n resolve()\n }\n idleWaiters.clear()\n\n if (state === \"draining\" || state === \"aborted\") {\n state = \"closed\"\n shutdownResolver?.()\n shutdownResolver = undefined\n }\n }\n\n const rejectCapacityWaiters = (reason: Error) => {\n if (capacityWaiters.length === 0) {\n return\n }\n\n const waiters = capacityWaiters.splice(0)\n for (const waiter of waiters) {\n waiter.reject(reason)\n }\n }\n\n const releaseCapacityWaiters = () => {\n if (!Number.isFinite(maxSize) || capacityWaiters.length === 0) {\n return\n }\n\n while (capacityWaiters.length > 0 && queuedTasks.length < maxSize && state === \"open\") {\n const waiter = capacityWaiters.shift()\n if (waiter !== undefined) {\n waiter.resolve()\n }\n }\n }\n\n const applyAbortToQueuedTasks = (reason: unknown) => {\n if (queuedTasks.length === 0) {\n return\n }\n\n const error = new QueueAbortedError({ reason })\n const tasks = queuedTasks.splice(0)\n for (const entry of tasks) {\n entry.reject(error)\n }\n }\n\n const waitForCapacity = (signal: AbortSignal | undefined): Promise<void> => {\n if (!Number.isFinite(maxSize)) {\n return Promise.resolve()\n }\n\n if (queuedTasks.length < maxSize) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter: CapacityWaiter = {\n resolve: () => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n resolve()\n },\n reject: (error) => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n reject(error)\n },\n signal,\n }\n\n const onAbort =\n signal === undefined\n ? undefined\n : () => {\n const index = capacityWaiters.indexOf(waiter)\n if (index !== -1) {\n capacityWaiters.splice(index, 1)\n }\n reject(queueTaskAbortedError(signal))\n }\n\n if (signal !== undefined && signal.aborted) {\n reject(queueTaskAbortedError(signal))\n return\n }\n\n if (signal !== undefined && onAbort !== undefined) {\n signal.addEventListener(\"abort\", onAbort, { once: true })\n }\n\n capacityWaiters.push(waiter)\n })\n }\n\n const closeIfNeeded = () => {\n if ((state === \"draining\" || state === \"aborted\") && pending === 0 && queuedTasks.length === 0) {\n resolveIdleIfNeeded()\n }\n }\n\n const runTask = <A>(entry: TaskEntry<A>) => {\n pending += 1\n\n const taskSignal = composeSignals(queueAbortController.signal, entry.signal)\n\n let taskResult: Promise<A>\n if (taskSignal.aborted) {\n taskResult = Promise.reject(queueTaskAbortedError(taskSignal))\n } else {\n try {\n taskResult = Promise.resolve(entry.task({ signal: taskSignal }))\n } catch (error) {\n taskResult = Promise.reject(toError(error))\n }\n }\n\n void taskResult\n .then(\n (value) => {\n entry.resolve(value)\n return undefined\n },\n (error: unknown) => {\n entry.reject(toError(error))\n return undefined\n },\n )\n .finally(() => {\n pending -= 1\n releaseCapacityWaiters()\n drainQueue()\n resolveIdleIfNeeded()\n })\n }\n\n const drainQueue = () => {\n if (draining) {\n return\n }\n\n draining = true\n try {\n if (state === \"aborted\") {\n closeIfNeeded()\n return\n }\n\n while (!paused && pending < concurrencyLimit && queuedTasks.length > 0) {\n const entry = queuedTasks.shift()\n if (entry === undefined) {\n break\n }\n releaseCapacityWaiters()\n runTask(entry)\n }\n\n closeIfNeeded()\n } finally {\n draining = false\n }\n }\n\n const enqueueErrorForState = (): QueueClosedError => {\n if (closeState !== undefined) {\n return queueClosedError(closeState)\n }\n\n if (state === \"aborted\") {\n return queueClosedError(\"aborted\")\n }\n\n if (state === \"draining\") {\n return queueClosedError(\"draining\")\n }\n\n if (state === \"closed\") {\n return queueClosedError(closeState ?? \"draining\")\n }\n\n return queueClosedError(\"draining\")\n }\n\n const queue: QueueType = {\n _tag: \"Queue\",\n\n get pending(): number {\n return pending\n },\n\n get size(): number {\n return queuedTasks.length\n },\n\n get isPaused(): boolean {\n return paused\n },\n\n get isShutdown(): boolean {\n return state !== \"open\"\n },\n\n enqueue<A>(task: QueueTask<A>, options?: { readonly signal?: AbortSignal }): Promise<A> {\n const signal = options?.signal\n\n if (signal !== undefined && signal.aborted) {\n return Promise.reject(queueTaskAbortedError(signal))\n }\n\n if (state !== \"open\") {\n return Promise.reject(enqueueErrorForState())\n }\n\n const enqueueTask = () =>\n new Promise<A>((resolve, reject) => {\n const entry: TaskEntry<A> = {\n task,\n resolve,\n reject,\n signal,\n }\n\n queuedTasks.push(entry)\n drainQueue()\n })\n\n if (!Number.isFinite(maxSize) || queuedTasks.length < maxSize) {\n return enqueueTask()\n }\n\n return waitForCapacity(signal).then(() => {\n if (signal !== undefined && signal.aborted) {\n throw queueTaskAbortedError(signal)\n }\n\n if (state !== \"open\") {\n throw enqueueErrorForState()\n }\n\n return enqueueTask()\n })\n },\n\n pause(): void {\n paused = true\n },\n\n resume(): void {\n if (!paused) {\n return\n }\n\n paused = false\n drainQueue()\n },\n\n awaitIdle(): Promise<void> {\n if (pending === 0 && queuedTasks.length === 0) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve) => {\n idleWaiters.add(resolve)\n })\n },\n\n shutdown(options?: QueueShutdownOptions): Promise<void> {\n const mode: QueueShutdownMode = options?.mode ?? \"drain\"\n\n if (shutdownPromise !== undefined && (state === \"draining\" || state === \"aborted\" || state === \"closed\")) {\n if (mode === \"abort\" && closeState !== \"aborted\") {\n closeState = \"aborted\"\n state = \"aborted\"\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n closeIfNeeded()\n }\n\n return shutdownPromise\n }\n\n shutdownPromise =\n shutdownPromise ??\n new Promise<void>((resolve) => {\n shutdownResolver = resolve\n })\n\n if (mode === \"abort\") {\n closeState = \"aborted\"\n state = \"aborted\"\n paused = false\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n } else {\n closeState = \"draining\"\n if (state === \"open\") {\n state = \"draining\"\n }\n paused = false\n rejectCapacityWaiters(queueClosedError(\"draining\"))\n }\n\n drainQueue()\n resolveIdleIfNeeded()\n\n return shutdownPromise\n },\n }\n\n return queue\n}\n\n/**\n * Create a queue with default unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n */\nexport const make = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/**\n * Create a queue with bounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.bounded(2)\n * const size = queue.size\n * // => 0\n * ```\n */\nexport const bounded = (maxSize: number, options?: QueueBoundedOptions): QueueType => createQueue(maxSize, options)\n\n/**\n * Create a queue with explicit unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.unbounded()\n * const paused = queue.isPaused\n * // => false\n * ```\n */\nexport const unbounded = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/* oxlint-enable max-classes-per-file */\n"],"mappings":"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"}
1
+ {"version":3,"file":"queue-CeEIUHcY.mjs","names":["Data.TaggedError","options"],"sources":["../src/queue/queue.ts"],"sourcesContent":["/**\n * Promise-based work queue with bounded/unbounded capacity and shutdown modes.\n *\n * **Mental model**\n * - A queue coordinates concurrent task execution with backpressure.\n * - Enqueue returns a promise for each task result.\n *\n * **Common tasks**\n * - Create queues via `Queue.make`, `Queue.bounded`, or `Queue.unbounded`.\n * - Pause/resume processing and await idle state.\n * - Shutdown with drain or abort semantics.\n *\n * **Gotchas**\n * - Bounded queues can block enqueue when capacity is reached.\n * - Aborted queues reject queued and future tasks.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n *\n * @module\n */\nimport { Data } from \"../data\"\nimport type {\n Concurrency,\n Queue as QueueType,\n QueueBoundedOptions,\n QueueOptions,\n QueueShutdownMode,\n QueueShutdownOptions,\n QueueTask,\n} from \"./queue.types\"\n\n/* oxlint-disable max-classes-per-file -- Queue exports dedicated error classes for precise instanceof checks at call sites. */\n/**\n * Error raised when enqueueing into a non-open queue.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueClosedError({ state: \"draining\" })\n * // => { _tag: \"QueueClosedError\", state: \"draining\" }\n * ```\n */\nexport class QueueClosedError extends Data.TaggedError(\"QueueClosedError\")<{ state: \"draining\" | \"aborted\" }> {}\n/**\n * Error raised when queue processing is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueAbortedError({ reason: \"manual\" })\n * // => { _tag: \"QueueAbortedError\", reason: \"manual\" }\n * ```\n */\nexport class QueueAbortedError extends Data.TaggedError(\"QueueAbortedError\")<{ reason?: unknown }> {}\n/**\n * Error raised when a specific task is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueTaskAbortedError({ reason: \"signal\" })\n * // => { _tag: \"QueueTaskAbortedError\", reason: \"signal\" }\n * ```\n */\nexport class QueueTaskAbortedError extends Data.TaggedError(\"QueueTaskAbortedError\")<{ reason?: unknown }> {}\n\ntype QueueState = \"open\" | \"draining\" | \"aborted\" | \"closed\"\n\ntype TaskEntry<A> = {\n readonly task: QueueTask<A>\n resolve(value: A | PromiseLike<A>): void\n reject(reason: unknown): void\n readonly signal: AbortSignal | undefined\n}\n\ntype CapacityWaiter = {\n resolve(): void\n reject(reason: Error): void\n readonly signal: AbortSignal | undefined\n}\n\nconst asConcurrencyLimit = (concurrency: Concurrency | undefined): number => {\n const resolved = concurrency ?? \"unbounded\"\n if (resolved === \"unbounded\") {\n return Number.POSITIVE_INFINITY\n }\n\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new RangeError(`Queue concurrency must be a positive integer or \"unbounded\", received: ${String(resolved)}`)\n }\n\n return resolved\n}\n\nconst assertMaxSize = (maxSize: number) => {\n if (maxSize === Number.POSITIVE_INFINITY) {\n return\n }\n\n if (!Number.isInteger(maxSize) || maxSize < 0) {\n throw new RangeError(`Queue maxSize must be an integer >= 0, received: ${String(maxSize)}`)\n }\n}\n\nconst queueTaskAbortedError = (signal: AbortSignal): QueueTaskAbortedError =>\n new QueueTaskAbortedError({ reason: signal.reason })\n\nconst queueClosedError = (state: \"draining\" | \"aborted\"): QueueClosedError => new QueueClosedError({ state })\n\nconst toError = (reason: unknown): Error =>\n reason instanceof Error ? reason : new Error(\"Queue rejection reason was not an Error\", { cause: reason })\n\nconst composeSignals = (queueSignal: AbortSignal, taskSignal: AbortSignal | undefined): AbortSignal => {\n if (taskSignal === undefined) {\n return queueSignal\n }\n\n if (taskSignal.aborted) {\n return taskSignal\n }\n\n if (queueSignal.aborted) {\n return queueSignal\n }\n\n const composite = new AbortController()\n\n const onQueueAbort = () => {\n composite.abort(queueSignal.reason)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n }\n\n const onTaskAbort = () => {\n composite.abort(taskSignal.reason)\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n }\n\n queueSignal.addEventListener(\"abort\", onQueueAbort, { once: true })\n taskSignal.addEventListener(\"abort\", onTaskAbort, { once: true })\n\n composite.signal.addEventListener(\n \"abort\",\n () => {\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n },\n { once: true },\n )\n\n return composite.signal\n}\n\n/**\n * Check if a value is a `Queue`.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const isQueue = Queue.is(queue)\n * // => true\n * ```\n */\nexport const is = (value: unknown): value is QueueType =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Queue\"\n\nconst createQueue = (maxSize: number, options?: QueueOptions): QueueType => {\n assertMaxSize(maxSize)\n\n const concurrencyLimit = asConcurrencyLimit(options?.concurrency)\n let state: QueueState = \"open\"\n let closeState: \"draining\" | \"aborted\" | undefined\n let paused = options?.autoStart === false\n let pending = 0\n let draining = false\n\n const queuedTasks: TaskEntry<unknown>[] = []\n const capacityWaiters: CapacityWaiter[] = []\n const idleWaiters = new Set<() => void>()\n\n const queueAbortController = new AbortController()\n\n let shutdownResolver: (() => void) | undefined\n let shutdownPromise: Promise<void> | undefined\n\n const resolveIdleIfNeeded = () => {\n if (pending !== 0 || queuedTasks.length > 0) {\n return\n }\n\n for (const resolve of idleWaiters) {\n resolve()\n }\n idleWaiters.clear()\n\n if (state === \"draining\" || state === \"aborted\") {\n state = \"closed\"\n shutdownResolver?.()\n shutdownResolver = undefined\n }\n }\n\n const rejectCapacityWaiters = (reason: Error) => {\n if (capacityWaiters.length === 0) {\n return\n }\n\n const waiters = capacityWaiters.splice(0)\n for (const waiter of waiters) {\n waiter.reject(reason)\n }\n }\n\n const releaseCapacityWaiters = () => {\n if (!Number.isFinite(maxSize) || capacityWaiters.length === 0) {\n return\n }\n\n while (capacityWaiters.length > 0 && queuedTasks.length < maxSize && state === \"open\") {\n const waiter = capacityWaiters.shift()\n if (waiter !== undefined) {\n waiter.resolve()\n }\n }\n }\n\n const applyAbortToQueuedTasks = (reason: unknown) => {\n if (queuedTasks.length === 0) {\n return\n }\n\n const error = new QueueAbortedError({ reason })\n const tasks = queuedTasks.splice(0)\n for (const entry of tasks) {\n entry.reject(error)\n }\n }\n\n const waitForCapacity = (signal: AbortSignal | undefined): Promise<void> => {\n if (!Number.isFinite(maxSize)) {\n return Promise.resolve()\n }\n\n if (queuedTasks.length < maxSize) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter: CapacityWaiter = {\n resolve: () => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n resolve()\n },\n reject: (error) => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n reject(error)\n },\n signal,\n }\n\n const onAbort =\n signal === undefined\n ? undefined\n : () => {\n const index = capacityWaiters.indexOf(waiter)\n if (index !== -1) {\n capacityWaiters.splice(index, 1)\n }\n reject(queueTaskAbortedError(signal))\n }\n\n if (signal !== undefined && signal.aborted) {\n reject(queueTaskAbortedError(signal))\n return\n }\n\n if (signal !== undefined && onAbort !== undefined) {\n signal.addEventListener(\"abort\", onAbort, { once: true })\n }\n\n capacityWaiters.push(waiter)\n })\n }\n\n const closeIfNeeded = () => {\n if ((state === \"draining\" || state === \"aborted\") && pending === 0 && queuedTasks.length === 0) {\n resolveIdleIfNeeded()\n }\n }\n\n const runTask = <A>(entry: TaskEntry<A>) => {\n pending += 1\n\n const taskSignal = composeSignals(queueAbortController.signal, entry.signal)\n\n let taskResult: Promise<A>\n if (taskSignal.aborted) {\n taskResult = Promise.reject(queueTaskAbortedError(taskSignal))\n } else {\n try {\n taskResult = Promise.resolve(entry.task({ signal: taskSignal }))\n } catch (error) {\n taskResult = Promise.reject(toError(error))\n }\n }\n\n void taskResult\n .then(\n (value) => {\n entry.resolve(value)\n return undefined\n },\n (error: unknown) => {\n entry.reject(toError(error))\n return undefined\n },\n )\n .finally(() => {\n pending -= 1\n releaseCapacityWaiters()\n drainQueue()\n resolveIdleIfNeeded()\n })\n }\n\n const drainQueue = () => {\n if (draining) {\n return\n }\n\n draining = true\n try {\n if (state === \"aborted\") {\n closeIfNeeded()\n return\n }\n\n while (!paused && pending < concurrencyLimit && queuedTasks.length > 0) {\n const entry = queuedTasks.shift()\n if (entry === undefined) {\n break\n }\n releaseCapacityWaiters()\n runTask(entry)\n }\n\n closeIfNeeded()\n } finally {\n draining = false\n }\n }\n\n const enqueueErrorForState = (): QueueClosedError => {\n if (closeState !== undefined) {\n return queueClosedError(closeState)\n }\n\n if (state === \"aborted\") {\n return queueClosedError(\"aborted\")\n }\n\n if (state === \"draining\") {\n return queueClosedError(\"draining\")\n }\n\n if (state === \"closed\") {\n return queueClosedError(closeState ?? \"draining\")\n }\n\n return queueClosedError(\"draining\")\n }\n\n const queue: QueueType = {\n _tag: \"Queue\",\n\n get pending(): number {\n return pending\n },\n\n get size(): number {\n return queuedTasks.length\n },\n\n get isPaused(): boolean {\n return paused\n },\n\n get isShutdown(): boolean {\n return state !== \"open\"\n },\n\n enqueue<A>(task: QueueTask<A>, options?: { readonly signal?: AbortSignal }): Promise<A> {\n const signal = options?.signal\n\n if (signal !== undefined && signal.aborted) {\n return Promise.reject(queueTaskAbortedError(signal))\n }\n\n if (state !== \"open\") {\n return Promise.reject(enqueueErrorForState())\n }\n\n const enqueueTask = () =>\n new Promise<A>((resolve, reject) => {\n const entry: TaskEntry<A> = {\n task,\n resolve,\n reject,\n signal,\n }\n\n queuedTasks.push(entry)\n drainQueue()\n })\n\n if (!Number.isFinite(maxSize) || queuedTasks.length < maxSize) {\n return enqueueTask()\n }\n\n return waitForCapacity(signal).then(() => {\n if (signal !== undefined && signal.aborted) {\n throw queueTaskAbortedError(signal)\n }\n\n if (state !== \"open\") {\n throw enqueueErrorForState()\n }\n\n return enqueueTask()\n })\n },\n\n pause(): void {\n paused = true\n },\n\n resume(): void {\n if (!paused) {\n return\n }\n\n paused = false\n drainQueue()\n },\n\n awaitIdle(): Promise<void> {\n if (pending === 0 && queuedTasks.length === 0) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve) => {\n idleWaiters.add(resolve)\n })\n },\n\n shutdown(options?: QueueShutdownOptions): Promise<void> {\n const mode: QueueShutdownMode = options?.mode ?? \"drain\"\n\n if (shutdownPromise !== undefined && (state === \"draining\" || state === \"aborted\" || state === \"closed\")) {\n if (mode === \"abort\" && closeState !== \"aborted\") {\n closeState = \"aborted\"\n state = \"aborted\"\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n closeIfNeeded()\n }\n\n return shutdownPromise\n }\n\n shutdownPromise =\n shutdownPromise ??\n new Promise<void>((resolve) => {\n shutdownResolver = resolve\n })\n\n if (mode === \"abort\") {\n closeState = \"aborted\"\n state = \"aborted\"\n paused = false\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n } else {\n closeState = \"draining\"\n if (state === \"open\") {\n state = \"draining\"\n }\n paused = false\n rejectCapacityWaiters(queueClosedError(\"draining\"))\n }\n\n drainQueue()\n resolveIdleIfNeeded()\n\n return shutdownPromise\n },\n }\n\n return queue\n}\n\n/**\n * Create a queue with default unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n */\nexport const make = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/**\n * Create a queue with bounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.bounded(2)\n * const size = queue.size\n * // => 0\n * ```\n */\nexport const bounded = (maxSize: number, options?: QueueBoundedOptions): QueueType => createQueue(maxSize, options)\n\n/**\n * Create a queue with explicit unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.unbounded()\n * const paused = queue.isPaused\n * // => false\n * ```\n */\nexport const unbounded = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/* oxlint-enable max-classes-per-file */\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as result_d_exports } from "../index-CIvNgjsx.mjs";
1
+ import { n as result_d_exports } from "../index-B4rHoUK4.mjs";
2
2
  export { result_d_exports as Result };
@@ -1 +1 @@
1
- import{a as e}from"../result-D3VY0qBG.mjs";export{e as Result};
1
+ import{a as e}from"../result-C74pRN2x.mjs";export{e as Result};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./chunk-oQKkju2G.mjs";import{t}from"./fx.types-DyQVgTS8.mjs";import{t as n}from"./dual-fN6OUwN_.mjs";import{n as r}from"./flow-CNyLsPGb.mjs";import{t as i}from"./pipeable-Dp1_23zH.mjs";var a=e({all:()=>g,err:()=>s,filter:()=>h,flatMap:()=>f,fromTry:()=>b,isErr:()=>l,isOk:()=>c,map:()=>u,mapErr:()=>d,match:()=>y,ok:()=>o,orElse:()=>m,tap:()=>p,try:()=>x,unwrapOr:()=>_,unwrapOrElse:()=>v});const o=e=>({_tag:`Ok`,value:e,pipe:i,[t]:{_A:()=>e,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){return e}}),s=e=>{let n={_tag:`Err`,error:e,pipe:i,[t]:{_A:()=>void 0,_E:()=>e,_R:()=>void 0},*[Symbol.iterator](){throw yield n,Error(`Unreachable: Fx.gen should short-circuit on error`)}};return n},c=e=>e._tag===`Ok`,l=e=>e._tag===`Err`,u=n(2,(e,t)=>{if(e._tag===`Err`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(o):o(n)}),d=n(2,(e,t)=>{if(e._tag===`Ok`)return e;let n=t(e.error);return r(n)?Promise.resolve(n).then(s):s(n)}),f=n(2,(e,t)=>e._tag===`Ok`?t(e.value):e),p=n(2,(e,t)=>{if(e._tag===`Err`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(()=>e):e}),m=n(2,(e,t)=>e._tag===`Ok`?e:t(e.error)),h=n(3,(e,t,n)=>e._tag===`Err`||t(e.value)?e:s(n(e.value))),g=e=>{if(Array.isArray(e)){let t=[];for(let n of e){if(n._tag===`Err`)return n;t.push(n.value)}return o(t)}let t={};for(let[n,r]of Object.entries(e)){let e=r;if(e._tag===`Err`)return r;t[n]=e.value}return o(t)},_=n(2,(e,t)=>e._tag===`Ok`?e.value:t),v=n(2,(e,t)=>e._tag===`Ok`?e.value:t(e.error)),y=n(2,(e,t)=>e._tag===`Ok`?t.Ok(e.value):t.Err(e.error)),b=e=>{let t=typeof e==`function`?e:e.try,n=typeof e==`function`?e=>e instanceof Error?e:Error(String(e)):e.catch,i=typeof e==`function`?void 0:e.finally,a=!1;try{let e=t();if(r(e)){a=!0;let t=Promise.resolve(e).then(o).catch(e=>s(n(e)));return i?t.finally(i):t}return o(e)}catch(e){return s(n(e))}finally{i&&!a&&i()}},x=b;export{a,o as i,b as n,l as r,s as t};
2
- //# sourceMappingURL=result-D3VY0qBG.mjs.map
1
+ import{t as e}from"./chunk-6rpU2rUb.mjs";import{t}from"./fx.types-Bg-Mmdm5.mjs";import{t as n}from"./dual-CZhzZslG.mjs";import{n as r}from"./flow-D8_tllWl.mjs";import{t as i}from"./pipeable-COGyGMUV.mjs";var a=e({all:()=>g,err:()=>s,filter:()=>h,flatMap:()=>f,fromTry:()=>b,isErr:()=>l,isOk:()=>c,map:()=>u,mapErr:()=>d,match:()=>y,ok:()=>o,orElse:()=>m,tap:()=>p,try:()=>x,unwrapOr:()=>_,unwrapOrElse:()=>v});const o=e=>({_tag:`Ok`,value:e,pipe:i,[t]:{_A:()=>e,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){return e}}),s=e=>{let n={_tag:`Err`,error:e,pipe:i,[t]:{_A:()=>void 0,_E:()=>e,_R:()=>void 0},*[Symbol.iterator](){throw yield n,Error(`Unreachable: Fx.gen should short-circuit on error`)}};return n},c=e=>e._tag===`Ok`,l=e=>e._tag===`Err`,u=n(2,(e,t)=>{if(e._tag===`Err`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(o):o(n)}),d=n(2,(e,t)=>{if(e._tag===`Ok`)return e;let n=t(e.error);return r(n)?Promise.resolve(n).then(s):s(n)}),f=n(2,(e,t)=>e._tag===`Ok`?t(e.value):e),p=n(2,(e,t)=>{if(e._tag===`Err`)return e;let n=t(e.value);return r(n)?Promise.resolve(n).then(()=>e):e}),m=n(2,(e,t)=>e._tag===`Ok`?e:t(e.error)),h=n(3,(e,t,n)=>e._tag===`Err`||t(e.value)?e:s(n(e.value))),g=e=>{if(Array.isArray(e)){let t=[];for(let n of e){if(n._tag===`Err`)return n;t.push(n.value)}return o(t)}let t={};for(let[n,r]of Object.entries(e)){let e=r;if(e._tag===`Err`)return r;t[n]=e.value}return o(t)},_=n(2,(e,t)=>e._tag===`Ok`?e.value:t),v=n(2,(e,t)=>e._tag===`Ok`?e.value:t(e.error)),y=n(2,(e,t)=>e._tag===`Ok`?t.Ok(e.value):t.Err(e.error)),b=e=>{let t=typeof e==`function`?e:e.try,n=typeof e==`function`?e=>e instanceof Error?e:Error(String(e)):e.catch,i=typeof e==`function`?void 0:e.finally,a=!1;try{let e=t();if(r(e)){a=!0;let t=Promise.resolve(e).then(o).catch(e=>s(n(e)));return i?t.finally(i):t}return o(e)}catch(e){return s(n(e))}finally{i&&!a&&i()}},x=b;export{a,o as i,b as n,l as r,s as t};
2
+ //# sourceMappingURL=result-C74pRN2x.mjs.map