@typed/fx 2.0.0-beta.1 → 2.0.0-beta.10

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 (664) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -21
  3. package/dist/Fx/Fx.d.ts +371 -19
  4. package/dist/Fx/Fx.d.ts.map +1 -1
  5. package/dist/Fx/Fx.js +37 -6
  6. package/dist/Fx/TypeId.d.ts +52 -6
  7. package/dist/Fx/TypeId.d.ts.map +1 -1
  8. package/dist/Fx/TypeId.js +41 -4
  9. package/dist/Fx/combinators/additive.d.ts +162 -11
  10. package/dist/Fx/combinators/additive.d.ts.map +1 -1
  11. package/dist/Fx/combinators/additive.js +162 -11
  12. package/dist/Fx/combinators/catch.d.ts +202 -29
  13. package/dist/Fx/combinators/catch.d.ts.map +1 -1
  14. package/dist/Fx/combinators/catch.js +193 -23
  15. package/dist/Fx/combinators/causes.d.ts +25 -2
  16. package/dist/Fx/combinators/causes.d.ts.map +1 -1
  17. package/dist/Fx/combinators/causes.js +25 -2
  18. package/dist/Fx/combinators/changesWithEffect.d.ts +21 -1
  19. package/dist/Fx/combinators/changesWithEffect.d.ts.map +1 -1
  20. package/dist/Fx/combinators/changesWithEffect.js +21 -1
  21. package/dist/Fx/combinators/compact.d.ts +18 -1
  22. package/dist/Fx/combinators/compact.d.ts.map +1 -1
  23. package/dist/Fx/combinators/compact.js +18 -1
  24. package/dist/Fx/combinators/concatMap.d.ts +86 -0
  25. package/dist/Fx/combinators/concatMap.d.ts.map +1 -0
  26. package/dist/Fx/combinators/concatMap.js +86 -0
  27. package/dist/Fx/combinators/continueWith.d.ts +113 -5
  28. package/dist/Fx/combinators/continueWith.d.ts.map +1 -1
  29. package/dist/Fx/combinators/continueWith.js +113 -5
  30. package/dist/Fx/combinators/debounce.d.ts +34 -0
  31. package/dist/Fx/combinators/debounce.d.ts.map +1 -0
  32. package/dist/Fx/combinators/debounce.js +35 -0
  33. package/dist/Fx/combinators/delay.d.ts +36 -0
  34. package/dist/Fx/combinators/delay.d.ts.map +1 -0
  35. package/dist/Fx/combinators/delay.js +33 -0
  36. package/dist/Fx/combinators/dropUntil.d.ts +44 -2
  37. package/dist/Fx/combinators/dropUntil.d.ts.map +1 -1
  38. package/dist/Fx/combinators/dropUntil.js +44 -2
  39. package/dist/Fx/combinators/during.d.ts +38 -0
  40. package/dist/Fx/combinators/during.d.ts.map +1 -0
  41. package/dist/Fx/combinators/during.js +85 -0
  42. package/dist/Fx/combinators/ensuring.d.ts +34 -4
  43. package/dist/Fx/combinators/ensuring.d.ts.map +1 -1
  44. package/dist/Fx/combinators/ensuring.js +34 -4
  45. package/dist/Fx/combinators/exhaustLatestMap.d.ts +41 -5
  46. package/dist/Fx/combinators/exhaustLatestMap.d.ts.map +1 -1
  47. package/dist/Fx/combinators/exhaustLatestMap.js +41 -5
  48. package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts +40 -4
  49. package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts.map +1 -1
  50. package/dist/Fx/combinators/exhaustLatestMapEffect.js +40 -4
  51. package/dist/Fx/combinators/exhaustMap.d.ts +38 -1
  52. package/dist/Fx/combinators/exhaustMap.d.ts.map +1 -1
  53. package/dist/Fx/combinators/exhaustMap.js +38 -1
  54. package/dist/Fx/combinators/exhaustMapEffect.d.ts +33 -1
  55. package/dist/Fx/combinators/exhaustMapEffect.d.ts.map +1 -1
  56. package/dist/Fx/combinators/exhaustMapEffect.js +33 -1
  57. package/dist/Fx/combinators/exit.d.ts +23 -2
  58. package/dist/Fx/combinators/exit.d.ts.map +1 -1
  59. package/dist/Fx/combinators/exit.js +23 -2
  60. package/dist/Fx/combinators/filter.d.ts +17 -1
  61. package/dist/Fx/combinators/filter.d.ts.map +1 -1
  62. package/dist/Fx/combinators/filter.js +17 -1
  63. package/dist/Fx/combinators/filterEffect.d.ts +22 -1
  64. package/dist/Fx/combinators/filterEffect.d.ts.map +1 -1
  65. package/dist/Fx/combinators/filterEffect.js +22 -1
  66. package/dist/Fx/combinators/filterMap.d.ts +20 -1
  67. package/dist/Fx/combinators/filterMap.d.ts.map +1 -1
  68. package/dist/Fx/combinators/filterMap.js +20 -1
  69. package/dist/Fx/combinators/filterMapEffect.d.ts +21 -1
  70. package/dist/Fx/combinators/filterMapEffect.d.ts.map +1 -1
  71. package/dist/Fx/combinators/filterMapEffect.js +21 -1
  72. package/dist/Fx/combinators/filterMapLoop.d.ts +20 -1
  73. package/dist/Fx/combinators/filterMapLoop.d.ts.map +1 -1
  74. package/dist/Fx/combinators/filterMapLoop.js +20 -1
  75. package/dist/Fx/combinators/filterMapLoopCause.d.ts +21 -1
  76. package/dist/Fx/combinators/filterMapLoopCause.d.ts.map +1 -1
  77. package/dist/Fx/combinators/filterMapLoopCause.js +21 -1
  78. package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts +21 -1
  79. package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts.map +1 -1
  80. package/dist/Fx/combinators/filterMapLoopCauseEffect.js +21 -1
  81. package/dist/Fx/combinators/filterMapLoopEffect.d.ts +21 -1
  82. package/dist/Fx/combinators/filterMapLoopEffect.d.ts.map +1 -1
  83. package/dist/Fx/combinators/filterMapLoopEffect.js +21 -1
  84. package/dist/Fx/combinators/flatMap.d.ts +50 -5
  85. package/dist/Fx/combinators/flatMap.d.ts.map +1 -1
  86. package/dist/Fx/combinators/flatMap.js +36 -3
  87. package/dist/Fx/combinators/flatMapConcurrently.d.ts +51 -4
  88. package/dist/Fx/combinators/flatMapConcurrently.d.ts.map +1 -1
  89. package/dist/Fx/combinators/flatMapConcurrently.js +48 -2
  90. package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts +48 -4
  91. package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts.map +1 -1
  92. package/dist/Fx/combinators/flatMapConcurrentlyEffect.js +40 -2
  93. package/dist/Fx/combinators/flatMapEffect.d.ts +46 -4
  94. package/dist/Fx/combinators/flatMapEffect.d.ts.map +1 -1
  95. package/dist/Fx/combinators/flatMapEffect.js +32 -2
  96. package/dist/Fx/combinators/flip.d.ts +34 -2
  97. package/dist/Fx/combinators/flip.d.ts.map +1 -1
  98. package/dist/Fx/combinators/flip.js +34 -2
  99. package/dist/Fx/combinators/gen.d.ts +29 -10
  100. package/dist/Fx/combinators/gen.d.ts.map +1 -1
  101. package/dist/Fx/combinators/gen.js +28 -4
  102. package/dist/Fx/combinators/genScoped.d.ts +33 -10
  103. package/dist/Fx/combinators/genScoped.d.ts.map +1 -1
  104. package/dist/Fx/combinators/genScoped.js +31 -3
  105. package/dist/Fx/combinators/grouped.d.ts +89 -0
  106. package/dist/Fx/combinators/grouped.d.ts.map +1 -0
  107. package/dist/Fx/combinators/grouped.js +146 -0
  108. package/dist/Fx/combinators/index.d.ts +35 -0
  109. package/dist/Fx/combinators/index.d.ts.map +1 -1
  110. package/dist/Fx/combinators/index.js +35 -0
  111. package/dist/Fx/combinators/keyed.d.ts +123 -9
  112. package/dist/Fx/combinators/keyed.d.ts.map +1 -1
  113. package/dist/Fx/combinators/keyed.js +69 -11
  114. package/dist/Fx/combinators/loop.d.ts +17 -1
  115. package/dist/Fx/combinators/loop.d.ts.map +1 -1
  116. package/dist/Fx/combinators/loop.js +17 -1
  117. package/dist/Fx/combinators/loopCause.d.ts +18 -1
  118. package/dist/Fx/combinators/loopCause.d.ts.map +1 -1
  119. package/dist/Fx/combinators/loopCause.js +18 -1
  120. package/dist/Fx/combinators/loopCauseEffect.d.ts +19 -1
  121. package/dist/Fx/combinators/loopCauseEffect.d.ts.map +1 -1
  122. package/dist/Fx/combinators/loopCauseEffect.js +19 -1
  123. package/dist/Fx/combinators/loopEffect.d.ts +24 -1
  124. package/dist/Fx/combinators/loopEffect.d.ts.map +1 -1
  125. package/dist/Fx/combinators/loopEffect.js +24 -1
  126. package/dist/Fx/combinators/map.d.ts +46 -1
  127. package/dist/Fx/combinators/map.d.ts.map +1 -1
  128. package/dist/Fx/combinators/map.js +43 -1
  129. package/dist/Fx/combinators/mapBoth.d.ts +20 -1
  130. package/dist/Fx/combinators/mapBoth.d.ts.map +1 -1
  131. package/dist/Fx/combinators/mapBoth.js +20 -1
  132. package/dist/Fx/combinators/mapEffect.d.ts +25 -1
  133. package/dist/Fx/combinators/mapEffect.d.ts.map +1 -1
  134. package/dist/Fx/combinators/mapEffect.js +25 -1
  135. package/dist/Fx/combinators/mapError.d.ts +21 -5
  136. package/dist/Fx/combinators/mapError.d.ts.map +1 -1
  137. package/dist/Fx/combinators/mapError.js +21 -5
  138. package/dist/Fx/combinators/mergeAll.d.ts +35 -1
  139. package/dist/Fx/combinators/mergeAll.d.ts.map +1 -1
  140. package/dist/Fx/combinators/mergeAll.js +35 -1
  141. package/dist/Fx/combinators/mergeOrdered.d.ts +36 -4
  142. package/dist/Fx/combinators/mergeOrdered.d.ts.map +1 -1
  143. package/dist/Fx/combinators/mergeOrdered.js +68 -14
  144. package/dist/Fx/combinators/onError.d.ts +34 -4
  145. package/dist/Fx/combinators/onError.d.ts.map +1 -1
  146. package/dist/Fx/combinators/onError.js +34 -4
  147. package/dist/Fx/combinators/onExit.d.ts +29 -3
  148. package/dist/Fx/combinators/onExit.d.ts.map +1 -1
  149. package/dist/Fx/combinators/onExit.js +29 -3
  150. package/dist/Fx/combinators/onInterrupt.d.ts +49 -4
  151. package/dist/Fx/combinators/onInterrupt.d.ts.map +1 -1
  152. package/dist/Fx/combinators/onInterrupt.js +49 -4
  153. package/dist/Fx/combinators/pairwise.d.ts +28 -0
  154. package/dist/Fx/combinators/pairwise.d.ts.map +1 -0
  155. package/dist/Fx/combinators/pairwise.js +31 -0
  156. package/dist/Fx/combinators/provide.d.ts +141 -20
  157. package/dist/Fx/combinators/provide.d.ts.map +1 -1
  158. package/dist/Fx/combinators/provide.js +137 -16
  159. package/dist/Fx/combinators/race.d.ts +92 -0
  160. package/dist/Fx/combinators/race.d.ts.map +1 -0
  161. package/dist/Fx/combinators/race.js +149 -0
  162. package/dist/Fx/combinators/repeat.d.ts +41 -0
  163. package/dist/Fx/combinators/repeat.d.ts.map +1 -0
  164. package/dist/Fx/combinators/repeat.js +57 -0
  165. package/dist/Fx/combinators/result.d.ts +23 -1
  166. package/dist/Fx/combinators/result.d.ts.map +1 -1
  167. package/dist/Fx/combinators/result.js +27 -13
  168. package/dist/Fx/combinators/retry.d.ts +53 -0
  169. package/dist/Fx/combinators/retry.d.ts.map +1 -0
  170. package/dist/Fx/combinators/retry.js +71 -0
  171. package/dist/Fx/combinators/sample.d.ts +31 -0
  172. package/dist/Fx/combinators/sample.d.ts.map +1 -0
  173. package/dist/Fx/combinators/sample.js +42 -0
  174. package/dist/Fx/combinators/scan.d.ts +41 -2
  175. package/dist/Fx/combinators/scan.d.ts.map +1 -1
  176. package/dist/Fx/combinators/scan.js +43 -4
  177. package/dist/Fx/combinators/since.d.ts +30 -0
  178. package/dist/Fx/combinators/since.d.ts.map +1 -0
  179. package/dist/Fx/combinators/since.js +39 -0
  180. package/dist/Fx/combinators/skip.d.ts +33 -2
  181. package/dist/Fx/combinators/skip.d.ts.map +1 -1
  182. package/dist/Fx/combinators/skip.js +33 -2
  183. package/dist/Fx/combinators/skipRepeats.d.ts +17 -1
  184. package/dist/Fx/combinators/skipRepeats.d.ts.map +1 -1
  185. package/dist/Fx/combinators/skipRepeats.js +17 -1
  186. package/dist/Fx/combinators/skipRepeatsWith.d.ts +18 -1
  187. package/dist/Fx/combinators/skipRepeatsWith.d.ts.map +1 -1
  188. package/dist/Fx/combinators/skipRepeatsWith.js +18 -1
  189. package/dist/Fx/combinators/skipWhile.d.ts +72 -4
  190. package/dist/Fx/combinators/skipWhile.d.ts.map +1 -1
  191. package/dist/Fx/combinators/skipWhile.js +72 -4
  192. package/dist/Fx/combinators/slice.d.ts +85 -3
  193. package/dist/Fx/combinators/slice.d.ts.map +1 -1
  194. package/dist/Fx/combinators/slice.js +35 -2
  195. package/dist/Fx/combinators/switchMap.d.ts +39 -1
  196. package/dist/Fx/combinators/switchMap.d.ts.map +1 -1
  197. package/dist/Fx/combinators/switchMap.js +43 -5
  198. package/dist/Fx/combinators/switchMapEffect.d.ts +38 -1
  199. package/dist/Fx/combinators/switchMapEffect.d.ts.map +1 -1
  200. package/dist/Fx/combinators/switchMapEffect.js +38 -1
  201. package/dist/Fx/combinators/take.d.ts +34 -2
  202. package/dist/Fx/combinators/take.d.ts.map +1 -1
  203. package/dist/Fx/combinators/take.js +34 -2
  204. package/dist/Fx/combinators/takeUntil.d.ts +49 -3
  205. package/dist/Fx/combinators/takeUntil.d.ts.map +1 -1
  206. package/dist/Fx/combinators/takeUntil.js +49 -3
  207. package/dist/Fx/combinators/takeWhile.d.ts +33 -2
  208. package/dist/Fx/combinators/takeWhile.d.ts.map +1 -1
  209. package/dist/Fx/combinators/takeWhile.js +33 -2
  210. package/dist/Fx/combinators/tapEffect.d.ts +17 -1
  211. package/dist/Fx/combinators/tapEffect.d.ts.map +1 -1
  212. package/dist/Fx/combinators/tapEffect.js +17 -1
  213. package/dist/Fx/combinators/throttle.d.ts +79 -0
  214. package/dist/Fx/combinators/throttle.d.ts.map +1 -0
  215. package/dist/Fx/combinators/throttle.js +99 -0
  216. package/dist/Fx/combinators/timeout.d.ts +76 -0
  217. package/dist/Fx/combinators/timeout.d.ts.map +1 -0
  218. package/dist/Fx/combinators/timeout.js +110 -0
  219. package/dist/Fx/combinators/tuple.d.ts +32 -2
  220. package/dist/Fx/combinators/tuple.d.ts.map +1 -1
  221. package/dist/Fx/combinators/tuple.js +36 -5
  222. package/dist/Fx/combinators/until.d.ts +27 -0
  223. package/dist/Fx/combinators/until.d.ts.map +1 -0
  224. package/dist/Fx/combinators/until.js +56 -0
  225. package/dist/Fx/combinators/unwrap.d.ts +31 -2
  226. package/dist/Fx/combinators/unwrap.d.ts.map +1 -1
  227. package/dist/Fx/combinators/unwrap.js +30 -1
  228. package/dist/Fx/combinators/unwrapScoped.d.ts +34 -1
  229. package/dist/Fx/combinators/unwrapScoped.d.ts.map +1 -1
  230. package/dist/Fx/combinators/unwrapScoped.js +34 -1
  231. package/dist/Fx/combinators/when.d.ts +37 -2
  232. package/dist/Fx/combinators/when.d.ts.map +1 -1
  233. package/dist/Fx/combinators/when.js +38 -3
  234. package/dist/Fx/combinators/withLatestFrom.d.ts +58 -0
  235. package/dist/Fx/combinators/withLatestFrom.d.ts.map +1 -0
  236. package/dist/Fx/combinators/withLatestFrom.js +68 -0
  237. package/dist/Fx/combinators/withSpan.d.ts +35 -1
  238. package/dist/Fx/combinators/withSpan.d.ts.map +1 -1
  239. package/dist/Fx/combinators/withSpan.js +34 -3
  240. package/dist/Fx/combinators/zip.d.ts +64 -4
  241. package/dist/Fx/combinators/zip.d.ts.map +1 -1
  242. package/dist/Fx/combinators/zip.js +64 -4
  243. package/dist/Fx/constructors/at.d.ts +21 -1
  244. package/dist/Fx/constructors/at.d.ts.map +1 -1
  245. package/dist/Fx/constructors/at.js +21 -1
  246. package/dist/Fx/constructors/die.d.ts +22 -1
  247. package/dist/Fx/constructors/die.d.ts.map +1 -1
  248. package/dist/Fx/constructors/die.js +22 -1
  249. package/dist/Fx/constructors/empty.d.ts +19 -1
  250. package/dist/Fx/constructors/empty.d.ts.map +1 -1
  251. package/dist/Fx/constructors/empty.js +19 -1
  252. package/dist/Fx/constructors/fail.d.ts +22 -1
  253. package/dist/Fx/constructors/fail.d.ts.map +1 -1
  254. package/dist/Fx/constructors/fail.js +22 -1
  255. package/dist/Fx/constructors/failCause.d.ts +23 -1
  256. package/dist/Fx/constructors/failCause.d.ts.map +1 -1
  257. package/dist/Fx/constructors/failCause.js +23 -1
  258. package/dist/Fx/constructors/fn.d.ts +116 -16
  259. package/dist/Fx/constructors/fn.d.ts.map +1 -1
  260. package/dist/Fx/constructors/fn.js +36 -0
  261. package/dist/Fx/constructors/fromEffect.d.ts +45 -3
  262. package/dist/Fx/constructors/fromEffect.d.ts.map +1 -1
  263. package/dist/Fx/constructors/fromEffect.js +45 -3
  264. package/dist/Fx/constructors/fromFailures.d.ts +25 -1
  265. package/dist/Fx/constructors/fromFailures.d.ts.map +1 -1
  266. package/dist/Fx/constructors/fromFailures.js +25 -1
  267. package/dist/Fx/constructors/fromIterable.d.ts +23 -1
  268. package/dist/Fx/constructors/fromIterable.d.ts.map +1 -1
  269. package/dist/Fx/constructors/fromIterable.js +23 -1
  270. package/dist/Fx/constructors/fromSchedule.d.ts +26 -1
  271. package/dist/Fx/constructors/fromSchedule.d.ts.map +1 -1
  272. package/dist/Fx/constructors/fromSchedule.js +28 -3
  273. package/dist/Fx/constructors/index.d.ts +2 -1
  274. package/dist/Fx/constructors/index.d.ts.map +1 -1
  275. package/dist/Fx/constructors/index.js +2 -1
  276. package/dist/Fx/constructors/interrupt.d.ts +22 -2
  277. package/dist/Fx/constructors/interrupt.d.ts.map +1 -1
  278. package/dist/Fx/constructors/interrupt.js +22 -2
  279. package/dist/Fx/constructors/make.d.ts +151 -4
  280. package/dist/Fx/constructors/make.d.ts.map +1 -1
  281. package/dist/Fx/constructors/make.js +60 -7
  282. package/dist/Fx/constructors/periodic.d.ts +30 -1
  283. package/dist/Fx/constructors/periodic.d.ts.map +1 -1
  284. package/dist/Fx/constructors/periodic.js +30 -1
  285. package/dist/Fx/constructors/succeed.d.ts +79 -7
  286. package/dist/Fx/constructors/succeed.d.ts.map +1 -1
  287. package/dist/Fx/constructors/succeed.js +79 -7
  288. package/dist/Fx/constructors/suspend.d.ts +28 -0
  289. package/dist/Fx/constructors/suspend.d.ts.map +1 -1
  290. package/dist/Fx/constructors/suspend.js +28 -0
  291. package/dist/Fx/constructors/sync.d.ts +32 -0
  292. package/dist/Fx/constructors/sync.d.ts.map +1 -0
  293. package/dist/Fx/constructors/sync.js +32 -0
  294. package/dist/Fx/internal/DeferredRef.d.ts +259 -7
  295. package/dist/Fx/internal/DeferredRef.d.ts.map +1 -1
  296. package/dist/Fx/internal/DeferredRef.js +260 -9
  297. package/dist/Fx/internal/UnionToTuple.d.ts +22 -0
  298. package/dist/Fx/internal/UnionToTuple.d.ts.map +1 -1
  299. package/dist/Fx/internal/diff.d.ts +586 -0
  300. package/dist/Fx/internal/diff.d.ts.map +1 -1
  301. package/dist/Fx/internal/diff.js +120 -9
  302. package/dist/Fx/internal/effectableEvaluateKey.d.ts +30 -0
  303. package/dist/Fx/internal/effectableEvaluateKey.d.ts.map +1 -0
  304. package/dist/Fx/internal/effectableEvaluateKey.js +29 -0
  305. package/dist/Fx/internal/effectableWithOverride.d.ts +55 -0
  306. package/dist/Fx/internal/effectableWithOverride.d.ts.map +1 -0
  307. package/dist/Fx/internal/effectableWithOverride.js +46 -0
  308. package/dist/Fx/internal/equivalence.d.ts +29 -0
  309. package/dist/Fx/internal/equivalence.d.ts.map +1 -1
  310. package/dist/Fx/internal/equivalence.js +29 -0
  311. package/dist/Fx/internal/multicast.d.ts +145 -2
  312. package/dist/Fx/internal/multicast.d.ts.map +1 -1
  313. package/dist/Fx/internal/multicast.js +146 -4
  314. package/dist/Fx/internal/ring-buffer.d.ts +149 -0
  315. package/dist/Fx/internal/ring-buffer.d.ts.map +1 -1
  316. package/dist/Fx/internal/ring-buffer.js +155 -0
  317. package/dist/Fx/internal/scope.d.ts +184 -0
  318. package/dist/Fx/internal/scope.d.ts.map +1 -1
  319. package/dist/Fx/internal/scope.js +150 -0
  320. package/dist/Fx/internal/yieldable.d.ts +117 -2
  321. package/dist/Fx/internal/yieldable.d.ts.map +1 -1
  322. package/dist/Fx/internal/yieldable.js +86 -3
  323. package/dist/Fx/run/collect.d.ts +93 -4
  324. package/dist/Fx/run/collect.d.ts.map +1 -1
  325. package/dist/Fx/run/collect.js +94 -5
  326. package/dist/Fx/run/first.d.ts +23 -1
  327. package/dist/Fx/run/first.d.ts.map +1 -1
  328. package/dist/Fx/run/first.js +23 -1
  329. package/dist/Fx/run/fork.d.ts +52 -2
  330. package/dist/Fx/run/fork.d.ts.map +1 -1
  331. package/dist/Fx/run/fork.js +52 -2
  332. package/dist/Fx/run/observe.d.ts +112 -4
  333. package/dist/Fx/run/observe.d.ts.map +1 -1
  334. package/dist/Fx/run/observe.js +137 -16
  335. package/dist/Fx/run/runPromise.d.ts +45 -2
  336. package/dist/Fx/run/runPromise.d.ts.map +1 -1
  337. package/dist/Fx/run/runPromise.js +45 -2
  338. package/dist/Fx/stream.d.ts +92 -0
  339. package/dist/Fx/stream.d.ts.map +1 -1
  340. package/dist/Fx/stream.js +60 -1
  341. package/dist/Push/Push.d.ts +1229 -104
  342. package/dist/Push/Push.d.ts.map +1 -1
  343. package/dist/Push/Push.js +1024 -95
  344. package/dist/RefArray.d.ts +2 -0
  345. package/dist/RefArray.d.ts.map +1 -0
  346. package/dist/RefArray.js +1 -0
  347. package/dist/RefBigDecimal.d.ts +2 -0
  348. package/dist/RefBigDecimal.d.ts.map +1 -0
  349. package/dist/RefBigDecimal.js +1 -0
  350. package/dist/RefBigInt.d.ts +2 -0
  351. package/dist/RefBigInt.d.ts.map +1 -0
  352. package/dist/RefBigInt.js +1 -0
  353. package/dist/RefBoolean.d.ts +2 -0
  354. package/dist/RefBoolean.d.ts.map +1 -0
  355. package/dist/RefBoolean.js +1 -0
  356. package/dist/RefCause.d.ts +2 -0
  357. package/dist/RefCause.d.ts.map +1 -0
  358. package/dist/RefCause.js +1 -0
  359. package/dist/RefChunk.d.ts +2 -0
  360. package/dist/RefChunk.d.ts.map +1 -0
  361. package/dist/RefChunk.js +1 -0
  362. package/dist/RefDateTime.d.ts +2 -0
  363. package/dist/RefDateTime.d.ts.map +1 -0
  364. package/dist/RefDateTime.js +1 -0
  365. package/dist/RefDuration.d.ts +2 -0
  366. package/dist/RefDuration.d.ts.map +1 -0
  367. package/dist/RefDuration.js +1 -0
  368. package/dist/RefGraph.d.ts +2 -0
  369. package/dist/RefGraph.d.ts.map +1 -0
  370. package/dist/RefGraph.js +1 -0
  371. package/dist/RefHashMap.d.ts +2 -0
  372. package/dist/RefHashMap.d.ts.map +1 -0
  373. package/dist/RefHashMap.js +1 -0
  374. package/dist/RefHashRing.d.ts +2 -0
  375. package/dist/RefHashRing.d.ts.map +1 -0
  376. package/dist/RefHashRing.js +1 -0
  377. package/dist/RefHashSet.d.ts +2 -0
  378. package/dist/RefHashSet.d.ts.map +1 -0
  379. package/dist/RefHashSet.js +1 -0
  380. package/dist/RefIterable.d.ts +2 -0
  381. package/dist/RefIterable.d.ts.map +1 -0
  382. package/dist/RefIterable.js +1 -0
  383. package/dist/RefOption.d.ts +2 -0
  384. package/dist/RefOption.d.ts.map +1 -0
  385. package/dist/RefOption.js +1 -0
  386. package/dist/RefRecord.d.ts +2 -0
  387. package/dist/RefRecord.d.ts.map +1 -0
  388. package/dist/RefRecord.js +1 -0
  389. package/dist/RefResult.d.ts +2 -0
  390. package/dist/RefResult.d.ts.map +1 -0
  391. package/dist/RefResult.js +1 -0
  392. package/dist/RefString.d.ts +2 -0
  393. package/dist/RefString.d.ts.map +1 -0
  394. package/dist/RefString.js +1 -0
  395. package/dist/RefStruct.d.ts +2 -0
  396. package/dist/RefStruct.d.ts.map +1 -0
  397. package/dist/RefStruct.js +1 -0
  398. package/dist/RefSubject/Hydration.d.ts +504 -0
  399. package/dist/RefSubject/Hydration.d.ts.map +1 -0
  400. package/dist/RefSubject/Hydration.js +300 -0
  401. package/dist/RefSubject/RefArray.d.ts +382 -35
  402. package/dist/RefSubject/RefArray.d.ts.map +1 -1
  403. package/dist/RefSubject/RefArray.js +374 -40
  404. package/dist/RefSubject/RefBigDecimal.d.ts +241 -21
  405. package/dist/RefSubject/RefBigDecimal.d.ts.map +1 -1
  406. package/dist/RefSubject/RefBigDecimal.js +229 -20
  407. package/dist/RefSubject/RefBigInt.d.ts +181 -16
  408. package/dist/RefSubject/RefBigInt.d.ts.map +1 -1
  409. package/dist/RefSubject/RefBigInt.js +169 -15
  410. package/dist/RefSubject/RefBoolean.d.ts +181 -16
  411. package/dist/RefSubject/RefBoolean.d.ts.map +1 -1
  412. package/dist/RefSubject/RefBoolean.js +169 -15
  413. package/dist/RefSubject/RefCause.d.ts +133 -12
  414. package/dist/RefSubject/RefCause.d.ts.map +1 -1
  415. package/dist/RefSubject/RefCause.js +121 -11
  416. package/dist/RefSubject/RefChunk.d.ts +481 -76
  417. package/dist/RefSubject/RefChunk.d.ts.map +1 -1
  418. package/dist/RefSubject/RefChunk.js +471 -75
  419. package/dist/RefSubject/RefDateTime.d.ts +133 -12
  420. package/dist/RefSubject/RefDateTime.d.ts.map +1 -1
  421. package/dist/RefSubject/RefDateTime.js +122 -12
  422. package/dist/RefSubject/RefDuration.d.ts +169 -15
  423. package/dist/RefSubject/RefDuration.d.ts.map +1 -1
  424. package/dist/RefSubject/RefDuration.js +157 -14
  425. package/dist/RefSubject/RefGraph.d.ts +349 -35
  426. package/dist/RefSubject/RefGraph.d.ts.map +1 -1
  427. package/dist/RefSubject/RefGraph.js +334 -32
  428. package/dist/RefSubject/RefHashMap.d.ts +323 -28
  429. package/dist/RefSubject/RefHashMap.d.ts.map +1 -1
  430. package/dist/RefSubject/RefHashMap.js +317 -29
  431. package/dist/RefSubject/RefHashRing.d.ts +159 -15
  432. package/dist/RefSubject/RefHashRing.d.ts.map +1 -1
  433. package/dist/RefSubject/RefHashRing.js +145 -12
  434. package/dist/RefSubject/RefHashSet.d.ts +251 -22
  435. package/dist/RefSubject/RefHashSet.d.ts.map +1 -1
  436. package/dist/RefSubject/RefHashSet.js +238 -20
  437. package/dist/RefSubject/RefIterable.d.ts +358 -32
  438. package/dist/RefSubject/RefIterable.d.ts.map +1 -1
  439. package/dist/RefSubject/RefIterable.js +350 -30
  440. package/dist/RefSubject/RefOption.d.ts +157 -14
  441. package/dist/RefSubject/RefOption.d.ts.map +1 -1
  442. package/dist/RefSubject/RefOption.js +145 -13
  443. package/dist/RefSubject/RefRecord.d.ts +402 -64
  444. package/dist/RefSubject/RefRecord.d.ts.map +1 -1
  445. package/dist/RefSubject/RefRecord.js +364 -39
  446. package/dist/RefSubject/RefResult.d.ts +167 -35
  447. package/dist/RefSubject/RefResult.d.ts.map +1 -1
  448. package/dist/RefSubject/RefResult.js +133 -12
  449. package/dist/RefSubject/RefString.d.ts +205 -18
  450. package/dist/RefSubject/RefString.d.ts.map +1 -1
  451. package/dist/RefSubject/RefString.js +193 -17
  452. package/dist/RefSubject/RefStruct.d.ts +169 -14
  453. package/dist/RefSubject/RefStruct.d.ts.map +1 -1
  454. package/dist/RefSubject/RefStruct.js +157 -13
  455. package/dist/RefSubject/RefSubject.d.ts +1197 -45
  456. package/dist/RefSubject/RefSubject.d.ts.map +1 -1
  457. package/dist/RefSubject/RefSubject.js +935 -88
  458. package/dist/RefSubject/RefTrie.d.ts +323 -37
  459. package/dist/RefSubject/RefTrie.d.ts.map +1 -1
  460. package/dist/RefSubject/RefTrie.js +311 -31
  461. package/dist/RefSubject/RefTuple.d.ts +127 -11
  462. package/dist/RefSubject/RefTuple.d.ts.map +1 -1
  463. package/dist/RefSubject/RefTuple.js +114 -9
  464. package/dist/RefSubject/index.d.ts +1 -0
  465. package/dist/RefSubject/index.d.ts.map +1 -1
  466. package/dist/RefSubject/index.js +1 -0
  467. package/dist/RefSubject.d.ts +2 -1
  468. package/dist/RefSubject.d.ts.map +1 -1
  469. package/dist/RefSubject.js +2 -1
  470. package/dist/RefTrie.d.ts +2 -0
  471. package/dist/RefTrie.d.ts.map +1 -0
  472. package/dist/RefTrie.js +1 -0
  473. package/dist/RefTuple.d.ts +2 -0
  474. package/dist/RefTuple.d.ts.map +1 -0
  475. package/dist/RefTuple.js +1 -0
  476. package/dist/Sink/Sink.d.ts +396 -23
  477. package/dist/Sink/Sink.d.ts.map +1 -1
  478. package/dist/Sink/Sink.js +55 -7
  479. package/dist/Sink/combinators.d.ts +740 -11
  480. package/dist/Sink/combinators.d.ts.map +1 -1
  481. package/dist/Sink/combinators.js +716 -14
  482. package/dist/Subject/Subject.d.ts +1022 -27
  483. package/dist/Subject/Subject.d.ts.map +1 -1
  484. package/dist/Subject/Subject.js +909 -43
  485. package/dist/Versioned/Versioned.d.ts +447 -27
  486. package/dist/Versioned/Versioned.d.ts.map +1 -1
  487. package/dist/Versioned/Versioned.js +282 -48
  488. package/dist/index.d.ts +22 -3
  489. package/dist/index.d.ts.map +1 -1
  490. package/dist/index.js +22 -3
  491. package/package.json +126 -16
  492. package/dist/Fx/constructors/fromYieldable.d.ts +0 -12
  493. package/dist/Fx/constructors/fromYieldable.d.ts.map +0 -1
  494. package/dist/Fx/constructors/fromYieldable.js +0 -12
  495. package/src/Fx/Fx.ts +0 -164
  496. package/src/Fx/TypeId.ts +0 -25
  497. package/src/Fx/combinators/additive.ts +0 -142
  498. package/src/Fx/combinators/catch.ts +0 -421
  499. package/src/Fx/combinators/causes.ts +0 -23
  500. package/src/Fx/combinators/changesWithEffect.ts +0 -66
  501. package/src/Fx/combinators/compact.ts +0 -15
  502. package/src/Fx/combinators/continueWith.ts +0 -78
  503. package/src/Fx/combinators/dropUntil.ts +0 -47
  504. package/src/Fx/combinators/ensuring.ts +0 -23
  505. package/src/Fx/combinators/exhaustLatestMap.ts +0 -74
  506. package/src/Fx/combinators/exhaustLatestMapEffect.ts +0 -25
  507. package/src/Fx/combinators/exhaustMap.ts +0 -36
  508. package/src/Fx/combinators/exhaustMapEffect.ts +0 -23
  509. package/src/Fx/combinators/exit.ts +0 -15
  510. package/src/Fx/combinators/filter.ts +0 -22
  511. package/src/Fx/combinators/filterEffect.ts +0 -31
  512. package/src/Fx/combinators/filterMap.ts +0 -23
  513. package/src/Fx/combinators/filterMapEffect.ts +0 -32
  514. package/src/Fx/combinators/filterMapLoop.ts +0 -35
  515. package/src/Fx/combinators/filterMapLoopCause.ts +0 -36
  516. package/src/Fx/combinators/filterMapLoopCauseEffect.ts +0 -46
  517. package/src/Fx/combinators/filterMapLoopEffect.ts +0 -36
  518. package/src/Fx/combinators/flatMap.ts +0 -51
  519. package/src/Fx/combinators/flatMapConcurrently.ts +0 -39
  520. package/src/Fx/combinators/flatMapConcurrentlyEffect.ts +0 -26
  521. package/src/Fx/combinators/flatMapEffect.ts +0 -42
  522. package/src/Fx/combinators/flip.ts +0 -14
  523. package/src/Fx/combinators/gen.ts +0 -24
  524. package/src/Fx/combinators/genScoped.ts +0 -24
  525. package/src/Fx/combinators/index.ts +0 -61
  526. package/src/Fx/combinators/keyed.ts +0 -369
  527. package/src/Fx/combinators/loop.ts +0 -27
  528. package/src/Fx/combinators/loopCause.ts +0 -34
  529. package/src/Fx/combinators/loopCauseEffect.ts +0 -36
  530. package/src/Fx/combinators/loopEffect.ts +0 -34
  531. package/src/Fx/combinators/map.ts +0 -22
  532. package/src/Fx/combinators/mapBoth.ts +0 -40
  533. package/src/Fx/combinators/mapEffect.ts +0 -32
  534. package/src/Fx/combinators/mapError.ts +0 -28
  535. package/src/Fx/combinators/mergeAll.ts +0 -22
  536. package/src/Fx/combinators/mergeOrdered.ts +0 -123
  537. package/src/Fx/combinators/onError.ts +0 -40
  538. package/src/Fx/combinators/onExit.ts +0 -82
  539. package/src/Fx/combinators/onInterrupt.ts +0 -87
  540. package/src/Fx/combinators/provide.ts +0 -124
  541. package/src/Fx/combinators/result.ts +0 -39
  542. package/src/Fx/combinators/scan.ts +0 -82
  543. package/src/Fx/combinators/skip.ts +0 -41
  544. package/src/Fx/combinators/skipRepeats.ts +0 -15
  545. package/src/Fx/combinators/skipRepeatsWith.ts +0 -40
  546. package/src/Fx/combinators/skipWhile.ts +0 -100
  547. package/src/Fx/combinators/slice.ts +0 -55
  548. package/src/Fx/combinators/switchMap.ts +0 -55
  549. package/src/Fx/combinators/switchMapEffect.ts +0 -25
  550. package/src/Fx/combinators/take.ts +0 -38
  551. package/src/Fx/combinators/takeUntil.ts +0 -88
  552. package/src/Fx/combinators/takeWhile.ts +0 -47
  553. package/src/Fx/combinators/tapEffect.ts +0 -39
  554. package/src/Fx/combinators/tuple.ts +0 -79
  555. package/src/Fx/combinators/unwrap.ts +0 -21
  556. package/src/Fx/combinators/unwrapScoped.ts +0 -26
  557. package/src/Fx/combinators/when.ts +0 -64
  558. package/src/Fx/combinators/withSpan.ts +0 -24
  559. package/src/Fx/combinators/zip.ts +0 -175
  560. package/src/Fx/constructors/at.ts +0 -23
  561. package/src/Fx/constructors/die.ts +0 -17
  562. package/src/Fx/constructors/empty.ts +0 -10
  563. package/src/Fx/constructors/fail.ts +0 -14
  564. package/src/Fx/constructors/failCause.ts +0 -14
  565. package/src/Fx/constructors/fn.ts +0 -245
  566. package/src/Fx/constructors/fromEffect.ts +0 -24
  567. package/src/Fx/constructors/fromFailures.ts +0 -19
  568. package/src/Fx/constructors/fromIterable.ts +0 -15
  569. package/src/Fx/constructors/fromSchedule.ts +0 -18
  570. package/src/Fx/constructors/fromYieldable.ts +0 -17
  571. package/src/Fx/constructors/index.ts +0 -15
  572. package/src/Fx/constructors/interrupt.ts +0 -13
  573. package/src/Fx/constructors/make.ts +0 -103
  574. package/src/Fx/constructors/periodic.ts +0 -15
  575. package/src/Fx/constructors/succeed.ts +0 -37
  576. package/src/Fx/constructors/suspend.ts +0 -6
  577. package/src/Fx/index.ts +0 -6
  578. package/src/Fx/internal/DeferredRef.ts +0 -87
  579. package/src/Fx/internal/UnionToTuple.ts +0 -12
  580. package/src/Fx/internal/diff.ts +0 -191
  581. package/src/Fx/internal/equivalence.ts +0 -12
  582. package/src/Fx/internal/multicast.ts +0 -51
  583. package/src/Fx/internal/ring-buffer.ts +0 -60
  584. package/src/Fx/internal/scope.ts +0 -58
  585. package/src/Fx/internal/yieldable.ts +0 -31
  586. package/src/Fx/run/collect.ts +0 -79
  587. package/src/Fx/run/first.ts +0 -20
  588. package/src/Fx/run/fork.ts +0 -40
  589. package/src/Fx/run/index.ts +0 -5
  590. package/src/Fx/run/observe.ts +0 -114
  591. package/src/Fx/run/runPromise.ts +0 -32
  592. package/src/Fx/stream.ts +0 -42
  593. package/src/Fx.additive-combinators.test.ts +0 -126
  594. package/src/Fx.catch-additive.test.ts +0 -206
  595. package/src/Fx.catch.test.ts +0 -60
  596. package/src/Fx.dropUntil.test.ts +0 -61
  597. package/src/Fx.fn.test.ts +0 -51
  598. package/src/Fx.lifecycle.test.ts +0 -79
  599. package/src/Fx.mapError-mapBoth.test.ts +0 -101
  600. package/src/Fx.provide-combinators.test.ts +0 -94
  601. package/src/Fx.result-changesWithEffect.test.ts +0 -112
  602. package/src/Fx.scan.test.ts +0 -73
  603. package/src/Fx.takeWhile-skipWhile.test.ts +0 -84
  604. package/src/Fx.test.ts +0 -71
  605. package/src/Fx.ts +0 -1
  606. package/src/Fx.zip-merge-additive.test.ts +0 -171
  607. package/src/Fx.zip.test.ts +0 -133
  608. package/src/Push/Push.ts +0 -1072
  609. package/src/Push/index.ts +0 -1
  610. package/src/Push.additive.test.ts +0 -256
  611. package/src/Push.test.ts +0 -26
  612. package/src/Push.ts +0 -1
  613. package/src/RefSubject/RefArray.ts +0 -512
  614. package/src/RefSubject/RefBigDecimal.test.ts +0 -56
  615. package/src/RefSubject/RefBigDecimal.ts +0 -295
  616. package/src/RefSubject/RefBigInt.test.ts +0 -56
  617. package/src/RefSubject/RefBigInt.ts +0 -189
  618. package/src/RefSubject/RefBoolean.test.ts +0 -57
  619. package/src/RefSubject/RefBoolean.ts +0 -185
  620. package/src/RefSubject/RefCause.test.ts +0 -53
  621. package/src/RefSubject/RefCause.ts +0 -146
  622. package/src/RefSubject/RefChunk.ts +0 -510
  623. package/src/RefSubject/RefDateTime.test.ts +0 -43
  624. package/src/RefSubject/RefDateTime.ts +0 -264
  625. package/src/RefSubject/RefDuration.test.ts +0 -49
  626. package/src/RefSubject/RefDuration.ts +0 -188
  627. package/src/RefSubject/RefGraph.ts +0 -650
  628. package/src/RefSubject/RefHashMap.ts +0 -465
  629. package/src/RefSubject/RefHashRing.ts +0 -262
  630. package/src/RefSubject/RefHashSet.ts +0 -308
  631. package/src/RefSubject/RefIterable.ts +0 -445
  632. package/src/RefSubject/RefOption.test.ts +0 -67
  633. package/src/RefSubject/RefOption.ts +0 -193
  634. package/src/RefSubject/RefRecord.ts +0 -612
  635. package/src/RefSubject/RefResult.test.ts +0 -63
  636. package/src/RefSubject/RefResult.ts +0 -209
  637. package/src/RefSubject/RefString.test.ts +0 -61
  638. package/src/RefSubject/RefString.ts +0 -256
  639. package/src/RefSubject/RefStruct.test.ts +0 -60
  640. package/src/RefSubject/RefStruct.ts +0 -253
  641. package/src/RefSubject/RefSubject.ts +0 -2646
  642. package/src/RefSubject/RefTrie.ts +0 -356
  643. package/src/RefSubject/RefTuple.test.ts +0 -60
  644. package/src/RefSubject/RefTuple.ts +0 -231
  645. package/src/RefSubject/index.ts +0 -21
  646. package/src/RefSubject.additive-parity.test.ts +0 -101
  647. package/src/RefSubject.test.ts +0 -65
  648. package/src/RefSubject.ts +0 -1
  649. package/src/Sink/Sink.ts +0 -159
  650. package/src/Sink/combinators.ts +0 -1115
  651. package/src/Sink/index.ts +0 -2
  652. package/src/Sink.combinators.test.ts +0 -88
  653. package/src/Sink.reduce-collect-head-last.test.ts +0 -107
  654. package/src/Sink.ts +0 -1
  655. package/src/Subject/Subject.ts +0 -441
  656. package/src/Subject/index.ts +0 -1
  657. package/src/Subject.test.ts +0 -47
  658. package/src/Subject.ts +0 -1
  659. package/src/Versioned/Versioned.ts +0 -597
  660. package/src/Versioned/index.ts +0 -1
  661. package/src/Versioned.filterMap.test.ts +0 -91
  662. package/src/Versioned.test.ts +0 -23
  663. package/src/Versioned.ts +0 -1
  664. package/src/index.ts +0 -7
@@ -1,3 +1,5 @@
1
+ import * as Cause from "effect/Cause";
2
+ import * as Deferred from "effect/Deferred";
1
3
  import * as Effect from "effect/Effect";
2
4
  import * as Exit from "effect/Exit";
3
5
  import * as Fiber from "effect/Fiber";
@@ -7,19 +9,57 @@ import * as MutableRef from "effect/MutableRef";
7
9
  import * as Option from "effect/Option";
8
10
  import { pipeArguments } from "effect/Pipeable";
9
11
  import * as Scope from "effect/Scope";
10
- import * as ServiceMap from "effect/ServiceMap";
12
+ import * as Context from "effect/Context";
13
+ import { fail } from "../Fx/constructors/fail.js";
11
14
  import { RingBuffer } from "../Fx/internal/ring-buffer.js";
12
15
  import { awaitScopeClose, withExtendedScope } from "../Fx/internal/scope.js";
13
16
  import { FxTypeId } from "../Fx/TypeId.js";
14
17
  /**
15
- * Shares the execution of an Fx among multiple subscribers using a Subject.
16
- * The source Fx is started when the first subscriber arrives and stopped when the last one leaves.
18
+ * Shares one active execution of an `Fx` among subscribers through the supplied `Subject`.
19
+ *
20
+ * @remarks
21
+ * ## Why
22
+ *
23
+ * Use `share` when the caller must choose the multicast boundary—for example, a replaying subject,
24
+ * a renderer-independent state object, or a service-backed subject—while ensuring that simultaneous
25
+ * consumers do not duplicate the source's effects.
26
+ *
27
+ * ## Subscription and publication
28
+ *
29
+ * A subscriber is registered with the subject before the source starts, so the first subscriber
30
+ * observes synchronous first values and failures. The first active subscriber starts the source;
31
+ * later subscribers join that execution. When the last subscriber leaves, the source fiber is
32
+ * interrupted. A later subscriber starts a fresh session.
33
+ *
34
+ * ## Errors, services, and interruption
35
+ *
36
+ * Source successes and failures are pushed unchanged through the subject. The returned `Fx`
37
+ * requires the union of source services and subject services.
38
+ *
39
+ * ## Ownership and lifetime
40
+ *
41
+ * `Scope` owns each individual subscription. The shared source is finalized exactly once when the
42
+ * active session ends or the source itself exits. `share` takes session ownership of the supplied
43
+ * subject: source exit calls its `interrupt`, closing all of that subject's subscribers and clearing
44
+ * retained state. Do not concurrently reuse the same subject for an independently owned producer
45
+ * or subscriber population.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { Effect } from "effect"
50
+ * import { Fx } from "@typed/fx"
51
+ * import * as Subject from "@typed/fx/Subject"
52
+ *
53
+ * const backing = Subject.unsafeMake<number>(1)
54
+ * const request = Fx.fromEffect(Effect.succeed(42))
55
+ * const shared = Subject.share(request, backing)
56
+ * ```
17
57
  *
18
58
  * @param fx - The source Fx.
19
59
  * @param subject - The subject to use for multicasting.
20
60
  * @returns A shared `Fx`.
21
61
  * @since 1.0.0
22
- * @category combinators
62
+ * @category Sharing sources
23
63
  */
24
64
  export function share(fx, subject) {
25
65
  return new Share(fx, subject);
@@ -38,21 +78,215 @@ const VARIANCE = {
38
78
  _E: identity,
39
79
  _R: identity,
40
80
  };
81
+ const MAX_REPLAY_CAPACITY = 4294967295;
82
+ const INVALID_REPLAY_CAPACITY_MESSAGE = "Replay capacity must be an integer from 0 through 4294967295";
83
+ const isReplayCapacity = (capacity) => Number.isInteger(capacity) && capacity >= 0 && capacity <= MAX_REPLAY_CAPACITY;
84
+ const invalidReplayCapacity = () => new Cause.IllegalArgumentError(INVALID_REPLAY_CAPACITY_MESSAGE);
85
+ /**
86
+ * The concrete lazy `Fx` returned by `share`.
87
+ *
88
+ * @remarks
89
+ * ## Why
90
+ *
91
+ * `Share` exposes the ref-counted sharing mechanism as an ordinary `Fx`: one source execution feeds
92
+ * the selected subject while each caller has an independently scoped subscription to that subject.
93
+ * Most callers should prefer `share`, `multicast`, `hold`, or `replay` for clearer intent.
94
+ *
95
+ * ## Ownership and lifetime
96
+ *
97
+ * Construction acquires nothing. The first executing `run` starts a detached source fiber; the
98
+ * final executing `run` interrupts it. Source completion interrupts the subject's current
99
+ * subscribers. Source, subject, and sink services are required only when `run` executes.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * import { Fx } from "@typed/fx"
104
+ * import { Share, unsafeMake } from "@typed/fx/Subject"
105
+ *
106
+ * const shared = new Share(Fx.succeed(1), unsafeMake<number>())
107
+ * ```
108
+ *
109
+ * @since 1.0.0
110
+ * @category Sharing sources
111
+ */
41
112
  export class Share {
113
+ /**
114
+ * Carries `Fx` variance information for the shared output, error, and service channels.
115
+ *
116
+ * @remarks
117
+ * ## Why
118
+ *
119
+ * Lets generic `Fx` utilities recognize and infer a `Share` without inspecting its runtime fields.
120
+ *
121
+ * ## Ownership and lifetime
122
+ *
123
+ * The marker is immutable metadata and acquires no resources.
124
+ *
125
+ * @since 1.0.0
126
+ * @category type-level
127
+ */
42
128
  [FxTypeId] = VARIANCE;
129
+ /**
130
+ * Tracks the source fiber for the current active subscriber session.
131
+ *
132
+ * @remarks
133
+ * ## Why
134
+ *
135
+ * Gives the final departing subscriber an exact fiber to interrupt without restarting or
136
+ * duplicating the source.
137
+ *
138
+ * ## Ownership and lifetime
139
+ *
140
+ * The reference is empty before a session, set after the first subscriber starts the source, and
141
+ * cleared before or when that session ends. It does not outlive the `Share` instance.
142
+ *
143
+ * @since 1.0.0
144
+ * @category state
145
+ */
43
146
  _FxFiber = MutableRef.make(Option.none());
147
+ /**
148
+ * Tracks how many executing `run` effects participate in the active source session.
149
+ *
150
+ * @remarks
151
+ * ## Why
152
+ *
153
+ * Implements the first-subscriber start and last-subscriber stop boundary.
154
+ *
155
+ * ## Ownership and lifetime
156
+ *
157
+ * The counter is owned by the `Share` instance and never falls below zero. Each executing `run`
158
+ * increments once and decrements in its exit finalizer.
159
+ *
160
+ * @since 1.0.0
161
+ * @category state
162
+ */
44
163
  _RefCount = new RefCounter();
164
+ /**
165
+ * The source whose execution is shared.
166
+ *
167
+ * @remarks
168
+ * ## Why
169
+ *
170
+ * Retains the original source so every active session can start exactly that `Fx`.
171
+ *
172
+ * ## Ownership and lifetime
173
+ *
174
+ * Holding the `Fx` value starts no work. Its `R` services and cleanup participate only while a
175
+ * subscriber session is active.
176
+ *
177
+ * @since 1.0.0
178
+ * @category inputs
179
+ */
45
180
  i0;
181
+ /**
182
+ * The multicast subject receiving source publications.
183
+ *
184
+ * @remarks
185
+ * ## Why
186
+ *
187
+ * Separates source sharing from retention and publication policy.
188
+ *
189
+ * ## Ownership and lifetime
190
+ *
191
+ * `Share` does not allocate this subject. It subscribes sinks to it and interrupts it when the
192
+ * source session exits; the subject's `R2` services remain required by `run`.
193
+ *
194
+ * @since 1.0.0
195
+ * @category inputs
196
+ */
46
197
  i1;
198
+ /**
199
+ * Creates the lazy shared `Fx`; source acquisition waits until the first call to `run` executes.
200
+ *
201
+ * @remarks
202
+ * ## Why
203
+ *
204
+ * Keeps selection of the source and multicast policy separate from their execution.
205
+ *
206
+ * ## Ownership and lifetime
207
+ *
208
+ * The constructor only stores `i0` and `i1`; it starts no fiber and installs no finalizer.
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * import { Fx } from "@typed/fx"
213
+ * import { Share, unsafeMake } from "@typed/fx/Subject"
214
+ *
215
+ * const shared = new Share(Fx.succeed("ready"), unsafeMake<string>())
216
+ * ```
217
+ *
218
+ * @since 1.0.0
219
+ * @category constructors
220
+ */
47
221
  constructor(i0, i1) {
48
222
  this.i0 = i0;
49
223
  this.i1 = i1;
50
224
  }
225
+ /**
226
+ * Returns this value through the concrete class's zero-argument pipe entrypoint.
227
+ *
228
+ * @remarks
229
+ * ## Why
230
+ *
231
+ * Supplies the runtime pipe hook required by `Fx`; the concrete `Share` declaration currently
232
+ * publishes only its zero-argument signature, so typed combinator composition should target the
233
+ * `Fx` returned by `share`, `multicast`, `hold`, or `replay`.
234
+ *
235
+ * ## Ownership and lifetime
236
+ *
237
+ * Calling `pipe` itself acquires no resources; only an executing downstream `run` starts work.
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * import { Fx } from "@typed/fx"
242
+ * import { Share, unsafeMake } from "@typed/fx/Subject"
243
+ *
244
+ * const shared = new Share(Fx.succeed(1), unsafeMake<number>())
245
+ * const same = shared.pipe()
246
+ * ```
247
+ *
248
+ * @since 1.0.0
249
+ * @category utilities
250
+ */
51
251
  pipe() {
52
252
  return pipeArguments(this, arguments);
53
253
  }
254
+ /**
255
+ * Registers `sink`, joins or starts the active source session, and remains active until the
256
+ * subscription ends. Interruption removes this subscriber and stops the source if it was last.
257
+ *
258
+ * @remarks
259
+ * ## Why
260
+ *
261
+ * Implements `Fx` consumption while coordinating one source execution across independent sinks.
262
+ *
263
+ * ## Ownership and lifetime
264
+ *
265
+ * The caller's `Scope` owns its subject subscription. Source `R`, subject `R2`, and sink `R3`
266
+ * services are required during execution. Source failures are published to the sink rather than
267
+ * failing this returned Effect, whose error channel is `never`.
268
+ *
269
+ * @example
270
+ * ```ts
271
+ * import { Effect } from "effect"
272
+ * import { Fx } from "@typed/fx"
273
+ * import * as Sink from "@typed/fx/Sink"
274
+ * import { Share, unsafeMake } from "@typed/fx/Subject"
275
+ *
276
+ * const shared = new Share(Fx.succeed(1), unsafeMake<number>())
277
+ * const run = shared.run(
278
+ * Sink.make(
279
+ * () => Effect.void,
280
+ * (value) => Effect.sync(() => console.log(value))
281
+ * )
282
+ * )
283
+ * ```
284
+ *
285
+ * @since 1.0.0
286
+ * @category runners
287
+ */
54
288
  run(sink) {
55
- return Effect.flatMap(this.initialize(), () => Effect.onExit(this.i1.run(sink), () => this._RefCount.decrement() === 0 ? this.interrupt() : Effect.void));
289
+ return Effect.onExit(Effect.acquireUseRelease(Effect.forkScoped(this.i1.run(sink), { startImmediately: true }), (fiber) => Effect.andThen(this.initialize(), Fiber.join(fiber)), Fiber.interrupt), () => (this._RefCount.decrement() === 0 ? this.interrupt() : Effect.void));
56
290
  }
57
291
  initialize() {
58
292
  return Effect.suspend(() => {
@@ -75,95 +309,384 @@ export class Share {
75
309
  }
76
310
  }
77
311
  /**
78
- * Multicasts an Fx to multiple subscribers.
79
- * The source Fx is shared, so side effects only happen once per active session (ref count > 0).
312
+ * Multicasts an `Fx` without replaying values that arrived before a subscriber joined.
313
+ *
314
+ * @remarks
315
+ * ## Why
316
+ *
317
+ * `multicast` is the zero-retention sharing policy: simultaneous subscribers share source work,
318
+ * while consumers that arrive later receive only later publications.
319
+ *
320
+ * ## Ownership and lifetime
321
+ *
322
+ * The first subscriber starts one source execution and the last subscriber interrupts it. A later
323
+ * subscriber starts a fresh execution. No replay buffer is retained. Source errors and services
324
+ * are preserved, and `Scope` owns each subscription.
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * import { Fx } from "@typed/fx"
329
+ * import * as Subject from "@typed/fx/Subject"
330
+ *
331
+ * const sharedTicks = Subject.multicast(Fx.periodic("1 second"))
332
+ * ```
80
333
  *
81
334
  * @param fx - The source Fx.
82
335
  * @returns A multicasted `Fx`.
83
336
  * @since 1.0.0
84
- * @category combinators
337
+ * @category Sharing sources
85
338
  */
86
339
  export function multicast(fx) {
87
340
  return new Share(fx, unsafeMake(0));
88
341
  }
89
342
  /**
90
- * Holds the latest value emitted by the Fx and replays it to new subscribers.
343
+ * Shares an `Fx` and immediately replays its latest success or failure to each new subscriber.
344
+ *
345
+ * @remarks
346
+ * ## Why
347
+ *
348
+ * `hold` gives late subscribers the current publication without restarting an already active
349
+ * source, making it suitable for current-value streams and state-like projections.
350
+ *
351
+ * ## Ownership and lifetime
352
+ *
353
+ * One retained `Exit` belongs to the active shared subject. The first subscriber starts the source,
354
+ * the last subscriber interrupts it, and interruption clears the retained exit. Source errors and
355
+ * services remain visible in the returned `Fx`; subscription cleanup belongs to `Scope`.
356
+ *
357
+ * ## Join-during-publication behavior
358
+ *
359
+ * The latest `Exit` is retained before it enters the serialized publication queue. If a subscriber
360
+ * joins while an earlier publication is still draining, it can receive that queued exit immediately
361
+ * as replay and then receive it again when the queue reaches it. Consumers that require exactly-once
362
+ * delivery across concurrent subscription and publication must coordinate that boundary externally.
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * import { Fx } from "@typed/fx"
367
+ * import * as Subject from "@typed/fx/Subject"
368
+ *
369
+ * const currentStatus = Subject.hold(Fx.succeed("ready"))
370
+ * ```
91
371
  *
92
372
  * @param fx - The source Fx.
93
373
  * @returns A shared `Fx` that replays the latest value.
94
374
  * @since 1.0.0
95
- * @category combinators
375
+ * @category Sharing sources
96
376
  */
97
377
  export function hold(fx) {
98
378
  return new Share(fx, unsafeMake(1));
99
379
  }
100
380
  /**
101
- * Replays the last `capacity` values emitted by the Fx to new subscribers.
381
+ * Shares an `Fx` and replays up to the last `capacity` successes or failures to new subscribers.
382
+ *
383
+ * @remarks
384
+ * ## Why
385
+ *
386
+ * `replay` makes retention an explicit caller-selected policy rather than an implicit property of
387
+ * every shared stream. Capacity `0` is equivalent to multicast retention; capacity `1` has hold
388
+ * semantics; larger values replay the retained window from oldest to newest.
389
+ *
390
+ * ## Errors and interruption
391
+ *
392
+ * A non-integer, negative, or larger-than-32-bit capacity produces an `Fx` that fails with
393
+ * `Cause.IllegalArgumentError` without starting the source. Valid buffers retain `Exit` values, so
394
+ * typed failures keep their original causes and order. The last subscriber interrupts the source
395
+ * and clears the buffer; source services remain in the return type.
396
+ *
397
+ * ## Ownership and lifetime
398
+ *
399
+ * `Scope` owns each subscription and the final subscriber owns shutdown of the active source
400
+ * session. Buffer memory belongs to that session and is cleared when it is interrupted.
102
401
  *
103
- * @param capacity - The number of values to buffer and replay.
402
+ * ## Join-during-publication behavior
403
+ *
404
+ * Each `Exit` enters the replay buffer before it enters the serialized publication queue. A
405
+ * subscriber joining while an earlier publication is still draining can replay a later queued exit
406
+ * and then receive the same exit again when normal delivery reaches it. Replay guarantees retained
407
+ * order, not exactly-once delivery across a concurrent subscribe/publish race.
408
+ *
409
+ * @example
410
+ * ```ts
411
+ * import { Fx } from "@typed/fx"
412
+ * import * as Subject from "@typed/fx/Subject"
413
+ *
414
+ * const recent = Fx.fromIterable([1, 2, 3]).pipe(Subject.replay(2))
415
+ * ```
416
+ *
417
+ * @param capacity - An integer from 0 through 4,294,967,295. The buffer can retain up to
418
+ * `capacity` values, so callers own the memory policy for valid capacities. Invalid capacities
419
+ * fail through the Fx error channel with `Cause.IllegalArgumentError`.
104
420
  * @param fx - The source Fx.
105
421
  * @returns A shared `Fx` that replays values.
106
422
  * @since 1.0.0
107
- * @category combinators
423
+ * @category Sharing sources
108
424
  */
109
425
  export const replay = dual(2, function replay(fx, capacity) {
426
+ if (!isReplayCapacity(capacity)) {
427
+ return fail(invalidReplayCapacity());
428
+ }
110
429
  return new Share(fx, unsafeMake(capacity));
111
430
  });
112
431
  const DISCARD = { discard: true };
113
432
  /**
433
+ * Implements a zero-replay subject with scoped subscribers and serialized publication delivery.
434
+ *
435
+ * @remarks
436
+ * ## Why
437
+ *
438
+ * This is the queueing core behind public subjects. It snapshots subscribers per publication and
439
+ * drains successes and failures in FIFO order without recursive stack growth.
440
+ *
441
+ * ## Publication and errors
442
+ *
443
+ * A non-reentrant publisher waits for its publication to finish delivery. A publisher called from
444
+ * the active drain fiber enqueues and returns immediately so subscriber callbacks cannot deadlock;
445
+ * the outer drain subsequently delivers that publication. Sink callback defects or interruption
446
+ * are handled by the sink boundary and do not become a typed Subject failure.
447
+ *
448
+ * ## Ownership and lifetime
449
+ *
450
+ * Each `run` call creates a child scope for its sink and removes it on closure. `interrupt` closes
451
+ * all current child scopes. The instance may accept later subscriptions and publications.
452
+ *
453
+ * This class remains marked `@internal` and is not a supported construction API even though the
454
+ * current wildcard package export makes it import-reachable. Use `make` or `unsafeMake`.
455
+ *
456
+ * @example
457
+ * ```ts
458
+ * import { Effect } from "effect"
459
+ * import * as Subject from "@typed/fx/Subject"
460
+ *
461
+ * const supported = Effect.scoped(Subject.make<number>())
462
+ * ```
463
+ *
464
+ * @since 1.0.0
465
+ * @category internal
114
466
  * @internal
115
467
  */
116
468
  export class SubjectImpl {
469
+ /**
470
+ * Carries the `Fx` variance channels implemented by this subject.
471
+ *
472
+ * @remarks
473
+ * ## Why
474
+ *
475
+ * Allows the implementation to satisfy the runtime `Fx` protocol.
476
+ *
477
+ * ## Ownership and lifetime
478
+ *
479
+ * Immutable metadata; it acquires no resources.
480
+ *
481
+ * @since 1.0.0
482
+ * @category internal
483
+ */
117
484
  [FxTypeId] = VARIANCE;
118
485
  sinks = new Set();
486
+ publications = [];
487
+ publicationIndex = 0;
488
+ activePublication;
489
+ activeDrainFiberId = null;
490
+ /**
491
+ * Creates an empty zero-replay subject and binds its producer callbacks.
492
+ *
493
+ * @remarks
494
+ * ## Why
495
+ *
496
+ * Initializes the internal queueing boundary without starting work.
497
+ *
498
+ * ## Ownership and lifetime
499
+ *
500
+ * Construction acquires no fibers or scopes; later `run` calls own subscriptions.
501
+ *
502
+ * @since 1.0.0
503
+ * @category internal
504
+ */
119
505
  constructor() {
120
506
  this.onFailure = this.onFailure.bind(this);
121
507
  this.onSuccess = this.onSuccess.bind(this);
122
508
  }
509
+ /**
510
+ * Delegates to the Effect pipeable protocol.
511
+ *
512
+ * @remarks
513
+ * ## Why
514
+ *
515
+ * Lets the implementation participate in ordinary `Fx` composition.
516
+ *
517
+ * ## Ownership and lifetime
518
+ *
519
+ * Piping starts no subscription; execution begins only when the resulting `Fx` is run.
520
+ *
521
+ * @since 1.0.0
522
+ * @category internal
523
+ */
123
524
  pipe() {
124
525
  return pipeArguments(this, arguments);
125
526
  }
527
+ /**
528
+ * Registers a sink until its child scope closes.
529
+ *
530
+ * @remarks
531
+ * ## Why
532
+ *
533
+ * Implements the subscription side of the `Fx` contract.
534
+ *
535
+ * ## Ownership and lifetime
536
+ *
537
+ * The caller's `Scope` owns this subscription and its captured `R2` context. Publications deliver
538
+ * `A` or `Cause<E>` to the sink; the returned Effect itself cannot fail.
539
+ *
540
+ * @since 1.0.0
541
+ * @category internal
542
+ */
126
543
  run(sink) {
127
544
  return this.addSink(sink, awaitScopeClose);
128
545
  }
546
+ /**
547
+ * Enqueues a failure publication for the current subscriber snapshot.
548
+ *
549
+ * @remarks
550
+ * ## Why
551
+ *
552
+ * Preserves the complete Effect `Cause`, including defects and interruption, at the Sink boundary.
553
+ *
554
+ * ## Ownership and lifetime
555
+ *
556
+ * Non-reentrant callers wait for delivery; a call from the active drain fiber returns after
557
+ * enqueueing. The publication is not retained for later subscribers.
558
+ *
559
+ * @since 1.0.0
560
+ * @category internal
561
+ */
129
562
  onFailure(cause) {
130
563
  return this.onCause(cause);
131
564
  }
565
+ /**
566
+ * Enqueues a successful value for the current subscriber snapshot.
567
+ *
568
+ * @remarks
569
+ * ## Why
570
+ *
571
+ * Provides the producer-facing push operation while preserving FIFO delivery.
572
+ *
573
+ * ## Ownership and lifetime
574
+ *
575
+ * Non-reentrant callers wait for delivery; a call from the active drain fiber returns after
576
+ * enqueueing. The value is not retained for later subscribers.
577
+ *
578
+ * @since 1.0.0
579
+ * @category internal
580
+ */
132
581
  onSuccess(a) {
133
582
  return this.onEvent(a);
134
583
  }
135
584
  interruptScopes = Effect.withFiber((fiber) => Effect.forEach(Array.from(this.sinks), ([, , scope]) => Scope.close(scope, Exit.interrupt(fiber.id)), DISCARD));
585
+ /**
586
+ * Closes every currently registered subscriber scope.
587
+ *
588
+ * @remarks
589
+ * ## Why
590
+ *
591
+ * Gives the owner one cleanup boundary for all active subscriptions.
592
+ *
593
+ * ## Ownership and lifetime
594
+ *
595
+ * Finalizers run for current subscribers; later subscriptions remain possible. This base class
596
+ * retains no replay state.
597
+ *
598
+ * @since 1.0.0
599
+ * @category internal
600
+ */
136
601
  interrupt = this.interruptScopes;
137
602
  addSink(sink, f) {
138
- return withExtendedScope((innerScope) => Effect.servicesWith((ctx) => {
603
+ return withExtendedScope((innerScope) => Effect.contextWith((ctx) => {
139
604
  const entry = [sink, ctx, innerScope];
140
605
  this.sinks.add(entry);
141
606
  const remove = Effect.sync(() => this.sinks.delete(entry));
142
607
  return Effect.flatMap(Scope.addFinalizer(innerScope, remove), () => f(innerScope));
143
608
  }), "sequential");
144
609
  }
610
+ /**
611
+ * Samples the number of currently registered sinks without subscribing.
612
+ *
613
+ * @remarks
614
+ * ## Why
615
+ *
616
+ * Exposes current demand for diagnostics and coordination.
617
+ *
618
+ * ## Ownership and lifetime
619
+ *
620
+ * The Effect reads the owned sink set when executed and retains no additional state.
621
+ *
622
+ * @since 1.0.0
623
+ * @category internal
624
+ */
145
625
  subscriberCount = Effect.sync(() => this.sinks.size);
146
626
  onEvent(a) {
147
- if (this.sinks.size === 0)
148
- return Effect.void;
149
- else if (this.sinks.size === 1) {
150
- const [sink, ctx] = this.sinks.values().next().value;
151
- return runSinkEvent(sink, ctx, a);
152
- }
153
- else {
154
- return Effect.forEach(this.sinks, ([sink, ctx]) => runSinkEvent(sink, ctx, a), DISCARD);
155
- }
627
+ return this.enqueue(Exit.succeed(a));
156
628
  }
157
629
  onCause(cause) {
158
- if (this.sinks.size === 0)
159
- return Effect.void;
160
- else if (this.sinks.size === 1) {
161
- const [sink, ctx, scope] = this.sinks.values().next().value;
162
- return runSinkCause(sink, ctx, scope, cause);
163
- }
164
- else {
165
- return Effect.forEach(this.sinks, ([sink, ctx, scope]) => runSinkCause(sink, ctx, scope, cause), DISCARD);
166
- }
630
+ return this.enqueue(Exit.failCause(cause));
631
+ }
632
+ enqueue(exit) {
633
+ return Effect.withFiber((fiber) => Effect.suspend(() => {
634
+ const publication = {
635
+ exit,
636
+ acknowledgement: Deferred.makeUnsafe(),
637
+ };
638
+ this.publications.push(publication);
639
+ if (this.activeDrainFiberId === fiber.id) {
640
+ return Effect.void;
641
+ }
642
+ else if (this.activeDrainFiberId !== null) {
643
+ return Deferred.await(publication.acknowledgement);
644
+ }
645
+ const ownerFiberId = fiber.id;
646
+ this.activeDrainFiberId = ownerFiberId;
647
+ return Effect.onExit(this.drain(ownerFiberId), (exit) => this.clearDrain(ownerFiberId, exit));
648
+ }));
649
+ }
650
+ drain(ownerFiberId) {
651
+ return Effect.suspend(() => {
652
+ const publication = this.publications[this.publicationIndex++];
653
+ if (publication === undefined) {
654
+ this.publications.length = 0;
655
+ this.publicationIndex = 0;
656
+ if (this.activeDrainFiberId === ownerFiberId) {
657
+ this.activeDrainFiberId = null;
658
+ }
659
+ return Effect.void;
660
+ }
661
+ this.activePublication = publication;
662
+ const sinks = Array.from(this.sinks);
663
+ const deliver = Exit.match(publication.exit, {
664
+ onFailure: (cause) => Effect.forEach(sinks, ([sink, ctx, scope]) => runSinkCause(sink, ctx, scope, cause), DISCARD),
665
+ onSuccess: (value) => Effect.forEach(sinks, ([sink, ctx]) => runSinkEvent(sink, ctx, value), DISCARD),
666
+ });
667
+ return Effect.andThen(deliver, Effect.sync(() => {
668
+ Deferred.doneUnsafe(publication.acknowledgement, Effect.void);
669
+ this.activePublication = undefined;
670
+ }).pipe(Effect.andThen(() => this.drain(ownerFiberId))));
671
+ });
672
+ }
673
+ clearDrain(ownerFiberId, exit) {
674
+ return Effect.sync(() => {
675
+ if (Exit.isSuccess(exit) || this.activeDrainFiberId !== ownerFiberId) {
676
+ return;
677
+ }
678
+ const completion = Exit.asVoid(exit);
679
+ if (this.activePublication !== undefined) {
680
+ Deferred.doneUnsafe(this.activePublication.acknowledgement, completion);
681
+ }
682
+ for (let i = this.publicationIndex; i < this.publications.length; i++) {
683
+ Deferred.doneUnsafe(this.publications[i].acknowledgement, completion);
684
+ }
685
+ this.publications.length = 0;
686
+ this.publicationIndex = 0;
687
+ this.activePublication = undefined;
688
+ this.activeDrainFiberId = null;
689
+ });
167
690
  }
168
691
  }
169
692
  function runSinkEvent(sink, ctx, a) {
@@ -173,15 +696,92 @@ function runSinkCause(sink, ctx, scope, cause) {
173
696
  return Effect.provide(Effect.catchCause(sink.onFailure(cause), (error) => Scope.close(scope, Exit.failCause(error))), ctx);
174
697
  }
175
698
  /**
699
+ * Internal one-exit replay implementation used for public hold semantics.
700
+ *
701
+ * @remarks
702
+ * ## Why
703
+ *
704
+ * Extends the serialized Subject core with a current `Exit`, allowing a new subscriber to observe
705
+ * the latest success or failure immediately.
706
+ *
707
+ * ## Join-during-publication behavior
708
+ *
709
+ * The current exit is updated before queue delivery. A subscriber joining while another
710
+ * publication drains can replay a later queued exit and receive it again when the queue reaches it.
711
+ *
712
+ * ## Ownership and lifetime
713
+ *
714
+ * The instance owns one retained exit. `interrupt` closes subscribers and clears it. This class is
715
+ * import-reachable under the current wildcard export but remains `@internal`; use `hold`, `make(1)`,
716
+ * or `unsafeMake(1)`.
717
+ *
718
+ * @example
719
+ * ```ts
720
+ * import { Fx } from "@typed/fx"
721
+ * import * as Subject from "@typed/fx/Subject"
722
+ *
723
+ * const supported = Subject.hold(Fx.succeed("ready"))
724
+ * ```
725
+ *
726
+ * @since 1.0.0
727
+ * @category internal
176
728
  * @internal
177
729
  */
178
730
  export class HoldSubjectImpl extends SubjectImpl {
731
+ /**
732
+ * Stores the most recently published success or failure.
733
+ *
734
+ * @remarks
735
+ * ## Why
736
+ *
737
+ * Supplies the immediate current-state replay used when a sink subscribes.
738
+ *
739
+ * ## Ownership and lifetime
740
+ *
741
+ * Updated before enqueueing each publication and cleared by `interrupt`; it retains at most one
742
+ * `Exit<A, E>`.
743
+ *
744
+ * @since 1.0.0
745
+ * @category internal
746
+ */
179
747
  lastValue = MutableRef.make(Option.none());
748
+ /**
749
+ * Retains a success, then enqueues it for serialized delivery.
750
+ *
751
+ * @remarks
752
+ * ## Why
753
+ *
754
+ * Makes the latest value immediately visible to subscribers without bypassing FIFO live delivery.
755
+ *
756
+ * ## Ownership and lifetime
757
+ *
758
+ * The retained value remains until replaced or interrupted. A reentrant call returns after
759
+ * enqueueing; a joining subscriber can therefore observe the queued value twice.
760
+ *
761
+ * @since 1.0.0
762
+ * @category internal
763
+ */
180
764
  onSuccess = (a) => Effect.suspend(() => {
181
765
  // Keep track of the last value emitted by the subject
182
766
  MutableRef.set(this.lastValue, Option.some(Exit.succeed(a)));
183
767
  return this.onEvent(a);
184
768
  });
769
+ /**
770
+ * Retains a failure cause, then enqueues it for serialized delivery.
771
+ *
772
+ * @remarks
773
+ * ## Why
774
+ *
775
+ * Gives late subscribers the same current failure, preserving its complete `Cause`.
776
+ *
777
+ * ## Ownership and lifetime
778
+ *
779
+ * The retained failure remains until replaced or interrupted. A joining subscriber can replay a
780
+ * queued cause and receive it again from the live drain.
781
+ *
782
+ * @since 1.0.0
783
+ * @category internal
784
+ */
185
785
  onFailure = (cause) => {
186
786
  return Effect.suspend(() => {
187
787
  // Keep track of the last value emitted by the subject
@@ -189,6 +789,23 @@ export class HoldSubjectImpl extends SubjectImpl {
189
789
  return this.onCause(cause);
190
790
  });
191
791
  };
792
+ /**
793
+ * Registers a sink, delivers the retained exit if present, then awaits scope closure.
794
+ *
795
+ * @remarks
796
+ * ## Why
797
+ *
798
+ * Combines a current-state read with the live Subject subscription.
799
+ *
800
+ * ## Ownership and lifetime
801
+ *
802
+ * The caller's `Scope` owns registration and captured `R2` services. Replay occurs before waiting
803
+ * for later publications; concurrent queued publication can duplicate that replay as described on
804
+ * the class.
805
+ *
806
+ * @since 1.0.0
807
+ * @category internal
808
+ */
192
809
  run(sink) {
193
810
  return this.addSink(sink, (scope) => Option.match(MutableRef.get(this.lastValue), {
194
811
  onNone: () => awaitScopeClose(scope),
@@ -196,38 +813,210 @@ export class HoldSubjectImpl extends SubjectImpl {
196
813
  onSome: (exit) => Effect.flatMap(Exit.match(exit, sink), () => awaitScopeClose(scope)),
197
814
  }));
198
815
  }
816
+ /**
817
+ * Closes current subscribers and clears the retained exit.
818
+ *
819
+ * @remarks
820
+ * ## Why
821
+ *
822
+ * Couples subscription cleanup with current-state cleanup.
823
+ *
824
+ * ## Ownership and lifetime
825
+ *
826
+ * Later subscriptions remain possible but have no replay until another publication arrives.
827
+ *
828
+ * @since 1.0.0
829
+ * @category internal
830
+ */
199
831
  interrupt = Effect.tap(this.interruptScopes, Effect.sync(() => MutableRef.set(this.lastValue, Option.none())));
200
832
  }
201
833
  /**
834
+ * Internal bounded replay implementation used for public replay semantics.
835
+ *
836
+ * @remarks
837
+ * ## Why
838
+ *
839
+ * Extends the serialized Subject core with an explicit-capacity FIFO window of successful and
840
+ * failed publications.
841
+ *
842
+ * ## Join-during-publication behavior
843
+ *
844
+ * Each exit enters the ring buffer before queue delivery. A subscriber joining while another
845
+ * publication drains can replay a later queued exit and receive it again when the queue reaches it.
846
+ *
847
+ * ## Ownership and lifetime
848
+ *
849
+ * The instance owns the supplied ring buffer. `interrupt` closes subscribers and clears the buffer.
850
+ * This class is import-reachable under the current wildcard export but remains `@internal`; use
851
+ * `replay`, `make`, or `unsafeMake`.
852
+ *
853
+ * @example
854
+ * ```ts
855
+ * import { Fx } from "@typed/fx"
856
+ * import * as Subject from "@typed/fx/Subject"
857
+ *
858
+ * const supported = Fx.fromIterable([1, 2, 3]).pipe(Subject.replay(2))
859
+ * ```
860
+ *
861
+ * @since 1.0.0
862
+ * @category internal
202
863
  * @internal
203
864
  */
204
865
  export class ReplaySubjectImpl extends SubjectImpl {
866
+ /**
867
+ * Stores the bounded FIFO window of retained successes and failures.
868
+ *
869
+ * @remarks
870
+ * ## Why
871
+ *
872
+ * Makes replay capacity and eviction explicit in the implementation.
873
+ *
874
+ * ## Ownership and lifetime
875
+ *
876
+ * Owned by this subject, filled before live queue delivery, and emptied by `interrupt`.
877
+ *
878
+ * @since 1.0.0
879
+ * @category internal
880
+ */
205
881
  buffer;
882
+ /**
883
+ * Creates a replay subject around an already allocated ring buffer.
884
+ *
885
+ * @remarks
886
+ * ## Why
887
+ *
888
+ * Keeps capacity validation and allocation in the public factories while this class owns replay.
889
+ *
890
+ * ## Ownership and lifetime
891
+ *
892
+ * Construction starts no fibers. The instance retains and later clears the supplied buffer.
893
+ *
894
+ * @since 1.0.0
895
+ * @category internal
896
+ */
206
897
  constructor(buffer) {
207
898
  super();
208
899
  this.buffer = buffer;
209
900
  }
901
+ /**
902
+ * Appends a success to the ring buffer, then enqueues it for live delivery.
903
+ *
904
+ * @remarks
905
+ * ## Why
906
+ *
907
+ * Preserves one order for retained and live values while bounding memory by capacity.
908
+ *
909
+ * ## Ownership and lifetime
910
+ *
911
+ * The buffer evicts its oldest exit when full. A joining subscriber can replay this queued value
912
+ * and receive it again from the live drain.
913
+ *
914
+ * @since 1.0.0
915
+ * @category internal
916
+ */
210
917
  onSuccess = (a) => Effect.suspend(() => {
211
918
  // Keep track of the last value emitted by the subject
212
919
  this.buffer.push(Exit.succeed(a));
213
920
  return this.onEvent(a);
214
921
  });
922
+ /**
923
+ * Appends a failure cause to the ring buffer, then enqueues it for live delivery.
924
+ *
925
+ * @remarks
926
+ * ## Why
927
+ *
928
+ * Replays failures in causal order without reducing them to typed error values.
929
+ *
930
+ * ## Ownership and lifetime
931
+ *
932
+ * The complete `Cause` remains retained until eviction or interruption. A joining subscriber can
933
+ * replay the queued cause and receive it again from the live drain.
934
+ *
935
+ * @since 1.0.0
936
+ * @category internal
937
+ */
215
938
  onFailure = (cause) => Effect.suspend(() => {
216
939
  this.buffer.push(Exit.failCause(cause));
217
940
  return this.onCause(cause);
218
941
  });
942
+ /**
943
+ * Registers a sink, replays the retained window oldest-to-newest, then awaits scope closure.
944
+ *
945
+ * @remarks
946
+ * ## Why
947
+ *
948
+ * Gives late subscribers bounded history before they consume subsequent live publications.
949
+ *
950
+ * ## Ownership and lifetime
951
+ *
952
+ * The caller's `Scope` owns registration and captured `R2` services. Replay itself does not remove
953
+ * entries. Concurrent queued publication can duplicate an exit as described on the class.
954
+ *
955
+ * @since 1.0.0
956
+ * @category internal
957
+ */
219
958
  run(sink) {
220
959
  return this.addSink(sink, (scope) => Effect.flatMap(this.buffer.forEach(Exit.match(sink)), () => awaitScopeClose(scope)));
221
960
  }
961
+ /**
962
+ * Closes current subscribers and empties the replay buffer.
963
+ *
964
+ * @remarks
965
+ * ## Why
966
+ *
967
+ * Releases both subscriber lifetimes and caller-selected retained memory at one boundary.
968
+ *
969
+ * ## Ownership and lifetime
970
+ *
971
+ * Later subscriptions remain possible but have no history until new publications arrive.
972
+ *
973
+ * @since 1.0.0
974
+ * @category internal
975
+ */
222
976
  interrupt = Effect.tap(this.interruptScopes, Effect.sync(() => this.buffer.clear()));
223
977
  }
224
978
  /**
225
- * Creates a `Subject` that replays the last `replay` values. You will need to manually call `interrupt` on the subject to clear resources.
226
- * @param replay - The number of values to replay.
979
+ * Immediately allocates a `Subject` with the requested replay capacity and manual ownership.
980
+ *
981
+ * @remarks
982
+ * ## Why
983
+ *
984
+ * `unsafeMake` is the escape hatch for owners that cannot acquire through an Effect `Scope`, such
985
+ * as a long-lived host object with its own explicit teardown. Prefer `make` inside Effect programs.
986
+ *
987
+ * ## Ownership and lifetime
988
+ *
989
+ * Allocation is synchronous and starts no fibers. The caller must execute `interrupt` to close
990
+ * subscribers and clear retained `Exit` values. Capacity `0` retains nothing, capacity `1` retains
991
+ * the latest publication, and larger capacities retain the newest window in FIFO replay order.
992
+ *
993
+ * ## Errors
994
+ *
995
+ * Invalid capacities throw `Cause.IllegalArgumentError` synchronously; this function has no typed
996
+ * Effect error channel. Publishing and subscribing use the `E` and service channels of the returned
997
+ * subject.
998
+ *
999
+ * @example
1000
+ * ```ts
1001
+ * import { Effect } from "effect"
1002
+ * import * as Subject from "@typed/fx/Subject"
1003
+ *
1004
+ * const events = Subject.unsafeMake<string>(10)
1005
+ *
1006
+ * const shutdown = events.interrupt
1007
+ * const publish = events.onSuccess("ready").pipe(Effect.asVoid)
1008
+ * ```
1009
+ *
1010
+ * @param replay - An integer from 0 through 4,294,967,295. The buffer can retain up to
1011
+ * `replay` values, so callers own the memory policy for valid capacities.
227
1012
  * @returns A `Subject` that replays the last `replay` values.
1013
+ * @since 1.0.0
1014
+ * @category Subject construction
228
1015
  */
229
1016
  export function unsafeMake(replay = 0) {
230
- replay = Math.max(0, replay);
1017
+ if (!isReplayCapacity(replay)) {
1018
+ throw invalidReplayCapacity();
1019
+ }
231
1020
  if (replay === 0) {
232
1021
  return new SubjectImpl();
233
1022
  }
@@ -239,31 +1028,108 @@ export function unsafeMake(replay = 0) {
239
1028
  }
240
1029
  }
241
1030
  /**
242
- * Create a Subject which utilizes a Scope to manage the lifecycle of the subject's resources.
1031
+ * Acquires a `Subject` whose subscribers and replay state are released with the current `Scope`.
1032
+ *
1033
+ * @remarks
1034
+ * ## Why
1035
+ *
1036
+ * `make` places the imperative subject boundary under Effect's structured resource ownership, so
1037
+ * cancellation and scope closure cannot leave subscriptions or retained values behind.
1038
+ *
1039
+ * ## Ownership and lifetime
1040
+ *
1041
+ * The effect allocates when executed, not when described. Its required `Scope` installs a finalizer
1042
+ * that runs `interrupt`, closing all subscriber scopes and clearing the replay buffer. Individual
1043
+ * subscriber scopes may still end earlier without affecting other subscribers.
1044
+ *
1045
+ * ## Errors
1046
+ *
1047
+ * Invalid capacities fail in the typed error channel with `Cause.IllegalArgumentError`; no subject
1048
+ * is allocated. Once acquired, publication callbacks have no typed failure result; the subject's
1049
+ * `E` parameter describes incoming Causes rather than publication acknowledgment errors.
1050
+ * Interruption and defects remain distinct from that typed channel.
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * import { Effect } from "effect"
1055
+ * import * as Subject from "@typed/fx/Subject"
1056
+ *
1057
+ * const program = Effect.gen(function* () {
1058
+ * const messages = yield* Subject.make<string>(1)
1059
+ * yield* messages.onSuccess("online")
1060
+ * return yield* messages.subscriberCount
1061
+ * }).pipe(Effect.scoped)
1062
+ * ```
1063
+ *
1064
+ * @since 1.0.0
1065
+ * @category Subject construction
243
1066
  */
244
1067
  export function make(replay) {
245
- return Effect.acquireRelease(Effect.sync(() => unsafeMake(replay)), (subject) => subject.interrupt);
1068
+ const capacity = replay ?? 0;
1069
+ if (!isReplayCapacity(capacity)) {
1070
+ return Effect.fail(invalidReplayCapacity());
1071
+ }
1072
+ return Effect.acquireRelease(Effect.sync(() => unsafeMake(capacity)), (subject) => subject.interrupt);
246
1073
  }
1074
+ /**
1075
+ * Defines an Effect context service that is simultaneously a `Subject`, `Fx`, and `Sink` facade.
1076
+ *
1077
+ * @remarks
1078
+ * ## Why
1079
+ *
1080
+ * A named subject often represents an application-wide event boundary. `Service` keeps that
1081
+ * boundary type-safe and lets producers, consumers, and layers compose through Effect's normal
1082
+ * service channel instead of a module-global mutable instance.
1083
+ *
1084
+ * ## Ownership and lifetime
1085
+ *
1086
+ * Defining the class acquires nothing. Calling its static `make` creates a layer backed by scoped
1087
+ * `Subject.make`; releasing the layer interrupts subscriptions and clears replay. Static `Fx` and
1088
+ * `Sink` operations require `Self`, then delegate to the installed subject. Invalid replay
1089
+ * capacities fail layer construction with `Cause.IllegalArgumentError`.
1090
+ *
1091
+ * @example
1092
+ * ```ts
1093
+ * import { Effect } from "effect"
1094
+ * import { Fx } from "@typed/fx"
1095
+ * import * as Subject from "@typed/fx/Subject"
1096
+ *
1097
+ * class Notifications extends Subject.Service<Notifications, string>()("Notifications") {}
1098
+ *
1099
+ * const program = Effect.gen(function* () {
1100
+ * yield* Notifications.onSuccess("saved")
1101
+ * return yield* Fx.first(Notifications)
1102
+ * }).pipe(Effect.provide(Notifications.make(1)), Effect.scoped)
1103
+ * ```
1104
+ *
1105
+ * @since 1.0.0
1106
+ * @category Subject services
1107
+ */
247
1108
  export function Service() {
248
1109
  return (id) => {
249
- const service = ServiceMap.Service(id);
1110
+ const service = Context.Service(id);
250
1111
  // eslint-disable-next-line @typescript-eslint/no-extraneous-class
251
1112
  return class SubjectService {
252
1113
  static id = id;
253
1114
  static service = service;
1115
+ static {
1116
+ // @effect-diagnostics-next-line floatingEffect:off
1117
+ Object.assign(this, service);
1118
+ Object.assign(this.prototype, Object.getPrototypeOf(service));
1119
+ }
254
1120
  static make = (replay) => Layer.effect(service, make(replay));
255
1121
  static [FxTypeId] = VARIANCE;
256
1122
  static pipe = function () {
257
1123
  return pipeArguments(this, arguments);
258
1124
  };
259
1125
  // Fx
260
- static run = (sink) => Effect.flatMap(service.asEffect(), (subject) => subject.run(sink));
1126
+ static run = (sink) => Effect.flatMap(service, (subject) => subject.run(sink));
261
1127
  // Sink
262
- static onSuccess = (value) => Effect.flatMap(service.asEffect(), (subject) => subject.onSuccess(value));
263
- static onFailure = (cause) => Effect.flatMap(service.asEffect(), (subject) => subject.onFailure(cause));
1128
+ static onSuccess = (value) => Effect.flatMap(service, (subject) => subject.onSuccess(value));
1129
+ static onFailure = (cause) => Effect.flatMap(service, (subject) => subject.onFailure(cause));
264
1130
  // Subject
265
- static subscriberCount = Effect.flatMap(service.asEffect(), (subject) => subject.subscriberCount);
266
- static interrupt = Effect.flatMap(service.asEffect(), (subject) => subject.interrupt);
1131
+ static subscriberCount = Effect.flatMap(service, (subject) => subject.subscriberCount);
1132
+ static interrupt = Effect.flatMap(service, (subject) => subject.interrupt);
267
1133
  constructor() {
268
1134
  return SubjectService;
269
1135
  }