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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (664) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -21
  3. package/dist/Fx/Fx.d.ts +371 -19
  4. package/dist/Fx/Fx.d.ts.map +1 -1
  5. package/dist/Fx/Fx.js +37 -6
  6. package/dist/Fx/TypeId.d.ts +52 -6
  7. package/dist/Fx/TypeId.d.ts.map +1 -1
  8. package/dist/Fx/TypeId.js +41 -4
  9. package/dist/Fx/combinators/additive.d.ts +162 -11
  10. package/dist/Fx/combinators/additive.d.ts.map +1 -1
  11. package/dist/Fx/combinators/additive.js +162 -11
  12. package/dist/Fx/combinators/catch.d.ts +202 -29
  13. package/dist/Fx/combinators/catch.d.ts.map +1 -1
  14. package/dist/Fx/combinators/catch.js +193 -23
  15. package/dist/Fx/combinators/causes.d.ts +25 -2
  16. package/dist/Fx/combinators/causes.d.ts.map +1 -1
  17. package/dist/Fx/combinators/causes.js +25 -2
  18. package/dist/Fx/combinators/changesWithEffect.d.ts +21 -1
  19. package/dist/Fx/combinators/changesWithEffect.d.ts.map +1 -1
  20. package/dist/Fx/combinators/changesWithEffect.js +21 -1
  21. package/dist/Fx/combinators/compact.d.ts +18 -1
  22. package/dist/Fx/combinators/compact.d.ts.map +1 -1
  23. package/dist/Fx/combinators/compact.js +18 -1
  24. package/dist/Fx/combinators/concatMap.d.ts +86 -0
  25. package/dist/Fx/combinators/concatMap.d.ts.map +1 -0
  26. package/dist/Fx/combinators/concatMap.js +86 -0
  27. package/dist/Fx/combinators/continueWith.d.ts +113 -5
  28. package/dist/Fx/combinators/continueWith.d.ts.map +1 -1
  29. package/dist/Fx/combinators/continueWith.js +113 -5
  30. package/dist/Fx/combinators/debounce.d.ts +34 -0
  31. package/dist/Fx/combinators/debounce.d.ts.map +1 -0
  32. package/dist/Fx/combinators/debounce.js +35 -0
  33. package/dist/Fx/combinators/delay.d.ts +36 -0
  34. package/dist/Fx/combinators/delay.d.ts.map +1 -0
  35. package/dist/Fx/combinators/delay.js +33 -0
  36. package/dist/Fx/combinators/dropUntil.d.ts +44 -2
  37. package/dist/Fx/combinators/dropUntil.d.ts.map +1 -1
  38. package/dist/Fx/combinators/dropUntil.js +44 -2
  39. package/dist/Fx/combinators/during.d.ts +38 -0
  40. package/dist/Fx/combinators/during.d.ts.map +1 -0
  41. package/dist/Fx/combinators/during.js +85 -0
  42. package/dist/Fx/combinators/ensuring.d.ts +34 -4
  43. package/dist/Fx/combinators/ensuring.d.ts.map +1 -1
  44. package/dist/Fx/combinators/ensuring.js +34 -4
  45. package/dist/Fx/combinators/exhaustLatestMap.d.ts +41 -5
  46. package/dist/Fx/combinators/exhaustLatestMap.d.ts.map +1 -1
  47. package/dist/Fx/combinators/exhaustLatestMap.js +41 -5
  48. package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts +40 -4
  49. package/dist/Fx/combinators/exhaustLatestMapEffect.d.ts.map +1 -1
  50. package/dist/Fx/combinators/exhaustLatestMapEffect.js +40 -4
  51. package/dist/Fx/combinators/exhaustMap.d.ts +38 -1
  52. package/dist/Fx/combinators/exhaustMap.d.ts.map +1 -1
  53. package/dist/Fx/combinators/exhaustMap.js +38 -1
  54. package/dist/Fx/combinators/exhaustMapEffect.d.ts +33 -1
  55. package/dist/Fx/combinators/exhaustMapEffect.d.ts.map +1 -1
  56. package/dist/Fx/combinators/exhaustMapEffect.js +33 -1
  57. package/dist/Fx/combinators/exit.d.ts +23 -2
  58. package/dist/Fx/combinators/exit.d.ts.map +1 -1
  59. package/dist/Fx/combinators/exit.js +23 -2
  60. package/dist/Fx/combinators/filter.d.ts +17 -1
  61. package/dist/Fx/combinators/filter.d.ts.map +1 -1
  62. package/dist/Fx/combinators/filter.js +17 -1
  63. package/dist/Fx/combinators/filterEffect.d.ts +22 -1
  64. package/dist/Fx/combinators/filterEffect.d.ts.map +1 -1
  65. package/dist/Fx/combinators/filterEffect.js +22 -1
  66. package/dist/Fx/combinators/filterMap.d.ts +20 -1
  67. package/dist/Fx/combinators/filterMap.d.ts.map +1 -1
  68. package/dist/Fx/combinators/filterMap.js +20 -1
  69. package/dist/Fx/combinators/filterMapEffect.d.ts +21 -1
  70. package/dist/Fx/combinators/filterMapEffect.d.ts.map +1 -1
  71. package/dist/Fx/combinators/filterMapEffect.js +21 -1
  72. package/dist/Fx/combinators/filterMapLoop.d.ts +20 -1
  73. package/dist/Fx/combinators/filterMapLoop.d.ts.map +1 -1
  74. package/dist/Fx/combinators/filterMapLoop.js +20 -1
  75. package/dist/Fx/combinators/filterMapLoopCause.d.ts +21 -1
  76. package/dist/Fx/combinators/filterMapLoopCause.d.ts.map +1 -1
  77. package/dist/Fx/combinators/filterMapLoopCause.js +21 -1
  78. package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts +21 -1
  79. package/dist/Fx/combinators/filterMapLoopCauseEffect.d.ts.map +1 -1
  80. package/dist/Fx/combinators/filterMapLoopCauseEffect.js +21 -1
  81. package/dist/Fx/combinators/filterMapLoopEffect.d.ts +21 -1
  82. package/dist/Fx/combinators/filterMapLoopEffect.d.ts.map +1 -1
  83. package/dist/Fx/combinators/filterMapLoopEffect.js +21 -1
  84. package/dist/Fx/combinators/flatMap.d.ts +50 -5
  85. package/dist/Fx/combinators/flatMap.d.ts.map +1 -1
  86. package/dist/Fx/combinators/flatMap.js +36 -3
  87. package/dist/Fx/combinators/flatMapConcurrently.d.ts +51 -4
  88. package/dist/Fx/combinators/flatMapConcurrently.d.ts.map +1 -1
  89. package/dist/Fx/combinators/flatMapConcurrently.js +48 -2
  90. package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts +48 -4
  91. package/dist/Fx/combinators/flatMapConcurrentlyEffect.d.ts.map +1 -1
  92. package/dist/Fx/combinators/flatMapConcurrentlyEffect.js +40 -2
  93. package/dist/Fx/combinators/flatMapEffect.d.ts +46 -4
  94. package/dist/Fx/combinators/flatMapEffect.d.ts.map +1 -1
  95. package/dist/Fx/combinators/flatMapEffect.js +32 -2
  96. package/dist/Fx/combinators/flip.d.ts +34 -2
  97. package/dist/Fx/combinators/flip.d.ts.map +1 -1
  98. package/dist/Fx/combinators/flip.js +34 -2
  99. package/dist/Fx/combinators/gen.d.ts +29 -10
  100. package/dist/Fx/combinators/gen.d.ts.map +1 -1
  101. package/dist/Fx/combinators/gen.js +28 -4
  102. package/dist/Fx/combinators/genScoped.d.ts +33 -10
  103. package/dist/Fx/combinators/genScoped.d.ts.map +1 -1
  104. package/dist/Fx/combinators/genScoped.js +31 -3
  105. package/dist/Fx/combinators/grouped.d.ts +89 -0
  106. package/dist/Fx/combinators/grouped.d.ts.map +1 -0
  107. package/dist/Fx/combinators/grouped.js +146 -0
  108. package/dist/Fx/combinators/index.d.ts +35 -0
  109. package/dist/Fx/combinators/index.d.ts.map +1 -1
  110. package/dist/Fx/combinators/index.js +35 -0
  111. package/dist/Fx/combinators/keyed.d.ts +123 -9
  112. package/dist/Fx/combinators/keyed.d.ts.map +1 -1
  113. package/dist/Fx/combinators/keyed.js +69 -11
  114. package/dist/Fx/combinators/loop.d.ts +17 -1
  115. package/dist/Fx/combinators/loop.d.ts.map +1 -1
  116. package/dist/Fx/combinators/loop.js +17 -1
  117. package/dist/Fx/combinators/loopCause.d.ts +18 -1
  118. package/dist/Fx/combinators/loopCause.d.ts.map +1 -1
  119. package/dist/Fx/combinators/loopCause.js +18 -1
  120. package/dist/Fx/combinators/loopCauseEffect.d.ts +19 -1
  121. package/dist/Fx/combinators/loopCauseEffect.d.ts.map +1 -1
  122. package/dist/Fx/combinators/loopCauseEffect.js +19 -1
  123. package/dist/Fx/combinators/loopEffect.d.ts +24 -1
  124. package/dist/Fx/combinators/loopEffect.d.ts.map +1 -1
  125. package/dist/Fx/combinators/loopEffect.js +24 -1
  126. package/dist/Fx/combinators/map.d.ts +46 -1
  127. package/dist/Fx/combinators/map.d.ts.map +1 -1
  128. package/dist/Fx/combinators/map.js +43 -1
  129. package/dist/Fx/combinators/mapBoth.d.ts +20 -1
  130. package/dist/Fx/combinators/mapBoth.d.ts.map +1 -1
  131. package/dist/Fx/combinators/mapBoth.js +20 -1
  132. package/dist/Fx/combinators/mapEffect.d.ts +25 -1
  133. package/dist/Fx/combinators/mapEffect.d.ts.map +1 -1
  134. package/dist/Fx/combinators/mapEffect.js +25 -1
  135. package/dist/Fx/combinators/mapError.d.ts +21 -5
  136. package/dist/Fx/combinators/mapError.d.ts.map +1 -1
  137. package/dist/Fx/combinators/mapError.js +21 -5
  138. package/dist/Fx/combinators/mergeAll.d.ts +35 -1
  139. package/dist/Fx/combinators/mergeAll.d.ts.map +1 -1
  140. package/dist/Fx/combinators/mergeAll.js +35 -1
  141. package/dist/Fx/combinators/mergeOrdered.d.ts +36 -4
  142. package/dist/Fx/combinators/mergeOrdered.d.ts.map +1 -1
  143. package/dist/Fx/combinators/mergeOrdered.js +68 -14
  144. package/dist/Fx/combinators/onError.d.ts +34 -4
  145. package/dist/Fx/combinators/onError.d.ts.map +1 -1
  146. package/dist/Fx/combinators/onError.js +34 -4
  147. package/dist/Fx/combinators/onExit.d.ts +29 -3
  148. package/dist/Fx/combinators/onExit.d.ts.map +1 -1
  149. package/dist/Fx/combinators/onExit.js +29 -3
  150. package/dist/Fx/combinators/onInterrupt.d.ts +49 -4
  151. package/dist/Fx/combinators/onInterrupt.d.ts.map +1 -1
  152. package/dist/Fx/combinators/onInterrupt.js +49 -4
  153. package/dist/Fx/combinators/pairwise.d.ts +28 -0
  154. package/dist/Fx/combinators/pairwise.d.ts.map +1 -0
  155. package/dist/Fx/combinators/pairwise.js +31 -0
  156. package/dist/Fx/combinators/provide.d.ts +141 -20
  157. package/dist/Fx/combinators/provide.d.ts.map +1 -1
  158. package/dist/Fx/combinators/provide.js +137 -16
  159. package/dist/Fx/combinators/race.d.ts +92 -0
  160. package/dist/Fx/combinators/race.d.ts.map +1 -0
  161. package/dist/Fx/combinators/race.js +149 -0
  162. package/dist/Fx/combinators/repeat.d.ts +41 -0
  163. package/dist/Fx/combinators/repeat.d.ts.map +1 -0
  164. package/dist/Fx/combinators/repeat.js +57 -0
  165. package/dist/Fx/combinators/result.d.ts +23 -1
  166. package/dist/Fx/combinators/result.d.ts.map +1 -1
  167. package/dist/Fx/combinators/result.js +27 -13
  168. package/dist/Fx/combinators/retry.d.ts +53 -0
  169. package/dist/Fx/combinators/retry.d.ts.map +1 -0
  170. package/dist/Fx/combinators/retry.js +71 -0
  171. package/dist/Fx/combinators/sample.d.ts +31 -0
  172. package/dist/Fx/combinators/sample.d.ts.map +1 -0
  173. package/dist/Fx/combinators/sample.js +42 -0
  174. package/dist/Fx/combinators/scan.d.ts +41 -2
  175. package/dist/Fx/combinators/scan.d.ts.map +1 -1
  176. package/dist/Fx/combinators/scan.js +43 -4
  177. package/dist/Fx/combinators/since.d.ts +30 -0
  178. package/dist/Fx/combinators/since.d.ts.map +1 -0
  179. package/dist/Fx/combinators/since.js +39 -0
  180. package/dist/Fx/combinators/skip.d.ts +33 -2
  181. package/dist/Fx/combinators/skip.d.ts.map +1 -1
  182. package/dist/Fx/combinators/skip.js +33 -2
  183. package/dist/Fx/combinators/skipRepeats.d.ts +17 -1
  184. package/dist/Fx/combinators/skipRepeats.d.ts.map +1 -1
  185. package/dist/Fx/combinators/skipRepeats.js +17 -1
  186. package/dist/Fx/combinators/skipRepeatsWith.d.ts +18 -1
  187. package/dist/Fx/combinators/skipRepeatsWith.d.ts.map +1 -1
  188. package/dist/Fx/combinators/skipRepeatsWith.js +18 -1
  189. package/dist/Fx/combinators/skipWhile.d.ts +72 -4
  190. package/dist/Fx/combinators/skipWhile.d.ts.map +1 -1
  191. package/dist/Fx/combinators/skipWhile.js +72 -4
  192. package/dist/Fx/combinators/slice.d.ts +85 -3
  193. package/dist/Fx/combinators/slice.d.ts.map +1 -1
  194. package/dist/Fx/combinators/slice.js +35 -2
  195. package/dist/Fx/combinators/switchMap.d.ts +39 -1
  196. package/dist/Fx/combinators/switchMap.d.ts.map +1 -1
  197. package/dist/Fx/combinators/switchMap.js +43 -5
  198. package/dist/Fx/combinators/switchMapEffect.d.ts +38 -1
  199. package/dist/Fx/combinators/switchMapEffect.d.ts.map +1 -1
  200. package/dist/Fx/combinators/switchMapEffect.js +38 -1
  201. package/dist/Fx/combinators/take.d.ts +34 -2
  202. package/dist/Fx/combinators/take.d.ts.map +1 -1
  203. package/dist/Fx/combinators/take.js +34 -2
  204. package/dist/Fx/combinators/takeUntil.d.ts +49 -3
  205. package/dist/Fx/combinators/takeUntil.d.ts.map +1 -1
  206. package/dist/Fx/combinators/takeUntil.js +49 -3
  207. package/dist/Fx/combinators/takeWhile.d.ts +33 -2
  208. package/dist/Fx/combinators/takeWhile.d.ts.map +1 -1
  209. package/dist/Fx/combinators/takeWhile.js +33 -2
  210. package/dist/Fx/combinators/tapEffect.d.ts +17 -1
  211. package/dist/Fx/combinators/tapEffect.d.ts.map +1 -1
  212. package/dist/Fx/combinators/tapEffect.js +17 -1
  213. package/dist/Fx/combinators/throttle.d.ts +79 -0
  214. package/dist/Fx/combinators/throttle.d.ts.map +1 -0
  215. package/dist/Fx/combinators/throttle.js +99 -0
  216. package/dist/Fx/combinators/timeout.d.ts +76 -0
  217. package/dist/Fx/combinators/timeout.d.ts.map +1 -0
  218. package/dist/Fx/combinators/timeout.js +110 -0
  219. package/dist/Fx/combinators/tuple.d.ts +32 -2
  220. package/dist/Fx/combinators/tuple.d.ts.map +1 -1
  221. package/dist/Fx/combinators/tuple.js +36 -5
  222. package/dist/Fx/combinators/until.d.ts +27 -0
  223. package/dist/Fx/combinators/until.d.ts.map +1 -0
  224. package/dist/Fx/combinators/until.js +56 -0
  225. package/dist/Fx/combinators/unwrap.d.ts +31 -2
  226. package/dist/Fx/combinators/unwrap.d.ts.map +1 -1
  227. package/dist/Fx/combinators/unwrap.js +30 -1
  228. package/dist/Fx/combinators/unwrapScoped.d.ts +34 -1
  229. package/dist/Fx/combinators/unwrapScoped.d.ts.map +1 -1
  230. package/dist/Fx/combinators/unwrapScoped.js +34 -1
  231. package/dist/Fx/combinators/when.d.ts +37 -2
  232. package/dist/Fx/combinators/when.d.ts.map +1 -1
  233. package/dist/Fx/combinators/when.js +38 -3
  234. package/dist/Fx/combinators/withLatestFrom.d.ts +58 -0
  235. package/dist/Fx/combinators/withLatestFrom.d.ts.map +1 -0
  236. package/dist/Fx/combinators/withLatestFrom.js +68 -0
  237. package/dist/Fx/combinators/withSpan.d.ts +35 -1
  238. package/dist/Fx/combinators/withSpan.d.ts.map +1 -1
  239. package/dist/Fx/combinators/withSpan.js +34 -3
  240. package/dist/Fx/combinators/zip.d.ts +64 -4
  241. package/dist/Fx/combinators/zip.d.ts.map +1 -1
  242. package/dist/Fx/combinators/zip.js +64 -4
  243. package/dist/Fx/constructors/at.d.ts +21 -1
  244. package/dist/Fx/constructors/at.d.ts.map +1 -1
  245. package/dist/Fx/constructors/at.js +21 -1
  246. package/dist/Fx/constructors/die.d.ts +22 -1
  247. package/dist/Fx/constructors/die.d.ts.map +1 -1
  248. package/dist/Fx/constructors/die.js +22 -1
  249. package/dist/Fx/constructors/empty.d.ts +19 -1
  250. package/dist/Fx/constructors/empty.d.ts.map +1 -1
  251. package/dist/Fx/constructors/empty.js +19 -1
  252. package/dist/Fx/constructors/fail.d.ts +22 -1
  253. package/dist/Fx/constructors/fail.d.ts.map +1 -1
  254. package/dist/Fx/constructors/fail.js +22 -1
  255. package/dist/Fx/constructors/failCause.d.ts +23 -1
  256. package/dist/Fx/constructors/failCause.d.ts.map +1 -1
  257. package/dist/Fx/constructors/failCause.js +23 -1
  258. package/dist/Fx/constructors/fn.d.ts +116 -16
  259. package/dist/Fx/constructors/fn.d.ts.map +1 -1
  260. package/dist/Fx/constructors/fn.js +36 -0
  261. package/dist/Fx/constructors/fromEffect.d.ts +45 -3
  262. package/dist/Fx/constructors/fromEffect.d.ts.map +1 -1
  263. package/dist/Fx/constructors/fromEffect.js +45 -3
  264. package/dist/Fx/constructors/fromFailures.d.ts +25 -1
  265. package/dist/Fx/constructors/fromFailures.d.ts.map +1 -1
  266. package/dist/Fx/constructors/fromFailures.js +25 -1
  267. package/dist/Fx/constructors/fromIterable.d.ts +23 -1
  268. package/dist/Fx/constructors/fromIterable.d.ts.map +1 -1
  269. package/dist/Fx/constructors/fromIterable.js +23 -1
  270. package/dist/Fx/constructors/fromSchedule.d.ts +26 -1
  271. package/dist/Fx/constructors/fromSchedule.d.ts.map +1 -1
  272. package/dist/Fx/constructors/fromSchedule.js +28 -3
  273. package/dist/Fx/constructors/index.d.ts +2 -1
  274. package/dist/Fx/constructors/index.d.ts.map +1 -1
  275. package/dist/Fx/constructors/index.js +2 -1
  276. package/dist/Fx/constructors/interrupt.d.ts +22 -2
  277. package/dist/Fx/constructors/interrupt.d.ts.map +1 -1
  278. package/dist/Fx/constructors/interrupt.js +22 -2
  279. package/dist/Fx/constructors/make.d.ts +151 -4
  280. package/dist/Fx/constructors/make.d.ts.map +1 -1
  281. package/dist/Fx/constructors/make.js +60 -7
  282. package/dist/Fx/constructors/periodic.d.ts +30 -1
  283. package/dist/Fx/constructors/periodic.d.ts.map +1 -1
  284. package/dist/Fx/constructors/periodic.js +30 -1
  285. package/dist/Fx/constructors/succeed.d.ts +79 -7
  286. package/dist/Fx/constructors/succeed.d.ts.map +1 -1
  287. package/dist/Fx/constructors/succeed.js +79 -7
  288. package/dist/Fx/constructors/suspend.d.ts +28 -0
  289. package/dist/Fx/constructors/suspend.d.ts.map +1 -1
  290. package/dist/Fx/constructors/suspend.js +28 -0
  291. package/dist/Fx/constructors/sync.d.ts +32 -0
  292. package/dist/Fx/constructors/sync.d.ts.map +1 -0
  293. package/dist/Fx/constructors/sync.js +32 -0
  294. package/dist/Fx/internal/DeferredRef.d.ts +259 -7
  295. package/dist/Fx/internal/DeferredRef.d.ts.map +1 -1
  296. package/dist/Fx/internal/DeferredRef.js +260 -9
  297. package/dist/Fx/internal/UnionToTuple.d.ts +22 -0
  298. package/dist/Fx/internal/UnionToTuple.d.ts.map +1 -1
  299. package/dist/Fx/internal/diff.d.ts +586 -0
  300. package/dist/Fx/internal/diff.d.ts.map +1 -1
  301. package/dist/Fx/internal/diff.js +120 -9
  302. package/dist/Fx/internal/effectableEvaluateKey.d.ts +30 -0
  303. package/dist/Fx/internal/effectableEvaluateKey.d.ts.map +1 -0
  304. package/dist/Fx/internal/effectableEvaluateKey.js +29 -0
  305. package/dist/Fx/internal/effectableWithOverride.d.ts +70 -0
  306. package/dist/Fx/internal/effectableWithOverride.d.ts.map +1 -0
  307. package/dist/Fx/internal/effectableWithOverride.js +54 -0
  308. package/dist/Fx/internal/equivalence.d.ts +29 -0
  309. package/dist/Fx/internal/equivalence.d.ts.map +1 -1
  310. package/dist/Fx/internal/equivalence.js +29 -0
  311. package/dist/Fx/internal/multicast.d.ts +145 -2
  312. package/dist/Fx/internal/multicast.d.ts.map +1 -1
  313. package/dist/Fx/internal/multicast.js +146 -4
  314. package/dist/Fx/internal/ring-buffer.d.ts +149 -0
  315. package/dist/Fx/internal/ring-buffer.d.ts.map +1 -1
  316. package/dist/Fx/internal/ring-buffer.js +155 -0
  317. package/dist/Fx/internal/scope.d.ts +184 -0
  318. package/dist/Fx/internal/scope.d.ts.map +1 -1
  319. package/dist/Fx/internal/scope.js +150 -0
  320. package/dist/Fx/internal/yieldable.d.ts +117 -2
  321. package/dist/Fx/internal/yieldable.d.ts.map +1 -1
  322. package/dist/Fx/internal/yieldable.js +86 -3
  323. package/dist/Fx/run/collect.d.ts +93 -4
  324. package/dist/Fx/run/collect.d.ts.map +1 -1
  325. package/dist/Fx/run/collect.js +94 -5
  326. package/dist/Fx/run/first.d.ts +23 -1
  327. package/dist/Fx/run/first.d.ts.map +1 -1
  328. package/dist/Fx/run/first.js +23 -1
  329. package/dist/Fx/run/fork.d.ts +52 -2
  330. package/dist/Fx/run/fork.d.ts.map +1 -1
  331. package/dist/Fx/run/fork.js +52 -2
  332. package/dist/Fx/run/observe.d.ts +112 -4
  333. package/dist/Fx/run/observe.d.ts.map +1 -1
  334. package/dist/Fx/run/observe.js +137 -16
  335. package/dist/Fx/run/runPromise.d.ts +45 -2
  336. package/dist/Fx/run/runPromise.d.ts.map +1 -1
  337. package/dist/Fx/run/runPromise.js +45 -2
  338. package/dist/Fx/stream.d.ts +92 -0
  339. package/dist/Fx/stream.d.ts.map +1 -1
  340. package/dist/Fx/stream.js +60 -1
  341. package/dist/Push/Push.d.ts +1229 -104
  342. package/dist/Push/Push.d.ts.map +1 -1
  343. package/dist/Push/Push.js +1024 -95
  344. package/dist/RefArray.d.ts +2 -0
  345. package/dist/RefArray.d.ts.map +1 -0
  346. package/dist/RefArray.js +1 -0
  347. package/dist/RefBigDecimal.d.ts +2 -0
  348. package/dist/RefBigDecimal.d.ts.map +1 -0
  349. package/dist/RefBigDecimal.js +1 -0
  350. package/dist/RefBigInt.d.ts +2 -0
  351. package/dist/RefBigInt.d.ts.map +1 -0
  352. package/dist/RefBigInt.js +1 -0
  353. package/dist/RefBoolean.d.ts +2 -0
  354. package/dist/RefBoolean.d.ts.map +1 -0
  355. package/dist/RefBoolean.js +1 -0
  356. package/dist/RefCause.d.ts +2 -0
  357. package/dist/RefCause.d.ts.map +1 -0
  358. package/dist/RefCause.js +1 -0
  359. package/dist/RefChunk.d.ts +2 -0
  360. package/dist/RefChunk.d.ts.map +1 -0
  361. package/dist/RefChunk.js +1 -0
  362. package/dist/RefDateTime.d.ts +2 -0
  363. package/dist/RefDateTime.d.ts.map +1 -0
  364. package/dist/RefDateTime.js +1 -0
  365. package/dist/RefDuration.d.ts +2 -0
  366. package/dist/RefDuration.d.ts.map +1 -0
  367. package/dist/RefDuration.js +1 -0
  368. package/dist/RefGraph.d.ts +2 -0
  369. package/dist/RefGraph.d.ts.map +1 -0
  370. package/dist/RefGraph.js +1 -0
  371. package/dist/RefHashMap.d.ts +2 -0
  372. package/dist/RefHashMap.d.ts.map +1 -0
  373. package/dist/RefHashMap.js +1 -0
  374. package/dist/RefHashRing.d.ts +2 -0
  375. package/dist/RefHashRing.d.ts.map +1 -0
  376. package/dist/RefHashRing.js +1 -0
  377. package/dist/RefHashSet.d.ts +2 -0
  378. package/dist/RefHashSet.d.ts.map +1 -0
  379. package/dist/RefHashSet.js +1 -0
  380. package/dist/RefIterable.d.ts +2 -0
  381. package/dist/RefIterable.d.ts.map +1 -0
  382. package/dist/RefIterable.js +1 -0
  383. package/dist/RefOption.d.ts +2 -0
  384. package/dist/RefOption.d.ts.map +1 -0
  385. package/dist/RefOption.js +1 -0
  386. package/dist/RefRecord.d.ts +2 -0
  387. package/dist/RefRecord.d.ts.map +1 -0
  388. package/dist/RefRecord.js +1 -0
  389. package/dist/RefResult.d.ts +2 -0
  390. package/dist/RefResult.d.ts.map +1 -0
  391. package/dist/RefResult.js +1 -0
  392. package/dist/RefString.d.ts +2 -0
  393. package/dist/RefString.d.ts.map +1 -0
  394. package/dist/RefString.js +1 -0
  395. package/dist/RefStruct.d.ts +2 -0
  396. package/dist/RefStruct.d.ts.map +1 -0
  397. package/dist/RefStruct.js +1 -0
  398. package/dist/RefSubject/Hydration.d.ts +504 -0
  399. package/dist/RefSubject/Hydration.d.ts.map +1 -0
  400. package/dist/RefSubject/Hydration.js +300 -0
  401. package/dist/RefSubject/RefArray.d.ts +382 -35
  402. package/dist/RefSubject/RefArray.d.ts.map +1 -1
  403. package/dist/RefSubject/RefArray.js +374 -40
  404. package/dist/RefSubject/RefBigDecimal.d.ts +241 -21
  405. package/dist/RefSubject/RefBigDecimal.d.ts.map +1 -1
  406. package/dist/RefSubject/RefBigDecimal.js +229 -20
  407. package/dist/RefSubject/RefBigInt.d.ts +181 -16
  408. package/dist/RefSubject/RefBigInt.d.ts.map +1 -1
  409. package/dist/RefSubject/RefBigInt.js +169 -15
  410. package/dist/RefSubject/RefBoolean.d.ts +181 -16
  411. package/dist/RefSubject/RefBoolean.d.ts.map +1 -1
  412. package/dist/RefSubject/RefBoolean.js +169 -15
  413. package/dist/RefSubject/RefCause.d.ts +133 -12
  414. package/dist/RefSubject/RefCause.d.ts.map +1 -1
  415. package/dist/RefSubject/RefCause.js +121 -11
  416. package/dist/RefSubject/RefChunk.d.ts +481 -76
  417. package/dist/RefSubject/RefChunk.d.ts.map +1 -1
  418. package/dist/RefSubject/RefChunk.js +471 -75
  419. package/dist/RefSubject/RefDateTime.d.ts +133 -12
  420. package/dist/RefSubject/RefDateTime.d.ts.map +1 -1
  421. package/dist/RefSubject/RefDateTime.js +122 -12
  422. package/dist/RefSubject/RefDuration.d.ts +169 -15
  423. package/dist/RefSubject/RefDuration.d.ts.map +1 -1
  424. package/dist/RefSubject/RefDuration.js +157 -14
  425. package/dist/RefSubject/RefGraph.d.ts +349 -35
  426. package/dist/RefSubject/RefGraph.d.ts.map +1 -1
  427. package/dist/RefSubject/RefGraph.js +334 -32
  428. package/dist/RefSubject/RefHashMap.d.ts +323 -28
  429. package/dist/RefSubject/RefHashMap.d.ts.map +1 -1
  430. package/dist/RefSubject/RefHashMap.js +317 -29
  431. package/dist/RefSubject/RefHashRing.d.ts +159 -15
  432. package/dist/RefSubject/RefHashRing.d.ts.map +1 -1
  433. package/dist/RefSubject/RefHashRing.js +145 -12
  434. package/dist/RefSubject/RefHashSet.d.ts +251 -22
  435. package/dist/RefSubject/RefHashSet.d.ts.map +1 -1
  436. package/dist/RefSubject/RefHashSet.js +238 -20
  437. package/dist/RefSubject/RefIterable.d.ts +358 -32
  438. package/dist/RefSubject/RefIterable.d.ts.map +1 -1
  439. package/dist/RefSubject/RefIterable.js +350 -30
  440. package/dist/RefSubject/RefOption.d.ts +157 -14
  441. package/dist/RefSubject/RefOption.d.ts.map +1 -1
  442. package/dist/RefSubject/RefOption.js +145 -13
  443. package/dist/RefSubject/RefRecord.d.ts +402 -64
  444. package/dist/RefSubject/RefRecord.d.ts.map +1 -1
  445. package/dist/RefSubject/RefRecord.js +364 -39
  446. package/dist/RefSubject/RefResult.d.ts +167 -35
  447. package/dist/RefSubject/RefResult.d.ts.map +1 -1
  448. package/dist/RefSubject/RefResult.js +133 -12
  449. package/dist/RefSubject/RefString.d.ts +205 -18
  450. package/dist/RefSubject/RefString.d.ts.map +1 -1
  451. package/dist/RefSubject/RefString.js +193 -17
  452. package/dist/RefSubject/RefStruct.d.ts +169 -14
  453. package/dist/RefSubject/RefStruct.d.ts.map +1 -1
  454. package/dist/RefSubject/RefStruct.js +157 -13
  455. package/dist/RefSubject/RefSubject.d.ts +1197 -45
  456. package/dist/RefSubject/RefSubject.d.ts.map +1 -1
  457. package/dist/RefSubject/RefSubject.js +935 -88
  458. package/dist/RefSubject/RefTrie.d.ts +323 -37
  459. package/dist/RefSubject/RefTrie.d.ts.map +1 -1
  460. package/dist/RefSubject/RefTrie.js +311 -31
  461. package/dist/RefSubject/RefTuple.d.ts +127 -11
  462. package/dist/RefSubject/RefTuple.d.ts.map +1 -1
  463. package/dist/RefSubject/RefTuple.js +114 -9
  464. package/dist/RefSubject/index.d.ts +1 -0
  465. package/dist/RefSubject/index.d.ts.map +1 -1
  466. package/dist/RefSubject/index.js +1 -0
  467. package/dist/RefSubject.d.ts +2 -1
  468. package/dist/RefSubject.d.ts.map +1 -1
  469. package/dist/RefSubject.js +2 -1
  470. package/dist/RefTrie.d.ts +2 -0
  471. package/dist/RefTrie.d.ts.map +1 -0
  472. package/dist/RefTrie.js +1 -0
  473. package/dist/RefTuple.d.ts +2 -0
  474. package/dist/RefTuple.d.ts.map +1 -0
  475. package/dist/RefTuple.js +1 -0
  476. package/dist/Sink/Sink.d.ts +396 -23
  477. package/dist/Sink/Sink.d.ts.map +1 -1
  478. package/dist/Sink/Sink.js +55 -7
  479. package/dist/Sink/combinators.d.ts +740 -11
  480. package/dist/Sink/combinators.d.ts.map +1 -1
  481. package/dist/Sink/combinators.js +716 -14
  482. package/dist/Subject/Subject.d.ts +1022 -27
  483. package/dist/Subject/Subject.d.ts.map +1 -1
  484. package/dist/Subject/Subject.js +909 -43
  485. package/dist/Versioned/Versioned.d.ts +447 -27
  486. package/dist/Versioned/Versioned.d.ts.map +1 -1
  487. package/dist/Versioned/Versioned.js +282 -48
  488. package/dist/index.d.ts +22 -3
  489. package/dist/index.d.ts.map +1 -1
  490. package/dist/index.js +22 -3
  491. package/package.json +126 -16
  492. package/dist/Fx/constructors/fromYieldable.d.ts +0 -12
  493. package/dist/Fx/constructors/fromYieldable.d.ts.map +0 -1
  494. package/dist/Fx/constructors/fromYieldable.js +0 -12
  495. package/src/Fx/Fx.ts +0 -164
  496. package/src/Fx/TypeId.ts +0 -25
  497. package/src/Fx/combinators/additive.ts +0 -142
  498. package/src/Fx/combinators/catch.ts +0 -421
  499. package/src/Fx/combinators/causes.ts +0 -23
  500. package/src/Fx/combinators/changesWithEffect.ts +0 -66
  501. package/src/Fx/combinators/compact.ts +0 -15
  502. package/src/Fx/combinators/continueWith.ts +0 -78
  503. package/src/Fx/combinators/dropUntil.ts +0 -47
  504. package/src/Fx/combinators/ensuring.ts +0 -23
  505. package/src/Fx/combinators/exhaustLatestMap.ts +0 -74
  506. package/src/Fx/combinators/exhaustLatestMapEffect.ts +0 -25
  507. package/src/Fx/combinators/exhaustMap.ts +0 -36
  508. package/src/Fx/combinators/exhaustMapEffect.ts +0 -23
  509. package/src/Fx/combinators/exit.ts +0 -15
  510. package/src/Fx/combinators/filter.ts +0 -22
  511. package/src/Fx/combinators/filterEffect.ts +0 -31
  512. package/src/Fx/combinators/filterMap.ts +0 -23
  513. package/src/Fx/combinators/filterMapEffect.ts +0 -32
  514. package/src/Fx/combinators/filterMapLoop.ts +0 -35
  515. package/src/Fx/combinators/filterMapLoopCause.ts +0 -36
  516. package/src/Fx/combinators/filterMapLoopCauseEffect.ts +0 -46
  517. package/src/Fx/combinators/filterMapLoopEffect.ts +0 -36
  518. package/src/Fx/combinators/flatMap.ts +0 -51
  519. package/src/Fx/combinators/flatMapConcurrently.ts +0 -39
  520. package/src/Fx/combinators/flatMapConcurrentlyEffect.ts +0 -26
  521. package/src/Fx/combinators/flatMapEffect.ts +0 -42
  522. package/src/Fx/combinators/flip.ts +0 -14
  523. package/src/Fx/combinators/gen.ts +0 -24
  524. package/src/Fx/combinators/genScoped.ts +0 -24
  525. package/src/Fx/combinators/index.ts +0 -61
  526. package/src/Fx/combinators/keyed.ts +0 -369
  527. package/src/Fx/combinators/loop.ts +0 -27
  528. package/src/Fx/combinators/loopCause.ts +0 -34
  529. package/src/Fx/combinators/loopCauseEffect.ts +0 -36
  530. package/src/Fx/combinators/loopEffect.ts +0 -34
  531. package/src/Fx/combinators/map.ts +0 -22
  532. package/src/Fx/combinators/mapBoth.ts +0 -40
  533. package/src/Fx/combinators/mapEffect.ts +0 -32
  534. package/src/Fx/combinators/mapError.ts +0 -28
  535. package/src/Fx/combinators/mergeAll.ts +0 -22
  536. package/src/Fx/combinators/mergeOrdered.ts +0 -123
  537. package/src/Fx/combinators/onError.ts +0 -40
  538. package/src/Fx/combinators/onExit.ts +0 -82
  539. package/src/Fx/combinators/onInterrupt.ts +0 -87
  540. package/src/Fx/combinators/provide.ts +0 -124
  541. package/src/Fx/combinators/result.ts +0 -39
  542. package/src/Fx/combinators/scan.ts +0 -82
  543. package/src/Fx/combinators/skip.ts +0 -41
  544. package/src/Fx/combinators/skipRepeats.ts +0 -15
  545. package/src/Fx/combinators/skipRepeatsWith.ts +0 -40
  546. package/src/Fx/combinators/skipWhile.ts +0 -100
  547. package/src/Fx/combinators/slice.ts +0 -55
  548. package/src/Fx/combinators/switchMap.ts +0 -55
  549. package/src/Fx/combinators/switchMapEffect.ts +0 -25
  550. package/src/Fx/combinators/take.ts +0 -38
  551. package/src/Fx/combinators/takeUntil.ts +0 -88
  552. package/src/Fx/combinators/takeWhile.ts +0 -47
  553. package/src/Fx/combinators/tapEffect.ts +0 -39
  554. package/src/Fx/combinators/tuple.ts +0 -79
  555. package/src/Fx/combinators/unwrap.ts +0 -21
  556. package/src/Fx/combinators/unwrapScoped.ts +0 -26
  557. package/src/Fx/combinators/when.ts +0 -64
  558. package/src/Fx/combinators/withSpan.ts +0 -24
  559. package/src/Fx/combinators/zip.ts +0 -175
  560. package/src/Fx/constructors/at.ts +0 -23
  561. package/src/Fx/constructors/die.ts +0 -17
  562. package/src/Fx/constructors/empty.ts +0 -10
  563. package/src/Fx/constructors/fail.ts +0 -14
  564. package/src/Fx/constructors/failCause.ts +0 -14
  565. package/src/Fx/constructors/fn.ts +0 -245
  566. package/src/Fx/constructors/fromEffect.ts +0 -24
  567. package/src/Fx/constructors/fromFailures.ts +0 -19
  568. package/src/Fx/constructors/fromIterable.ts +0 -15
  569. package/src/Fx/constructors/fromSchedule.ts +0 -18
  570. package/src/Fx/constructors/fromYieldable.ts +0 -17
  571. package/src/Fx/constructors/index.ts +0 -15
  572. package/src/Fx/constructors/interrupt.ts +0 -13
  573. package/src/Fx/constructors/make.ts +0 -103
  574. package/src/Fx/constructors/periodic.ts +0 -15
  575. package/src/Fx/constructors/succeed.ts +0 -37
  576. package/src/Fx/constructors/suspend.ts +0 -6
  577. package/src/Fx/index.ts +0 -6
  578. package/src/Fx/internal/DeferredRef.ts +0 -87
  579. package/src/Fx/internal/UnionToTuple.ts +0 -12
  580. package/src/Fx/internal/diff.ts +0 -191
  581. package/src/Fx/internal/equivalence.ts +0 -12
  582. package/src/Fx/internal/multicast.ts +0 -51
  583. package/src/Fx/internal/ring-buffer.ts +0 -60
  584. package/src/Fx/internal/scope.ts +0 -58
  585. package/src/Fx/internal/yieldable.ts +0 -31
  586. package/src/Fx/run/collect.ts +0 -79
  587. package/src/Fx/run/first.ts +0 -20
  588. package/src/Fx/run/fork.ts +0 -40
  589. package/src/Fx/run/index.ts +0 -5
  590. package/src/Fx/run/observe.ts +0 -114
  591. package/src/Fx/run/runPromise.ts +0 -32
  592. package/src/Fx/stream.ts +0 -42
  593. package/src/Fx.additive-combinators.test.ts +0 -126
  594. package/src/Fx.catch-additive.test.ts +0 -206
  595. package/src/Fx.catch.test.ts +0 -60
  596. package/src/Fx.dropUntil.test.ts +0 -61
  597. package/src/Fx.fn.test.ts +0 -51
  598. package/src/Fx.lifecycle.test.ts +0 -79
  599. package/src/Fx.mapError-mapBoth.test.ts +0 -101
  600. package/src/Fx.provide-combinators.test.ts +0 -94
  601. package/src/Fx.result-changesWithEffect.test.ts +0 -112
  602. package/src/Fx.scan.test.ts +0 -73
  603. package/src/Fx.takeWhile-skipWhile.test.ts +0 -84
  604. package/src/Fx.test.ts +0 -71
  605. package/src/Fx.ts +0 -1
  606. package/src/Fx.zip-merge-additive.test.ts +0 -171
  607. package/src/Fx.zip.test.ts +0 -133
  608. package/src/Push/Push.ts +0 -1072
  609. package/src/Push/index.ts +0 -1
  610. package/src/Push.additive.test.ts +0 -256
  611. package/src/Push.test.ts +0 -26
  612. package/src/Push.ts +0 -1
  613. package/src/RefSubject/RefArray.ts +0 -512
  614. package/src/RefSubject/RefBigDecimal.test.ts +0 -56
  615. package/src/RefSubject/RefBigDecimal.ts +0 -295
  616. package/src/RefSubject/RefBigInt.test.ts +0 -56
  617. package/src/RefSubject/RefBigInt.ts +0 -189
  618. package/src/RefSubject/RefBoolean.test.ts +0 -57
  619. package/src/RefSubject/RefBoolean.ts +0 -185
  620. package/src/RefSubject/RefCause.test.ts +0 -53
  621. package/src/RefSubject/RefCause.ts +0 -146
  622. package/src/RefSubject/RefChunk.ts +0 -510
  623. package/src/RefSubject/RefDateTime.test.ts +0 -43
  624. package/src/RefSubject/RefDateTime.ts +0 -264
  625. package/src/RefSubject/RefDuration.test.ts +0 -49
  626. package/src/RefSubject/RefDuration.ts +0 -188
  627. package/src/RefSubject/RefGraph.ts +0 -650
  628. package/src/RefSubject/RefHashMap.ts +0 -465
  629. package/src/RefSubject/RefHashRing.ts +0 -262
  630. package/src/RefSubject/RefHashSet.ts +0 -308
  631. package/src/RefSubject/RefIterable.ts +0 -445
  632. package/src/RefSubject/RefOption.test.ts +0 -67
  633. package/src/RefSubject/RefOption.ts +0 -193
  634. package/src/RefSubject/RefRecord.ts +0 -612
  635. package/src/RefSubject/RefResult.test.ts +0 -63
  636. package/src/RefSubject/RefResult.ts +0 -209
  637. package/src/RefSubject/RefString.test.ts +0 -61
  638. package/src/RefSubject/RefString.ts +0 -256
  639. package/src/RefSubject/RefStruct.test.ts +0 -60
  640. package/src/RefSubject/RefStruct.ts +0 -253
  641. package/src/RefSubject/RefSubject.ts +0 -2646
  642. package/src/RefSubject/RefTrie.ts +0 -356
  643. package/src/RefSubject/RefTuple.test.ts +0 -60
  644. package/src/RefSubject/RefTuple.ts +0 -231
  645. package/src/RefSubject/index.ts +0 -21
  646. package/src/RefSubject.additive-parity.test.ts +0 -101
  647. package/src/RefSubject.test.ts +0 -65
  648. package/src/RefSubject.ts +0 -1
  649. package/src/Sink/Sink.ts +0 -159
  650. package/src/Sink/combinators.ts +0 -1115
  651. package/src/Sink/index.ts +0 -2
  652. package/src/Sink.combinators.test.ts +0 -88
  653. package/src/Sink.reduce-collect-head-last.test.ts +0 -107
  654. package/src/Sink.ts +0 -1
  655. package/src/Subject/Subject.ts +0 -441
  656. package/src/Subject/index.ts +0 -1
  657. package/src/Subject.test.ts +0 -47
  658. package/src/Subject.ts +0 -1
  659. package/src/Versioned/Versioned.ts +0 -597
  660. package/src/Versioned/index.ts +0 -1
  661. package/src/Versioned.filterMap.test.ts +0 -91
  662. package/src/Versioned.test.ts +0 -23
  663. package/src/Versioned.ts +0 -1
  664. package/src/index.ts +0 -7
@@ -2,6 +2,7 @@
2
2
  /** @effect-diagnostics missingEffectContext:skip-file */
3
3
  import * as Array from "effect/Array";
4
4
  import * as Effect from "effect/Effect";
5
+ import * as Effectable from "effect/Effectable";
5
6
  import * as Semaphore from "effect/Semaphore";
6
7
  import { equals } from "effect/Equal";
7
8
  import * as Exit from "effect/Exit";
@@ -13,17 +14,18 @@ import { sum } from "effect/Number";
13
14
  import * as Option from "effect/Option";
14
15
  import { pipeArguments } from "effect/Pipeable";
15
16
  import * as Scope from "effect/Scope";
16
- import * as ServiceMap from "effect/ServiceMap";
17
+ import * as Context from "effect/Context";
17
18
  import * as Stream from "effect/Stream";
18
19
  import { compact as fxCompact } from "../Fx/combinators/compact.js";
19
20
  import { continueWith } from "../Fx/combinators/continueWith.js";
20
21
  import { filterMapEffect as fxFilterMapEffect } from "../Fx/combinators/filterMapEffect.js";
21
22
  import { mapEffect as fxMapEffect } from "../Fx/combinators/mapEffect.js";
23
+ import { mergeAll as fxMergeAll } from "../Fx/combinators/mergeAll.js";
24
+ import { scanEffect as fxScanEffect } from "../Fx/combinators/scan.js";
22
25
  import { skipRepeats } from "../Fx/combinators/skipRepeats.js";
23
26
  import { slice as fxSlice } from "../Fx/combinators/slice.js";
24
27
  import { unwrap } from "../Fx/combinators/unwrap.js";
25
28
  import { fromEffect as fxFromEffect } from "../Fx/constructors/fromEffect.js";
26
- import { fromYieldable } from "../Fx/constructors/fromYieldable.js";
27
29
  import * as DeferredRef from "../Fx/internal/DeferredRef.js";
28
30
  import { getExitEquivalence } from "../Fx/internal/equivalence.js";
29
31
  import { YieldableFx } from "../Fx/internal/yieldable.js";
@@ -31,13 +33,92 @@ import { FxTypeId, isFx } from "../Fx/TypeId.js";
31
33
  import * as Sink from "../Sink/Sink.js";
32
34
  import * as Subject from "../Subject/Subject.js";
33
35
  import * as Versioned from "../Versioned/Versioned.js";
36
+ import { hasProperty } from "effect/Predicate";
37
+ /**
38
+ * Runtime symbol identifying writable RefSubject values.
39
+ *
40
+ * @remarks
41
+ * ## Why
42
+ *
43
+ * Provides stable runtime identity for RefSubject values without relying on classes or a renderer.
44
+ *
45
+ * ## Ownership and lifetime
46
+ *
47
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
48
+ * source errors, services, and lifetime.
49
+ *
50
+ * @since 1.18.0
51
+ * @category Type identity
52
+ */
34
53
  export const RefSubjectTypeId = Symbol.for("@typed/fx/RefSubject");
54
+ /**
55
+ * Runtime symbol identifying read-only Computed values.
56
+ *
57
+ * @remarks
58
+ * ## Why
59
+ *
60
+ * Provides stable runtime identity for Computed values without relying on classes or a renderer.
61
+ *
62
+ * ## Ownership and lifetime
63
+ *
64
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
65
+ * source errors, services, and lifetime.
66
+ *
67
+ * @since 1.18.0
68
+ * @category Type identity
69
+ */
35
70
  export const ComputedTypeId = Symbol.for("@typed/fx/Computed");
71
+ /**
72
+ * Runtime symbol identifying conditionally available Filtered values.
73
+ *
74
+ * @remarks
75
+ * ## Why
76
+ *
77
+ * Provides stable runtime identity for Filtered values without relying on classes or a renderer.
78
+ *
79
+ * ## Ownership and lifetime
80
+ *
81
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
82
+ * source errors, services, and lifetime.
83
+ *
84
+ * @since 1.18.0
85
+ * @category Type identity
86
+ */
36
87
  export const FilteredTypeId = Symbol.for("@typed/fx/Filtered");
37
- export const CurrentComputedBehavior = ServiceMap.Reference("@typed/fx/CurrentComputedBehavior", {
88
+ /**
89
+ * Selects whether a computed Fx observes only its current value or also follows later pushes.
90
+ *
91
+ * @remarks
92
+ * ## Why
93
+ *
94
+ * `"multiple"` (the default) emits the current value and then follows distinct source pushes.
95
+ * `"one"` emits only the current value. Hydration temporarily uses `"one"` when it must resolve a
96
+ * single server value without leaving a live observation running.
97
+ *
98
+ * ## Ownership and lifetime
99
+ *
100
+ * This is an Effect Context reference with a default value, not mutable global state. Supplying a
101
+ * value changes computed observation only in the provided Effect context; the observing Scope
102
+ * still owns any subscription created by `"multiple"`.
103
+ *
104
+ * @since 1.18.0
105
+ * @category Observation policy
106
+ */
107
+ export const CurrentComputedBehavior = Context.Reference("@typed/fx/CurrentComputedBehavior", {
38
108
  defaultValue: () => "multiple",
39
109
  });
40
- const checkIsMultiple = (ctx) => ServiceMap.getReferenceUnsafe(ctx, CurrentComputedBehavior) === "multiple";
110
+ const checkIsMultiple = (ctx) => Context.getUnsafe(ctx, CurrentComputedBehavior) === "multiple";
111
+ function holdInContext(fx) {
112
+ const contexts = new WeakMap();
113
+ return unwrap(Effect.map(Effect.context(), (context) => {
114
+ let shared = contexts.get(context);
115
+ if (!shared) {
116
+ shared = Subject.hold(fx);
117
+ contexts.set(context, shared);
118
+ }
119
+ return shared;
120
+ }));
121
+ }
41
122
  class ComputedImpl extends Versioned.VersionedTransform {
42
123
  [ComputedTypeId] = ComputedTypeId;
43
124
  _computed;
@@ -47,20 +128,145 @@ class ComputedImpl extends Versioned.VersionedTransform {
47
128
  super(input, (fx) => fxMapEffect(fx, f), Effect.flatMap(f));
48
129
  this.input = input;
49
130
  this.f = f;
50
- this._computed = Subject.hold(unwrap(Effect.map(Effect.services(), (ctx) => {
131
+ this._computed = holdInContext(unwrap(Effect.map(Effect.context(), (ctx) => {
51
132
  if (checkIsMultiple(ctx)) {
52
- return fromYieldable(input).pipe(continueWith(() => input), skipRepeats, fxMapEffect(f));
133
+ return fxFromEffect(input).pipe(continueWith(() => input), skipRepeats, fxMapEffect(f));
53
134
  }
54
- return fxFromEffect(Effect.flatMap(input.asEffect(), f));
135
+ return fxFromEffect(Effect.flatMap(input, f));
55
136
  })));
56
137
  }
57
138
  run(sink) {
58
139
  return this._computed.run(sink);
59
140
  }
60
141
  }
142
+ /**
143
+ * Builds a read-only Computed projection from a Versioned source.
144
+ *
145
+ * @remarks
146
+ * ## Why
147
+ *
148
+ * Applies the same Effectful projection to current reads and pushed versions, preserving all three
149
+ * Versioned channels without granting writes to the source.
150
+ *
151
+ * ## Ownership and lifetime
152
+ *
153
+ * Current reads cache the transformed input by source version within each Effect Context. The
154
+ * pushed channel uses `Subject.hold`: observers with the same Context object share one upstream
155
+ * session and its retained projection; distinct Context objects have separate sessions. The last
156
+ * observer ends its session and clears its held value. The observing Scope owns cleanup.
157
+ *
158
+ * @since 1.18.0
159
+ * @category Derived queries
160
+ */
61
161
  export function makeComputed(input, f) {
62
162
  return new ComputedImpl(input, f);
63
163
  }
164
+ /**
165
+ * Stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the accumulated state.
166
+ *
167
+ * Fx subscriptions follow `Fx.scan` semantics (emit `initial`, then fold each source value).
168
+ * Effect sampling accumulates across source versions via a private state ref (do not mix heavy
169
+ * subscribe + sample on the same scan if you need a single shared accumulator).
170
+ *
171
+ * @remarks
172
+ * ## Why
173
+ *
174
+ * Stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the accumulated state.
175
+ * Fx subscriptions follow `Fx.scan` semantics (emit `initial`, then fold each source value).
176
+ * Effect sampling accumulates across source versions via a private state ref (do not mix heavy
177
+ * subscribe + sample on the same scan if you need a single shared accumulator). The result remains
178
+ * a lazy view rather than a duplicated mutable value.
179
+ *
180
+ * ## Ownership and lifetime
181
+ *
182
+ * Each Effect Context object gets a private current-read accumulator, advanced after a successful
183
+ * fold for a new source version. The pushed channel runs `Fx.scanEffect` from `initial` inside
184
+ * `Subject.hold`: observers using the same Context share that active scan and retained result.
185
+ * The last observer ends its session and clears its held value. The observing Scope owns
186
+ * subscription cleanup. Read accumulators are weakly held by Context and need no finalizer.
187
+ *
188
+ * @since 1.0.0
189
+ * @category Accumulation
190
+ */
191
+ export const scan = dual(3, function scan(versioned, initial, f) {
192
+ return new ComputedScanImpl(versioned, initial, (s, a) => Effect.succeed(f(s, a)));
193
+ });
194
+ /**
195
+ * Effectful stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the accumulated state.
196
+ *
197
+ * @remarks
198
+ * ## Why
199
+ *
200
+ * Effectful stateful scan over a `RefSubject` / `Computed`, producing a `Computed` of the
201
+ * accumulated state. The result remains a lazy view rather than a duplicated mutable value.
202
+ *
203
+ * ## Ownership and lifetime
204
+ *
205
+ * Each Effect Context object gets a private current-read accumulator. It advances only after `f`
206
+ * succeeds, so a typed failure leaves the previous state intact. The pushed channel runs
207
+ * `Fx.scanEffect` from `initial` inside `Subject.hold`: observers using the same Context share
208
+ * that active scan and retained result; each fold requires `R3`. The last observer ends its
209
+ * session and clears its held value. The observing Scope owns cleanup. Read accumulators are
210
+ * weakly held by Context and need no finalizer.
211
+ *
212
+ * @since 1.0.0
213
+ * @category Accumulation
214
+ */
215
+ export const scanEffect = dual(3, function scanEffect(versioned, initial, f) {
216
+ return new ComputedScanImpl(versioned, initial, f);
217
+ });
218
+ class ComputedScanImpl extends Versioned.VersionedTransform {
219
+ [ComputedTypeId] = ComputedTypeId;
220
+ _computed;
221
+ input;
222
+ initial;
223
+ f;
224
+ constructor(input, initial, f) {
225
+ const states = new WeakMap();
226
+ super(input, (fx) => fxScanEffect(fx, initial, f), (effect) => Effect.contextWith((context) => {
227
+ let state = states.get(context);
228
+ if (!state) {
229
+ state = MutableRef.make(initial);
230
+ states.set(context, state);
231
+ }
232
+ const current = state;
233
+ return Effect.flatMap(effect, (a) => Effect.flatMap(f(MutableRef.get(current), a), (next) => Effect.sync(() => {
234
+ MutableRef.set(current, next);
235
+ return next;
236
+ })));
237
+ }));
238
+ this.input = input;
239
+ this.initial = initial;
240
+ this.f = f;
241
+ this._computed = holdInContext(unwrap(Effect.map(Effect.context(), (ctx) => {
242
+ if (checkIsMultiple(ctx)) {
243
+ return fxFromEffect(input).pipe(continueWith(() => input), skipRepeats, fxScanEffect(initial, f));
244
+ }
245
+ return fxFromEffect(Effect.flatMap(input, (a) => f(initial, a)));
246
+ })));
247
+ }
248
+ run(sink) {
249
+ return this._computed.run(sink);
250
+ }
251
+ }
252
+ /**
253
+ * Builds a Filtered view from the three channels of a Versioned source.
254
+ *
255
+ * @remarks
256
+ * ## Why
257
+ *
258
+ * Applies `f` to current reads and later pushes while preserving absence as Filtered semantics:
259
+ * Effect reads fail with `NoSuchElementError`, whereas the Fx channel simply omits absent values.
260
+ *
261
+ * ## Ownership and lifetime
262
+ *
263
+ * Sampled results and pushed sessions are isolated by Effect Context identity. Within one Context,
264
+ * current reads cache by source version and observers share the active held projection. Its
265
+ * Effect read fails with NoSuchElement while absent; the observing Scope owns its subscription.
266
+ *
267
+ * @since 1.18.0
268
+ * @category Optional queries
269
+ */
64
270
  export function makeFiltered(input, f) {
65
271
  return new FilteredImpl(input, f);
66
272
  }
@@ -70,14 +276,14 @@ class FilteredImpl extends Versioned.VersionedTransform {
70
276
  input;
71
277
  f;
72
278
  constructor(input, f) {
73
- super(input, (fx) => fxFilterMapEffect(fx, f), (effect) => Effect.flatMap(Effect.flatMap(effect, f), (option) => option.asEffect()));
279
+ super(input, (fx) => fxFilterMapEffect(fx, f), (effect) => Effect.flatMap(Effect.flatMap(effect, f), Effect.fromOption));
74
280
  this.input = input;
75
281
  this.f = f;
76
- this._computed = Subject.hold(unwrap(Effect.map(Effect.services(), (ctx) => {
282
+ this._computed = holdInContext(unwrap(Effect.map(Effect.context(), (ctx) => {
77
283
  if (checkIsMultiple(ctx)) {
78
- return fromYieldable(input).pipe(continueWith(() => input), skipRepeats, fxFilterMapEffect(f));
284
+ return fxFromEffect(input).pipe(continueWith(() => input), skipRepeats, fxFilterMapEffect(f));
79
285
  }
80
- return fxCompact(fxFromEffect(Effect.flatMap(input.asEffect(), f)));
286
+ return fxCompact(fxFromEffect(Effect.flatMap(input, f)));
81
287
  })));
82
288
  }
83
289
  run(sink) {
@@ -87,6 +293,7 @@ class FilteredImpl extends Versioned.VersionedTransform {
87
293
  return new ComputedImpl(this.input, this.f);
88
294
  }
89
295
  }
296
+ let nextTransactionOrder = 0;
90
297
  class RefSubjectCore {
91
298
  initial;
92
299
  subject;
@@ -94,6 +301,7 @@ class RefSubjectCore {
94
301
  scope;
95
302
  deferredRef;
96
303
  semaphore;
304
+ transactionOrder = nextTransactionOrder++;
97
305
  constructor(initial, subject, services, scope, deferredRef, semaphore) {
98
306
  this.initial = initial;
99
307
  this.subject = subject;
@@ -104,10 +312,116 @@ class RefSubjectCore {
104
312
  }
105
313
  _fiber = undefined;
106
314
  }
107
- function getSetDelete(ref) {
315
+ function combineTransactionCores(accesses) {
316
+ return [...new Set(accesses.flatMap((access) => access.cores))].sort((left, right) => left.transactionOrder - right.transactionOrder);
317
+ }
318
+ function getTupleTransactionAccess(refs) {
319
+ const accessEffects = refs.map(getTransactionAccess);
320
+ if (!accessEffects.every((access) => access !== undefined)) {
321
+ return undefined;
322
+ }
323
+ return Effect.map(Effect.all(accessEffects, UNBOUNDED), (accessOptions) => Option.map(Option.all(accessOptions), (accesses) => ({
324
+ cores: combineTransactionCores(accesses),
325
+ getSetDelete: (recordCommit) => {
326
+ const transactions = accesses.map((access) => access.getSetDelete(recordCommit));
327
+ return {
328
+ get: Effect.all(transactions.map((transaction) => transaction.get), UNBOUNDED),
329
+ set: (value) => Effect.all(transactions.map((transaction, index) => transaction.set(value[index])), UNBOUNDED),
330
+ delete: Effect.map(Effect.all(transactions.map((transaction) => transaction.delete), UNBOUNDED), Option.all),
331
+ };
332
+ },
333
+ })));
334
+ }
335
+ function getStructTransactionAccess(refs) {
336
+ const keys = Object.keys(refs);
337
+ const accessEffects = keys.map((key) => getTransactionAccess(refs[key]));
338
+ if (!accessEffects.every((access) => access !== undefined)) {
339
+ return undefined;
340
+ }
341
+ return Effect.map(Effect.all(accessEffects, UNBOUNDED), (accessOptions) => Option.map(Option.all(accessOptions), (accesses) => ({
342
+ cores: combineTransactionCores(accesses),
343
+ getSetDelete: (recordCommit) => {
344
+ const transactions = accesses.map((access) => access.getSetDelete(recordCommit));
345
+ return {
346
+ get: Effect.map(Effect.all(transactions.map((transaction) => transaction.get), UNBOUNDED), (values) => Object.fromEntries(keys.map((key, index) => [key, values[index]]))),
347
+ set: (value) => Effect.all(transactions.map((transaction, index) => transaction.set(value[keys[index]])), UNBOUNDED),
348
+ delete: Effect.map(Effect.all(transactions.map((transaction) => transaction.delete), UNBOUNDED), (values) => Option.all(Object.fromEntries(keys.map((key, index) => [key, values[index]])))),
349
+ };
350
+ },
351
+ })));
352
+ }
353
+ function getTransactionAccess(ref) {
354
+ if (ref instanceof RefSubjectImpl) {
355
+ return Effect.succeed(Option.some({
356
+ cores: [ref.core],
357
+ getSetDelete: (recordCommit) => getSetDelete(ref.core, (exit) => recordCommit([ref.core, exit, ref.core.deferredRef.version])),
358
+ }));
359
+ }
360
+ if (ref instanceof RefSubjectSimpleTransform)
361
+ return getTransactionAccess(ref.ref);
362
+ if (ref instanceof RefSubjectTransform) {
363
+ const accessEffect = getTransactionAccess(ref.ref);
364
+ if (!accessEffect)
365
+ return undefined;
366
+ return Effect.map(accessEffect, Option.map((access) => ({
367
+ cores: access.cores,
368
+ getSetDelete: (recordCommit) => {
369
+ const transaction = access.getSetDelete(recordCommit);
370
+ return {
371
+ get: Effect.map(transaction.get, ref.toB),
372
+ set: (value) => Effect.map(transaction.set(ref.toA(value)), ref.toB),
373
+ delete: Effect.map(transaction.delete, Option.map(ref.toB)),
374
+ };
375
+ },
376
+ })));
377
+ }
378
+ if (ref instanceof RefSubjectTuple)
379
+ return getTupleTransactionAccess(ref.refs);
380
+ if (ref instanceof RefSubjectStruct)
381
+ return getStructTransactionAccess(ref.refs);
382
+ if (typeof ref === "function") {
383
+ const service = ref.service;
384
+ if (Effect.isEffect(service)) {
385
+ return Effect.flatMap(service, (providedRef) => {
386
+ const accessEffect = getTransactionAccess(providedRef);
387
+ return accessEffect ?? Effect.succeed(Option.none());
388
+ });
389
+ }
390
+ }
391
+ return undefined;
392
+ }
393
+ function withTransactionLocks(cores, effect) {
394
+ let locked = effect;
395
+ for (let index = cores.length - 1; index >= 0; index--) {
396
+ locked = cores[index].semaphore.withPermits(1)(locked);
397
+ }
398
+ return locked;
399
+ }
400
+ function runTransaction(access, run) {
401
+ return Effect.uninterruptibleMask((restore) => {
402
+ const commits = [];
403
+ const transaction = restore(withTransactionLocks(access.cores, Effect.suspend(() => run(access.getSetDelete((commit) => {
404
+ commits.push(commit);
405
+ })))));
406
+ return Effect.flatMap(Effect.exit(transaction), (exit) => Effect.andThen(Effect.forEach(commits, ([core, commit, version]) => sendCurrentEvent(core, commit, version), {
407
+ discard: true,
408
+ }), exit));
409
+ });
410
+ }
411
+ function sendCurrentEvent(core, commit, version) {
412
+ return Effect.suspend(() => {
413
+ const current = MutableRef.get(core.deferredRef.current);
414
+ return core.deferredRef.version === version &&
415
+ Option.isSome(current) &&
416
+ core.deferredRef.eq(current.value, commit)
417
+ ? sendEvent(core, commit)
418
+ : Effect.void;
419
+ });
420
+ }
421
+ function getSetDelete(ref, recordCommit) {
108
422
  return {
109
423
  get: getOrInitializeCore(ref, false),
110
- set: (a) => setCore(ref, a),
424
+ set: (a) => bufferSuccessCore(ref, a, recordCommit),
111
425
  delete: deleteCore(ref),
112
426
  };
113
427
  }
@@ -117,7 +431,6 @@ class RefSubjectImpl extends YieldableFx {
117
431
  version;
118
432
  interrupt;
119
433
  subscriberCount;
120
- getSetDelete;
121
434
  core;
122
435
  constructor(core) {
123
436
  super();
@@ -125,25 +438,25 @@ class RefSubjectImpl extends YieldableFx {
125
438
  this.version = Effect.sync(() => core.deferredRef.version);
126
439
  this.interrupt = Effect.provide(interruptCore(core), core.services);
127
440
  this.subscriberCount = Effect.provide(core.subject.subscriberCount, core.services);
128
- this.getSetDelete = getSetDelete(core);
129
441
  this.updates = this.updates.bind(this);
130
442
  this.onSuccess = this.onSuccess.bind(this);
131
443
  this.onFailure = this.onFailure.bind(this);
132
444
  }
133
445
  run(sink) {
446
+ const subscribe = Effect.provide(this.core.subject.run(sink), this.core.services);
134
447
  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),
448
+ onFailure: () => subscribe,
449
+ onSuccess: () => subscribe,
137
450
  });
138
451
  }
139
452
  updates(run) {
140
- return this.core.semaphore.withPermits(1)(run(this.getSetDelete));
453
+ return updateCore(this.core, (recordCommit) => run(getSetDelete(this.core, recordCommit)));
141
454
  }
142
455
  onSuccess(value) {
143
- return setCore(this.core, value);
456
+ return updateCore(this.core, (recordCommit) => bufferSuccessCore(this.core, value, recordCommit));
144
457
  }
145
458
  onFailure(cause) {
146
- return onFailureCore(this.core, cause);
459
+ return updateCore(this.core, (recordCommit) => bufferFailureCore(this.core, cause, recordCommit));
147
460
  }
148
461
  toEffect() {
149
462
  return getOrInitializeCore(this.core, true);
@@ -152,6 +465,31 @@ class RefSubjectImpl extends YieldableFx {
152
465
  /**
153
466
  * Creates a new `RefSubject` from a value, `Effect`, or `Fx`.
154
467
  *
468
+ * @remarks
469
+ * ## Why
470
+ *
471
+ * `RefSubject` keeps current state and pushed changes independent of any UI
472
+ * renderer. Domain transitions can therefore be constructed, composed, and
473
+ * tested with Effect alone; rendering is one optional consumer of the state.
474
+ * Plain values, Effect programs, pull-based Effect `Stream`s, and push-based
475
+ * `Fx` sources all enter through the same state boundary.
476
+ *
477
+ * ## Ownership and lifetime
478
+ *
479
+ * Creation requires an Effect `Scope`. That scope owns source acquisition,
480
+ * subscriptions, and finalization. The returned `RefSubject` exposes the
481
+ * source error type when read or observed, while construction itself cannot
482
+ * fail. Closing the scope interrupts a live source and releases its resources.
483
+ *
484
+ * ## Initialization
485
+ *
486
+ * Calling `make` is lazy because it returns an Effect: nothing is allocated and no source runs
487
+ * until that creation Effect is executed. After creation, a plain value is immediately available.
488
+ * An Effect input runs once on the first current read or observation. Fx and Stream inputs instead
489
+ * start one shared source run when the creation Effect executes; reads wait for their first value
490
+ * or failure and later emissions replace the retained current state. Equality and buffering
491
+ * behavior can be customized with `RefSubjectOptions`.
492
+ *
155
493
  * @example
156
494
  * ```ts
157
495
  * import { Effect } from "effect"
@@ -185,7 +523,7 @@ class RefSubjectImpl extends YieldableFx {
185
523
  * ```
186
524
  *
187
525
  * @since 1.0.0
188
- * @category constructors
526
+ * @category Constructors
189
527
  */
190
528
  export function make(effect, options) {
191
529
  if (isFx(effect)) {
@@ -204,6 +542,19 @@ export function make(effect, options) {
204
542
  /**
205
543
  * Creates a `RefSubject` from an `Effect`.
206
544
  *
545
+ * @remarks
546
+ * ## Why
547
+ *
548
+ * Makes effect acquisition explicit while normalizing it into current RefSubject state and
549
+ * subsequent pushed versions.
550
+ *
551
+ * ## Ownership and lifetime
552
+ *
553
+ * The creation Effect requires Scope and the source's services, which it captures for the private
554
+ * initializer Scope. The source Effect itself stays deferred until the first current read or
555
+ * observation and runs at most once. Source failures remain visible on reads and observations;
556
+ * closing the creation Scope interrupts an initializer that is still running.
557
+ *
207
558
  * @example
208
559
  * ```ts
209
560
  * import { Effect } from "effect"
@@ -220,7 +571,7 @@ export function make(effect, options) {
220
571
  * ```
221
572
  *
222
573
  * @since 1.0.0
223
- * @category constructors
574
+ * @category Source adapters
224
575
  */
225
576
  export function fromEffect(effect, options) {
226
577
  return Effect.map(makeCore(effect, options), (core) => new RefSubjectImpl(core));
@@ -228,6 +579,17 @@ export function fromEffect(effect, options) {
228
579
  /**
229
580
  * Creates a `RefSubject` from an `Fx`, tracking the latest emitted value.
230
581
  *
582
+ * @remarks
583
+ * ## Why
584
+ *
585
+ * Makes fx acquisition explicit while normalizing it into current RefSubject state and subsequent
586
+ * pushed versions.
587
+ *
588
+ * ## Ownership and lifetime
589
+ *
590
+ * The creation Effect requires Scope. It owns initializer acquisition, live source subscriptions,
591
+ * and cleanup; source failures and services stay on reads and pushes.
592
+ *
231
593
  * @example
232
594
  * ```ts
233
595
  * import { Effect } from "effect"
@@ -248,27 +610,59 @@ export function fromEffect(effect, options) {
248
610
  * ```
249
611
  *
250
612
  * @since 1.0.0
251
- * @category constructors
613
+ * @category Source adapters
252
614
  */
253
615
  export function fromFx(fx, options) {
254
616
  return Effect.gen(function* () {
255
617
  const core = yield* makeDeferredCore(options);
256
618
  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 });
619
+ 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
620
  return ref;
259
621
  });
260
622
  }
623
+ /**
624
+ * Creates a RefSubject that tracks the latest value emitted by an Effect Stream.
625
+ *
626
+ * @remarks
627
+ * ## Why
628
+ *
629
+ * Bridges a pull-based Stream into renderer-independent state: each emitted value enters the
630
+ * RefSubject's serialized commit path, while a stream failure becomes the ref's current and pushed
631
+ * failure.
632
+ *
633
+ * ## Ownership and lifetime
634
+ *
635
+ * Construction forks stream consumption immediately into the RefSubject's private Scope and cannot
636
+ * fail. `R` is required while constructing that fiber; closing the outer Scope interrupts it.
637
+ * Before the first value or failure, a current read waits for initialization. Later reads and pushes
638
+ * expose `E`.
639
+ *
640
+ * @since 1.18.0
641
+ * @category Source adapters
642
+ */
261
643
  export function fromStream(stream, options) {
262
644
  return Effect.gen(function* () {
263
645
  const core = yield* makeDeferredCore(options);
264
646
  const ref = new RefSubjectImpl(core);
265
- yield* Effect.forkIn(stream.pipe(redirectCause(core), Stream.runForEach((value) => setCore(core, value))), core.scope, { startImmediately: true });
647
+ yield* Effect.forkIn(stream.pipe(redirectCause(core), Stream.runForEach((value) => updateCore(core, (recordCommit) => bufferSuccessCore(core, value, recordCommit)))), core.scope, { startImmediately: true });
266
648
  return ref;
267
649
  });
268
650
  }
269
651
  /**
270
652
  * Creates a `RefSubject` from an `Option` value.
271
653
  *
654
+ * @remarks
655
+ * ## Why
656
+ *
657
+ * Stores the Option itself in writable state. `None` is an ordinary current value and does not add
658
+ * `NoSuchElementError`; callers opt into absence semantics with `compact`, or a fallback with
659
+ * `getOrElse`.
660
+ *
661
+ * ## Ownership and lifetime
662
+ *
663
+ * Construction requires Scope because it delegates to `make`, but the supplied Option needs no
664
+ * services and cannot fail. The returned RefSubject owns and publishes subsequent Option writes.
665
+ *
272
666
  * @example
273
667
  * ```ts
274
668
  * import { Effect, Option } from "effect"
@@ -282,7 +676,7 @@ export function fromStream(stream, options) {
282
676
  * ```
283
677
  *
284
678
  * @since 1.0.0
285
- * @category constructors
679
+ * @category Source adapters
286
680
  */
287
681
  export function fromOption(option, options) {
288
682
  return make(option, options);
@@ -307,23 +701,41 @@ export function fromOption(option, options) {
307
701
  * ```
308
702
  *
309
703
  * @since 1.0.0
310
- * @category constructors
704
+ * @category Source adapters
311
705
  */
312
706
  function optionFromNullable(value) {
313
707
  return value === null || value === undefined
314
708
  ? Option.none()
315
709
  : Option.some(value);
316
710
  }
711
+ /**
712
+ * Creates Option-valued RefSubject state from a nullable input.
713
+ *
714
+ * @remarks
715
+ * ## Why
716
+ *
717
+ * Converts `null` and `undefined` to `Option.none` and every other value to `Option.some`, then
718
+ * stores that Option in a writable RefSubject. It does not create Filtered state or add
719
+ * `NoSuchElementError`.
720
+ *
721
+ * ## Ownership and lifetime
722
+ *
723
+ * Construction requires Scope because it delegates to `make`; it needs no services and cannot
724
+ * fail. The returned RefSubject owns and publishes subsequent Option writes.
725
+ *
726
+ * @since 1.18.0
727
+ * @category Source adapters
728
+ */
317
729
  export function fromNullable(value, options) {
318
730
  return make(optionFromNullable(value), options);
319
731
  }
320
732
  function redirectCause(core) {
321
- return Stream.catchCause((cause) => Stream.unwrap(Effect.as(onFailureCore(core, cause), Stream.empty)));
733
+ return Stream.catchCause((cause) => Stream.unwrap(Effect.as(updateCore(core, (recordCommit) => bufferFailureCore(core, cause, recordCommit)), Stream.empty)));
322
734
  }
323
735
  function makeCore(initial, options, deferredRef) {
324
736
  return Effect.gen(function* () {
325
- const services = yield* Effect.services();
326
- const scope = yield* Scope.fork(ServiceMap.get(services, Scope.Scope));
737
+ const services = yield* Effect.context();
738
+ const scope = yield* Scope.fork(Context.get(services, Scope.Scope));
327
739
  const id = yield* Effect.withFiber((fiber) => Effect.succeed(fiber.id));
328
740
  const subject = new Subject.HoldSubjectImpl();
329
741
  const core = new RefSubjectCore(initial, subject, services, scope, deferredRef ??
@@ -335,7 +747,7 @@ function makeCore(initial, options, deferredRef) {
335
747
  function makeDeferredCore(options) {
336
748
  return Effect.gen(function* () {
337
749
  const deferredRef = yield* DeferredRef.make(getExitEquivalence(options?.eq ?? equals));
338
- return yield* makeCore(deferredRef.asEffect(), options, deferredRef);
750
+ return yield* makeCore(deferredRef, options, deferredRef);
339
751
  });
340
752
  }
341
753
  function getOrInitializeCore(core, lockInitialize) {
@@ -344,30 +756,51 @@ function getOrInitializeCore(core, lockInitialize) {
344
756
  return initializeCoreAndTap(core, lockInitialize);
345
757
  }
346
758
  else {
347
- return core.deferredRef.asEffect();
759
+ return core.deferredRef;
348
760
  }
349
761
  });
350
762
  }
351
763
  function initializeCoreEffect(core, lock) {
764
+ let completed = false;
352
765
  const initialize = Effect.onExit(Effect.provide(core.initial, core.services), (exit) => Effect.sync(() => {
766
+ completed = true;
353
767
  core._fiber = undefined;
354
768
  core.deferredRef.done(exit);
355
769
  }));
356
- return Effect.flatMap(Effect.forkIn(lock ? core.semaphore.withPermits(1)(initialize) : initialize, core.scope), (fiber) => Effect.sync(() => (core._fiber = fiber)));
770
+ const isSourceBacked = core.initial === core.deferredRef;
771
+ return Effect.flatMap(Effect.forkIn(lock && !isSourceBacked ? core.semaphore.withPermits(1)(initialize) : initialize, core.scope,
772
+ // Acquire the initializer's permit before a competing update can hold it while awaiting us.
773
+ { startImmediately: true }), (fiber) => Effect.sync(() => {
774
+ // A synchronous initializer has already cleared its ownership in onExit.
775
+ if (!completed)
776
+ core._fiber = fiber;
777
+ return fiber;
778
+ }));
357
779
  }
358
780
  function initializeCoreAndTap(core, lock) {
359
- return Effect.flatMapEager(initializeCoreEffect(core, lock), () => tapEventCore(core, core.deferredRef.asEffect()));
781
+ return Effect.flatMapEager(initializeCoreEffect(core, lock), () =>
782
+ // Kind of weird hack, but this second clause will happen for HydrationRefs that are already hydrated
783
+ core.deferredRef.current === core.subject.lastValue
784
+ ? tapEventCore(core, core.deferredRef)
785
+ : core.deferredRef);
786
+ }
787
+ function updateCore(core, run) {
788
+ return Effect.uninterruptibleMask((restore) => {
789
+ const commits = [];
790
+ const transaction = restore(core.semaphore.withPermits(1)(Effect.suspend(() => run((commit) => {
791
+ commits.push(commit);
792
+ }))));
793
+ return Effect.flatMap(Effect.exit(transaction), (exit) => Effect.andThen(Effect.forEach(commits, (commit) => sendEvent(core, commit), { discard: true }), exit));
794
+ });
360
795
  }
361
796
  function setCore(core, a) {
362
797
  return Effect.suspend(() => {
363
798
  const exit = Exit.succeed(a);
364
799
  if (core.deferredRef.done(exit)) {
365
- // If the value changed, send an event
366
- return Effect.as(sendEvent(core, exit), a);
800
+ return Effect.succeed(Option.some(exit));
367
801
  }
368
802
  else {
369
- // Otherwise, just return the current value
370
- return Effect.succeed(a);
803
+ return Effect.succeed(Option.none());
371
804
  }
372
805
  });
373
806
  }
@@ -375,13 +808,26 @@ function onFailureCore(core, cause) {
375
808
  const exit = Exit.failCause(cause);
376
809
  return Effect.suspend(() => {
377
810
  if (core.deferredRef.done(exit)) {
378
- return sendEvent(core, exit);
811
+ return Effect.succeed(Option.some(exit));
379
812
  }
380
813
  else {
381
- return Effect.void;
814
+ return Effect.succeed(Option.none());
382
815
  }
383
816
  });
384
817
  }
818
+ function bufferSuccessCore(core, value, recordCommit) {
819
+ return Effect.map(setCore(core, value), (commit) => {
820
+ if (Option.isSome(commit))
821
+ recordCommit(commit.value);
822
+ return value;
823
+ });
824
+ }
825
+ function bufferFailureCore(core, cause, recordCommit) {
826
+ return Effect.asVoid(Effect.map(onFailureCore(core, cause), (commit) => {
827
+ if (Option.isSome(commit))
828
+ recordCommit(commit.value);
829
+ }));
830
+ }
385
831
  function interruptCore(core) {
386
832
  return Effect.withFiber((fiber) => {
387
833
  core.deferredRef.reset();
@@ -415,6 +861,17 @@ function sendEvent(core, exit) {
415
861
  /**
416
862
  * Sets the value of a `RefSubject`.
417
863
  *
864
+ * @remarks
865
+ * ## Why
866
+ *
867
+ * Sets the value of a `RefSubject`. The transition is serialized at the RefSubject rather than
868
+ * coordinated by callers or UI components.
869
+ *
870
+ * ## Ownership and lifetime
871
+ *
872
+ * Running set performs one serialized subject transition and resolves with its committed value. It
873
+ * acquires no resource; failures and services remain those of the source ref.
874
+ *
418
875
  * @example
419
876
  * ```ts
420
877
  * import { Effect } from "effect"
@@ -436,7 +893,7 @@ function sendEvent(core, exit) {
436
893
  * ```
437
894
  *
438
895
  * @since 1.0.0
439
- * @category combinators
896
+ * @category State updates
440
897
  */
441
898
  export const set = dual(2, function set(ref, a) {
442
899
  return ref.updates((ref) => ref.set(a));
@@ -444,6 +901,17 @@ export const set = dual(2, function set(ref, a) {
444
901
  /**
445
902
  * Resets a `RefSubject` to its initial value, returning the previous value if it existed.
446
903
  *
904
+ * @remarks
905
+ * ## Why
906
+ *
907
+ * Resets a `RefSubject` to its initial value, returning the previous value if it existed. The
908
+ * transition is serialized at the RefSubject rather than coordinated by callers or UI components.
909
+ *
910
+ * ## Ownership and lifetime
911
+ *
912
+ * Running reset performs one serialized subject transition and resolves with its committed value.
913
+ * It acquires no resource; failures and services remain those of the source ref.
914
+ *
447
915
  * @example
448
916
  * ```ts
449
917
  * import { Effect, Option } from "effect"
@@ -467,7 +935,7 @@ export const set = dual(2, function set(ref, a) {
467
935
  * ```
468
936
  *
469
937
  * @since 1.0.0
470
- * @category combinators
938
+ * @category State updates
471
939
  */
472
940
  export function reset(ref) {
473
941
  return ref.updates((ref) => ref.delete);
@@ -497,12 +965,23 @@ export {
497
965
  * ```
498
966
  *
499
967
  * @since 1.20.0
500
- * @category combinators
968
+ * @category State updates
501
969
  */
502
970
  reset as delete, };
503
971
  /**
504
972
  * Updates a `RefSubject` using an `Effect`ful function.
505
973
  *
974
+ * @remarks
975
+ * ## Why
976
+ *
977
+ * Updates a `RefSubject` using an `Effect`ful function. The transition is serialized at the
978
+ * RefSubject rather than coordinated by callers or UI components.
979
+ *
980
+ * ## Ownership and lifetime
981
+ *
982
+ * Running update effect performs one serialized subject transition and resolves with its committed
983
+ * value. It acquires no resource; failures and services remain those of the source ref.
984
+ *
506
985
  * @example
507
986
  * ```ts
508
987
  * import { Effect } from "effect"
@@ -522,7 +1001,7 @@ reset as delete, };
522
1001
  * ```
523
1002
  *
524
1003
  * @since 1.0.0
525
- * @category combinators
1004
+ * @category State updates
526
1005
  */
527
1006
  export const updateEffect = dual(2, function updateEffect(ref, f) {
528
1007
  return ref.updates((ref) => Effect.flatMap(Effect.flatMap(ref.get, f), ref.set));
@@ -530,6 +1009,26 @@ export const updateEffect = dual(2, function updateEffect(ref, f) {
530
1009
  /**
531
1010
  * Updates a `RefSubject` using a pure function.
532
1011
  *
1012
+ * @remarks
1013
+ * ## Why
1014
+ *
1015
+ * `update` expresses a state transition where the state lives, without moving
1016
+ * transition logic into a component or renderer. The same function can run in
1017
+ * application code, tests, workers, event handlers, or a Typed template.
1018
+ *
1019
+ * ## Ownership and lifetime
1020
+ *
1021
+ * The update runs inside the RefSubject's existing synchronized update
1022
+ * boundary: it reads the committed value, derives the next value, commits it,
1023
+ * and publishes that change. It acquires no independent resource and retains
1024
+ * the subject's existing error and service channels.
1025
+ *
1026
+ * ## Concurrency and failure
1027
+ *
1028
+ * Concurrent updates are serialized by the subject core so each function sees
1029
+ * a committed value. A pure updater adds no error channel; failures already
1030
+ * associated with reading or writing the RefSubject remain explicit in `E`.
1031
+ *
533
1032
  * @example
534
1033
  * ```ts
535
1034
  * import { Effect } from "effect"
@@ -551,7 +1050,7 @@ export const updateEffect = dual(2, function updateEffect(ref, f) {
551
1050
  * ```
552
1051
  *
553
1052
  * @since 1.0.0
554
- * @category combinators
1053
+ * @category State updates
555
1054
  */
556
1055
  export const update = dual(2, function update(ref, f) {
557
1056
  return updateEffect(ref, (value) => Effect.succeed(f(value)));
@@ -559,6 +1058,18 @@ export const update = dual(2, function update(ref, f) {
559
1058
  /**
560
1059
  * Modifies a `RefSubject` using an `Effect`ful function that returns both a result and a new value.
561
1060
  *
1061
+ * @remarks
1062
+ * ## Why
1063
+ *
1064
+ * Modifies a `RefSubject` using an `Effect`ful function that returns both a result and a new
1065
+ * value. The transition is serialized at the RefSubject rather than coordinated by callers or UI
1066
+ * components.
1067
+ *
1068
+ * ## Ownership and lifetime
1069
+ *
1070
+ * Running modify effect performs one serialized subject transition and resolves with its committed
1071
+ * value. It acquires no resource; failures and services remain those of the source ref.
1072
+ *
562
1073
  * @example
563
1074
  * ```ts
564
1075
  * import { Effect } from "effect"
@@ -579,14 +1090,25 @@ export const update = dual(2, function update(ref, f) {
579
1090
  * ```
580
1091
  *
581
1092
  * @since 1.0.0
582
- * @category combinators
1093
+ * @category Transactions
583
1094
  */
584
1095
  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)))));
1096
+ return ref.updates((ref) => Effect.flatMap(ref.get, (value) => Effect.flatMap(f(value), ([b, a]) => Effect.as(ref.set(a), b))));
586
1097
  });
587
1098
  /**
588
1099
  * Modifies a `RefSubject` using a pure function that returns both a result and a new value.
589
1100
  *
1101
+ * @remarks
1102
+ * ## Why
1103
+ *
1104
+ * Modifies a `RefSubject` using a pure function that returns both a result and a new value. The
1105
+ * transition is serialized at the RefSubject rather than coordinated by callers or UI components.
1106
+ *
1107
+ * ## Ownership and lifetime
1108
+ *
1109
+ * Running modify performs one serialized subject transition and resolves with its committed value.
1110
+ * It acquires no resource; failures and services remain those of the source ref.
1111
+ *
590
1112
  * @example
591
1113
  * ```ts
592
1114
  * import { Effect } from "effect"
@@ -605,7 +1127,7 @@ export const modifyEffect = dual(2, function modifyEffect(ref, f) {
605
1127
  * ```
606
1128
  *
607
1129
  * @since 1.0.0
608
- * @category combinators
1130
+ * @category Transactions
609
1131
  */
610
1132
  export const modify = dual(2, function modify(ref, f) {
611
1133
  return modifyEffect(ref, (value) => Effect.succeed(f(value)));
@@ -613,6 +1135,16 @@ export const modify = dual(2, function modify(ref, f) {
613
1135
  /**
614
1136
  * Checks if a value is a `RefSubject`.
615
1137
  *
1138
+ * @remarks
1139
+ * ## Why
1140
+ *
1141
+ * Checks if a value is a `RefSubject`.
1142
+ *
1143
+ * ## Ownership and lifetime
1144
+ *
1145
+ * The derived ref owns no independent state or subscription. It follows the source lifetime and
1146
+ * routes writes through the source's synchronized update boundary.
1147
+ *
616
1148
  * @example
617
1149
  * ```ts
618
1150
  * import { Effect } from "effect"
@@ -630,14 +1162,45 @@ export const modify = dual(2, function modify(ref, f) {
630
1162
  * ```
631
1163
  *
632
1164
  * @since 1.0.0
633
- * @category guards
1165
+ * @category Type guards
634
1166
  */
635
1167
  export function isRefSubject(value) {
636
- return value && typeof value === "object" && value[RefSubjectTypeId] === RefSubjectTypeId;
1168
+ return hasProperty(value, RefSubjectTypeId) && value[RefSubjectTypeId] === RefSubjectTypeId;
637
1169
  }
638
1170
  const isRefSubjectDataFirst = (args) => isRefSubject(args[0]);
639
1171
  /**
1172
+ * Tests whether a value carries the public Computed TypeId.
1173
+ *
1174
+ * @remarks
1175
+ * ## Why
1176
+ *
1177
+ * Uses the TypeId contract rather than a concrete implementation class, so custom Computed values
1178
+ * and service facades participate in the same runtime guard.
1179
+ *
1180
+ * ## Ownership and lifetime
1181
+ *
1182
+ * This synchronous predicate performs no Effect, subscription, or acquisition.
1183
+ *
1184
+ * @since 1.18.0
1185
+ * @category Type guards
1186
+ */
1187
+ export function isComputed(value) {
1188
+ return hasProperty(value, ComputedTypeId) && value[ComputedTypeId] === ComputedTypeId;
1189
+ }
1190
+ /**
1191
+ * Runs an effect that can modify a `RefSubject` transactionally, with optional interrupt handling.
1192
+ *
1193
+ * @remarks
1194
+ * ## Why
1195
+ *
640
1196
  * Runs an effect that can modify a `RefSubject` transactionally, with optional interrupt handling.
1197
+ * The transition is serialized at the RefSubject rather than coordinated by callers or UI
1198
+ * components.
1199
+ *
1200
+ * ## Ownership and lifetime
1201
+ *
1202
+ * Running run updates performs one serialized subject transition and resolves with its committed
1203
+ * value. It acquires no resource; failures and services remain those of the source ref.
641
1204
  *
642
1205
  * @example
643
1206
  * ```ts
@@ -668,7 +1231,7 @@ const isRefSubjectDataFirst = (args) => isRefSubject(args[0]);
668
1231
  * ```
669
1232
  *
670
1233
  * @since 1.0.0
671
- * @category combinators
1234
+ * @category Transactions
672
1235
  */
673
1236
  export const runUpdates = dual(isRefSubjectDataFirst, function runUpdates(ref, f, options) {
674
1237
  if (options === undefined) {
@@ -684,6 +1247,17 @@ export const runUpdates = dual(isRefSubjectDataFirst, function runUpdates(ref, f
684
1247
  /**
685
1248
  * Increments a numeric `RefSubject` by 1.
686
1249
  *
1250
+ * @remarks
1251
+ * ## Why
1252
+ *
1253
+ * Increments a numeric `RefSubject` by 1. The transition is serialized at the RefSubject rather
1254
+ * than coordinated by callers or UI components.
1255
+ *
1256
+ * ## Ownership and lifetime
1257
+ *
1258
+ * Running increment performs one serialized subject transition and resolves with its committed
1259
+ * value. It acquires no resource; failures and services remain those of the source ref.
1260
+ *
687
1261
  * @example
688
1262
  * ```ts
689
1263
  * import { Effect } from "effect"
@@ -703,7 +1277,7 @@ export const runUpdates = dual(isRefSubjectDataFirst, function runUpdates(ref, f
703
1277
  * ```
704
1278
  *
705
1279
  * @since 1.0.0
706
- * @category combinators
1280
+ * @category State updates
707
1281
  */
708
1282
  export function increment(ref) {
709
1283
  return update(ref, (value) => value + 1);
@@ -711,6 +1285,17 @@ export function increment(ref) {
711
1285
  /**
712
1286
  * Decrements a numeric `RefSubject` by 1.
713
1287
  *
1288
+ * @remarks
1289
+ * ## Why
1290
+ *
1291
+ * Decrements a numeric `RefSubject` by 1. The transition is serialized at the RefSubject rather
1292
+ * than coordinated by callers or UI components.
1293
+ *
1294
+ * ## Ownership and lifetime
1295
+ *
1296
+ * Running decrement performs one serialized subject transition and resolves with its committed
1297
+ * value. It acquires no resource; failures and services remain those of the source ref.
1298
+ *
714
1299
  * @example
715
1300
  * ```ts
716
1301
  * import { Effect } from "effect"
@@ -730,7 +1315,7 @@ export function increment(ref) {
730
1315
  * ```
731
1316
  *
732
1317
  * @since 1.0.0
733
- * @category combinators
1318
+ * @category State updates
734
1319
  */
735
1320
  export function decrement(ref) {
736
1321
  return update(ref, (value) => value - 1);
@@ -740,12 +1325,42 @@ const Variance = {
740
1325
  _E: identity,
741
1326
  _R: identity,
742
1327
  };
1328
+ /**
1329
+ * Creates a Context-backed RefSubject service facade and Layer constructors.
1330
+ *
1331
+ * @remarks
1332
+ * ## Why
1333
+ *
1334
+ * The returned class is simultaneously a service tag, a current-value Effect, an Fx source, and a
1335
+ * writable RefSubject facade. This lets consumers read, observe, and update renderer-independent
1336
+ * state without manually retrieving the underlying service from Context.
1337
+ *
1338
+ * ## Ownership and lifetime
1339
+ *
1340
+ * Calling `Service` is pure. `layer` installs an existing scoped RefSubject; `make` constructs one
1341
+ * and installs it in a Layer. The Layer Scope owns the subject and its initializer subscription.
1342
+ * Reads and pushes expose the declared `E` channel; construction requirements remain on the Layer,
1343
+ * while consumers require only the generated `Self` service.
1344
+ *
1345
+ * @since 1.18.0
1346
+ * @category Services
1347
+ */
743
1348
  export function Service() {
744
1349
  return (id) => {
745
- const service = ServiceMap.Service(id);
1350
+ const service = Context.Service(id);
746
1351
  // eslint-disable-next-line @typescript-eslint/no-extraneous-class
747
1352
  return class RefSubjectService {
748
1353
  /// Service
1354
+ static {
1355
+ // @effect-diagnostics-next-line floatingEffect:off
1356
+ Object.assign(this, service);
1357
+ Object.setPrototypeOf(this, Object.getPrototypeOf(service));
1358
+ // @effect-diagnostics-next-line floatingEffect:off
1359
+ Object.assign(this, Effectable.Prototype({
1360
+ label: "RefSubject.Service",
1361
+ evaluate: () => Effect.flatMap(service, identity),
1362
+ }));
1363
+ }
749
1364
  static id = id;
750
1365
  static service = service;
751
1366
  static layer = (make) => Layer.effect(service, make);
@@ -755,21 +1370,21 @@ export function Service() {
755
1370
  };
756
1371
  // Fx
757
1372
  static [FxTypeId] = Variance;
758
- static run = (sink) => Effect.flatMap(service.asEffect(), (ref) => ref.run(sink));
1373
+ static run = (sink) => Effect.flatMap(service, (ref) => ref.run(sink));
759
1374
  // 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));
1375
+ static onSuccess = (value) => Effect.flatMap(service, (ref) => ref.onSuccess(value));
1376
+ static onFailure = (cause) => Effect.flatMap(service, (ref) => ref.onFailure(cause));
762
1377
  /// Computed
763
1378
  static [ComputedTypeId] = ComputedTypeId;
764
- static version = Effect.flatMap(service.asEffect(), (ref) => ref.version);
1379
+ static version = Effect.flatMap(service, (ref) => ref.version);
765
1380
  // Subject
766
- static subscriberCount = Effect.flatMap(service.asEffect(), (ref) => ref.subscriberCount);
767
- static interrupt = Effect.flatMap(service.asEffect(), (ref) => ref.interrupt);
1381
+ static subscriberCount = Effect.flatMap(service, (ref) => ref.subscriberCount);
1382
+ static interrupt = Effect.flatMap(service, (ref) => ref.interrupt);
768
1383
  // RefSubject
769
1384
  static [RefSubjectTypeId] = RefSubjectTypeId;
770
- static updates = (f) => Effect.flatMap(service.asEffect(), (ref) => ref.updates(f));
1385
+ static updates = (f) => Effect.flatMap(service, (ref) => ref.updates(f));
771
1386
  // Yieldable
772
- static asEffect = () => Effect.flatMap(service.asEffect(), Effect.fromYieldable);
1387
+ static override = Effect.flatten(service);
773
1388
  static [Symbol.iterator] = function* () {
774
1389
  const ref = yield* service;
775
1390
  return yield* ref;
@@ -793,6 +1408,19 @@ function getDefaultBounds(options) {
793
1408
  * Extract all values from an object using a Proxy.
794
1409
  * Allows accessing nested properties of a `Computed` or `Filtered` object/array as individual computed values.
795
1410
  *
1411
+ * @remarks
1412
+ * ## Why
1413
+ *
1414
+ * Lazily creates one property projection per accessed key and memoizes that projection on the
1415
+ * JavaScript Proxy. A Computed or RefSubject source produces Computed properties; only a Filtered
1416
+ * source produces Filtered properties and preserves conditional absence.
1417
+ *
1418
+ * ## Ownership and lifetime
1419
+ *
1420
+ * The Proxy caches derived view objects, not property values. Computed property reads expose only
1421
+ * the source's `E`; Filtered property reads can additionally fail with `NoSuchElementError` while
1422
+ * their source is absent. Each observed property follows the source and uses the observing Scope.
1423
+ *
796
1424
  * @example
797
1425
  * ```ts
798
1426
  * import { Effect } from "effect"
@@ -821,7 +1449,7 @@ function getDefaultBounds(options) {
821
1449
  * ```
822
1450
  *
823
1451
  * @since 2.0.0
824
- * @category combinators
1452
+ * @category Derived queries
825
1453
  */
826
1454
  export const proxy = (source) => {
827
1455
  const target = {};
@@ -836,6 +1464,20 @@ export const proxy = (source) => {
836
1464
  /**
837
1465
  * Transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function.
838
1466
  *
1467
+ * @remarks
1468
+ * ## Why
1469
+ *
1470
+ * Applies one Effectful derivation to current reads and pushed versions. RefSubject and Computed
1471
+ * inputs return Computed and add only `E2`; a Filtered input returns Filtered and preserves its
1472
+ * conditional absence in addition to `E2`.
1473
+ *
1474
+ * ## Ownership and lifetime
1475
+ *
1476
+ * No callback runs until the result is read or observed. Computed results cannot become absent and
1477
+ * do not add `NoSuchElementError`; only the Filtered overload can fail a current read for absence.
1478
+ * Callback services and failures remain `R2` and `E2`, and the observing Scope owns subscription
1479
+ * cleanup.
1480
+ *
839
1481
  * @example
840
1482
  * ```ts
841
1483
  * import { Effect } from "effect"
@@ -862,7 +1504,7 @@ export const proxy = (source) => {
862
1504
  * ```
863
1505
  *
864
1506
  * @since 1.0.0
865
- * @category combinators
1507
+ * @category Derived queries
866
1508
  */
867
1509
  export const mapEffect = dual(2, function mapEffect(versioned, f) {
868
1510
  return FilteredTypeId in versioned
@@ -872,6 +1514,25 @@ export const mapEffect = dual(2, function mapEffect(versioned, f) {
872
1514
  /**
873
1515
  * Transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function.
874
1516
  *
1517
+ * @remarks
1518
+ * ## Why
1519
+ *
1520
+ * `map` creates derived state instead of copying source state into a component.
1521
+ * Reads and pushed updates remain connected to the original `Versioned` value,
1522
+ * so a projection can be tested without rendering and consumed by any renderer.
1523
+ *
1524
+ * ## Ownership and lifetime
1525
+ *
1526
+ * The returned `Computed` or `Filtered` view does not take ownership of the
1527
+ * source. It follows the source lifetime and preserves its error and service
1528
+ * channels. The pure mapping function adds neither resources nor failures.
1529
+ *
1530
+ * ## Re-computation
1531
+ *
1532
+ * The mapping function runs for the current value and subsequent committed
1533
+ * source versions. Updates still occur on the writable source; the derived view
1534
+ * is read-only unless a more specific bidirectional combinator is used.
1535
+ *
875
1536
  * @example
876
1537
  * ```ts
877
1538
  * import { Effect } from "effect"
@@ -896,7 +1557,7 @@ export const mapEffect = dual(2, function mapEffect(versioned, f) {
896
1557
  * ```
897
1558
  *
898
1559
  * @since 1.0.0
899
- * @category combinators
1560
+ * @category Derived queries
900
1561
  */
901
1562
  export const map = dual(2, function map(versioned, f) {
902
1563
  return mapEffect(versioned, (a) => Effect.succeed(f(a)));
@@ -904,6 +1565,18 @@ export const map = dual(2, function map(versioned, f) {
904
1565
  /**
905
1566
  * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function that returns an `Option`.
906
1567
  *
1568
+ * @remarks
1569
+ * ## Why
1570
+ *
1571
+ * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using an `Effect`ful function
1572
+ * that returns an `Option`. Current reads and pushed versions use the same derivation, preventing
1573
+ * snapshot and subscription behavior from diverging.
1574
+ *
1575
+ * ## Ownership and lifetime
1576
+ *
1577
+ * The filter map effect view retains no independent value. Its Effect read fails with NoSuchElement
1578
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
1579
+ *
907
1580
  * @example
908
1581
  * ```ts
909
1582
  * import { Effect, Option } from "effect"
@@ -923,7 +1596,7 @@ export const map = dual(2, function map(versioned, f) {
923
1596
  * ```
924
1597
  *
925
1598
  * @since 1.0.0
926
- * @category combinators
1599
+ * @category Optional queries
927
1600
  */
928
1601
  export const filterMapEffect = dual(2, function filterMapEffect(versioned, f) {
929
1602
  return new FilteredImpl(versioned, f);
@@ -931,6 +1604,18 @@ export const filterMapEffect = dual(2, function filterMapEffect(versioned, f) {
931
1604
  /**
932
1605
  * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function that returns an `Option`.
933
1606
  *
1607
+ * @remarks
1608
+ * ## Why
1609
+ *
1610
+ * Filters and transforms a `RefSubject`, `Computed`, or `Filtered` using a pure function that
1611
+ * returns an `Option`. Current reads and pushed versions use the same derivation, preventing
1612
+ * snapshot and subscription behavior from diverging.
1613
+ *
1614
+ * ## Ownership and lifetime
1615
+ *
1616
+ * The filter map view retains no independent value. Its Effect read fails with NoSuchElement
1617
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
1618
+ *
934
1619
  * @example
935
1620
  * ```ts
936
1621
  * import { Effect, Option } from "effect"
@@ -950,7 +1635,7 @@ export const filterMapEffect = dual(2, function filterMapEffect(versioned, f) {
950
1635
  * ```
951
1636
  *
952
1637
  * @since 1.0.0
953
- * @category combinators
1638
+ * @category Optional queries
954
1639
  */
955
1640
  export const filterMap = dual(2, function filterMap(versioned, f) {
956
1641
  return new FilteredImpl(versioned, (a) => Effect.succeed(f(a)));
@@ -958,6 +1643,18 @@ export const filterMap = dual(2, function filterMap(versioned, f) {
958
1643
  /**
959
1644
  * Converts a `Computed` or `Filtered` of `Option<A>` into a `Filtered<A>`, filtering out `None` values.
960
1645
  *
1646
+ * @remarks
1647
+ * ## Why
1648
+ *
1649
+ * Converts a `Computed` or `Filtered` of `Option<A>` into a `Filtered<A>`, filtering out `None`
1650
+ * values. Current reads and pushed versions use the same derivation, preventing snapshot and
1651
+ * subscription behavior from diverging.
1652
+ *
1653
+ * ## Ownership and lifetime
1654
+ *
1655
+ * The compact view retains no independent value. Its Effect read fails with NoSuchElement
1656
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
1657
+ *
961
1658
  * @example
962
1659
  * ```ts
963
1660
  * import { Effect, Option } from "effect"
@@ -979,7 +1676,7 @@ export const filterMap = dual(2, function filterMap(versioned, f) {
979
1676
  * ```
980
1677
  *
981
1678
  * @since 1.0.0
982
- * @category combinators
1679
+ * @category Optional queries
983
1680
  */
984
1681
  export const compact = function compact(versioned) {
985
1682
  return new FilteredImpl(versioned, Effect.succeed);
@@ -988,6 +1685,20 @@ export const compact = function compact(versioned) {
988
1685
  * Returns a `Computed` that yields the value inside the `Option`, or the fallback when `None`.
989
1686
  * Works with `Computed<Option<A>>` (e.g. from `fromOption` / `fromNullable`) and with `Filtered<A>`.
990
1687
  *
1688
+ * @remarks
1689
+ * ## Why
1690
+ *
1691
+ * Returns a `Computed` that yields the value inside the `Option`, or the fallback when `None`.
1692
+ * Works with `Computed<Option<A>>` (e.g. from `fromOption` / `fromNullable`) and with
1693
+ * `Filtered<A>`. Current reads and pushed versions use the same derivation, preventing snapshot
1694
+ * and subscription behavior from diverging.
1695
+ *
1696
+ * ## Ownership and lifetime
1697
+ *
1698
+ * The returned Computed never fails for absence: `None` or an absent Filtered value invokes
1699
+ * `fallback`. It preserves only the input's declared `E` and `R`; the pure fallback adds no failure,
1700
+ * service, subscription, or retained value.
1701
+ *
991
1702
  * @example
992
1703
  * ```ts
993
1704
  * import { Effect, Option } from "effect"
@@ -1005,7 +1716,7 @@ export const compact = function compact(versioned) {
1005
1716
  * ```
1006
1717
  *
1007
1718
  * @since 1.0.0
1008
- * @category combinators
1719
+ * @category Optional queries
1009
1720
  */
1010
1721
  export const getOrElse = dual(2, function getOrElse(ref, fallback) {
1011
1722
  const computed = FilteredTypeId in ref ? ref.asComputed() : ref;
@@ -1035,7 +1746,7 @@ class RefSubjectSimpleTransform extends YieldableFx {
1035
1746
  return this._fx.run(sink);
1036
1747
  }
1037
1748
  toEffect() {
1038
- return this.transformEffect(this.ref.asEffect());
1749
+ return this.transformEffect(this.ref);
1039
1750
  }
1040
1751
  updates(run) {
1041
1752
  return this.ref.updates(run);
@@ -1047,6 +1758,25 @@ class RefSubjectSimpleTransform extends YieldableFx {
1047
1758
  return this.ref.onSuccess(value);
1048
1759
  }
1049
1760
  }
1761
+ /**
1762
+ * Limits which pushed versions a RefSubject view observes without changing its state.
1763
+ *
1764
+ * @remarks
1765
+ * ## Why
1766
+ *
1767
+ * Applies `skip` and `take` only to the Fx observation channel. Current reads still sample the
1768
+ * underlying RefSubject directly, and writes still use its original serialized update boundary.
1769
+ *
1770
+ * ## Ownership and lifetime
1771
+ *
1772
+ * Creating the view starts nothing and retains no value. Each observation uses its Scope and ends
1773
+ * after `take` selected pushes; ending that observation does not interrupt or delete the source.
1774
+ * Version, interruption, subscriber count, reads, failures, services, and writes delegate to the
1775
+ * source RefSubject.
1776
+ *
1777
+ * @since 1.18.0
1778
+ * @category Observation policy
1779
+ */
1050
1780
  export const slice = dual(3, function slice(ref, skip, take) {
1051
1781
  return new RefSubjectSimpleTransform(ref, (_) => fxSlice(_, { skip, take }), identity);
1052
1782
  });
@@ -1074,7 +1804,7 @@ class RefSubjectTransform extends YieldableFx {
1074
1804
  return this._fx.run(sink);
1075
1805
  }
1076
1806
  toEffect() {
1077
- return Effect.map(this.ref.asEffect(), this.toB);
1807
+ return Effect.map(this.ref, this.toB);
1078
1808
  }
1079
1809
  updates(run) {
1080
1810
  return this.ref.updates((innerRef) => {
@@ -1096,6 +1826,17 @@ class RefSubjectTransform extends YieldableFx {
1096
1826
  /**
1097
1827
  * Transforms a `RefSubject` invariantly using bidirectional mapping functions.
1098
1828
  *
1829
+ * @remarks
1830
+ * ## Why
1831
+ *
1832
+ * Creates a bidirectional lens over state: reads map outward and writes map back to the original
1833
+ * RefSubject without allocating a second store.
1834
+ *
1835
+ * ## Ownership and lifetime
1836
+ *
1837
+ * The derived ref owns no independent state or subscription. It follows the source lifetime and
1838
+ * routes writes through the source's synchronized update boundary.
1839
+ *
1099
1840
  * @example
1100
1841
  * ```ts
1101
1842
  * import { Effect } from "effect"
@@ -1124,7 +1865,7 @@ class RefSubjectTransform extends YieldableFx {
1124
1865
  * ```
1125
1866
  *
1126
1867
  * @since 1.0.0
1127
- * @category combinators
1868
+ * @category Writable views
1128
1869
  */
1129
1870
  export const transform = dual(3, function transform(ref, toB, toA) {
1130
1871
  return new RefSubjectTransform(ref, toB, toA);
@@ -1156,6 +1897,17 @@ function getRefKind(refs) {
1156
1897
  /**
1157
1898
  * Combines multiple `RefSubject`, `Computed`, or `Filtered` instances into a single struct.
1158
1899
  *
1900
+ * @remarks
1901
+ * ## Why
1902
+ *
1903
+ * Combines several refs into one state value while preserving whether the result is writable,
1904
+ * computed, or filtered from its inputs.
1905
+ *
1906
+ * ## Ownership and lifetime
1907
+ *
1908
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
1909
+ * source errors, services, and lifetime.
1910
+ *
1159
1911
  * @example
1160
1912
  * ```ts
1161
1913
  * import { Effect } from "effect"
@@ -1186,7 +1938,7 @@ function getRefKind(refs) {
1186
1938
  * ```
1187
1939
  *
1188
1940
  * @since 1.0.0
1189
- * @category combinators
1941
+ * @category State composition
1190
1942
  */
1191
1943
  export function struct(refs) {
1192
1944
  const kind = getRefKind(Object.values(refs));
@@ -1202,6 +1954,17 @@ export function struct(refs) {
1202
1954
  /**
1203
1955
  * Combines multiple `RefSubject`, `Computed`, or `Filtered` instances into a single tuple.
1204
1956
  *
1957
+ * @remarks
1958
+ * ## Why
1959
+ *
1960
+ * Combines several refs into one state value while preserving whether the result is writable,
1961
+ * computed, or filtered from its inputs.
1962
+ *
1963
+ * ## Ownership and lifetime
1964
+ *
1965
+ * This declaration performs no acquisition and retains no resources. Implementations preserve
1966
+ * source errors, services, and lifetime.
1967
+ *
1205
1968
  * @example
1206
1969
  * ```ts
1207
1970
  * import { Effect } from "effect"
@@ -1228,7 +1991,7 @@ export function struct(refs) {
1228
1991
  * ```
1229
1992
  *
1230
1993
  * @since 1.0.0
1231
- * @category combinators
1994
+ * @category State composition
1232
1995
  */
1233
1996
  export function tuple(refs) {
1234
1997
  const kind = getRefKind(refs);
@@ -1245,6 +2008,38 @@ function makeTupleRef(refs) {
1245
2008
  return new RefSubjectTuple(refs);
1246
2009
  }
1247
2010
  const UNBOUNDED = { concurrency: "unbounded" };
2011
+ const sampleRefSubject = (ref) =>
2012
+ // @effect-diagnostics-next-line unnecessaryEffectGen:off
2013
+ Effect.gen(function* () {
2014
+ return yield* ref;
2015
+ });
2016
+ function versionedInContext(make) {
2017
+ // Automatic composites share both pushed sessions and in-flight reads only within one Context.
2018
+ const contexts = new WeakMap();
2019
+ const current = Effect.map(Effect.context(), (context) => {
2020
+ let versioned = contexts.get(context);
2021
+ if (!versioned) {
2022
+ versioned = make();
2023
+ contexts.set(context, versioned);
2024
+ }
2025
+ return versioned;
2026
+ });
2027
+ return new (class extends YieldableFx {
2028
+ version = Effect.flatMap(current, (versioned) => versioned.version);
2029
+ interrupt = Effect.flatMap(current, (versioned) => versioned.interrupt);
2030
+ run(sink) {
2031
+ return Effect.flatMap(current, (versioned) => versioned.run(sink));
2032
+ }
2033
+ toEffect() {
2034
+ return Effect.flatMap(current, identity);
2035
+ }
2036
+ })();
2037
+ }
2038
+ function makeCompositeVersioned(refs, current) {
2039
+ const version = Effect.map(Effect.all(refs.map((ref) => ref.version), UNBOUNDED), (versions) => versions.reduce(sum, 0));
2040
+ const changes = skipRepeats(fxMapEffect(fxMergeAll(...refs), () => current));
2041
+ return versionedInContext(() => Versioned.hold(Versioned.make(version, changes, current)));
2042
+ }
1248
2043
  class RefSubjectTuple extends YieldableFx {
1249
2044
  [ComputedTypeId] = ComputedTypeId;
1250
2045
  [RefSubjectTypeId] = RefSubjectTypeId;
@@ -1257,12 +2052,14 @@ class RefSubjectTuple extends YieldableFx {
1257
2052
  constructor(refs) {
1258
2053
  super();
1259
2054
  this.refs = refs;
1260
- this.versioned = Versioned.hold(Versioned.tuple(refs));
2055
+ this.versioned = (refs.length > 0 && getTupleTransactionAccess(refs)
2056
+ ? makeCompositeVersioned(refs, Effect.all(refs.map(sampleRefSubject), UNBOUNDED))
2057
+ : versionedInContext(() => Versioned.hold(Versioned.tuple(refs))));
1261
2058
  this.version = this.versioned.version;
1262
2059
  this.interrupt = Effect.all(refs.map((r) => r.interrupt), UNBOUNDED);
1263
2060
  this.subscriberCount = Effect.map(Effect.all(refs.map((r) => r.subscriberCount), UNBOUNDED), Array.reduce(0, sum));
1264
2061
  this.getSetDelete = {
1265
- get: this.versioned.asEffect(),
2062
+ get: this.versioned,
1266
2063
  set: (a) => Effect.all(refs.map((r, i) => set(r, a[i])), UNBOUNDED),
1267
2064
  delete: Effect.map(Effect.all(refs.map((r) => reset(r)), UNBOUNDED), Option.all),
1268
2065
  };
@@ -1274,10 +2071,15 @@ class RefSubjectTuple extends YieldableFx {
1274
2071
  return this.versioned.run(sink);
1275
2072
  }
1276
2073
  toEffect() {
1277
- return this.versioned.asEffect();
2074
+ return this.versioned;
1278
2075
  }
1279
2076
  updates(run) {
1280
- return run(this.getSetDelete);
2077
+ const accessEffect = getTransactionAccess(this);
2078
+ return accessEffect
2079
+ ? Effect.flatMap(accessEffect, (transactionAccess) => Option.isSome(transactionAccess)
2080
+ ? runTransaction(transactionAccess.value, run)
2081
+ : Effect.suspend(() => run(this.getSetDelete)))
2082
+ : Effect.suspend(() => run(this.getSetDelete));
1281
2083
  }
1282
2084
  onFailure(cause) {
1283
2085
  return Effect.all(this.refs.map((ref) => ref.onFailure(cause)));
@@ -1287,10 +2089,10 @@ class RefSubjectTuple extends YieldableFx {
1287
2089
  }
1288
2090
  }
1289
2091
  function makeTupleComputed(refs) {
1290
- return new ComputedImpl(Versioned.tuple(refs), Effect.succeed);
2092
+ return new ComputedImpl(versionedInContext(() => Versioned.tuple(refs)), Effect.succeed);
1291
2093
  }
1292
2094
  function makeTupleFiltered(refs) {
1293
- return new FilteredImpl(Versioned.tuple(refs), Effect.succeedSome);
2095
+ return new FilteredImpl(versionedInContext(() => Versioned.tuple(refs)), Effect.succeedSome);
1294
2096
  }
1295
2097
  function makeStructRef(refs) {
1296
2098
  return new RefSubjectStruct(refs);
@@ -1307,12 +2109,16 @@ class RefSubjectStruct extends YieldableFx {
1307
2109
  constructor(refs) {
1308
2110
  super();
1309
2111
  this.refs = refs;
1310
- this.versioned = Versioned.hold(Versioned.struct(refs));
2112
+ const keys = Object.keys(refs);
2113
+ const current = Effect.map(Effect.all(keys.map((key) => sampleRefSubject(refs[key])), UNBOUNDED), (values) => Object.fromEntries(keys.map((key, index) => [key, values[index]])));
2114
+ this.versioned = (keys.length > 0 && getStructTransactionAccess(refs)
2115
+ ? makeCompositeVersioned(Object.values(refs), current)
2116
+ : versionedInContext(() => Versioned.hold(Versioned.struct(refs))));
1311
2117
  this.version = this.versioned.version;
1312
2118
  this.interrupt = Effect.all(Object.values(refs).map((r) => r.interrupt), UNBOUNDED);
1313
2119
  this.subscriberCount = Effect.map(Effect.all(Object.values(refs).map((r) => r.subscriberCount), UNBOUNDED), Array.reduce(0, sum));
1314
2120
  this.getSetDelete = {
1315
- get: this.versioned.asEffect(),
2121
+ get: this.versioned,
1316
2122
  set: (a) => Effect.all(Object.keys(refs).map((k) => set(refs[k], a[k])), UNBOUNDED),
1317
2123
  delete: Effect.map(Effect.all(Object.values(refs).map((r) => reset(r)), UNBOUNDED), Option.all),
1318
2124
  };
@@ -1324,10 +2130,15 @@ class RefSubjectStruct extends YieldableFx {
1324
2130
  return this.versioned.run(sink);
1325
2131
  }
1326
2132
  toEffect() {
1327
- return this.versioned.asEffect();
2133
+ return this.versioned;
1328
2134
  }
1329
2135
  updates(run) {
1330
- return run(this.getSetDelete);
2136
+ const accessEffect = getTransactionAccess(this);
2137
+ return accessEffect
2138
+ ? Effect.flatMap(accessEffect, (transactionAccess) => Option.isSome(transactionAccess)
2139
+ ? runTransaction(transactionAccess.value, run)
2140
+ : Effect.suspend(() => run(this.getSetDelete)))
2141
+ : Effect.suspend(() => run(this.getSetDelete));
1331
2142
  }
1332
2143
  onFailure(cause) {
1333
2144
  return Effect.all(Object.values(this.refs).map((ref) => ref.onFailure(cause)));
@@ -1337,11 +2148,29 @@ class RefSubjectStruct extends YieldableFx {
1337
2148
  }
1338
2149
  }
1339
2150
  function makeStructComputed(refs) {
1340
- return new ComputedImpl(Versioned.struct(refs), Effect.succeed);
2151
+ return new ComputedImpl(versionedInContext(() => Versioned.struct(refs)), Effect.succeed);
1341
2152
  }
1342
2153
  function makeStructFiltered(refs) {
1343
- return new FilteredImpl(Versioned.struct(refs), Effect.succeedSome);
2154
+ return new FilteredImpl(versionedInContext(() => Versioned.struct(refs)), Effect.succeedSome);
1344
2155
  }
2156
+ /**
2157
+ * Lifts an Effect-provided Computed into a Computed facade.
2158
+ *
2159
+ * @remarks
2160
+ * ## Why
2161
+ *
2162
+ * Defers service lookup until each version read, current read, interruption, or Fx observation, so
2163
+ * callers can compose a Context-provided Computed without manually flat-mapping the service Effect.
2164
+ *
2165
+ * ## Ownership and lifetime
2166
+ *
2167
+ * The facade caches neither the resolved Computed nor its value. Each operation runs the supplied
2168
+ * Effect, then delegates to the resolved Computed. Service requirements combine as `R | R2`, source
2169
+ * failures remain `E`, and the observing Scope owns the delegated subscription.
2170
+ *
2171
+ * @since 1.18.0
2172
+ * @category Services
2173
+ */
1345
2174
  export function computedFromService(effect) {
1346
2175
  return new ComputedFromService(effect);
1347
2176
  }
@@ -1360,9 +2189,26 @@ class ComputedFromService extends YieldableFx {
1360
2189
  return Effect.flatMap(this.effect, (c) => c.run(sink));
1361
2190
  }
1362
2191
  toEffect() {
1363
- return Effect.flatMap(this.effect, (c) => c.asEffect());
2192
+ return Effect.flatMap(this.effect, (c) => c);
1364
2193
  }
1365
2194
  }
2195
+ /**
2196
+ * Defers retrieval of a Filtered value from Effect Context while preserving Filtered behavior.
2197
+ *
2198
+ * @remarks
2199
+ * ## Why
2200
+ *
2201
+ * Lets a service-provided Filtered participate directly in Effect reads and Fx observation without
2202
+ * manually flat-mapping the service tag at every use.
2203
+ *
2204
+ * ## Ownership and lifetime
2205
+ *
2206
+ * The filtered from service view retains no independent value. Its Effect read fails with NoSuchElement
2207
+ * while absent; the observing Scope owns and finalizes its Fx subscription.
2208
+ *
2209
+ * @since 1.18.0
2210
+ * @category Services
2211
+ */
1366
2212
  export function filteredFromService(effect) {
1367
2213
  return new FilteredFromService(effect);
1368
2214
  }
@@ -1381,9 +2227,10 @@ class FilteredFromService extends YieldableFx {
1381
2227
  return Effect.flatMap(this.effect, (c) => c.run(sink));
1382
2228
  }
1383
2229
  toEffect() {
1384
- return Effect.flatMap(this.effect, (c) => c.asEffect());
2230
+ return Effect.flatMap(this.effect, (c) => c);
1385
2231
  }
1386
2232
  asComputed() {
1387
2233
  return computedFromService(Effect.map(this.effect, (c) => c.asComputed()));
1388
2234
  }
1389
2235
  }
2236
+ export * from "./Hydration.js";