@typed/fx 2.0.0-beta.4 → 2.0.0-beta.6

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 (663) hide show
  1. package/README.md +34 -20
  2. package/dist/Fx/Fx.d.ts +362 -10
  3. package/dist/Fx/Fx.d.ts.map +1 -1
  4. package/dist/Fx/Fx.js +32 -1
  5. package/dist/Fx/TypeId.d.ts +49 -3
  6. package/dist/Fx/TypeId.d.ts.map +1 -1
  7. package/dist/Fx/TypeId.js +39 -2
  8. package/dist/Fx/combinators/additive.d.ts +156 -5
  9. package/dist/Fx/combinators/additive.d.ts.map +1 -1
  10. package/dist/Fx/combinators/additive.js +156 -5
  11. package/dist/Fx/combinators/catch.d.ts +195 -22
  12. package/dist/Fx/combinators/catch.d.ts.map +1 -1
  13. package/dist/Fx/combinators/catch.js +186 -16
  14. package/dist/Fx/combinators/causes.d.ts +24 -1
  15. package/dist/Fx/combinators/causes.d.ts.map +1 -1
  16. package/dist/Fx/combinators/causes.js +24 -1
  17. package/dist/Fx/combinators/changesWithEffect.d.ts +20 -0
  18. package/dist/Fx/combinators/changesWithEffect.d.ts.map +1 -1
  19. package/dist/Fx/combinators/changesWithEffect.js +20 -0
  20. package/dist/Fx/combinators/compact.d.ts +17 -0
  21. package/dist/Fx/combinators/compact.d.ts.map +1 -1
  22. package/dist/Fx/combinators/compact.js +17 -0
  23. package/dist/Fx/combinators/concatMap.d.ts +86 -0
  24. package/dist/Fx/combinators/concatMap.d.ts.map +1 -0
  25. package/dist/Fx/combinators/concatMap.js +86 -0
  26. package/dist/Fx/combinators/continueWith.d.ts +109 -1
  27. package/dist/Fx/combinators/continueWith.d.ts.map +1 -1
  28. package/dist/Fx/combinators/continueWith.js +109 -1
  29. package/dist/Fx/combinators/debounce.d.ts +34 -0
  30. package/dist/Fx/combinators/debounce.d.ts.map +1 -0
  31. package/dist/Fx/combinators/debounce.js +35 -0
  32. package/dist/Fx/combinators/delay.d.ts +34 -0
  33. package/dist/Fx/combinators/delay.d.ts.map +1 -0
  34. package/dist/Fx/combinators/delay.js +31 -0
  35. package/dist/Fx/combinators/dropUntil.d.ts +42 -0
  36. package/dist/Fx/combinators/dropUntil.d.ts.map +1 -1
  37. package/dist/Fx/combinators/dropUntil.js +42 -0
  38. package/dist/Fx/combinators/during.d.ts +38 -0
  39. package/dist/Fx/combinators/during.d.ts.map +1 -0
  40. package/dist/Fx/combinators/during.js +85 -0
  41. package/dist/Fx/combinators/ensuring.d.ts +33 -3
  42. package/dist/Fx/combinators/ensuring.d.ts.map +1 -1
  43. package/dist/Fx/combinators/ensuring.js +33 -3
  44. package/dist/Fx/combinators/exhaustLatestMap.d.ts +40 -4
  45. package/dist/Fx/combinators/exhaustLatestMap.d.ts.map +1 -1
  46. package/dist/Fx/combinators/exhaustLatestMap.js +40 -4
  47. package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts +39 -3
  48. package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts.map +1 -1
  49. package/dist/Fx/combinators/exhaustLatestMapEffect.js +39 -3
  50. package/dist/Fx/combinators/exhaustMap.d.ts +37 -0
  51. package/dist/Fx/combinators/exhaustMap.d.ts.map +1 -1
  52. package/dist/Fx/combinators/exhaustMap.js +37 -0
  53. package/dist/Fx/combinators/exhaustMapEffect.d.ts +32 -0
  54. package/dist/Fx/combinators/exhaustMapEffect.d.ts.map +1 -1
  55. package/dist/Fx/combinators/exhaustMapEffect.js +32 -0
  56. package/dist/Fx/combinators/exit.d.ts +22 -1
  57. package/dist/Fx/combinators/exit.d.ts.map +1 -1
  58. package/dist/Fx/combinators/exit.js +22 -1
  59. package/dist/Fx/combinators/filter.d.ts +16 -0
  60. package/dist/Fx/combinators/filter.d.ts.map +1 -1
  61. package/dist/Fx/combinators/filter.js +16 -0
  62. package/dist/Fx/combinators/filterEffect.d.ts +21 -0
  63. package/dist/Fx/combinators/filterEffect.d.ts.map +1 -1
  64. package/dist/Fx/combinators/filterEffect.js +21 -0
  65. package/dist/Fx/combinators/filterMap.d.ts +19 -0
  66. package/dist/Fx/combinators/filterMap.d.ts.map +1 -1
  67. package/dist/Fx/combinators/filterMap.js +19 -0
  68. package/dist/Fx/combinators/filterMapEffect.d.ts +20 -0
  69. package/dist/Fx/combinators/filterMapEffect.d.ts.map +1 -1
  70. package/dist/Fx/combinators/filterMapEffect.js +20 -0
  71. package/dist/Fx/combinators/filterMapLoop.d.ts +19 -0
  72. package/dist/Fx/combinators/filterMapLoop.d.ts.map +1 -1
  73. package/dist/Fx/combinators/filterMapLoop.js +19 -0
  74. package/dist/Fx/combinators/filterMapLoopCause.d.ts +20 -0
  75. package/dist/Fx/combinators/filterMapLoopCause.d.ts.map +1 -1
  76. package/dist/Fx/combinators/filterMapLoopCause.js +20 -0
  77. package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts +20 -0
  78. package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts.map +1 -1
  79. package/dist/Fx/combinators/filterMapLoopCauseEffect.js +20 -0
  80. package/dist/Fx/combinators/filterMapLoopEffect.d.ts +20 -0
  81. package/dist/Fx/combinators/filterMapLoopEffect.d.ts.map +1 -1
  82. package/dist/Fx/combinators/filterMapLoopEffect.js +20 -0
  83. package/dist/Fx/combinators/flatMap.d.ts +48 -3
  84. package/dist/Fx/combinators/flatMap.d.ts.map +1 -1
  85. package/dist/Fx/combinators/flatMap.js +35 -2
  86. package/dist/Fx/combinators/flatMapConcurrently.d.ts +50 -3
  87. package/dist/Fx/combinators/flatMapConcurrently.d.ts.map +1 -1
  88. package/dist/Fx/combinators/flatMapConcurrently.js +47 -1
  89. package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts +47 -3
  90. package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts.map +1 -1
  91. package/dist/Fx/combinators/flatMapConcurrentlyEffect.js +39 -1
  92. package/dist/Fx/combinators/flatMapEffect.d.ts +44 -2
  93. package/dist/Fx/combinators/flatMapEffect.d.ts.map +1 -1
  94. package/dist/Fx/combinators/flatMapEffect.js +31 -1
  95. package/dist/Fx/combinators/flip.d.ts +33 -1
  96. package/dist/Fx/combinators/flip.d.ts.map +1 -1
  97. package/dist/Fx/combinators/flip.js +33 -1
  98. package/dist/Fx/combinators/gen.d.ts +28 -9
  99. package/dist/Fx/combinators/gen.d.ts.map +1 -1
  100. package/dist/Fx/combinators/gen.js +27 -3
  101. package/dist/Fx/combinators/genScoped.d.ts +32 -9
  102. package/dist/Fx/combinators/genScoped.d.ts.map +1 -1
  103. package/dist/Fx/combinators/genScoped.js +30 -2
  104. package/dist/Fx/combinators/grouped.d.ts +89 -0
  105. package/dist/Fx/combinators/grouped.d.ts.map +1 -0
  106. package/dist/Fx/combinators/grouped.js +146 -0
  107. package/dist/Fx/combinators/index.d.ts +35 -0
  108. package/dist/Fx/combinators/index.d.ts.map +1 -1
  109. package/dist/Fx/combinators/index.js +35 -0
  110. package/dist/Fx/combinators/keyed.d.ts +121 -7
  111. package/dist/Fx/combinators/keyed.d.ts.map +1 -1
  112. package/dist/Fx/combinators/keyed.js +64 -6
  113. package/dist/Fx/combinators/loop.d.ts +16 -0
  114. package/dist/Fx/combinators/loop.d.ts.map +1 -1
  115. package/dist/Fx/combinators/loop.js +16 -0
  116. package/dist/Fx/combinators/loopCause.d.ts +17 -0
  117. package/dist/Fx/combinators/loopCause.d.ts.map +1 -1
  118. package/dist/Fx/combinators/loopCause.js +17 -0
  119. package/dist/Fx/combinators/loopCauseEffect.d.ts +18 -0
  120. package/dist/Fx/combinators/loopCauseEffect.d.ts.map +1 -1
  121. package/dist/Fx/combinators/loopCauseEffect.js +18 -0
  122. package/dist/Fx/combinators/loopEffect.d.ts +23 -0
  123. package/dist/Fx/combinators/loopEffect.d.ts.map +1 -1
  124. package/dist/Fx/combinators/loopEffect.js +23 -0
  125. package/dist/Fx/combinators/map.d.ts +45 -0
  126. package/dist/Fx/combinators/map.d.ts.map +1 -1
  127. package/dist/Fx/combinators/map.js +42 -0
  128. package/dist/Fx/combinators/mapBoth.d.ts +19 -0
  129. package/dist/Fx/combinators/mapBoth.d.ts.map +1 -1
  130. package/dist/Fx/combinators/mapBoth.js +19 -0
  131. package/dist/Fx/combinators/mapEffect.d.ts +24 -0
  132. package/dist/Fx/combinators/mapEffect.d.ts.map +1 -1
  133. package/dist/Fx/combinators/mapEffect.js +24 -0
  134. package/dist/Fx/combinators/mapError.d.ts +20 -4
  135. package/dist/Fx/combinators/mapError.d.ts.map +1 -1
  136. package/dist/Fx/combinators/mapError.js +20 -4
  137. package/dist/Fx/combinators/mergeAll.d.ts +34 -0
  138. package/dist/Fx/combinators/mergeAll.d.ts.map +1 -1
  139. package/dist/Fx/combinators/mergeAll.js +34 -0
  140. package/dist/Fx/combinators/mergeOrdered.d.ts +35 -3
  141. package/dist/Fx/combinators/mergeOrdered.d.ts.map +1 -1
  142. package/dist/Fx/combinators/mergeOrdered.js +35 -3
  143. package/dist/Fx/combinators/onError.d.ts +33 -3
  144. package/dist/Fx/combinators/onError.d.ts.map +1 -1
  145. package/dist/Fx/combinators/onError.js +33 -3
  146. package/dist/Fx/combinators/onExit.d.ts +28 -2
  147. package/dist/Fx/combinators/onExit.d.ts.map +1 -1
  148. package/dist/Fx/combinators/onExit.js +28 -2
  149. package/dist/Fx/combinators/onInterrupt.d.ts +48 -3
  150. package/dist/Fx/combinators/onInterrupt.d.ts.map +1 -1
  151. package/dist/Fx/combinators/onInterrupt.js +48 -3
  152. package/dist/Fx/combinators/pairwise.d.ts +28 -0
  153. package/dist/Fx/combinators/pairwise.d.ts.map +1 -0
  154. package/dist/Fx/combinators/pairwise.js +31 -0
  155. package/dist/Fx/combinators/provide.d.ts +130 -9
  156. package/dist/Fx/combinators/provide.d.ts.map +1 -1
  157. package/dist/Fx/combinators/provide.js +130 -9
  158. package/dist/Fx/combinators/race.d.ts +92 -0
  159. package/dist/Fx/combinators/race.d.ts.map +1 -0
  160. package/dist/Fx/combinators/race.js +149 -0
  161. package/dist/Fx/combinators/repeat.d.ts +41 -0
  162. package/dist/Fx/combinators/repeat.d.ts.map +1 -0
  163. package/dist/Fx/combinators/repeat.js +57 -0
  164. package/dist/Fx/combinators/result.d.ts +22 -0
  165. package/dist/Fx/combinators/result.d.ts.map +1 -1
  166. package/dist/Fx/combinators/result.js +26 -12
  167. package/dist/Fx/combinators/retry.d.ts +53 -0
  168. package/dist/Fx/combinators/retry.d.ts.map +1 -0
  169. package/dist/Fx/combinators/retry.js +71 -0
  170. package/dist/Fx/combinators/sample.d.ts +31 -0
  171. package/dist/Fx/combinators/sample.d.ts.map +1 -0
  172. package/dist/Fx/combinators/sample.js +42 -0
  173. package/dist/Fx/combinators/scan.d.ts +39 -0
  174. package/dist/Fx/combinators/scan.d.ts.map +1 -1
  175. package/dist/Fx/combinators/scan.js +39 -0
  176. package/dist/Fx/combinators/since.d.ts +30 -0
  177. package/dist/Fx/combinators/since.d.ts.map +1 -0
  178. package/dist/Fx/combinators/since.js +39 -0
  179. package/dist/Fx/combinators/skip.d.ts +31 -0
  180. package/dist/Fx/combinators/skip.d.ts.map +1 -1
  181. package/dist/Fx/combinators/skip.js +31 -0
  182. package/dist/Fx/combinators/skipRepeats.d.ts +16 -0
  183. package/dist/Fx/combinators/skipRepeats.d.ts.map +1 -1
  184. package/dist/Fx/combinators/skipRepeats.js +16 -0
  185. package/dist/Fx/combinators/skipRepeatsWith.d.ts +17 -0
  186. package/dist/Fx/combinators/skipRepeatsWith.d.ts.map +1 -1
  187. package/dist/Fx/combinators/skipRepeatsWith.js +17 -0
  188. package/dist/Fx/combinators/skipWhile.d.ts +68 -0
  189. package/dist/Fx/combinators/skipWhile.d.ts.map +1 -1
  190. package/dist/Fx/combinators/skipWhile.js +68 -0
  191. package/dist/Fx/combinators/slice.d.ts +82 -0
  192. package/dist/Fx/combinators/slice.d.ts.map +1 -1
  193. package/dist/Fx/combinators/slice.js +33 -0
  194. package/dist/Fx/combinators/switchMap.d.ts +38 -0
  195. package/dist/Fx/combinators/switchMap.d.ts.map +1 -1
  196. package/dist/Fx/combinators/switchMap.js +38 -0
  197. package/dist/Fx/combinators/switchMapEffect.d.ts +37 -0
  198. package/dist/Fx/combinators/switchMapEffect.d.ts.map +1 -1
  199. package/dist/Fx/combinators/switchMapEffect.js +37 -0
  200. package/dist/Fx/combinators/take.d.ts +32 -0
  201. package/dist/Fx/combinators/take.d.ts.map +1 -1
  202. package/dist/Fx/combinators/take.js +32 -0
  203. package/dist/Fx/combinators/takeUntil.d.ts +46 -0
  204. package/dist/Fx/combinators/takeUntil.d.ts.map +1 -1
  205. package/dist/Fx/combinators/takeUntil.js +46 -0
  206. package/dist/Fx/combinators/takeWhile.d.ts +31 -0
  207. package/dist/Fx/combinators/takeWhile.d.ts.map +1 -1
  208. package/dist/Fx/combinators/takeWhile.js +31 -0
  209. package/dist/Fx/combinators/tapEffect.d.ts +16 -0
  210. package/dist/Fx/combinators/tapEffect.d.ts.map +1 -1
  211. package/dist/Fx/combinators/tapEffect.js +16 -0
  212. package/dist/Fx/combinators/throttle.d.ts +79 -0
  213. package/dist/Fx/combinators/throttle.d.ts.map +1 -0
  214. package/dist/Fx/combinators/throttle.js +99 -0
  215. package/dist/Fx/combinators/timeout.d.ts +76 -0
  216. package/dist/Fx/combinators/timeout.d.ts.map +1 -0
  217. package/dist/Fx/combinators/timeout.js +110 -0
  218. package/dist/Fx/combinators/tuple.d.ts +30 -0
  219. package/dist/Fx/combinators/tuple.d.ts.map +1 -1
  220. package/dist/Fx/combinators/tuple.js +34 -3
  221. package/dist/Fx/combinators/until.d.ts +27 -0
  222. package/dist/Fx/combinators/until.d.ts.map +1 -0
  223. package/dist/Fx/combinators/until.js +56 -0
  224. package/dist/Fx/combinators/unwrap.d.ts +29 -0
  225. package/dist/Fx/combinators/unwrap.d.ts.map +1 -1
  226. package/dist/Fx/combinators/unwrap.js +29 -0
  227. package/dist/Fx/combinators/unwrapScoped.d.ts +33 -0
  228. package/dist/Fx/combinators/unwrapScoped.d.ts.map +1 -1
  229. package/dist/Fx/combinators/unwrapScoped.js +33 -0
  230. package/dist/Fx/combinators/when.d.ts +35 -0
  231. package/dist/Fx/combinators/when.d.ts.map +1 -1
  232. package/dist/Fx/combinators/when.js +36 -1
  233. package/dist/Fx/combinators/withLatestFrom.d.ts +58 -0
  234. package/dist/Fx/combinators/withLatestFrom.d.ts.map +1 -0
  235. package/dist/Fx/combinators/withLatestFrom.js +68 -0
  236. package/dist/Fx/combinators/withSpan.d.ts +35 -1
  237. package/dist/Fx/combinators/withSpan.d.ts.map +1 -1
  238. package/dist/Fx/combinators/withSpan.js +34 -3
  239. package/dist/Fx/combinators/zip.d.ts +60 -0
  240. package/dist/Fx/combinators/zip.d.ts.map +1 -1
  241. package/dist/Fx/combinators/zip.js +60 -0
  242. package/dist/Fx/constructors/at.d.ts +20 -0
  243. package/dist/Fx/constructors/at.d.ts.map +1 -1
  244. package/dist/Fx/constructors/at.js +20 -0
  245. package/dist/Fx/constructors/die.d.ts +21 -0
  246. package/dist/Fx/constructors/die.d.ts.map +1 -1
  247. package/dist/Fx/constructors/die.js +21 -0
  248. package/dist/Fx/constructors/empty.d.ts +18 -0
  249. package/dist/Fx/constructors/empty.d.ts.map +1 -1
  250. package/dist/Fx/constructors/empty.js +18 -0
  251. package/dist/Fx/constructors/fail.d.ts +21 -0
  252. package/dist/Fx/constructors/fail.d.ts.map +1 -1
  253. package/dist/Fx/constructors/fail.js +21 -0
  254. package/dist/Fx/constructors/failCause.d.ts +22 -0
  255. package/dist/Fx/constructors/failCause.d.ts.map +1 -1
  256. package/dist/Fx/constructors/failCause.js +22 -0
  257. package/dist/Fx/constructors/fn.d.ts +113 -13
  258. package/dist/Fx/constructors/fn.d.ts.map +1 -1
  259. package/dist/Fx/constructors/fn.js +36 -0
  260. package/dist/Fx/constructors/fromEffect.d.ts +43 -1
  261. package/dist/Fx/constructors/fromEffect.d.ts.map +1 -1
  262. package/dist/Fx/constructors/fromEffect.js +43 -1
  263. package/dist/Fx/constructors/fromFailures.d.ts +24 -0
  264. package/dist/Fx/constructors/fromFailures.d.ts.map +1 -1
  265. package/dist/Fx/constructors/fromFailures.js +24 -0
  266. package/dist/Fx/constructors/fromIterable.d.ts +22 -0
  267. package/dist/Fx/constructors/fromIterable.d.ts.map +1 -1
  268. package/dist/Fx/constructors/fromIterable.js +22 -0
  269. package/dist/Fx/constructors/fromSchedule.d.ts +23 -0
  270. package/dist/Fx/constructors/fromSchedule.d.ts.map +1 -1
  271. package/dist/Fx/constructors/fromSchedule.js +25 -2
  272. package/dist/Fx/constructors/index.d.ts +2 -1
  273. package/dist/Fx/constructors/index.d.ts.map +1 -1
  274. package/dist/Fx/constructors/index.js +2 -1
  275. package/dist/Fx/constructors/interrupt.d.ts +21 -1
  276. package/dist/Fx/constructors/interrupt.d.ts.map +1 -1
  277. package/dist/Fx/constructors/interrupt.js +21 -1
  278. package/dist/Fx/constructors/make.d.ts +146 -1
  279. package/dist/Fx/constructors/make.d.ts.map +1 -1
  280. package/dist/Fx/constructors/make.js +54 -3
  281. package/dist/Fx/constructors/periodic.d.ts +29 -0
  282. package/dist/Fx/constructors/periodic.d.ts.map +1 -1
  283. package/dist/Fx/constructors/periodic.js +29 -0
  284. package/dist/Fx/constructors/succeed.d.ts +75 -3
  285. package/dist/Fx/constructors/succeed.d.ts.map +1 -1
  286. package/dist/Fx/constructors/succeed.js +75 -3
  287. package/dist/Fx/constructors/suspend.d.ts +28 -0
  288. package/dist/Fx/constructors/suspend.d.ts.map +1 -1
  289. package/dist/Fx/constructors/suspend.js +28 -0
  290. package/dist/Fx/constructors/sync.d.ts +32 -0
  291. package/dist/Fx/constructors/sync.d.ts.map +1 -0
  292. package/dist/Fx/constructors/sync.js +32 -0
  293. package/dist/Fx/internal/DeferredRef.d.ts +259 -7
  294. package/dist/Fx/internal/DeferredRef.d.ts.map +1 -1
  295. package/dist/Fx/internal/DeferredRef.js +260 -9
  296. package/dist/Fx/internal/UnionToTuple.d.ts +22 -0
  297. package/dist/Fx/internal/UnionToTuple.d.ts.map +1 -1
  298. package/dist/Fx/internal/diff.d.ts +586 -0
  299. package/dist/Fx/internal/diff.d.ts.map +1 -1
  300. package/dist/Fx/internal/diff.js +120 -9
  301. package/dist/Fx/internal/effectableEvaluateKey.d.ts +30 -0
  302. package/dist/Fx/internal/effectableEvaluateKey.d.ts.map +1 -0
  303. package/dist/Fx/internal/effectableEvaluateKey.js +29 -0
  304. package/dist/Fx/internal/effectableWithOverride.d.ts +55 -0
  305. package/dist/Fx/internal/effectableWithOverride.d.ts.map +1 -0
  306. package/dist/Fx/internal/effectableWithOverride.js +46 -0
  307. package/dist/Fx/internal/equivalence.d.ts +29 -0
  308. package/dist/Fx/internal/equivalence.d.ts.map +1 -1
  309. package/dist/Fx/internal/equivalence.js +29 -0
  310. package/dist/Fx/internal/multicast.d.ts +145 -2
  311. package/dist/Fx/internal/multicast.d.ts.map +1 -1
  312. package/dist/Fx/internal/multicast.js +146 -4
  313. package/dist/Fx/internal/ring-buffer.d.ts +149 -0
  314. package/dist/Fx/internal/ring-buffer.d.ts.map +1 -1
  315. package/dist/Fx/internal/ring-buffer.js +155 -0
  316. package/dist/Fx/internal/scope.d.ts +184 -0
  317. package/dist/Fx/internal/scope.d.ts.map +1 -1
  318. package/dist/Fx/internal/scope.js +150 -0
  319. package/dist/Fx/internal/yieldable.d.ts +117 -2
  320. package/dist/Fx/internal/yieldable.d.ts.map +1 -1
  321. package/dist/Fx/internal/yieldable.js +86 -3
  322. package/dist/Fx/run/collect.d.ts +89 -0
  323. package/dist/Fx/run/collect.d.ts.map +1 -1
  324. package/dist/Fx/run/collect.js +90 -1
  325. package/dist/Fx/run/first.d.ts +22 -0
  326. package/dist/Fx/run/first.d.ts.map +1 -1
  327. package/dist/Fx/run/first.js +22 -0
  328. package/dist/Fx/run/fork.d.ts +50 -0
  329. package/dist/Fx/run/fork.d.ts.map +1 -1
  330. package/dist/Fx/run/fork.js +50 -0
  331. package/dist/Fx/run/observe.d.ts +106 -0
  332. package/dist/Fx/run/observe.d.ts.map +1 -1
  333. package/dist/Fx/run/observe.js +106 -0
  334. package/dist/Fx/run/runPromise.d.ts +43 -0
  335. package/dist/Fx/run/runPromise.d.ts.map +1 -1
  336. package/dist/Fx/run/runPromise.js +43 -0
  337. package/dist/Fx/stream.d.ts +92 -0
  338. package/dist/Fx/stream.d.ts.map +1 -1
  339. package/dist/Fx/stream.js +60 -1
  340. package/dist/Push/Push.d.ts +1216 -91
  341. package/dist/Push/Push.d.ts.map +1 -1
  342. package/dist/Push/Push.js +1012 -83
  343. package/dist/RefArray.d.ts +2 -0
  344. package/dist/RefArray.d.ts.map +1 -0
  345. package/dist/RefArray.js +1 -0
  346. package/dist/RefBigDecimal.d.ts +2 -0
  347. package/dist/RefBigDecimal.d.ts.map +1 -0
  348. package/dist/RefBigDecimal.js +1 -0
  349. package/dist/RefBigInt.d.ts +2 -0
  350. package/dist/RefBigInt.d.ts.map +1 -0
  351. package/dist/RefBigInt.js +1 -0
  352. package/dist/RefBoolean.d.ts +2 -0
  353. package/dist/RefBoolean.d.ts.map +1 -0
  354. package/dist/RefBoolean.js +1 -0
  355. package/dist/RefCause.d.ts +2 -0
  356. package/dist/RefCause.d.ts.map +1 -0
  357. package/dist/RefCause.js +1 -0
  358. package/dist/RefChunk.d.ts +2 -0
  359. package/dist/RefChunk.d.ts.map +1 -0
  360. package/dist/RefChunk.js +1 -0
  361. package/dist/RefDateTime.d.ts +2 -0
  362. package/dist/RefDateTime.d.ts.map +1 -0
  363. package/dist/RefDateTime.js +1 -0
  364. package/dist/RefDuration.d.ts +2 -0
  365. package/dist/RefDuration.d.ts.map +1 -0
  366. package/dist/RefDuration.js +1 -0
  367. package/dist/RefGraph.d.ts +2 -0
  368. package/dist/RefGraph.d.ts.map +1 -0
  369. package/dist/RefGraph.js +1 -0
  370. package/dist/RefHashMap.d.ts +2 -0
  371. package/dist/RefHashMap.d.ts.map +1 -0
  372. package/dist/RefHashMap.js +1 -0
  373. package/dist/RefHashRing.d.ts +2 -0
  374. package/dist/RefHashRing.d.ts.map +1 -0
  375. package/dist/RefHashRing.js +1 -0
  376. package/dist/RefHashSet.d.ts +2 -0
  377. package/dist/RefHashSet.d.ts.map +1 -0
  378. package/dist/RefHashSet.js +1 -0
  379. package/dist/RefIterable.d.ts +2 -0
  380. package/dist/RefIterable.d.ts.map +1 -0
  381. package/dist/RefIterable.js +1 -0
  382. package/dist/RefOption.d.ts +2 -0
  383. package/dist/RefOption.d.ts.map +1 -0
  384. package/dist/RefOption.js +1 -0
  385. package/dist/RefRecord.d.ts +2 -0
  386. package/dist/RefRecord.d.ts.map +1 -0
  387. package/dist/RefRecord.js +1 -0
  388. package/dist/RefResult.d.ts +2 -0
  389. package/dist/RefResult.d.ts.map +1 -0
  390. package/dist/RefResult.js +1 -0
  391. package/dist/RefString.d.ts +2 -0
  392. package/dist/RefString.d.ts.map +1 -0
  393. package/dist/RefString.js +1 -0
  394. package/dist/RefStruct.d.ts +2 -0
  395. package/dist/RefStruct.d.ts.map +1 -0
  396. package/dist/RefStruct.js +1 -0
  397. package/dist/RefSubject/Hydration.d.ts +504 -0
  398. package/dist/RefSubject/Hydration.d.ts.map +1 -0
  399. package/dist/RefSubject/Hydration.js +300 -0
  400. package/dist/RefSubject/RefArray.d.ts +351 -4
  401. package/dist/RefSubject/RefArray.d.ts.map +1 -1
  402. package/dist/RefSubject/RefArray.js +339 -3
  403. package/dist/RefSubject/RefBigDecimal.d.ts +221 -1
  404. package/dist/RefSubject/RefBigDecimal.d.ts.map +1 -1
  405. package/dist/RefSubject/RefBigDecimal.js +210 -1
  406. package/dist/RefSubject/RefBigInt.d.ts +166 -1
  407. package/dist/RefSubject/RefBigInt.d.ts.map +1 -1
  408. package/dist/RefSubject/RefBigInt.js +155 -1
  409. package/dist/RefSubject/RefBoolean.d.ts +166 -1
  410. package/dist/RefSubject/RefBoolean.d.ts.map +1 -1
  411. package/dist/RefSubject/RefBoolean.js +155 -1
  412. package/dist/RefSubject/RefCause.d.ts +122 -1
  413. package/dist/RefSubject/RefCause.d.ts.map +1 -1
  414. package/dist/RefSubject/RefCause.js +111 -1
  415. package/dist/RefSubject/RefChunk.d.ts +406 -1
  416. package/dist/RefSubject/RefChunk.d.ts.map +1 -1
  417. package/dist/RefSubject/RefChunk.js +394 -0
  418. package/dist/RefSubject/RefDateTime.d.ts +122 -1
  419. package/dist/RefSubject/RefDateTime.d.ts.map +1 -1
  420. package/dist/RefSubject/RefDateTime.js +111 -1
  421. package/dist/RefSubject/RefDuration.d.ts +155 -1
  422. package/dist/RefSubject/RefDuration.d.ts.map +1 -1
  423. package/dist/RefSubject/RefDuration.js +144 -1
  424. package/dist/RefSubject/RefGraph.d.ts +320 -6
  425. package/dist/RefSubject/RefGraph.d.ts.map +1 -1
  426. package/dist/RefSubject/RefGraph.js +303 -0
  427. package/dist/RefSubject/RefHashMap.d.ts +296 -1
  428. package/dist/RefSubject/RefHashMap.d.ts.map +1 -1
  429. package/dist/RefSubject/RefHashMap.js +284 -0
  430. package/dist/RefSubject/RefHashRing.d.ts +146 -2
  431. package/dist/RefSubject/RefHashRing.d.ts.map +1 -1
  432. package/dist/RefSubject/RefHashRing.js +133 -0
  433. package/dist/RefSubject/RefHashSet.d.ts +230 -1
  434. package/dist/RefSubject/RefHashSet.d.ts.map +1 -1
  435. package/dist/RefSubject/RefHashSet.js +218 -0
  436. package/dist/RefSubject/RefIterable.d.ts +327 -1
  437. package/dist/RefSubject/RefIterable.d.ts.map +1 -1
  438. package/dist/RefSubject/RefIterable.js +315 -0
  439. package/dist/RefSubject/RefOption.d.ts +144 -1
  440. package/dist/RefSubject/RefOption.d.ts.map +1 -1
  441. package/dist/RefSubject/RefOption.js +133 -1
  442. package/dist/RefSubject/RefRecord.d.ts +339 -1
  443. package/dist/RefSubject/RefRecord.d.ts.map +1 -1
  444. package/dist/RefSubject/RefRecord.js +327 -0
  445. package/dist/RefSubject/RefResult.d.ts +155 -23
  446. package/dist/RefSubject/RefResult.d.ts.map +1 -1
  447. package/dist/RefSubject/RefResult.js +122 -1
  448. package/dist/RefSubject/RefString.d.ts +188 -1
  449. package/dist/RefSubject/RefString.d.ts.map +1 -1
  450. package/dist/RefSubject/RefString.js +177 -1
  451. package/dist/RefSubject/RefStruct.d.ts +156 -1
  452. package/dist/RefSubject/RefStruct.d.ts.map +1 -1
  453. package/dist/RefSubject/RefStruct.js +145 -1
  454. package/dist/RefSubject/RefSubject.d.ts +1166 -13
  455. package/dist/RefSubject/RefSubject.d.ts.map +1 -1
  456. package/dist/RefSubject/RefSubject.js +843 -51
  457. package/dist/RefSubject/RefTrie.d.ts +290 -4
  458. package/dist/RefSubject/RefTrie.d.ts.map +1 -1
  459. package/dist/RefSubject/RefTrie.js +278 -3
  460. package/dist/RefSubject/RefTuple.d.ts +117 -1
  461. package/dist/RefSubject/RefTuple.d.ts.map +1 -1
  462. package/dist/RefSubject/RefTuple.js +106 -1
  463. package/dist/RefSubject/index.d.ts +1 -0
  464. package/dist/RefSubject/index.d.ts.map +1 -1
  465. package/dist/RefSubject/index.js +1 -0
  466. package/dist/RefSubject.d.ts +2 -1
  467. package/dist/RefSubject.d.ts.map +1 -1
  468. package/dist/RefSubject.js +2 -1
  469. package/dist/RefTrie.d.ts +2 -0
  470. package/dist/RefTrie.d.ts.map +1 -0
  471. package/dist/RefTrie.js +1 -0
  472. package/dist/RefTuple.d.ts +2 -0
  473. package/dist/RefTuple.d.ts.map +1 -0
  474. package/dist/RefTuple.js +1 -0
  475. package/dist/Sink/Sink.d.ts +381 -10
  476. package/dist/Sink/Sink.d.ts.map +1 -1
  477. package/dist/Sink/Sink.js +49 -2
  478. package/dist/Sink/combinators.d.ts +731 -2
  479. package/dist/Sink/combinators.d.ts.map +1 -1
  480. package/dist/Sink/combinators.js +706 -4
  481. package/dist/Subject/Subject.d.ts +1013 -19
  482. package/dist/Subject/Subject.d.ts.map +1 -1
  483. package/dist/Subject/Subject.js +901 -36
  484. package/dist/Versioned/Versioned.d.ts +424 -7
  485. package/dist/Versioned/Versioned.d.ts.map +1 -1
  486. package/dist/Versioned/Versioned.js +238 -12
  487. package/dist/index.d.ts +22 -3
  488. package/dist/index.d.ts.map +1 -1
  489. package/dist/index.js +22 -3
  490. package/package.json +123 -14
  491. package/dist/Fx/constructors/fromYieldable.d.ts +0 -12
  492. package/dist/Fx/constructors/fromYieldable.d.ts.map +0 -1
  493. package/dist/Fx/constructors/fromYieldable.js +0 -12
  494. package/src/Fx/Fx.ts +0 -164
  495. package/src/Fx/TypeId.ts +0 -25
  496. package/src/Fx/combinators/additive.ts +0 -142
  497. package/src/Fx/combinators/catch.ts +0 -416
  498. package/src/Fx/combinators/causes.ts +0 -23
  499. package/src/Fx/combinators/changesWithEffect.ts +0 -66
  500. package/src/Fx/combinators/compact.ts +0 -15
  501. package/src/Fx/combinators/continueWith.ts +0 -78
  502. package/src/Fx/combinators/dropUntil.ts +0 -47
  503. package/src/Fx/combinators/ensuring.ts +0 -23
  504. package/src/Fx/combinators/exhaustLatestMap.ts +0 -74
  505. package/src/Fx/combinators/exhaustLatestMapEffect.ts +0 -25
  506. package/src/Fx/combinators/exhaustMap.ts +0 -36
  507. package/src/Fx/combinators/exhaustMapEffect.ts +0 -23
  508. package/src/Fx/combinators/exit.ts +0 -15
  509. package/src/Fx/combinators/filter.ts +0 -22
  510. package/src/Fx/combinators/filterEffect.ts +0 -31
  511. package/src/Fx/combinators/filterMap.ts +0 -23
  512. package/src/Fx/combinators/filterMapEffect.ts +0 -32
  513. package/src/Fx/combinators/filterMapLoop.ts +0 -35
  514. package/src/Fx/combinators/filterMapLoopCause.ts +0 -36
  515. package/src/Fx/combinators/filterMapLoopCauseEffect.ts +0 -46
  516. package/src/Fx/combinators/filterMapLoopEffect.ts +0 -36
  517. package/src/Fx/combinators/flatMap.ts +0 -51
  518. package/src/Fx/combinators/flatMapConcurrently.ts +0 -39
  519. package/src/Fx/combinators/flatMapConcurrentlyEffect.ts +0 -26
  520. package/src/Fx/combinators/flatMapEffect.ts +0 -42
  521. package/src/Fx/combinators/flip.ts +0 -14
  522. package/src/Fx/combinators/gen.ts +0 -24
  523. package/src/Fx/combinators/genScoped.ts +0 -24
  524. package/src/Fx/combinators/index.ts +0 -61
  525. package/src/Fx/combinators/keyed.ts +0 -369
  526. package/src/Fx/combinators/loop.ts +0 -27
  527. package/src/Fx/combinators/loopCause.ts +0 -34
  528. package/src/Fx/combinators/loopCauseEffect.ts +0 -36
  529. package/src/Fx/combinators/loopEffect.ts +0 -34
  530. package/src/Fx/combinators/map.ts +0 -22
  531. package/src/Fx/combinators/mapBoth.ts +0 -40
  532. package/src/Fx/combinators/mapEffect.ts +0 -32
  533. package/src/Fx/combinators/mapError.ts +0 -28
  534. package/src/Fx/combinators/mergeAll.ts +0 -22
  535. package/src/Fx/combinators/mergeOrdered.ts +0 -123
  536. package/src/Fx/combinators/onError.ts +0 -40
  537. package/src/Fx/combinators/onExit.ts +0 -82
  538. package/src/Fx/combinators/onInterrupt.ts +0 -87
  539. package/src/Fx/combinators/provide.ts +0 -124
  540. package/src/Fx/combinators/result.ts +0 -39
  541. package/src/Fx/combinators/scan.ts +0 -82
  542. package/src/Fx/combinators/skip.ts +0 -41
  543. package/src/Fx/combinators/skipRepeats.ts +0 -15
  544. package/src/Fx/combinators/skipRepeatsWith.ts +0 -40
  545. package/src/Fx/combinators/skipWhile.ts +0 -100
  546. package/src/Fx/combinators/slice.ts +0 -55
  547. package/src/Fx/combinators/switchMap.ts +0 -55
  548. package/src/Fx/combinators/switchMapEffect.ts +0 -25
  549. package/src/Fx/combinators/take.ts +0 -38
  550. package/src/Fx/combinators/takeUntil.ts +0 -88
  551. package/src/Fx/combinators/takeWhile.ts +0 -47
  552. package/src/Fx/combinators/tapEffect.ts +0 -39
  553. package/src/Fx/combinators/tuple.ts +0 -79
  554. package/src/Fx/combinators/unwrap.ts +0 -21
  555. package/src/Fx/combinators/unwrapScoped.ts +0 -26
  556. package/src/Fx/combinators/when.ts +0 -64
  557. package/src/Fx/combinators/withSpan.ts +0 -24
  558. package/src/Fx/combinators/zip.ts +0 -175
  559. package/src/Fx/constructors/at.ts +0 -23
  560. package/src/Fx/constructors/die.ts +0 -17
  561. package/src/Fx/constructors/empty.ts +0 -10
  562. package/src/Fx/constructors/fail.ts +0 -14
  563. package/src/Fx/constructors/failCause.ts +0 -14
  564. package/src/Fx/constructors/fn.ts +0 -245
  565. package/src/Fx/constructors/fromEffect.ts +0 -24
  566. package/src/Fx/constructors/fromFailures.ts +0 -19
  567. package/src/Fx/constructors/fromIterable.ts +0 -15
  568. package/src/Fx/constructors/fromSchedule.ts +0 -18
  569. package/src/Fx/constructors/fromYieldable.ts +0 -17
  570. package/src/Fx/constructors/index.ts +0 -15
  571. package/src/Fx/constructors/interrupt.ts +0 -13
  572. package/src/Fx/constructors/make.ts +0 -103
  573. package/src/Fx/constructors/periodic.ts +0 -15
  574. package/src/Fx/constructors/succeed.ts +0 -37
  575. package/src/Fx/constructors/suspend.ts +0 -6
  576. package/src/Fx/index.ts +0 -6
  577. package/src/Fx/internal/DeferredRef.ts +0 -87
  578. package/src/Fx/internal/UnionToTuple.ts +0 -12
  579. package/src/Fx/internal/diff.ts +0 -191
  580. package/src/Fx/internal/equivalence.ts +0 -12
  581. package/src/Fx/internal/multicast.ts +0 -51
  582. package/src/Fx/internal/ring-buffer.ts +0 -60
  583. package/src/Fx/internal/scope.ts +0 -58
  584. package/src/Fx/internal/yieldable.ts +0 -31
  585. package/src/Fx/run/collect.ts +0 -79
  586. package/src/Fx/run/first.ts +0 -20
  587. package/src/Fx/run/fork.ts +0 -40
  588. package/src/Fx/run/index.ts +0 -5
  589. package/src/Fx/run/observe.ts +0 -114
  590. package/src/Fx/run/runPromise.ts +0 -32
  591. package/src/Fx/stream.ts +0 -42
  592. package/src/Fx.additive-combinators.test.ts +0 -126
  593. package/src/Fx.catch-additive.test.ts +0 -206
  594. package/src/Fx.catch.test.ts +0 -60
  595. package/src/Fx.dropUntil.test.ts +0 -61
  596. package/src/Fx.fn.test.ts +0 -51
  597. package/src/Fx.lifecycle.test.ts +0 -79
  598. package/src/Fx.mapError-mapBoth.test.ts +0 -101
  599. package/src/Fx.provide-combinators.test.ts +0 -94
  600. package/src/Fx.result-changesWithEffect.test.ts +0 -112
  601. package/src/Fx.scan.test.ts +0 -73
  602. package/src/Fx.takeWhile-skipWhile.test.ts +0 -84
  603. package/src/Fx.test.ts +0 -71
  604. package/src/Fx.ts +0 -1
  605. package/src/Fx.zip-merge-additive.test.ts +0 -171
  606. package/src/Fx.zip.test.ts +0 -133
  607. package/src/Push/Push.ts +0 -1093
  608. package/src/Push/index.ts +0 -1
  609. package/src/Push.additive.test.ts +0 -256
  610. package/src/Push.test.ts +0 -26
  611. package/src/Push.ts +0 -1
  612. package/src/RefSubject/RefArray.ts +0 -516
  613. package/src/RefSubject/RefBigDecimal.test.ts +0 -56
  614. package/src/RefSubject/RefBigDecimal.ts +0 -295
  615. package/src/RefSubject/RefBigInt.test.ts +0 -56
  616. package/src/RefSubject/RefBigInt.ts +0 -189
  617. package/src/RefSubject/RefBoolean.test.ts +0 -57
  618. package/src/RefSubject/RefBoolean.ts +0 -185
  619. package/src/RefSubject/RefCause.test.ts +0 -53
  620. package/src/RefSubject/RefCause.ts +0 -146
  621. package/src/RefSubject/RefChunk.ts +0 -516
  622. package/src/RefSubject/RefDateTime.test.ts +0 -43
  623. package/src/RefSubject/RefDateTime.ts +0 -261
  624. package/src/RefSubject/RefDuration.test.ts +0 -49
  625. package/src/RefSubject/RefDuration.ts +0 -188
  626. package/src/RefSubject/RefGraph.ts +0 -649
  627. package/src/RefSubject/RefHashMap.ts +0 -474
  628. package/src/RefSubject/RefHashRing.ts +0 -262
  629. package/src/RefSubject/RefHashSet.ts +0 -308
  630. package/src/RefSubject/RefIterable.ts +0 -454
  631. package/src/RefSubject/RefOption.test.ts +0 -67
  632. package/src/RefSubject/RefOption.ts +0 -193
  633. package/src/RefSubject/RefRecord.ts +0 -621
  634. package/src/RefSubject/RefResult.test.ts +0 -63
  635. package/src/RefSubject/RefResult.ts +0 -209
  636. package/src/RefSubject/RefString.test.ts +0 -61
  637. package/src/RefSubject/RefString.ts +0 -256
  638. package/src/RefSubject/RefStruct.test.ts +0 -60
  639. package/src/RefSubject/RefStruct.ts +0 -253
  640. package/src/RefSubject/RefSubject.ts +0 -2642
  641. package/src/RefSubject/RefTrie.ts +0 -365
  642. package/src/RefSubject/RefTuple.test.ts +0 -60
  643. package/src/RefSubject/RefTuple.ts +0 -231
  644. package/src/RefSubject/index.ts +0 -21
  645. package/src/RefSubject.additive-parity.test.ts +0 -101
  646. package/src/RefSubject.test.ts +0 -65
  647. package/src/RefSubject.ts +0 -1
  648. package/src/Sink/Sink.ts +0 -159
  649. package/src/Sink/combinators.ts +0 -1115
  650. package/src/Sink/index.ts +0 -2
  651. package/src/Sink.combinators.test.ts +0 -88
  652. package/src/Sink.reduce-collect-head-last.test.ts +0 -107
  653. package/src/Sink.ts +0 -1
  654. package/src/Subject/Subject.ts +0 -440
  655. package/src/Subject/index.ts +0 -1
  656. package/src/Subject.test.ts +0 -47
  657. package/src/Subject.ts +0 -1
  658. package/src/Versioned/Versioned.ts +0 -595
  659. package/src/Versioned/index.ts +0 -1
  660. package/src/Versioned.filterMap.test.ts +0 -91
  661. package/src/Versioned.test.ts +0 -23
  662. package/src/Versioned.ts +0 -1
  663. package/src/index.ts +0 -7
@@ -19,11 +19,12 @@ import { compact as fxCompact } from "../Fx/combinators/compact.js";
19
19
  import { continueWith } from "../Fx/combinators/continueWith.js";
20
20
  import { filterMapEffect as fxFilterMapEffect } from "../Fx/combinators/filterMapEffect.js";
21
21
  import { mapEffect as fxMapEffect } from "../Fx/combinators/mapEffect.js";
22
+ import { mergeAll as fxMergeAll } from "../Fx/combinators/mergeAll.js";
23
+ import { scanEffect as fxScanEffect } from "../Fx/combinators/scan.js";
22
24
  import { skipRepeats } from "../Fx/combinators/skipRepeats.js";
23
25
  import { slice as fxSlice } from "../Fx/combinators/slice.js";
24
26
  import { unwrap } from "../Fx/combinators/unwrap.js";
25
27
  import { fromEffect as fxFromEffect } from "../Fx/constructors/fromEffect.js";
26
- import { fromYieldable } from "../Fx/constructors/fromYieldable.js";
27
28
  import * as DeferredRef from "../Fx/internal/DeferredRef.js";
28
29
  import { getExitEquivalence } from "../Fx/internal/equivalence.js";
29
30
  import { YieldableFx } from "../Fx/internal/yieldable.js";
@@ -31,13 +32,81 @@ import { FxTypeId, isFx } from "../Fx/TypeId.js";
31
32
  import * as Sink from "../Sink/Sink.js";
32
33
  import * as Subject from "../Subject/Subject.js";
33
34
  import * as Versioned from "../Versioned/Versioned.js";
35
+ import { hasProperty } from "effect/Predicate";
36
+ /**
37
+ * Runtime symbol identifying writable RefSubject values.
38
+ *
39
+ * @remarks
40
+ * ## Why
41
+ *
42
+ * Provides stable runtime identity for RefSubject values without relying on classes or a renderer.
43
+ *
44
+ * ## Ownership and lifetime
45
+ *
46
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
47
+ * source errors, services, and lifetime.
48
+ *
49
+ * @since 1.18.0
50
+ * @category combinators
51
+ */
34
52
  export const RefSubjectTypeId = Symbol.for("@typed/fx/RefSubject");
53
+ /**
54
+ * Runtime symbol identifying read-only Computed values.
55
+ *
56
+ * @remarks
57
+ * ## Why
58
+ *
59
+ * Provides stable runtime identity for Computed values without relying on classes or a renderer.
60
+ *
61
+ * ## Ownership and lifetime
62
+ *
63
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
64
+ * source errors, services, and lifetime.
65
+ *
66
+ * @since 1.18.0
67
+ * @category combinators
68
+ */
35
69
  export const ComputedTypeId = Symbol.for("@typed/fx/Computed");
70
+ /**
71
+ * Runtime symbol identifying conditionally available Filtered values.
72
+ *
73
+ * @remarks
74
+ * ## Why
75
+ *
76
+ * Provides stable runtime identity for Filtered values without relying on classes or a renderer.
77
+ *
78
+ * ## Ownership and lifetime
79
+ *
80
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
81
+ * source errors, services, and lifetime.
82
+ *
83
+ * @since 1.18.0
84
+ * @category combinators
85
+ */
36
86
  export const FilteredTypeId = Symbol.for("@typed/fx/Filtered");
87
+ /**
88
+ * Selects whether a computed Fx observes only its current value or also follows later pushes.
89
+ *
90
+ * @remarks
91
+ * ## Why
92
+ *
93
+ * `"multiple"` (the default) emits the current value and then follows distinct source pushes.
94
+ * `"one"` emits only the current value. Hydration temporarily uses `"one"` when it must resolve a
95
+ * single server value without leaving a live observation running.
96
+ *
97
+ * ## Ownership and lifetime
98
+ *
99
+ * This is an Effect Context reference with a default value, not mutable global state. Supplying a
100
+ * value changes computed observation only in the provided Effect context; the observing Scope
101
+ * still owns any subscription created by `"multiple"`.
102
+ *
103
+ * @since 1.18.0
104
+ * @category combinators
105
+ */
37
106
  export const CurrentComputedBehavior = Context.Reference("@typed/fx/CurrentComputedBehavior", {
38
107
  defaultValue: () => "multiple",
39
108
  });
40
- const checkIsMultiple = (ctx) => Context.getReferenceUnsafe(ctx, CurrentComputedBehavior) === "multiple";
109
+ const checkIsMultiple = (ctx) => Context.getUnsafe(ctx, CurrentComputedBehavior) === "multiple";
41
110
  class ComputedImpl extends Versioned.VersionedTransform {
42
111
  [ComputedTypeId] = ComputedTypeId;
43
112
  _computed;
@@ -49,18 +118,136 @@ class ComputedImpl extends Versioned.VersionedTransform {
49
118
  this.f = f;
50
119
  this._computed = Subject.hold(unwrap(Effect.map(Effect.context(), (ctx) => {
51
120
  if (checkIsMultiple(ctx)) {
52
- return fromYieldable(input).pipe(continueWith(() => input), skipRepeats, fxMapEffect(f));
121
+ return fxFromEffect(input).pipe(continueWith(() => input), skipRepeats, fxMapEffect(f));
53
122
  }
54
- return fxFromEffect(Effect.flatMap(input.asEffect(), f));
123
+ return fxFromEffect(Effect.flatMap(input, f));
55
124
  })));
56
125
  }
57
126
  run(sink) {
58
127
  return this._computed.run(sink);
59
128
  }
60
129
  }
130
+ /**
131
+ * Builds a read-only Computed projection from a Versioned source.
132
+ *
133
+ * @remarks
134
+ * ## Why
135
+ *
136
+ * Applies the same Effectful projection to current reads and pushed versions, preserving all three
137
+ * Versioned channels without granting writes to the source.
138
+ *
139
+ * ## Ownership and lifetime
140
+ *
141
+ * Current reads directly sample and transform the input. The pushed channel uses `Subject.hold`:
142
+ * concurrent observers share one active upstream session and its latest retained projection; the
143
+ * last observer ends the session and clears that held value. The observing Scope owns cleanup.
144
+ *
145
+ * @since 1.18.0
146
+ * @category combinators
147
+ */
61
148
  export function makeComputed(input, f) {
62
149
  return new ComputedImpl(input, f);
63
150
  }
151
+ /**
152
+ * Stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the accumulated state.
153
+ *
154
+ * Fx subscriptions follow `Fx.scan` semantics (emit `initial`, then fold each source value).
155
+ * Effect sampling accumulates across source versions via a private state ref (do not mix heavy
156
+ * subscribe + sample on the same scan if you need a single shared accumulator).
157
+ *
158
+ * @remarks
159
+ * ## Why
160
+ *
161
+ * Stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the accumulated state.
162
+ * Fx subscriptions follow `Fx.scan` semantics (emit `initial`, then fold each source value).
163
+ * Effect sampling accumulates across source versions via a private state ref (do not mix heavy
164
+ * subscribe + sample on the same scan if you need a single shared accumulator). The result remains
165
+ * a lazy view rather than a duplicated mutable value.
166
+ *
167
+ * ## Ownership and lifetime
168
+ *
169
+ * Calling `scan` allocates one private `MutableRef` for the returned Computed's Effect-read
170
+ * accumulator. Every Effect read of that same Computed shares it and advances it after a
171
+ * successful fold; separate `scan` calls do not share state. The pushed channel runs
172
+ * `Fx.scanEffect` from `initial` inside `Subject.hold`: concurrent observers share the active scan
173
+ * and its latest retained result, while the last observer ends that session and clears the held
174
+ * value. The observing Scope owns subscription cleanup. The private read accumulator has no
175
+ * finalizer and is collected with the returned Computed.
176
+ *
177
+ * @since 1.0.0
178
+ * @category combinators
179
+ */
180
+ export const scan = dual(3, function scan(versioned, initial, f) {
181
+ return new ComputedScanImpl(versioned, initial, (s, a) => Effect.succeed(f(s, a)));
182
+ });
183
+ /**
184
+ * Effectful stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the accumulated state.
185
+ *
186
+ * @remarks
187
+ * ## Why
188
+ *
189
+ * Effectful stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the
190
+ * accumulated state. The result remains a lazy view rather than a duplicated mutable value.
191
+ *
192
+ * ## Ownership and lifetime
193
+ *
194
+ * Calling `scanEffect` allocates one private `MutableRef` for the returned Computed's Effect-read
195
+ * accumulator. Every Effect read of that same Computed shares it; the accumulator advances only
196
+ * after `f` succeeds, so a typed failure leaves the previous state intact. The pushed channel runs
197
+ * `Fx.scanEffect` from `initial` inside `Subject.hold`: concurrent observers share the active scan
198
+ * and latest retained result, and each fold requires `R3`. The last observer ends that session and
199
+ * clears the held value. The observing Scope owns cleanup; the private read accumulator has no
200
+ * finalizer and is collected with the returned Computed.
201
+ *
202
+ * @since 1.0.0
203
+ * @category combinators
204
+ */
205
+ export const scanEffect = dual(3, function scanEffect(versioned, initial, f) {
206
+ return new ComputedScanImpl(versioned, initial, f);
207
+ });
208
+ class ComputedScanImpl extends Versioned.VersionedTransform {
209
+ [ComputedTypeId] = ComputedTypeId;
210
+ _computed;
211
+ input;
212
+ initial;
213
+ f;
214
+ constructor(input, initial, f) {
215
+ const state = MutableRef.make(initial);
216
+ super(input, (fx) => fxScanEffect(fx, initial, f), (effect) => Effect.flatMap(effect, (a) => Effect.flatMap(f(MutableRef.get(state), a), (next) => Effect.sync(() => {
217
+ MutableRef.set(state, next);
218
+ return next;
219
+ }))));
220
+ this.input = input;
221
+ this.initial = initial;
222
+ this.f = f;
223
+ this._computed = Subject.hold(unwrap(Effect.map(Effect.context(), (ctx) => {
224
+ if (checkIsMultiple(ctx)) {
225
+ return fxFromEffect(input).pipe(continueWith(() => input), skipRepeats, fxScanEffect(initial, f));
226
+ }
227
+ return fxFromEffect(Effect.flatMap(input, (a) => f(initial, a)));
228
+ })));
229
+ }
230
+ run(sink) {
231
+ return this._computed.run(sink);
232
+ }
233
+ }
234
+ /**
235
+ * Builds a Filtered view from the three channels of a Versioned source.
236
+ *
237
+ * @remarks
238
+ * ## Why
239
+ *
240
+ * Applies `f` to current reads and later pushes while preserving absence as Filtered semantics:
241
+ * Effect reads fail with `NoSuchElementError`, whereas the Fx channel simply omits absent values.
242
+ *
243
+ * ## Ownership and lifetime
244
+ *
245
+ * The make filtered view retains no independent value. Its Effect read fails with NoSuchElement
246
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
247
+ *
248
+ * @since 1.18.0
249
+ * @category combinators
250
+ */
64
251
  export function makeFiltered(input, f) {
65
252
  return new FilteredImpl(input, f);
66
253
  }
@@ -70,14 +257,14 @@ class FilteredImpl extends Versioned.VersionedTransform {
70
257
  input;
71
258
  f;
72
259
  constructor(input, f) {
73
- super(input, (fx) => fxFilterMapEffect(fx, f), (effect) => Effect.flatMap(Effect.flatMap(effect, f), (option) => option.asEffect()));
260
+ super(input, (fx) => fxFilterMapEffect(fx, f), (effect) => Effect.flatMap(Effect.flatMap(effect, f), Effect.fromOption));
74
261
  this.input = input;
75
262
  this.f = f;
76
263
  this._computed = Subject.hold(unwrap(Effect.map(Effect.context(), (ctx) => {
77
264
  if (checkIsMultiple(ctx)) {
78
- return fromYieldable(input).pipe(continueWith(() => input), skipRepeats, fxFilterMapEffect(f));
265
+ return fxFromEffect(input).pipe(continueWith(() => input), skipRepeats, fxFilterMapEffect(f));
79
266
  }
80
- return fxCompact(fxFromEffect(Effect.flatMap(input.asEffect(), f)));
267
+ return fxCompact(fxFromEffect(Effect.flatMap(input, f)));
81
268
  })));
82
269
  }
83
270
  run(sink) {
@@ -87,6 +274,7 @@ class FilteredImpl extends Versioned.VersionedTransform {
87
274
  return new ComputedImpl(this.input, this.f);
88
275
  }
89
276
  }
277
+ let nextTransactionOrder = 0;
90
278
  class RefSubjectCore {
91
279
  initial;
92
280
  subject;
@@ -94,6 +282,7 @@ class RefSubjectCore {
94
282
  scope;
95
283
  deferredRef;
96
284
  semaphore;
285
+ transactionOrder = nextTransactionOrder++;
97
286
  constructor(initial, subject, services, scope, deferredRef, semaphore) {
98
287
  this.initial = initial;
99
288
  this.subject = subject;
@@ -104,10 +293,116 @@ class RefSubjectCore {
104
293
  }
105
294
  _fiber = undefined;
106
295
  }
107
- function getSetDelete(ref) {
296
+ function combineTransactionCores(accesses) {
297
+ return [...new Set(accesses.flatMap((access) => access.cores))].sort((left, right) => left.transactionOrder - right.transactionOrder);
298
+ }
299
+ function getTupleTransactionAccess(refs) {
300
+ const accessEffects = refs.map(getTransactionAccess);
301
+ if (!accessEffects.every((access) => access !== undefined)) {
302
+ return undefined;
303
+ }
304
+ return Effect.map(Effect.all(accessEffects, UNBOUNDED), (accessOptions) => Option.map(Option.all(accessOptions), (accesses) => ({
305
+ cores: combineTransactionCores(accesses),
306
+ getSetDelete: (recordCommit) => {
307
+ const transactions = accesses.map((access) => access.getSetDelete(recordCommit));
308
+ return {
309
+ get: Effect.all(transactions.map((transaction) => transaction.get), UNBOUNDED),
310
+ set: (value) => Effect.all(transactions.map((transaction, index) => transaction.set(value[index])), UNBOUNDED),
311
+ delete: Effect.map(Effect.all(transactions.map((transaction) => transaction.delete), UNBOUNDED), Option.all),
312
+ };
313
+ },
314
+ })));
315
+ }
316
+ function getStructTransactionAccess(refs) {
317
+ const keys = Object.keys(refs);
318
+ const accessEffects = keys.map((key) => getTransactionAccess(refs[key]));
319
+ if (!accessEffects.every((access) => access !== undefined)) {
320
+ return undefined;
321
+ }
322
+ return Effect.map(Effect.all(accessEffects, UNBOUNDED), (accessOptions) => Option.map(Option.all(accessOptions), (accesses) => ({
323
+ cores: combineTransactionCores(accesses),
324
+ getSetDelete: (recordCommit) => {
325
+ const transactions = accesses.map((access) => access.getSetDelete(recordCommit));
326
+ return {
327
+ get: Effect.map(Effect.all(transactions.map((transaction) => transaction.get), UNBOUNDED), (values) => Object.fromEntries(keys.map((key, index) => [key, values[index]]))),
328
+ set: (value) => Effect.all(transactions.map((transaction, index) => transaction.set(value[keys[index]])), UNBOUNDED),
329
+ delete: Effect.map(Effect.all(transactions.map((transaction) => transaction.delete), UNBOUNDED), (values) => Option.all(Object.fromEntries(keys.map((key, index) => [key, values[index]])))),
330
+ };
331
+ },
332
+ })));
333
+ }
334
+ function getTransactionAccess(ref) {
335
+ if (ref instanceof RefSubjectImpl) {
336
+ return Effect.succeed(Option.some({
337
+ cores: [ref.core],
338
+ getSetDelete: (recordCommit) => getSetDelete(ref.core, (exit) => recordCommit([ref.core, exit, ref.core.deferredRef.version])),
339
+ }));
340
+ }
341
+ if (ref instanceof RefSubjectSimpleTransform)
342
+ return getTransactionAccess(ref.ref);
343
+ if (ref instanceof RefSubjectTransform) {
344
+ const accessEffect = getTransactionAccess(ref.ref);
345
+ if (!accessEffect)
346
+ return undefined;
347
+ return Effect.map(accessEffect, Option.map((access) => ({
348
+ cores: access.cores,
349
+ getSetDelete: (recordCommit) => {
350
+ const transaction = access.getSetDelete(recordCommit);
351
+ return {
352
+ get: Effect.map(transaction.get, ref.toB),
353
+ set: (value) => Effect.map(transaction.set(ref.toA(value)), ref.toB),
354
+ delete: Effect.map(transaction.delete, Option.map(ref.toB)),
355
+ };
356
+ },
357
+ })));
358
+ }
359
+ if (ref instanceof RefSubjectTuple)
360
+ return getTupleTransactionAccess(ref.refs);
361
+ if (ref instanceof RefSubjectStruct)
362
+ return getStructTransactionAccess(ref.refs);
363
+ if (typeof ref === "function") {
364
+ const service = ref.service;
365
+ if (Effect.isEffect(service)) {
366
+ return Effect.flatMap(service, (providedRef) => {
367
+ const accessEffect = getTransactionAccess(providedRef);
368
+ return accessEffect ?? Effect.succeed(Option.none());
369
+ });
370
+ }
371
+ }
372
+ return undefined;
373
+ }
374
+ function withTransactionLocks(cores, effect) {
375
+ let locked = effect;
376
+ for (let index = cores.length - 1; index >= 0; index--) {
377
+ locked = cores[index].semaphore.withPermits(1)(locked);
378
+ }
379
+ return locked;
380
+ }
381
+ function runTransaction(access, run) {
382
+ return Effect.uninterruptibleMask((restore) => {
383
+ const commits = [];
384
+ const transaction = restore(withTransactionLocks(access.cores, Effect.suspend(() => run(access.getSetDelete((commit) => {
385
+ commits.push(commit);
386
+ })))));
387
+ return Effect.flatMap(Effect.exit(transaction), (exit) => Effect.andThen(Effect.forEach(commits, ([core, commit, version]) => sendCurrentEvent(core, commit, version), {
388
+ discard: true,
389
+ }), exit));
390
+ });
391
+ }
392
+ function sendCurrentEvent(core, commit, version) {
393
+ return Effect.suspend(() => {
394
+ const current = MutableRef.get(core.deferredRef.current);
395
+ return core.deferredRef.version === version &&
396
+ Option.isSome(current) &&
397
+ core.deferredRef.eq(current.value, commit)
398
+ ? sendEvent(core, commit)
399
+ : Effect.void;
400
+ });
401
+ }
402
+ function getSetDelete(ref, recordCommit) {
108
403
  return {
109
404
  get: getOrInitializeCore(ref, false),
110
- set: (a) => setCore(ref, a),
405
+ set: (a) => bufferSuccessCore(ref, a, recordCommit),
111
406
  delete: deleteCore(ref),
112
407
  };
113
408
  }
@@ -117,7 +412,6 @@ class RefSubjectImpl extends YieldableFx {
117
412
  version;
118
413
  interrupt;
119
414
  subscriberCount;
120
- getSetDelete;
121
415
  core;
122
416
  constructor(core) {
123
417
  super();
@@ -125,25 +419,25 @@ class RefSubjectImpl extends YieldableFx {
125
419
  this.version = Effect.sync(() => core.deferredRef.version);
126
420
  this.interrupt = Effect.provide(interruptCore(core), core.services);
127
421
  this.subscriberCount = Effect.provide(core.subject.subscriberCount, core.services);
128
- this.getSetDelete = getSetDelete(core);
129
422
  this.updates = this.updates.bind(this);
130
423
  this.onSuccess = this.onSuccess.bind(this);
131
424
  this.onFailure = this.onFailure.bind(this);
132
425
  }
133
426
  run(sink) {
427
+ const subscribe = Effect.provide(this.core.subject.run(sink), this.core.services);
134
428
  return Effect.matchCauseEffect(getOrInitializeCore(this.core, true), {
135
- onFailure: (cause) => sink.onFailure(cause),
136
- onSuccess: () => Effect.provide(this.core.subject.run(sink), this.core.services),
429
+ onFailure: () => subscribe,
430
+ onSuccess: () => subscribe,
137
431
  });
138
432
  }
139
433
  updates(run) {
140
- return this.core.semaphore.withPermits(1)(run(this.getSetDelete));
434
+ return updateCore(this.core, (recordCommit) => run(getSetDelete(this.core, recordCommit)));
141
435
  }
142
436
  onSuccess(value) {
143
- return setCore(this.core, value);
437
+ return updateCore(this.core, (recordCommit) => bufferSuccessCore(this.core, value, recordCommit));
144
438
  }
145
439
  onFailure(cause) {
146
- return onFailureCore(this.core, cause);
440
+ return updateCore(this.core, (recordCommit) => bufferFailureCore(this.core, cause, recordCommit));
147
441
  }
148
442
  toEffect() {
149
443
  return getOrInitializeCore(this.core, true);
@@ -152,6 +446,31 @@ class RefSubjectImpl extends YieldableFx {
152
446
  /**
153
447
  * Creates a new `RefSubject` from a value, `Effect`, or `Fx`.
154
448
  *
449
+ * @remarks
450
+ * ## Why
451
+ *
452
+ * `RefSubject` keeps current state and pushed changes independent of any UI
453
+ * renderer. Domain transitions can therefore be constructed, composed, and
454
+ * tested with Effect alone; rendering is one optional consumer of the state.
455
+ * Plain values, Effect programs, pull-based Effect `Stream`s, and push-based
456
+ * `Fx` sources all enter through the same state boundary.
457
+ *
458
+ * ## Ownership and lifetime
459
+ *
460
+ * Creation requires an Effect `Scope`. That scope owns source acquisition,
461
+ * subscriptions, and finalization. The returned `RefSubject` exposes the
462
+ * source error type when read or observed, while construction itself cannot
463
+ * fail. Closing the scope interrupts a live source and releases its resources.
464
+ *
465
+ * ## Initialization
466
+ *
467
+ * Calling `make` is lazy because it returns an Effect: nothing is allocated and no source runs
468
+ * until that creation Effect is executed. After creation, a plain value is immediately available.
469
+ * An Effect input runs once on the first current read or observation. Fx and Stream inputs instead
470
+ * start one shared source run when the creation Effect executes; reads wait for their first value
471
+ * or failure and later emissions replace the retained current state. Equality and buffering
472
+ * behavior can be customized with `RefSubjectOptions`.
473
+ *
155
474
  * @example
156
475
  * ```ts
157
476
  * import { Effect } from "effect"
@@ -204,6 +523,19 @@ export function make(effect, options) {
204
523
  /**
205
524
  * Creates a `RefSubject` from an `Effect`.
206
525
  *
526
+ * @remarks
527
+ * ## Why
528
+ *
529
+ * Makes effect acquisition explicit while normalizing it into current RefSubject state and
530
+ * subsequent pushed versions.
531
+ *
532
+ * ## Ownership and lifetime
533
+ *
534
+ * The creation Effect requires Scope and the source's services, which it captures for the private
535
+ * initializer Scope. The source Effect itself stays deferred until the first current read or
536
+ * observation and runs at most once. Source failures remain visible on reads and observations;
537
+ * closing the creation Scope interrupts an initializer that is still running.
538
+ *
207
539
  * @example
208
540
  * ```ts
209
541
  * import { Effect } from "effect"
@@ -228,6 +560,17 @@ export function fromEffect(effect, options) {
228
560
  /**
229
561
  * Creates a `RefSubject` from an `Fx`, tracking the latest emitted value.
230
562
  *
563
+ * @remarks
564
+ * ## Why
565
+ *
566
+ * Makes fx acquisition explicit while normalizing it into current RefSubject state and subsequent
567
+ * pushed versions.
568
+ *
569
+ * ## Ownership and lifetime
570
+ *
571
+ * The creation Effect requires Scope. It owns initializer acquisition, live source subscriptions,
572
+ * and cleanup; source failures and services stay on reads and pushes.
573
+ *
231
574
  * @example
232
575
  * ```ts
233
576
  * import { Effect } from "effect"
@@ -254,21 +597,53 @@ export function fromFx(fx, options) {
254
597
  return Effect.gen(function* () {
255
598
  const core = yield* makeDeferredCore(options);
256
599
  const ref = new RefSubjectImpl(core);
257
- yield* Effect.forkIn(fx.run(Sink.make((cause) => onFailureCore(core, cause), (value) => setCore(core, value))), core.scope, { startImmediately: true });
600
+ yield* Effect.forkIn(fx.run(Sink.make((cause) => updateCore(core, (recordCommit) => bufferFailureCore(core, cause, recordCommit)), (value) => updateCore(core, (recordCommit) => bufferSuccessCore(core, value, recordCommit)))), core.scope, { startImmediately: true });
258
601
  return ref;
259
602
  });
260
603
  }
604
+ /**
605
+ * Creates a RefSubject that tracks the latest value emitted by an Effect Stream.
606
+ *
607
+ * @remarks
608
+ * ## Why
609
+ *
610
+ * Bridges a pull-based Stream into renderer-independent state: each emitted value enters the
611
+ * RefSubject's serialized commit path, while a stream failure becomes the ref's current and pushed
612
+ * failure.
613
+ *
614
+ * ## Ownership and lifetime
615
+ *
616
+ * Construction forks stream consumption immediately into the RefSubject's private Scope and cannot
617
+ * fail. `R` is required while constructing that fiber; closing the outer Scope interrupts it.
618
+ * Before the first value or failure, a current read waits for initialization. Later reads and pushes
619
+ * expose `E`.
620
+ *
621
+ * @since 1.18.0
622
+ * @category combinators
623
+ */
261
624
  export function fromStream(stream, options) {
262
625
  return Effect.gen(function* () {
263
626
  const core = yield* makeDeferredCore(options);
264
627
  const ref = new RefSubjectImpl(core);
265
- yield* Effect.forkIn(stream.pipe(redirectCause(core), Stream.runForEach((value) => setCore(core, value))), core.scope, { startImmediately: true });
628
+ yield* Effect.forkIn(stream.pipe(redirectCause(core), Stream.runForEach((value) => updateCore(core, (recordCommit) => bufferSuccessCore(core, value, recordCommit)))), core.scope, { startImmediately: true });
266
629
  return ref;
267
630
  });
268
631
  }
269
632
  /**
270
633
  * Creates a `RefSubject` from an `Option` value.
271
634
  *
635
+ * @remarks
636
+ * ## Why
637
+ *
638
+ * Stores the Option itself in writable state. `None` is an ordinary current value and does not add
639
+ * `NoSuchElementError`; callers opt into absence semantics with `compact`, or a fallback with
640
+ * `getOrElse`.
641
+ *
642
+ * ## Ownership and lifetime
643
+ *
644
+ * Construction requires Scope because it delegates to `make`, but the supplied Option needs no
645
+ * services and cannot fail. The returned RefSubject owns and publishes subsequent Option writes.
646
+ *
272
647
  * @example
273
648
  * ```ts
274
649
  * import { Effect, Option } from "effect"
@@ -314,11 +689,29 @@ function optionFromNullable(value) {
314
689
  ? Option.none()
315
690
  : Option.some(value);
316
691
  }
692
+ /**
693
+ * Creates Option-valued RefSubject state from a nullable input.
694
+ *
695
+ * @remarks
696
+ * ## Why
697
+ *
698
+ * Converts `null` and `undefined` to `Option.none` and every other value to `Option.some`, then
699
+ * stores that Option in a writable RefSubject. It does not create Filtered state or add
700
+ * `NoSuchElementError`.
701
+ *
702
+ * ## Ownership and lifetime
703
+ *
704
+ * Construction requires Scope because it delegates to `make`; it needs no services and cannot
705
+ * fail. The returned RefSubject owns and publishes subsequent Option writes.
706
+ *
707
+ * @since 1.18.0
708
+ * @category combinators
709
+ */
317
710
  export function fromNullable(value, options) {
318
711
  return make(optionFromNullable(value), options);
319
712
  }
320
713
  function redirectCause(core) {
321
- return Stream.catchCause((cause) => Stream.unwrap(Effect.as(onFailureCore(core, cause), Stream.empty)));
714
+ return Stream.catchCause((cause) => Stream.unwrap(Effect.as(updateCore(core, (recordCommit) => bufferFailureCore(core, cause, recordCommit)), Stream.empty)));
322
715
  }
323
716
  function makeCore(initial, options, deferredRef) {
324
717
  return Effect.gen(function* () {
@@ -335,7 +728,7 @@ function makeCore(initial, options, deferredRef) {
335
728
  function makeDeferredCore(options) {
336
729
  return Effect.gen(function* () {
337
730
  const deferredRef = yield* DeferredRef.make(getExitEquivalence(options?.eq ?? equals));
338
- return yield* makeCore(deferredRef.asEffect(), options, deferredRef);
731
+ return yield* makeCore(deferredRef, options, deferredRef);
339
732
  });
340
733
  }
341
734
  function getOrInitializeCore(core, lockInitialize) {
@@ -344,7 +737,7 @@ function getOrInitializeCore(core, lockInitialize) {
344
737
  return initializeCoreAndTap(core, lockInitialize);
345
738
  }
346
739
  else {
347
- return core.deferredRef.asEffect();
740
+ return core.deferredRef;
348
741
  }
349
742
  });
350
743
  }
@@ -353,21 +746,33 @@ function initializeCoreEffect(core, lock) {
353
746
  core._fiber = undefined;
354
747
  core.deferredRef.done(exit);
355
748
  }));
356
- return Effect.flatMap(Effect.forkIn(lock ? core.semaphore.withPermits(1)(initialize) : initialize, core.scope), (fiber) => Effect.sync(() => (core._fiber = fiber)));
749
+ const isSourceBacked = core.initial === core.deferredRef;
750
+ return Effect.flatMap(Effect.forkIn(lock && !isSourceBacked ? core.semaphore.withPermits(1)(initialize) : initialize, core.scope), (fiber) => Effect.sync(() => (core._fiber = fiber)));
357
751
  }
358
752
  function initializeCoreAndTap(core, lock) {
359
- return Effect.flatMapEager(initializeCoreEffect(core, lock), () => tapEventCore(core, core.deferredRef.asEffect()));
753
+ return Effect.flatMapEager(initializeCoreEffect(core, lock), () =>
754
+ // Kind of weird hack, but this second clause will happen for HydrationRefs that are already hydrated
755
+ core.deferredRef.current === core.subject.lastValue
756
+ ? tapEventCore(core, core.deferredRef)
757
+ : core.deferredRef);
758
+ }
759
+ function updateCore(core, run) {
760
+ return Effect.uninterruptibleMask((restore) => {
761
+ const commits = [];
762
+ const transaction = restore(core.semaphore.withPermits(1)(Effect.suspend(() => run((commit) => {
763
+ commits.push(commit);
764
+ }))));
765
+ return Effect.flatMap(Effect.exit(transaction), (exit) => Effect.andThen(Effect.forEach(commits, (commit) => sendEvent(core, commit), { discard: true }), exit));
766
+ });
360
767
  }
361
768
  function setCore(core, a) {
362
769
  return Effect.suspend(() => {
363
770
  const exit = Exit.succeed(a);
364
771
  if (core.deferredRef.done(exit)) {
365
- // If the value changed, send an event
366
- return Effect.as(sendEvent(core, exit), a);
772
+ return Effect.succeed(Option.some(exit));
367
773
  }
368
774
  else {
369
- // Otherwise, just return the current value
370
- return Effect.succeed(a);
775
+ return Effect.succeed(Option.none());
371
776
  }
372
777
  });
373
778
  }
@@ -375,13 +780,26 @@ function onFailureCore(core, cause) {
375
780
  const exit = Exit.failCause(cause);
376
781
  return Effect.suspend(() => {
377
782
  if (core.deferredRef.done(exit)) {
378
- return sendEvent(core, exit);
783
+ return Effect.succeed(Option.some(exit));
379
784
  }
380
785
  else {
381
- return Effect.void;
786
+ return Effect.succeed(Option.none());
382
787
  }
383
788
  });
384
789
  }
790
+ function bufferSuccessCore(core, value, recordCommit) {
791
+ return Effect.map(setCore(core, value), (commit) => {
792
+ if (Option.isSome(commit))
793
+ recordCommit(commit.value);
794
+ return value;
795
+ });
796
+ }
797
+ function bufferFailureCore(core, cause, recordCommit) {
798
+ return Effect.asVoid(Effect.map(onFailureCore(core, cause), (commit) => {
799
+ if (Option.isSome(commit))
800
+ recordCommit(commit.value);
801
+ }));
802
+ }
385
803
  function interruptCore(core) {
386
804
  return Effect.withFiber((fiber) => {
387
805
  core.deferredRef.reset();
@@ -415,6 +833,17 @@ function sendEvent(core, exit) {
415
833
  /**
416
834
  * Sets the value of a `RefSubject`.
417
835
  *
836
+ * @remarks
837
+ * ## Why
838
+ *
839
+ * Sets the value of a `RefSubject`. The transition is serialized at the RefSubject rather than
840
+ * coordinated by callers or UI components.
841
+ *
842
+ * ## Ownership and lifetime
843
+ *
844
+ * Running set performs one serialized subject transition and resolves with its committed value. It
845
+ * acquires no resource; failures and services remain those of the source ref.
846
+ *
418
847
  * @example
419
848
  * ```ts
420
849
  * import { Effect } from "effect"
@@ -444,6 +873,17 @@ export const set = dual(2, function set(ref, a) {
444
873
  /**
445
874
  * Resets a `RefSubject` to its initial value, returning the previous value if it existed.
446
875
  *
876
+ * @remarks
877
+ * ## Why
878
+ *
879
+ * Resets a `RefSubject` to its initial value, returning the previous value if it existed. The
880
+ * transition is serialized at the RefSubject rather than coordinated by callers or UI components.
881
+ *
882
+ * ## Ownership and lifetime
883
+ *
884
+ * Running reset performs one serialized subject transition and resolves with its committed value.
885
+ * It acquires no resource; failures and services remain those of the source ref.
886
+ *
447
887
  * @example
448
888
  * ```ts
449
889
  * import { Effect, Option } from "effect"
@@ -503,6 +943,17 @@ reset as delete, };
503
943
  /**
504
944
  * Updates a `RefSubject` using an `Effect`ful function.
505
945
  *
946
+ * @remarks
947
+ * ## Why
948
+ *
949
+ * Updates a `RefSubject` using an `Effect`ful function. The transition is serialized at the
950
+ * RefSubject rather than coordinated by callers or UI components.
951
+ *
952
+ * ## Ownership and lifetime
953
+ *
954
+ * Running update effect performs one serialized subject transition and resolves with its committed
955
+ * value. It acquires no resource; failures and services remain those of the source ref.
956
+ *
506
957
  * @example
507
958
  * ```ts
508
959
  * import { Effect } from "effect"
@@ -530,6 +981,26 @@ export const updateEffect = dual(2, function updateEffect(ref, f) {
530
981
  /**
531
982
  * Updates a `RefSubject` using a pure function.
532
983
  *
984
+ * @remarks
985
+ * ## Why
986
+ *
987
+ * `update` expresses a state transition where the state lives, without moving
988
+ * transition logic into a component or renderer. The same function can run in
989
+ * application code, tests, workers, event handlers, or a Typed template.
990
+ *
991
+ * ## Ownership and lifetime
992
+ *
993
+ * The update runs inside the RefSubject's existing synchronized update
994
+ * boundary: it reads the committed value, derives the next value, commits it,
995
+ * and publishes that change. It acquires no independent resource and retains
996
+ * the subject's existing error and service channels.
997
+ *
998
+ * ## Concurrency and failure
999
+ *
1000
+ * Concurrent updates are serialized by the subject core so each function sees
1001
+ * a committed value. A pure updater adds no error channel; failures already
1002
+ * associated with reading or writing the RefSubject remain explicit in `E`.
1003
+ *
533
1004
  * @example
534
1005
  * ```ts
535
1006
  * import { Effect } from "effect"
@@ -559,6 +1030,18 @@ export const update = dual(2, function update(ref, f) {
559
1030
  /**
560
1031
  * Modifies a `RefSubject` using an `Effect`ful function that returns both a result and a new value.
561
1032
  *
1033
+ * @remarks
1034
+ * ## Why
1035
+ *
1036
+ * Modifies a `RefSubject` using an `Effect`ful function that returns both a result and a new
1037
+ * value. The transition is serialized at the RefSubject rather than coordinated by callers or UI
1038
+ * components.
1039
+ *
1040
+ * ## Ownership and lifetime
1041
+ *
1042
+ * Running modify effect performs one serialized subject transition and resolves with its committed
1043
+ * value. It acquires no resource; failures and services remain those of the source ref.
1044
+ *
562
1045
  * @example
563
1046
  * ```ts
564
1047
  * import { Effect } from "effect"
@@ -582,11 +1065,22 @@ export const update = dual(2, function update(ref, f) {
582
1065
  * @category combinators
583
1066
  */
584
1067
  export const modifyEffect = dual(2, function modifyEffect(ref, f) {
585
- return ref.updates((ref) => Effect.flatMap(ref.get, (value) => Effect.flatMap(f(value), ([b, a]) => Effect.flatMap(ref.set(a), () => Effect.succeed(b)))));
1068
+ return ref.updates((ref) => Effect.flatMap(ref.get, (value) => Effect.flatMap(f(value), ([b, a]) => Effect.as(ref.set(a), b))));
586
1069
  });
587
1070
  /**
588
1071
  * Modifies a `RefSubject` using a pure function that returns both a result and a new value.
589
1072
  *
1073
+ * @remarks
1074
+ * ## Why
1075
+ *
1076
+ * Modifies a `RefSubject` using a pure function that returns both a result and a new value. The
1077
+ * transition is serialized at the RefSubject rather than coordinated by callers or UI components.
1078
+ *
1079
+ * ## Ownership and lifetime
1080
+ *
1081
+ * Running modify performs one serialized subject transition and resolves with its committed value.
1082
+ * It acquires no resource; failures and services remain those of the source ref.
1083
+ *
590
1084
  * @example
591
1085
  * ```ts
592
1086
  * import { Effect } from "effect"
@@ -613,6 +1107,16 @@ export const modify = dual(2, function modify(ref, f) {
613
1107
  /**
614
1108
  * Checks if a value is a `RefSubject`.
615
1109
  *
1110
+ * @remarks
1111
+ * ## Why
1112
+ *
1113
+ * Checks if a value is a `RefSubject`.
1114
+ *
1115
+ * ## Ownership and lifetime
1116
+ *
1117
+ * The derived ref owns no independent state or subscription. It follows the source lifetime and
1118
+ * routes writes through the source's synchronized update boundary.
1119
+ *
616
1120
  * @example
617
1121
  * ```ts
618
1122
  * import { Effect } from "effect"
@@ -633,12 +1137,43 @@ export const modify = dual(2, function modify(ref, f) {
633
1137
  * @category guards
634
1138
  */
635
1139
  export function isRefSubject(value) {
636
- return value && typeof value === "object" && value[RefSubjectTypeId] === RefSubjectTypeId;
1140
+ return hasProperty(value, RefSubjectTypeId) && value[RefSubjectTypeId] === RefSubjectTypeId;
637
1141
  }
638
1142
  const isRefSubjectDataFirst = (args) => isRefSubject(args[0]);
1143
+ /**
1144
+ * Tests whether a value carries the public Computed TypeId.
1145
+ *
1146
+ * @remarks
1147
+ * ## Why
1148
+ *
1149
+ * Uses the TypeId contract rather than a concrete implementation class, so custom Computed values
1150
+ * and service facades participate in the same runtime guard.
1151
+ *
1152
+ * ## Ownership and lifetime
1153
+ *
1154
+ * This synchronous predicate performs no Effect, subscription, or acquisition.
1155
+ *
1156
+ * @since 1.18.0
1157
+ * @category guards
1158
+ */
1159
+ export function isComputed(value) {
1160
+ return hasProperty(value, ComputedTypeId) && value[ComputedTypeId] === ComputedTypeId;
1161
+ }
639
1162
  /**
640
1163
  * Runs an effect that can modify a `RefSubject` transactionally, with optional interrupt handling.
641
1164
  *
1165
+ * @remarks
1166
+ * ## Why
1167
+ *
1168
+ * Runs an effect that can modify a `RefSubject` transactionally, with optional interrupt handling.
1169
+ * The transition is serialized at the RefSubject rather than coordinated by callers or UI
1170
+ * components.
1171
+ *
1172
+ * ## Ownership and lifetime
1173
+ *
1174
+ * Running run updates performs one serialized subject transition and resolves with its committed
1175
+ * value. It acquires no resource; failures and services remain those of the source ref.
1176
+ *
642
1177
  * @example
643
1178
  * ```ts
644
1179
  * import { Effect } from "effect"
@@ -684,6 +1219,17 @@ export const runUpdates = dual(isRefSubjectDataFirst, function runUpdates(ref, f
684
1219
  /**
685
1220
  * Increments a numeric `RefSubject` by 1.
686
1221
  *
1222
+ * @remarks
1223
+ * ## Why
1224
+ *
1225
+ * Increments a numeric `RefSubject` by 1. The transition is serialized at the RefSubject rather
1226
+ * than coordinated by callers or UI components.
1227
+ *
1228
+ * ## Ownership and lifetime
1229
+ *
1230
+ * Running increment performs one serialized subject transition and resolves with its committed
1231
+ * value. It acquires no resource; failures and services remain those of the source ref.
1232
+ *
687
1233
  * @example
688
1234
  * ```ts
689
1235
  * import { Effect } from "effect"
@@ -711,6 +1257,17 @@ export function increment(ref) {
711
1257
  /**
712
1258
  * Decrements a numeric `RefSubject` by 1.
713
1259
  *
1260
+ * @remarks
1261
+ * ## Why
1262
+ *
1263
+ * Decrements a numeric `RefSubject` by 1. The transition is serialized at the RefSubject rather
1264
+ * than coordinated by callers or UI components.
1265
+ *
1266
+ * ## Ownership and lifetime
1267
+ *
1268
+ * Running decrement performs one serialized subject transition and resolves with its committed
1269
+ * value. It acquires no resource; failures and services remain those of the source ref.
1270
+ *
714
1271
  * @example
715
1272
  * ```ts
716
1273
  * import { Effect } from "effect"
@@ -740,12 +1297,37 @@ const Variance = {
740
1297
  _E: identity,
741
1298
  _R: identity,
742
1299
  };
1300
+ /**
1301
+ * Creates a Context-backed RefSubject service facade and Layer constructors.
1302
+ *
1303
+ * @remarks
1304
+ * ## Why
1305
+ *
1306
+ * The returned class is simultaneously a service tag, a current-value Effect, an Fx source, and a
1307
+ * writable RefSubject facade. This lets consumers read, observe, and update renderer-independent
1308
+ * state without manually retrieving the underlying service from Context.
1309
+ *
1310
+ * ## Ownership and lifetime
1311
+ *
1312
+ * Calling `Service` is pure. `layer` installs an existing scoped RefSubject; `make` constructs one
1313
+ * and installs it in a Layer. The Layer Scope owns the subject and its initializer subscription.
1314
+ * Reads and pushes expose the declared `E` channel; construction requirements remain on the Layer,
1315
+ * while consumers require only the generated `Self` service.
1316
+ *
1317
+ * @since 1.18.0
1318
+ * @category combinators
1319
+ */
743
1320
  export function Service() {
744
1321
  return (id) => {
745
1322
  const service = Context.Service(id);
746
1323
  // eslint-disable-next-line @typescript-eslint/no-extraneous-class
747
1324
  return class RefSubjectService {
748
1325
  /// Service
1326
+ static {
1327
+ // @effect-diagnostics-next-line floatingEffect:off
1328
+ Object.assign(this, service);
1329
+ Object.setPrototypeOf(this, Object.getPrototypeOf(service));
1330
+ }
749
1331
  static id = id;
750
1332
  static service = service;
751
1333
  static layer = (make) => Layer.effect(service, make);
@@ -755,21 +1337,21 @@ export function Service() {
755
1337
  };
756
1338
  // Fx
757
1339
  static [FxTypeId] = Variance;
758
- static run = (sink) => Effect.flatMap(service.asEffect(), (ref) => ref.run(sink));
1340
+ static run = (sink) => Effect.flatMap(service, (ref) => ref.run(sink));
759
1341
  // Sink
760
- static onSuccess = (value) => Effect.flatMap(service.asEffect(), (ref) => ref.onSuccess(value));
761
- static onFailure = (cause) => Effect.flatMap(service.asEffect(), (ref) => ref.onFailure(cause));
1342
+ static onSuccess = (value) => Effect.flatMap(service, (ref) => ref.onSuccess(value));
1343
+ static onFailure = (cause) => Effect.flatMap(service, (ref) => ref.onFailure(cause));
762
1344
  /// Computed
763
1345
  static [ComputedTypeId] = ComputedTypeId;
764
- static version = Effect.flatMap(service.asEffect(), (ref) => ref.version);
1346
+ static version = Effect.flatMap(service, (ref) => ref.version);
765
1347
  // Subject
766
- static subscriberCount = Effect.flatMap(service.asEffect(), (ref) => ref.subscriberCount);
767
- static interrupt = Effect.flatMap(service.asEffect(), (ref) => ref.interrupt);
1348
+ static subscriberCount = Effect.flatMap(service, (ref) => ref.subscriberCount);
1349
+ static interrupt = Effect.flatMap(service, (ref) => ref.interrupt);
768
1350
  // RefSubject
769
1351
  static [RefSubjectTypeId] = RefSubjectTypeId;
770
- static updates = (f) => Effect.flatMap(service.asEffect(), (ref) => ref.updates(f));
1352
+ static updates = (f) => Effect.flatMap(service, (ref) => ref.updates(f));
771
1353
  // Yieldable
772
- static asEffect = () => Effect.flatMap(service.asEffect(), Effect.fromYieldable);
1354
+ static override = service;
773
1355
  static [Symbol.iterator] = function* () {
774
1356
  const ref = yield* service;
775
1357
  return yield* ref;
@@ -793,6 +1375,19 @@ function getDefaultBounds(options) {
793
1375
  * Extract all values from an object using a Proxy.
794
1376
  * Allows accessing nested properties of a `Computed` or `Filtered` object/array as individual computed values.
795
1377
  *
1378
+ * @remarks
1379
+ * ## Why
1380
+ *
1381
+ * Lazily creates one property projection per accessed key and memoizes that projection on the
1382
+ * JavaScript Proxy. A Computed or RefSubject source produces Computed properties; only a Filtered
1383
+ * source produces Filtered properties and preserves conditional absence.
1384
+ *
1385
+ * ## Ownership and lifetime
1386
+ *
1387
+ * The Proxy caches derived view objects, not property values. Computed property reads expose only
1388
+ * the source's `E`; Filtered property reads can additionally fail with `NoSuchElementError` while
1389
+ * their source is absent. Each observed property follows the source and uses the observing Scope.
1390
+ *
796
1391
  * @example
797
1392
  * ```ts
798
1393
  * import { Effect } from "effect"
@@ -836,6 +1431,20 @@ export const proxy = (source) => {
836
1431
  /**
837
1432
  * Transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function.
838
1433
  *
1434
+ * @remarks
1435
+ * ## Why
1436
+ *
1437
+ * Applies one Effectful derivation to current reads and pushed versions. RefSubject and Computed
1438
+ * inputs return Computed and add only `E2`; a Filtered input returns Filtered and preserves its
1439
+ * conditional absence in addition to `E2`.
1440
+ *
1441
+ * ## Ownership and lifetime
1442
+ *
1443
+ * No callback runs until the result is read or observed. Computed results cannot become absent and
1444
+ * do not add `NoSuchElementError`; only the Filtered overload can fail a current read for absence.
1445
+ * Callback services and failures remain `R2` and `E2`, and the observing Scope owns subscription
1446
+ * cleanup.
1447
+ *
839
1448
  * @example
840
1449
  * ```ts
841
1450
  * import { Effect } from "effect"
@@ -872,6 +1481,25 @@ export const mapEffect = dual(2, function mapEffect(versioned, f) {
872
1481
  /**
873
1482
  * Transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function.
874
1483
  *
1484
+ * @remarks
1485
+ * ## Why
1486
+ *
1487
+ * `map` creates derived state instead of copying source state into a component.
1488
+ * Reads and pushed updates remain connected to the original `Versioned` value,
1489
+ * so a projection can be tested without rendering and consumed by any renderer.
1490
+ *
1491
+ * ## Ownership and lifetime
1492
+ *
1493
+ * The returned `Computed` or `Filtered` view does not take ownership of the
1494
+ * source. It follows the source lifetime and preserves its error and service
1495
+ * channels. The pure mapping function adds neither resources nor failures.
1496
+ *
1497
+ * ## Re-computation
1498
+ *
1499
+ * The mapping function runs for the current value and subsequent committed
1500
+ * source versions. Updates still occur on the writable source; the derived view
1501
+ * is read-only unless a more specific bidirectional combinator is used.
1502
+ *
875
1503
  * @example
876
1504
  * ```ts
877
1505
  * import { Effect } from "effect"
@@ -904,6 +1532,18 @@ export const map = dual(2, function map(versioned, f) {
904
1532
  /**
905
1533
  * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function that returns an `Option`.
906
1534
  *
1535
+ * @remarks
1536
+ * ## Why
1537
+ *
1538
+ * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function
1539
+ * that returns an `Option`. Current reads and pushed versions use the same derivation, preventing
1540
+ * snapshot and subscription behavior from diverging.
1541
+ *
1542
+ * ## Ownership and lifetime
1543
+ *
1544
+ * The filter map effect view retains no independent value. Its Effect read fails with NoSuchElement
1545
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
1546
+ *
907
1547
  * @example
908
1548
  * ```ts
909
1549
  * import { Effect, Option } from "effect"
@@ -931,6 +1571,18 @@ export const filterMapEffect = dual(2, function filterMapEffect(versioned, f) {
931
1571
  /**
932
1572
  * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function that returns an `Option`.
933
1573
  *
1574
+ * @remarks
1575
+ * ## Why
1576
+ *
1577
+ * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function that
1578
+ * returns an `Option`. Current reads and pushed versions use the same derivation, preventing
1579
+ * snapshot and subscription behavior from diverging.
1580
+ *
1581
+ * ## Ownership and lifetime
1582
+ *
1583
+ * The filter map view retains no independent value. Its Effect read fails with NoSuchElement
1584
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
1585
+ *
934
1586
  * @example
935
1587
  * ```ts
936
1588
  * import { Effect, Option } from "effect"
@@ -958,6 +1610,18 @@ export const filterMap = dual(2, function filterMap(versioned, f) {
958
1610
  /**
959
1611
  * Converts a `Computed` or `Filtered` of `Option<A>` into a `Filtered<A>`, filtering out `None` values.
960
1612
  *
1613
+ * @remarks
1614
+ * ## Why
1615
+ *
1616
+ * Converts a `Computed` or `Filtered` of `Option<A>` into a `Filtered<A>`, filtering out `None`
1617
+ * values. Current reads and pushed versions use the same derivation, preventing snapshot and
1618
+ * subscription behavior from diverging.
1619
+ *
1620
+ * ## Ownership and lifetime
1621
+ *
1622
+ * The compact view retains no independent value. Its Effect read fails with NoSuchElement
1623
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
1624
+ *
961
1625
  * @example
962
1626
  * ```ts
963
1627
  * import { Effect, Option } from "effect"
@@ -988,6 +1652,20 @@ export const compact = function compact(versioned) {
988
1652
  * Returns a `Computed` that yields the value inside the `Option`, or the fallback when `None`.
989
1653
  * Works with `Computed<Option<A>>` (e.g. from `fromOption` / `fromNullable`) and with `Filtered<A>`.
990
1654
  *
1655
+ * @remarks
1656
+ * ## Why
1657
+ *
1658
+ * Returns a `Computed` that yields the value inside the `Option`, or the fallback when `None`.
1659
+ * Works with `Computed<Option<A>>` (e.g. from `fromOption` / `fromNullable`) and with
1660
+ * `Filtered<A>`. Current reads and pushed versions use the same derivation, preventing snapshot
1661
+ * and subscription behavior from diverging.
1662
+ *
1663
+ * ## Ownership and lifetime
1664
+ *
1665
+ * The returned Computed never fails for absence: `None` or an absent Filtered value invokes
1666
+ * `fallback`. It preserves only the input's declared `E` and `R`; the pure fallback adds no failure,
1667
+ * service, subscription, or retained value.
1668
+ *
991
1669
  * @example
992
1670
  * ```ts
993
1671
  * import { Effect, Option } from "effect"
@@ -1035,7 +1713,7 @@ class RefSubjectSimpleTransform extends YieldableFx {
1035
1713
  return this._fx.run(sink);
1036
1714
  }
1037
1715
  toEffect() {
1038
- return this.transformEffect(this.ref.asEffect());
1716
+ return this.transformEffect(this.ref);
1039
1717
  }
1040
1718
  updates(run) {
1041
1719
  return this.ref.updates(run);
@@ -1047,6 +1725,25 @@ class RefSubjectSimpleTransform extends YieldableFx {
1047
1725
  return this.ref.onSuccess(value);
1048
1726
  }
1049
1727
  }
1728
+ /**
1729
+ * Limits which pushed versions a RefSubject view observes without changing its state.
1730
+ *
1731
+ * @remarks
1732
+ * ## Why
1733
+ *
1734
+ * Applies `skip` and `take` only to the Fx observation channel. Current reads still sample the
1735
+ * underlying RefSubject directly, and writes still use its original serialized update boundary.
1736
+ *
1737
+ * ## Ownership and lifetime
1738
+ *
1739
+ * Creating the view starts nothing and retains no value. Each observation uses its Scope and ends
1740
+ * after `take` selected pushes; ending that observation does not interrupt or delete the source.
1741
+ * Version, interruption, subscriber count, reads, failures, services, and writes delegate to the
1742
+ * source RefSubject.
1743
+ *
1744
+ * @since 1.18.0
1745
+ * @category combinators
1746
+ */
1050
1747
  export const slice = dual(3, function slice(ref, skip, take) {
1051
1748
  return new RefSubjectSimpleTransform(ref, (_) => fxSlice(_, { skip, take }), identity);
1052
1749
  });
@@ -1074,7 +1771,7 @@ class RefSubjectTransform extends YieldableFx {
1074
1771
  return this._fx.run(sink);
1075
1772
  }
1076
1773
  toEffect() {
1077
- return Effect.map(this.ref.asEffect(), this.toB);
1774
+ return Effect.map(this.ref, this.toB);
1078
1775
  }
1079
1776
  updates(run) {
1080
1777
  return this.ref.updates((innerRef) => {
@@ -1096,6 +1793,17 @@ class RefSubjectTransform extends YieldableFx {
1096
1793
  /**
1097
1794
  * Transforms a `RefSubject` invariantly using bidirectional mapping functions.
1098
1795
  *
1796
+ * @remarks
1797
+ * ## Why
1798
+ *
1799
+ * Creates a bidirectional lens over state: reads map outward and writes map back to the original
1800
+ * RefSubject without allocating a second store.
1801
+ *
1802
+ * ## Ownership and lifetime
1803
+ *
1804
+ * The derived ref owns no independent state or subscription. It follows the source lifetime and
1805
+ * routes writes through the source's synchronized update boundary.
1806
+ *
1099
1807
  * @example
1100
1808
  * ```ts
1101
1809
  * import { Effect } from "effect"
@@ -1156,6 +1864,17 @@ function getRefKind(refs) {
1156
1864
  /**
1157
1865
  * Combines multiple `RefSubject`, `Computed`, or `Filtered` instances into a single struct.
1158
1866
  *
1867
+ * @remarks
1868
+ * ## Why
1869
+ *
1870
+ * Combines several refs into one state value while preserving whether the result is writable,
1871
+ * computed, or filtered from its inputs.
1872
+ *
1873
+ * ## Ownership and lifetime
1874
+ *
1875
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
1876
+ * source errors, services, and lifetime.
1877
+ *
1159
1878
  * @example
1160
1879
  * ```ts
1161
1880
  * import { Effect } from "effect"
@@ -1202,6 +1921,17 @@ export function struct(refs) {
1202
1921
  /**
1203
1922
  * Combines multiple `RefSubject`, `Computed`, or `Filtered` instances into a single tuple.
1204
1923
  *
1924
+ * @remarks
1925
+ * ## Why
1926
+ *
1927
+ * Combines several refs into one state value while preserving whether the result is writable,
1928
+ * computed, or filtered from its inputs.
1929
+ *
1930
+ * ## Ownership and lifetime
1931
+ *
1932
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
1933
+ * source errors, services, and lifetime.
1934
+ *
1205
1935
  * @example
1206
1936
  * ```ts
1207
1937
  * import { Effect } from "effect"
@@ -1245,6 +1975,16 @@ function makeTupleRef(refs) {
1245
1975
  return new RefSubjectTuple(refs);
1246
1976
  }
1247
1977
  const UNBOUNDED = { concurrency: "unbounded" };
1978
+ const sampleRefSubject = (ref) =>
1979
+ // @effect-diagnostics-next-line unnecessaryEffectGen:off
1980
+ Effect.gen(function* () {
1981
+ return yield* ref;
1982
+ });
1983
+ function makeCompositeVersioned(refs, current) {
1984
+ const version = Effect.map(Effect.all(refs.map((ref) => ref.version), UNBOUNDED), (versions) => versions.reduce(sum, 0));
1985
+ const changes = skipRepeats(fxMapEffect(fxMergeAll(...refs), () => current));
1986
+ return Versioned.hold(Versioned.make(version, changes, current));
1987
+ }
1248
1988
  class RefSubjectTuple extends YieldableFx {
1249
1989
  [ComputedTypeId] = ComputedTypeId;
1250
1990
  [RefSubjectTypeId] = RefSubjectTypeId;
@@ -1257,12 +1997,14 @@ class RefSubjectTuple extends YieldableFx {
1257
1997
  constructor(refs) {
1258
1998
  super();
1259
1999
  this.refs = refs;
1260
- this.versioned = Versioned.hold(Versioned.tuple(refs));
2000
+ this.versioned = (refs.length > 0 && getTupleTransactionAccess(refs)
2001
+ ? makeCompositeVersioned(refs, Effect.all(refs.map(sampleRefSubject), UNBOUNDED))
2002
+ : Versioned.hold(Versioned.tuple(refs)));
1261
2003
  this.version = this.versioned.version;
1262
2004
  this.interrupt = Effect.all(refs.map((r) => r.interrupt), UNBOUNDED);
1263
2005
  this.subscriberCount = Effect.map(Effect.all(refs.map((r) => r.subscriberCount), UNBOUNDED), Array.reduce(0, sum));
1264
2006
  this.getSetDelete = {
1265
- get: this.versioned.asEffect(),
2007
+ get: this.versioned,
1266
2008
  set: (a) => Effect.all(refs.map((r, i) => set(r, a[i])), UNBOUNDED),
1267
2009
  delete: Effect.map(Effect.all(refs.map((r) => reset(r)), UNBOUNDED), Option.all),
1268
2010
  };
@@ -1274,10 +2016,15 @@ class RefSubjectTuple extends YieldableFx {
1274
2016
  return this.versioned.run(sink);
1275
2017
  }
1276
2018
  toEffect() {
1277
- return this.versioned.asEffect();
2019
+ return this.versioned;
1278
2020
  }
1279
2021
  updates(run) {
1280
- return run(this.getSetDelete);
2022
+ const accessEffect = getTransactionAccess(this);
2023
+ return accessEffect
2024
+ ? Effect.flatMap(accessEffect, (transactionAccess) => Option.isSome(transactionAccess)
2025
+ ? runTransaction(transactionAccess.value, run)
2026
+ : Effect.suspend(() => run(this.getSetDelete)))
2027
+ : Effect.suspend(() => run(this.getSetDelete));
1281
2028
  }
1282
2029
  onFailure(cause) {
1283
2030
  return Effect.all(this.refs.map((ref) => ref.onFailure(cause)));
@@ -1307,12 +2054,16 @@ class RefSubjectStruct extends YieldableFx {
1307
2054
  constructor(refs) {
1308
2055
  super();
1309
2056
  this.refs = refs;
1310
- this.versioned = Versioned.hold(Versioned.struct(refs));
2057
+ const keys = Object.keys(refs);
2058
+ const current = Effect.map(Effect.all(keys.map((key) => sampleRefSubject(refs[key])), UNBOUNDED), (values) => Object.fromEntries(keys.map((key, index) => [key, values[index]])));
2059
+ this.versioned = (keys.length > 0 && getStructTransactionAccess(refs)
2060
+ ? makeCompositeVersioned(Object.values(refs), current)
2061
+ : Versioned.hold(Versioned.struct(refs)));
1311
2062
  this.version = this.versioned.version;
1312
2063
  this.interrupt = Effect.all(Object.values(refs).map((r) => r.interrupt), UNBOUNDED);
1313
2064
  this.subscriberCount = Effect.map(Effect.all(Object.values(refs).map((r) => r.subscriberCount), UNBOUNDED), Array.reduce(0, sum));
1314
2065
  this.getSetDelete = {
1315
- get: this.versioned.asEffect(),
2066
+ get: this.versioned,
1316
2067
  set: (a) => Effect.all(Object.keys(refs).map((k) => set(refs[k], a[k])), UNBOUNDED),
1317
2068
  delete: Effect.map(Effect.all(Object.values(refs).map((r) => reset(r)), UNBOUNDED), Option.all),
1318
2069
  };
@@ -1324,10 +2075,15 @@ class RefSubjectStruct extends YieldableFx {
1324
2075
  return this.versioned.run(sink);
1325
2076
  }
1326
2077
  toEffect() {
1327
- return this.versioned.asEffect();
2078
+ return this.versioned;
1328
2079
  }
1329
2080
  updates(run) {
1330
- return run(this.getSetDelete);
2081
+ const accessEffect = getTransactionAccess(this);
2082
+ return accessEffect
2083
+ ? Effect.flatMap(accessEffect, (transactionAccess) => Option.isSome(transactionAccess)
2084
+ ? runTransaction(transactionAccess.value, run)
2085
+ : Effect.suspend(() => run(this.getSetDelete)))
2086
+ : Effect.suspend(() => run(this.getSetDelete));
1331
2087
  }
1332
2088
  onFailure(cause) {
1333
2089
  return Effect.all(Object.values(this.refs).map((ref) => ref.onFailure(cause)));
@@ -1342,6 +2098,24 @@ function makeStructComputed(refs) {
1342
2098
  function makeStructFiltered(refs) {
1343
2099
  return new FilteredImpl(Versioned.struct(refs), Effect.succeedSome);
1344
2100
  }
2101
+ /**
2102
+ * Lifts an Effect-provided Computed into a Computed facade.
2103
+ *
2104
+ * @remarks
2105
+ * ## Why
2106
+ *
2107
+ * Defers service lookup until each version read, current read, interruption, or Fx observation, so
2108
+ * callers can compose a Context-provided Computed without manually flat-mapping the service Effect.
2109
+ *
2110
+ * ## Ownership and lifetime
2111
+ *
2112
+ * The facade caches neither the resolved Computed nor its value. Each operation runs the supplied
2113
+ * Effect, then delegates to the resolved Computed. Service requirements combine as `R | R2`, source
2114
+ * failures remain `E`, and the observing Scope owns the delegated subscription.
2115
+ *
2116
+ * @since 1.18.0
2117
+ * @category combinators
2118
+ */
1345
2119
  export function computedFromService(effect) {
1346
2120
  return new ComputedFromService(effect);
1347
2121
  }
@@ -1360,9 +2134,26 @@ class ComputedFromService extends YieldableFx {
1360
2134
  return Effect.flatMap(this.effect, (c) => c.run(sink));
1361
2135
  }
1362
2136
  toEffect() {
1363
- return Effect.flatMap(this.effect, (c) => c.asEffect());
2137
+ return Effect.flatMap(this.effect, (c) => c);
1364
2138
  }
1365
2139
  }
2140
+ /**
2141
+ * Defers retrieval of a Filtered value from Effect Context while preserving Filtered behavior.
2142
+ *
2143
+ * @remarks
2144
+ * ## Why
2145
+ *
2146
+ * Lets a service-provided Filtered participate directly in Effect reads and Fx observation without
2147
+ * manually flat-mapping the service tag at every use.
2148
+ *
2149
+ * ## Ownership and lifetime
2150
+ *
2151
+ * The filtered from service view retains no independent value. Its Effect read fails with NoSuchElement
2152
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
2153
+ *
2154
+ * @since 1.18.0
2155
+ * @category combinators
2156
+ */
1366
2157
  export function filteredFromService(effect) {
1367
2158
  return new FilteredFromService(effect);
1368
2159
  }
@@ -1381,9 +2172,10 @@ class FilteredFromService extends YieldableFx {
1381
2172
  return Effect.flatMap(this.effect, (c) => c.run(sink));
1382
2173
  }
1383
2174
  toEffect() {
1384
- return Effect.flatMap(this.effect, (c) => c.asEffect());
2175
+ return Effect.flatMap(this.effect, (c) => c);
1385
2176
  }
1386
2177
  asComputed() {
1387
2178
  return computedFromService(Effect.map(this.effect, (c) => c.asComputed()));
1388
2179
  }
1389
2180
  }
2181
+ export * from "./Hydration.js";