@typed/fx 1.19.0 → 1.20.1

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 (411) hide show
  1. package/AsyncData/package.json +6 -0
  2. package/Push/package.json +6 -0
  3. package/dist/cjs/AsyncData.js +177 -0
  4. package/dist/cjs/AsyncData.js.map +1 -0
  5. package/dist/cjs/Emitter.js +24 -21
  6. package/dist/cjs/Emitter.js.map +1 -1
  7. package/dist/cjs/Form.js +78 -21
  8. package/dist/cjs/Form.js.map +1 -1
  9. package/dist/cjs/FormEntry.js +75 -48
  10. package/dist/cjs/FormEntry.js.map +1 -1
  11. package/dist/cjs/Fx.js +517 -872
  12. package/dist/cjs/Fx.js.map +1 -1
  13. package/dist/cjs/Guard.js +21 -13
  14. package/dist/cjs/Guard.js.map +1 -1
  15. package/dist/cjs/Idle.js +49 -37
  16. package/dist/cjs/Idle.js.map +1 -1
  17. package/dist/cjs/Match.js +99 -61
  18. package/dist/cjs/Match.js.map +1 -1
  19. package/dist/cjs/Pull.js.map +1 -1
  20. package/dist/cjs/Push.js +168 -0
  21. package/dist/cjs/Push.js.map +1 -0
  22. package/dist/cjs/RefArray.js +32 -30
  23. package/dist/cjs/RefArray.js.map +1 -1
  24. package/dist/cjs/RefChunk.js +26 -24
  25. package/dist/cjs/RefChunk.js.map +1 -1
  26. package/dist/cjs/RefHashMap.js +20 -20
  27. package/dist/cjs/RefHashMap.js.map +1 -1
  28. package/dist/cjs/RefHashSet.js +11 -8
  29. package/dist/cjs/RefHashSet.js.map +1 -1
  30. package/dist/cjs/RefSubject.js +904 -158
  31. package/dist/cjs/RefSubject.js.map +1 -1
  32. package/dist/cjs/Sink.js +588 -62
  33. package/dist/cjs/Sink.js.map +1 -1
  34. package/dist/cjs/Stream.js +15 -10
  35. package/dist/cjs/Stream.js.map +1 -1
  36. package/dist/cjs/Subject.js +156 -55
  37. package/dist/cjs/Subject.js.map +1 -1
  38. package/dist/cjs/TypeId.js +10 -5
  39. package/dist/cjs/TypeId.js.map +1 -1
  40. package/dist/cjs/Typeclass.js +28 -31
  41. package/dist/cjs/Typeclass.js.map +1 -1
  42. package/dist/cjs/Versioned.js +118 -57
  43. package/dist/cjs/Versioned.js.map +1 -1
  44. package/dist/cjs/index.js +44 -8
  45. package/dist/cjs/index.js.map +1 -1
  46. package/dist/cjs/internal/{deferred-ref.js → DeferredRef.js} +45 -13
  47. package/dist/cjs/internal/DeferredRef.js.map +1 -0
  48. package/dist/cjs/internal/UnionToTuple.js +6 -0
  49. package/dist/cjs/internal/UnionToTuple.js.map +1 -0
  50. package/dist/cjs/internal/core.js +1590 -779
  51. package/dist/cjs/internal/core.js.map +1 -1
  52. package/dist/cjs/internal/diff.js +114 -0
  53. package/dist/cjs/internal/diff.js.map +1 -0
  54. package/dist/cjs/internal/effect-loop-operator.js +288 -0
  55. package/dist/cjs/internal/effect-loop-operator.js.map +1 -0
  56. package/dist/cjs/internal/effect-operator.js +46 -37
  57. package/dist/cjs/internal/effect-operator.js.map +1 -1
  58. package/dist/cjs/internal/effect-producer.js +74 -0
  59. package/dist/cjs/internal/effect-producer.js.map +1 -0
  60. package/dist/cjs/internal/helpers.js +158 -128
  61. package/dist/cjs/internal/helpers.js.map +1 -1
  62. package/dist/cjs/internal/keyed.js +136 -173
  63. package/dist/cjs/internal/keyed.js.map +1 -1
  64. package/dist/cjs/internal/loop-operator.js +213 -0
  65. package/dist/cjs/internal/loop-operator.js.map +1 -0
  66. package/dist/cjs/internal/operator.js +79 -0
  67. package/dist/cjs/internal/operator.js.map +1 -0
  68. package/dist/cjs/internal/protos.js +19 -81
  69. package/dist/cjs/internal/protos.js.map +1 -1
  70. package/dist/cjs/internal/provide.js +47 -25
  71. package/dist/cjs/internal/provide.js.map +1 -1
  72. package/dist/cjs/internal/requestIdleCallback.js +5 -5
  73. package/dist/cjs/internal/requestIdleCallback.js.map +1 -1
  74. package/dist/cjs/internal/share.js +12 -15
  75. package/dist/cjs/internal/share.js.map +1 -1
  76. package/dist/cjs/internal/sync-operator.js +50 -22
  77. package/dist/cjs/internal/sync-operator.js.map +1 -1
  78. package/dist/cjs/internal/sync-producer.js +114 -0
  79. package/dist/cjs/internal/sync-producer.js.map +1 -0
  80. package/dist/cjs/internal/withKey.js +45 -51
  81. package/dist/cjs/internal/withKey.js.map +1 -1
  82. package/dist/dts/AsyncData.d.ts +185 -0
  83. package/dist/dts/AsyncData.d.ts.map +1 -0
  84. package/dist/dts/Emitter.d.ts +13 -20
  85. package/dist/dts/Emitter.d.ts.map +1 -1
  86. package/dist/dts/Form.d.ts +45 -28
  87. package/dist/dts/Form.d.ts.map +1 -1
  88. package/dist/dts/FormEntry.d.ts +25 -13
  89. package/dist/dts/FormEntry.d.ts.map +1 -1
  90. package/dist/dts/Fx.d.ts +980 -1390
  91. package/dist/dts/Fx.d.ts.map +1 -1
  92. package/dist/dts/Guard.d.ts +8 -1
  93. package/dist/dts/Guard.d.ts.map +1 -1
  94. package/dist/dts/Idle.d.ts +3 -3
  95. package/dist/dts/Idle.d.ts.map +1 -1
  96. package/dist/dts/Match.d.ts +8 -8
  97. package/dist/dts/Match.d.ts.map +1 -1
  98. package/dist/dts/Pull.d.ts +5 -5
  99. package/dist/dts/Pull.d.ts.map +1 -1
  100. package/dist/dts/Push.d.ts +170 -0
  101. package/dist/dts/Push.d.ts.map +1 -0
  102. package/dist/dts/RefArray.d.ts +21 -23
  103. package/dist/dts/RefArray.d.ts.map +1 -1
  104. package/dist/dts/RefChunk.d.ts +17 -19
  105. package/dist/dts/RefChunk.d.ts.map +1 -1
  106. package/dist/dts/RefHashMap.d.ts +19 -20
  107. package/dist/dts/RefHashMap.d.ts.map +1 -1
  108. package/dist/dts/RefHashSet.d.ts +12 -16
  109. package/dist/dts/RefHashSet.d.ts.map +1 -1
  110. package/dist/dts/RefSubject.d.ts +413 -184
  111. package/dist/dts/RefSubject.d.ts.map +1 -1
  112. package/dist/dts/Sink.d.ts +193 -93
  113. package/dist/dts/Sink.d.ts.map +1 -1
  114. package/dist/dts/Stream.d.ts +7 -1
  115. package/dist/dts/Stream.d.ts.map +1 -1
  116. package/dist/dts/Subject.d.ts +27 -36
  117. package/dist/dts/Subject.d.ts.map +1 -1
  118. package/dist/dts/TypeId.d.ts +10 -0
  119. package/dist/dts/TypeId.d.ts.map +1 -1
  120. package/dist/dts/Typeclass.d.ts +2 -2
  121. package/dist/dts/Typeclass.d.ts.map +1 -1
  122. package/dist/dts/Versioned.d.ts +50 -78
  123. package/dist/dts/Versioned.d.ts.map +1 -1
  124. package/dist/dts/index.d.ts +66 -6
  125. package/dist/dts/index.d.ts.map +1 -1
  126. package/dist/dts/internal/DeferredRef.d.ts +20 -0
  127. package/dist/dts/internal/DeferredRef.d.ts.map +1 -0
  128. package/dist/dts/internal/UnionToTuple.d.ts +6 -0
  129. package/dist/dts/internal/UnionToTuple.d.ts.map +1 -0
  130. package/dist/dts/internal/core.d.ts +218 -450
  131. package/dist/dts/internal/core.d.ts.map +1 -1
  132. package/dist/dts/internal/diff.d.ts +38 -0
  133. package/dist/dts/internal/diff.d.ts.map +1 -0
  134. package/dist/dts/internal/effect-loop-operator.d.ts +34 -0
  135. package/dist/dts/internal/effect-loop-operator.d.ts.map +1 -0
  136. package/dist/dts/internal/effect-operator.d.ts +8 -5
  137. package/dist/dts/internal/effect-operator.d.ts.map +1 -1
  138. package/dist/dts/internal/effect-producer.d.ts +25 -0
  139. package/dist/dts/internal/effect-producer.d.ts.map +1 -0
  140. package/dist/dts/internal/helpers.d.ts +33 -24
  141. package/dist/dts/internal/helpers.d.ts.map +1 -1
  142. package/dist/dts/internal/keyed.d.ts +3 -3
  143. package/dist/dts/internal/keyed.d.ts.map +1 -1
  144. package/dist/dts/internal/loop-operator.d.ts +40 -0
  145. package/dist/dts/internal/loop-operator.d.ts.map +1 -0
  146. package/dist/dts/internal/operator.d.ts +16 -0
  147. package/dist/dts/internal/operator.d.ts.map +1 -0
  148. package/dist/dts/internal/protos.d.ts +16 -43
  149. package/dist/dts/internal/protos.d.ts.map +1 -1
  150. package/dist/dts/internal/provide.d.ts +7 -1
  151. package/dist/dts/internal/provide.d.ts.map +1 -1
  152. package/dist/dts/internal/share.d.ts +12 -9
  153. package/dist/dts/internal/share.d.ts.map +1 -1
  154. package/dist/dts/internal/sync-operator.d.ts +7 -3
  155. package/dist/dts/internal/sync-operator.d.ts.map +1 -1
  156. package/dist/dts/internal/sync-producer.d.ts +36 -0
  157. package/dist/dts/internal/sync-producer.d.ts.map +1 -0
  158. package/dist/dts/internal/withKey.d.ts +3 -3
  159. package/dist/dts/internal/withKey.d.ts.map +1 -1
  160. package/dist/esm/AsyncData.js +151 -0
  161. package/dist/esm/AsyncData.js.map +1 -0
  162. package/dist/esm/Emitter.js +24 -21
  163. package/dist/esm/Emitter.js.map +1 -1
  164. package/dist/esm/Form.js +69 -14
  165. package/dist/esm/Form.js.map +1 -1
  166. package/dist/esm/FormEntry.js +77 -52
  167. package/dist/esm/FormEntry.js.map +1 -1
  168. package/dist/esm/Fx.js +509 -874
  169. package/dist/esm/Fx.js.map +1 -1
  170. package/dist/esm/Guard.js +5 -1
  171. package/dist/esm/Guard.js.map +1 -1
  172. package/dist/esm/Idle.js +49 -39
  173. package/dist/esm/Idle.js.map +1 -1
  174. package/dist/esm/Match.js +103 -63
  175. package/dist/esm/Match.js.map +1 -1
  176. package/dist/esm/Pull.js.map +1 -1
  177. package/dist/esm/Push.js +159 -0
  178. package/dist/esm/Push.js.map +1 -0
  179. package/dist/esm/RefArray.js +32 -30
  180. package/dist/esm/RefArray.js.map +1 -1
  181. package/dist/esm/RefChunk.js +26 -24
  182. package/dist/esm/RefChunk.js.map +1 -1
  183. package/dist/esm/RefHashMap.js +20 -20
  184. package/dist/esm/RefHashMap.js.map +1 -1
  185. package/dist/esm/RefHashSet.js +11 -8
  186. package/dist/esm/RefHashSet.js.map +1 -1
  187. package/dist/esm/RefSubject.js +876 -150
  188. package/dist/esm/RefSubject.js.map +1 -1
  189. package/dist/esm/Sink.js +608 -57
  190. package/dist/esm/Sink.js.map +1 -1
  191. package/dist/esm/Stream.js +13 -9
  192. package/dist/esm/Stream.js.map +1 -1
  193. package/dist/esm/Subject.js +154 -56
  194. package/dist/esm/Subject.js.map +1 -1
  195. package/dist/esm/TypeId.js +9 -4
  196. package/dist/esm/TypeId.js.map +1 -1
  197. package/dist/esm/Typeclass.js +29 -29
  198. package/dist/esm/Typeclass.js.map +1 -1
  199. package/dist/esm/Versioned.js +110 -53
  200. package/dist/esm/Versioned.js.map +1 -1
  201. package/dist/esm/index.js +66 -6
  202. package/dist/esm/index.js.map +1 -1
  203. package/dist/esm/internal/DeferredRef.js +54 -0
  204. package/dist/esm/internal/DeferredRef.js.map +1 -0
  205. package/dist/esm/internal/UnionToTuple.js +2 -0
  206. package/dist/esm/internal/UnionToTuple.js.map +1 -0
  207. package/dist/esm/internal/core.js +1439 -719
  208. package/dist/esm/internal/core.js.map +1 -1
  209. package/dist/esm/internal/diff.js +82 -0
  210. package/dist/esm/internal/diff.js.map +1 -0
  211. package/dist/esm/internal/effect-loop-operator.js +269 -0
  212. package/dist/esm/internal/effect-loop-operator.js.map +1 -0
  213. package/dist/esm/internal/effect-operator.js +44 -37
  214. package/dist/esm/internal/effect-operator.js.map +1 -1
  215. package/dist/esm/internal/effect-producer.js +47 -0
  216. package/dist/esm/internal/effect-producer.js.map +1 -0
  217. package/dist/esm/internal/helpers.js +157 -129
  218. package/dist/esm/internal/helpers.js.map +1 -1
  219. package/dist/esm/internal/keyed.js +128 -139
  220. package/dist/esm/internal/keyed.js.map +1 -1
  221. package/dist/esm/internal/loop-operator.js +186 -0
  222. package/dist/esm/internal/loop-operator.js.map +1 -0
  223. package/dist/esm/internal/operator.js +68 -0
  224. package/dist/esm/internal/operator.js.map +1 -0
  225. package/dist/esm/internal/protos.js +16 -75
  226. package/dist/esm/internal/protos.js.map +1 -1
  227. package/dist/esm/internal/provide.js +33 -25
  228. package/dist/esm/internal/provide.js.map +1 -1
  229. package/dist/esm/internal/requestIdleCallback.js +5 -5
  230. package/dist/esm/internal/requestIdleCallback.js.map +1 -1
  231. package/dist/esm/internal/share.js +12 -12
  232. package/dist/esm/internal/share.js.map +1 -1
  233. package/dist/esm/internal/sync-operator.js +49 -21
  234. package/dist/esm/internal/sync-operator.js.map +1 -1
  235. package/dist/esm/internal/sync-producer.js +88 -0
  236. package/dist/esm/internal/sync-producer.js.map +1 -0
  237. package/dist/esm/internal/withKey.js +46 -47
  238. package/dist/esm/internal/withKey.js.map +1 -1
  239. package/package.json +22 -62
  240. package/src/AsyncData.ts +447 -0
  241. package/src/Emitter.ts +47 -38
  242. package/src/Form.ts +185 -65
  243. package/src/FormEntry.ts +142 -109
  244. package/src/Fx.ts +1682 -1854
  245. package/src/Guard.ts +12 -1
  246. package/src/Idle.ts +76 -62
  247. package/src/Match.ts +149 -93
  248. package/src/Pull.ts +8 -8
  249. package/src/Push.ts +472 -0
  250. package/src/RefArray.ts +53 -51
  251. package/src/RefChunk.ts +44 -41
  252. package/src/RefHashMap.ts +57 -43
  253. package/src/RefHashSet.ts +21 -31
  254. package/src/RefSubject.ts +2003 -446
  255. package/src/Sink.ts +922 -171
  256. package/src/Stream.ts +32 -20
  257. package/src/Subject.ts +236 -87
  258. package/src/TypeId.ts +16 -4
  259. package/src/Typeclass.ts +31 -32
  260. package/src/Versioned.ts +220 -168
  261. package/src/index.ts +78 -6
  262. package/src/internal/DeferredRef.ts +62 -0
  263. package/src/internal/UnionToTuple.ts +11 -0
  264. package/src/internal/core.ts +2491 -1950
  265. package/src/internal/diff.ts +157 -0
  266. package/src/internal/effect-loop-operator.ts +466 -0
  267. package/src/internal/effect-operator.ts +89 -54
  268. package/src/internal/effect-producer.ts +125 -0
  269. package/src/internal/helpers.ts +275 -205
  270. package/src/internal/keyed.ts +192 -241
  271. package/src/internal/loop-operator.ts +266 -0
  272. package/src/internal/operator.ts +87 -0
  273. package/src/internal/protos.ts +29 -104
  274. package/src/internal/provide.ts +48 -40
  275. package/src/internal/requestIdleCallback.ts +5 -6
  276. package/src/internal/share.ts +26 -24
  277. package/src/internal/sync-operator.ts +68 -27
  278. package/src/internal/sync-producer.ts +146 -0
  279. package/src/internal/withKey.ts +64 -74
  280. package/Computed/package.json +0 -6
  281. package/Filtered/package.json +0 -6
  282. package/Model/package.json +0 -6
  283. package/RefAsyncData/package.json +0 -6
  284. package/RefAsyncDataArray/package.json +0 -6
  285. package/RefBoolean/package.json +0 -6
  286. package/RefNumber/package.json +0 -6
  287. package/dist/cjs/Computed.js +0 -115
  288. package/dist/cjs/Computed.js.map +0 -1
  289. package/dist/cjs/Filtered.js +0 -95
  290. package/dist/cjs/Filtered.js.map +0 -1
  291. package/dist/cjs/Model.js +0 -119
  292. package/dist/cjs/Model.js.map +0 -1
  293. package/dist/cjs/RefAsyncData.js +0 -187
  294. package/dist/cjs/RefAsyncData.js.map +0 -1
  295. package/dist/cjs/RefAsyncDataArray.js +0 -38
  296. package/dist/cjs/RefAsyncDataArray.js.map +0 -1
  297. package/dist/cjs/RefBoolean.js +0 -45
  298. package/dist/cjs/RefBoolean.js.map +0 -1
  299. package/dist/cjs/RefNumber.js +0 -49
  300. package/dist/cjs/RefNumber.js.map +0 -1
  301. package/dist/cjs/internal/core-ref-subject.js +0 -254
  302. package/dist/cjs/internal/core-ref-subject.js.map +0 -1
  303. package/dist/cjs/internal/core-subject.js +0 -108
  304. package/dist/cjs/internal/core-subject.js.map +0 -1
  305. package/dist/cjs/internal/deferred-ref.js.map +0 -1
  306. package/dist/cjs/internal/effect-primitive.js +0 -47
  307. package/dist/cjs/internal/effect-primitive.js.map +0 -1
  308. package/dist/cjs/internal/fx-effect-proto.js +0 -58
  309. package/dist/cjs/internal/fx-effect-proto.js.map +0 -1
  310. package/dist/cjs/internal/fx-primitive.js +0 -193
  311. package/dist/cjs/internal/fx-primitive.js.map +0 -1
  312. package/dist/cjs/internal/fx.js +0 -240
  313. package/dist/cjs/internal/fx.js.map +0 -1
  314. package/dist/cjs/internal/matchers.js +0 -34
  315. package/dist/cjs/internal/matchers.js.map +0 -1
  316. package/dist/cjs/internal/run.js +0 -54
  317. package/dist/cjs/internal/run.js.map +0 -1
  318. package/dist/cjs/internal/schema-ref-subject.js +0 -132
  319. package/dist/cjs/internal/schema-ref-subject.js.map +0 -1
  320. package/dist/cjs/internal/versioned-transform.js +0 -46
  321. package/dist/cjs/internal/versioned-transform.js.map +0 -1
  322. package/dist/dts/Computed.d.ts +0 -106
  323. package/dist/dts/Computed.d.ts.map +0 -1
  324. package/dist/dts/Filtered.d.ts +0 -97
  325. package/dist/dts/Filtered.d.ts.map +0 -1
  326. package/dist/dts/Model.d.ts +0 -200
  327. package/dist/dts/Model.d.ts.map +0 -1
  328. package/dist/dts/RefAsyncData.d.ts +0 -236
  329. package/dist/dts/RefAsyncData.d.ts.map +0 -1
  330. package/dist/dts/RefAsyncDataArray.d.ts +0 -56
  331. package/dist/dts/RefAsyncDataArray.d.ts.map +0 -1
  332. package/dist/dts/RefBoolean.d.ts +0 -47
  333. package/dist/dts/RefBoolean.d.ts.map +0 -1
  334. package/dist/dts/RefNumber.d.ts +0 -48
  335. package/dist/dts/RefNumber.d.ts.map +0 -1
  336. package/dist/dts/internal/core-ref-subject.d.ts +0 -100
  337. package/dist/dts/internal/core-ref-subject.d.ts.map +0 -1
  338. package/dist/dts/internal/core-subject.d.ts +0 -5
  339. package/dist/dts/internal/core-subject.d.ts.map +0 -1
  340. package/dist/dts/internal/deferred-ref.d.ts +0 -12
  341. package/dist/dts/internal/deferred-ref.d.ts.map +0 -1
  342. package/dist/dts/internal/effect-primitive.d.ts +0 -6
  343. package/dist/dts/internal/effect-primitive.d.ts.map +0 -1
  344. package/dist/dts/internal/fx-effect-proto.d.ts +0 -30
  345. package/dist/dts/internal/fx-effect-proto.d.ts.map +0 -1
  346. package/dist/dts/internal/fx-primitive.d.ts +0 -109
  347. package/dist/dts/internal/fx-primitive.d.ts.map +0 -1
  348. package/dist/dts/internal/fx.d.ts +0 -245
  349. package/dist/dts/internal/fx.d.ts.map +0 -1
  350. package/dist/dts/internal/matchers.d.ts +0 -33
  351. package/dist/dts/internal/matchers.d.ts.map +0 -1
  352. package/dist/dts/internal/run.d.ts +0 -8
  353. package/dist/dts/internal/run.d.ts.map +0 -1
  354. package/dist/dts/internal/schema-ref-subject.d.ts +0 -5
  355. package/dist/dts/internal/schema-ref-subject.d.ts.map +0 -1
  356. package/dist/dts/internal/versioned-transform.d.ts +0 -17
  357. package/dist/dts/internal/versioned-transform.d.ts.map +0 -1
  358. package/dist/esm/Computed.js +0 -103
  359. package/dist/esm/Computed.js.map +0 -1
  360. package/dist/esm/Filtered.js +0 -83
  361. package/dist/esm/Filtered.js.map +0 -1
  362. package/dist/esm/Model.js +0 -100
  363. package/dist/esm/Model.js.map +0 -1
  364. package/dist/esm/RefAsyncData.js +0 -163
  365. package/dist/esm/RefAsyncData.js.map +0 -1
  366. package/dist/esm/RefAsyncDataArray.js +0 -27
  367. package/dist/esm/RefAsyncDataArray.js.map +0 -1
  368. package/dist/esm/RefBoolean.js +0 -31
  369. package/dist/esm/RefBoolean.js.map +0 -1
  370. package/dist/esm/RefNumber.js +0 -35
  371. package/dist/esm/RefNumber.js.map +0 -1
  372. package/dist/esm/internal/core-ref-subject.js +0 -242
  373. package/dist/esm/internal/core-ref-subject.js.map +0 -1
  374. package/dist/esm/internal/core-subject.js +0 -90
  375. package/dist/esm/internal/core-subject.js.map +0 -1
  376. package/dist/esm/internal/deferred-ref.js +0 -23
  377. package/dist/esm/internal/deferred-ref.js.map +0 -1
  378. package/dist/esm/internal/effect-primitive.js +0 -41
  379. package/dist/esm/internal/effect-primitive.js.map +0 -1
  380. package/dist/esm/internal/fx-effect-proto.js +0 -43
  381. package/dist/esm/internal/fx-effect-proto.js.map +0 -1
  382. package/dist/esm/internal/fx-primitive.js +0 -175
  383. package/dist/esm/internal/fx-primitive.js.map +0 -1
  384. package/dist/esm/internal/fx.js +0 -216
  385. package/dist/esm/internal/fx.js.map +0 -1
  386. package/dist/esm/internal/matchers.js +0 -38
  387. package/dist/esm/internal/matchers.js.map +0 -1
  388. package/dist/esm/internal/run.js +0 -32
  389. package/dist/esm/internal/run.js.map +0 -1
  390. package/dist/esm/internal/schema-ref-subject.js +0 -121
  391. package/dist/esm/internal/schema-ref-subject.js.map +0 -1
  392. package/dist/esm/internal/versioned-transform.js +0 -37
  393. package/dist/esm/internal/versioned-transform.js.map +0 -1
  394. package/src/Computed.ts +0 -289
  395. package/src/Filtered.ts +0 -274
  396. package/src/Model.ts +0 -483
  397. package/src/RefAsyncData.ts +0 -547
  398. package/src/RefAsyncDataArray.ts +0 -135
  399. package/src/RefBoolean.ts +0 -71
  400. package/src/RefNumber.ts +0 -77
  401. package/src/internal/core-ref-subject.ts +0 -528
  402. package/src/internal/core-subject.ts +0 -143
  403. package/src/internal/deferred-ref.ts +0 -26
  404. package/src/internal/effect-primitive.ts +0 -230
  405. package/src/internal/fx-effect-proto.ts +0 -56
  406. package/src/internal/fx-primitive.ts +0 -223
  407. package/src/internal/fx.ts +0 -619
  408. package/src/internal/matchers.ts +0 -83
  409. package/src/internal/run.ts +0 -51
  410. package/src/internal/schema-ref-subject.ts +0 -163
  411. package/src/internal/versioned-transform.ts +0 -48
package/src/RefSubject.ts CHANGED
@@ -1,115 +1,110 @@
1
1
  /**
2
- * A RefSubject is the core abstraction for keeping state and subscribing to its
3
- * changes over time.
4
- *
5
- * @since 1.18.0
2
+ * A RefSubject is a Subject that can be used to read and write a value.
3
+ * @since 1.20.0
6
4
  */
7
5
 
8
- import type { Schema } from "@effect/schema"
9
6
  import * as C from "@typed/context"
10
- import type { Stream, SubscriptionRef } from "effect"
11
- import { Cause, Exit, identity } from "effect"
7
+ import type { Equivalence, FiberId, Runtime } from "effect"
8
+ import { Fiber } from "effect"
9
+ import * as Boolean from "effect/Boolean"
10
+ import * as Cause from "effect/Cause"
12
11
  import * as Effect from "effect/Effect"
13
- import { equals } from "effect/Equal"
14
- import type { Equivalence } from "effect/Equivalence"
15
- import { dual } from "effect/Function"
16
- import type * as Layer from "effect/Layer"
12
+ import * as Equal from "effect/Equal"
13
+ import * as ExecutionStrategy from "effect/ExecutionStrategy"
14
+ import * as Exit from "effect/Exit"
15
+ import { dual, identity } from "effect/Function"
16
+ import * as Layer from "effect/Layer"
17
+ import { sum } from "effect/Number"
17
18
  import * as Option from "effect/Option"
18
- import type * as Scope from "effect/Scope"
19
- import { Computed, fromTag } from "./Computed.js"
20
- import { Filtered } from "./Filtered.js"
21
- import type * as Fx from "./Fx.js"
22
- import * as coreRefSubject from "./internal/core-ref-subject.js"
23
- import { fromStream, provide, skipRepeatsWith } from "./internal/core.js"
24
- import { exit, fromFxEffect } from "./internal/fx.js"
19
+ import * as ReadonlyArray from "effect/ReadonlyArray"
20
+ import * as Scope from "effect/Scope"
21
+ import type { Fx } from "./Fx.js"
22
+ import * as core from "./internal/core.js"
23
+ import * as DeferredRef from "./internal/DeferredRef.js"
24
+ import { getExitEquivalence, matchEffectPrimitive, withScope } from "./internal/helpers.js"
25
25
  import { FxEffectBase } from "./internal/protos.js"
26
- import { fromRefSubject, toRefSubject } from "./internal/schema-ref-subject.js"
27
- import type * as Subject from "./Subject.js"
28
- import { ComputedTypeId, RefSubjectTypeId } from "./TypeId.js"
26
+ import { runtimeToLayer } from "./internal/provide.js"
27
+ import * as share from "./internal/share.js"
28
+ import type { UnionToTuple } from "./internal/UnionToTuple.js"
29
+ import * as Sink from "./Sink.js"
30
+ import * as Subject from "./Subject.js"
31
+ import { ComputedTypeId, FilteredTypeId, RefSubjectTypeId, TypeId } from "./TypeId.js"
29
32
  import * as Versioned from "./Versioned.js"
30
33
 
34
+ const UNBOUNDED = { concurrency: "unbounded" } as const
35
+
31
36
  /**
32
- * A RefSubject is a Subject that has a current value that can be read and updated.
33
- * @since 1.18.0
34
- * @category models
37
+ * A Computed is essentially a readonly RefSubject.
38
+ * @since 1.20.0
35
39
  */
36
- export interface RefSubject<R, in out E, in out A> extends Computed<R, E, A>, Subject.Subject<R, E, A> {
37
- readonly [RefSubjectTypeId]: RefSubjectTypeId
38
-
39
- /**
40
- * Get the current value of this RefSubject. If the RefSubject has not been initialized
41
- * then the initial value will be computed and returned. Concurrent calls to `get` will
42
- * only compute the initial value once.
43
- * @since 1.18.0
44
- */
45
- readonly get: Effect.Effect<R, E, A>
46
-
47
- /**
48
- * Set the current value of this RefSubject.
49
- * @since 1.18.0
50
- */
51
- readonly set: (a: A) => Effect.Effect<R, never, A>
52
-
53
- /**
54
- * Modify the current value of this RefSubject using the provided function.
55
- * @since 1.18.0
56
- */
57
- readonly update: (f: (a: A) => A) => Effect.Effect<R, E, A>
40
+ export interface Computed<out R, out E, out A> extends Versioned.Versioned<R, E, R | Scope.Scope, E, A, R, E, A> {
41
+ readonly [ComputedTypeId]: ComputedTypeId
42
+ }
58
43
 
44
+ /**
45
+ * @since 1.20.0
46
+ */
47
+ export namespace Computed {
59
48
  /**
60
- * Modify the current value of this RefSubject and compute a new value.
61
- * @since 1.18.0
49
+ * @since 1.20.0
62
50
  */
63
- readonly modify: <B>(f: (a: A) => readonly [B, A]) => Effect.Effect<R, E, B>
51
+ export type Any =
52
+ | Computed<any, any, any>
53
+ | Computed<never, any, any>
54
+ | Computed<any, never, any>
55
+ | Computed<never, never, any>
56
+ }
64
57
 
65
- /**
66
- * Delete the current value of this RefSubject. If it was not initialized the Option.none will be returned.
67
- * Otherwise the current value will be returned as an Option.some and the RefSubject will be uninitialized.
68
- * If there are existing subscribers to this RefSubject then the RefSubject will be re-initialized.
69
- * @since 1.18.0
70
- */
71
- readonly delete: Effect.Effect<R, never, Option.Option<A>>
58
+ /**
59
+ * A Filtered is essentially a readonly RefSubject that may have its values filtered out.
60
+ * @since 1.20.0
61
+ */
62
+ export interface Filtered<out R, out E, out A>
63
+ extends Versioned.Versioned<R, E, R | Scope.Scope, E, A, R, E | Cause.NoSuchElementException, A>
64
+ {
65
+ readonly [FilteredTypeId]: FilteredTypeId
72
66
 
73
67
  /**
74
- * Modify the current value of this RefSubject and compute a new value using the provided effectful function.
75
- * @since 1.18.0
68
+ * @since 1.20.0
76
69
  */
77
- readonly modifyEffect: <R2, E2, B>(
78
- f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>
79
- ) => Effect.Effect<R | R2, E | E2, B>
70
+ asComputed(): Computed<R, E, Option.Option<A>>
71
+ }
80
72
 
73
+ /**
74
+ * @since 1.20.0
75
+ */
76
+ export namespace Filtered {
81
77
  /**
82
- * Modify the current value of this RefSubject using the provided effectful function.
83
- * @since 1.18.0
78
+ * @since 1.20.0
84
79
  */
85
- readonly updateEffect: <R2, E2>(f: (a: A) => Effect.Effect<R2, E2, A>) => Effect.Effect<R | R2, E | E2, A>
80
+ export type Any =
81
+ | Filtered<any, any, any>
82
+ | Filtered<never, any, any>
83
+ | Filtered<any, never, any>
84
+ | Filtered<never, never, any>
85
+ }
86
86
 
87
- /**
88
- * Modify the current value of this RefSubject and compute a new value using the provided effectful function.
89
- * The key difference is it will allow running a workflow and setting the value multiple times. Optionally,
90
- * another function can be provided to change the value
91
- * @since 1.18.0
92
- */
93
- readonly runUpdate: <R2, E2, B, R3 = never, E3 = never>(
94
- updates: (
95
- get: RefSubject<R, E, A>["get"],
96
- set: RefSubject<R, E, A>["set"]
97
- ) => Effect.Effect<R2, E2, B>,
98
- onInterrupt?: (a: A) => Effect.Effect<R3, E3, A>
99
- ) => Effect.Effect<R | R2 | R3, E | E2 | E3, B>
87
+ /**
88
+ * A RefSubject is a Subject that can be used to read and write a value.
89
+ * @since 1.20.0
90
+ */
91
+ export interface RefSubject<out R, in out E, in out A> extends Computed<R, E, A>, Subject.Subject<R, E, A> {
92
+ readonly [RefSubjectTypeId]: RefSubjectTypeId
100
93
 
101
94
  /**
102
- * Interrupt the current Fibers.
95
+ * @since 1.20.0
103
96
  */
104
- readonly interrupt: Effect.Effect<R, never, void>
97
+ readonly runUpdates: <R2, E2, B>(
98
+ f: (ref: GetSetDelete<R, E, A>) => Effect.Effect<R2, E2, B>
99
+ ) => Effect.Effect<R | R2, E2, B>
105
100
  }
106
101
 
107
102
  /**
108
- * @since 1.18.0
103
+ * @since 1.20.0
109
104
  */
110
105
  export namespace RefSubject {
111
106
  /**
112
- * @since 1.18.0
107
+ * @since 1.20.0
113
108
  */
114
109
  export type Any =
115
110
  | RefSubject<any, any, any>
@@ -118,43 +113,17 @@ export namespace RefSubject {
118
113
  | RefSubject<never, never, any>
119
114
 
120
115
  /**
121
- * A Contextual wrapper around a RefSubject
122
- * @since 1.18.0
123
- * @category models
116
+ * @since 1.20.0
124
117
  */
125
118
  export interface Tagged<I, E, A> extends RefSubject<I, E, A> {
126
- readonly tag: C.Tagged<I, RefSubject<never, E, A>>
127
-
128
- /**
129
- * Make a layer initializing a RefSubject
130
- * @since 1.18.0
131
- */
132
- readonly make: <R = never>(
133
- fx: Exclude<Fx.FxInput<R, E, A>, Iterable<A>>,
134
- eq?: Equivalence<A>
135
- ) => Layer.Layer<R, never, I>
136
-
137
- /**
138
- * Make a layer initializing a RefSubject
139
- * @since 1.18.0
140
- */
141
- readonly of: (value: A, eq?: Equivalence<A>) => Layer.Layer<never, never, I>
142
-
143
119
  /**
144
- * Provide an implementation of this RefSubject
145
- * @since 1.18.0
120
+ * @since 1.20.0
146
121
  */
147
- readonly provide: <R2>(fx: Fx.FxInput<R2, E, A>, eq?: Equivalence<A>) => <R3, E3, C>(
148
- effect: Effect.Effect<R3, E3, C>
149
- ) => Effect.Effect<R2 | Exclude<R3, I> | Scope.Scope, E | E3, C>
150
-
122
+ readonly tag: C.Tagged<I, RefSubject<never, E, A>>
151
123
  /**
152
- * Provide an implementation of this RefSubject
153
- * @since 1.18.0
124
+ * @since 1.20.0
154
125
  */
155
- readonly provideFx: <R2>(fx: Fx.FxInput<R2, E, A>, eq?: Equivalence<A>) => <R3, E3, C>(
156
- effect: Fx.Fx<R3, E3, C>
157
- ) => Fx.Fx<R2 | Exclude<R3, I> | Scope.Scope, E | E3, C>
126
+ readonly make: <R>(fxOrEffect: Fx<R, E, A> | Effect.Effect<R, E, A>) => Layer.Layer<R, never, I>
158
127
  }
159
128
 
160
129
  /**
@@ -162,482 +131,2070 @@ export namespace RefSubject {
162
131
  * @since 1.18.0
163
132
  * @category models
164
133
  */
165
- export interface Derived<R0, R, E, A> extends RefSubject<R, E, A> {
166
- readonly persist: Effect.Effect<R0, never, void>
134
+ export interface Derived<R, E, A> extends RefSubject<R, E, A> {
135
+ readonly persist: Effect.Effect<R, never, void>
167
136
  }
168
137
 
169
138
  /**
170
- * Extract the Identifier from a RefSubject
171
- * @since 1.18.0
139
+ * @since 1.20.0
172
140
  */
173
- export type Context<T> = T extends RefSubject<infer I, infer _, infer __> ? I : never
141
+ export type Context<T> = T extends RefSubject<infer R, infer _E, infer _A> ? R : never
174
142
 
175
143
  /**
176
- * Extract the Error from a RefSubject
177
- * @since 1.18.0
144
+ * @since 1.20.0
178
145
  */
179
- export type Error<T> = T extends RefSubject<infer _, infer E, infer __> ? E : never
146
+
147
+ export type Error<T> = T extends RefSubject<infer _R, infer E, infer _A> ? E : never
180
148
 
181
149
  /**
182
- * Extract the State from a RefSubject
183
- * @since 1.18.0
150
+ * @since 1.20.0
151
+ */
152
+ export type Success<T> = T extends RefSubject<infer _R, infer _E, infer A> ? A : never
153
+
154
+ /**
155
+ * @since 1.20.0
184
156
  */
185
- export type Success<T> = T extends RefSubject<infer _, infer __, infer S> ? S : never
157
+ export type Identifier<T> = T extends RefSubject.Tagged<infer R, infer _E, infer _A> ? R : never
186
158
  }
187
159
 
188
160
  /**
189
- * Extract the Identifier from a RefSubject
190
- * @since 1.18.0
161
+ * @since 1.20.0
191
162
  */
192
163
  export type Context<T> = RefSubject.Context<T>
193
164
 
194
165
  /**
195
- * Extract the Error from a RefSubject
196
- * @since 1.18.0
166
+ * @since 1.20.0
197
167
  */
198
168
  export type Error<T> = RefSubject.Error<T>
199
169
 
200
170
  /**
201
- * Extract the State from a RefSubject
202
- * @since 1.18.0
171
+ * @since 1.20.0
203
172
  */
204
173
  export type Success<T> = RefSubject.Success<T>
205
174
 
206
175
  /**
207
- * Construct a RefSubject with a lazily initialized value.
208
- * @since 1.18.0
209
- * @category constructors
176
+ * @since 1.20.0
177
+ */
178
+ export type Identifier<T> = RefSubject.Identifier<T>
179
+
180
+ /**
181
+ * @since 1.20.0
182
+ */
183
+ export interface RefSubjectOptions<A> {
184
+ readonly eq?: Equivalence.Equivalence<A>
185
+ readonly replay?: number
186
+ readonly executionStrategy?: ExecutionStrategy.ExecutionStrategy
187
+ }
188
+
189
+ /**
190
+ * @since 1.20.0
210
191
  */
211
192
  export function fromEffect<R, E, A>(
212
- initial: Effect.Effect<R, E, A>,
213
- eq?: Equivalence<A>
193
+ effect: Effect.Effect<R, E, A>,
194
+ options?: RefSubjectOptions<A>
214
195
  ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A>> {
215
- return coreRefSubject.fromEffect(initial, eq)
196
+ return Effect.map(makeCore(effect, options), (core) => new RefSubjectImpl(core))
216
197
  }
217
198
 
218
199
  /**
219
- * Construct a RefSubject from a synchronous value.
220
- * @since 1.18.0
221
- * @category constructors
200
+ * @since 1.20.0
222
201
  */
223
- export function of<A, E = never>(
224
- initial: A,
225
- eq?: Equivalence<A>
226
- ): Effect.Effect<Scope.Scope, never, RefSubject<never, E, A>> {
227
- return fromEffect<never, E, A>(Effect.succeed(initial), eq)
202
+ export function fromFx<R, E, A>(
203
+ fx: Fx<R, E, A>,
204
+ options?: RefSubjectOptions<A>
205
+ ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A>> {
206
+ return DeferredRef.make<E, A>(getExitEquivalence(options?.eq ?? Equal.equals)).pipe(
207
+ Effect.bindTo("deferredRef"),
208
+ Effect.bind("core", ({ deferredRef }) => makeCore(deferredRef, options)),
209
+ Effect.tap(({ core, deferredRef }) =>
210
+ Effect.forkIn(
211
+ fx.run(Sink.make(
212
+ (cause) =>
213
+ Effect.flatMap(Effect.sync(() => deferredRef.done(Exit.failCause(cause))), () =>
214
+ core.subject.onFailure(cause)),
215
+ (value) =>
216
+ Effect.flatMap(Effect.sync(() => deferredRef.done(Exit.succeed(value))), () => setCore(core, value))
217
+ )),
218
+ core.scope
219
+ )
220
+ ),
221
+ Effect.map(({ core }) => new RefSubjectImpl(core))
222
+ )
228
223
  }
229
224
 
230
225
  /**
231
- * Construct a RefSubject from a synchronous value.
232
- * @since 1.18.0
233
- * @category constructors
226
+ * @since 1.20.0
234
227
  */
235
- export function sync<A, E = never>(
236
- initial: () => A,
237
- eq?: Equivalence<A>
238
- ): Effect.Effect<Scope.Scope, never, RefSubject<never, E, A>> {
239
- return fromEffect<never, E, A>(Effect.sync(initial), eq)
228
+ export function fromRefSubject<R, E, A>(
229
+ ref: RefSubject<R, E, A>,
230
+ options?: RefSubjectOptions<A>
231
+ ): Effect.Effect<R | Scope.Scope, never, RefSubject.Derived<never, E, A>> {
232
+ return DeferredRef.make<E, A>(getExitEquivalence(options?.eq ?? Equal.equals)).pipe(
233
+ Effect.bindTo("deferredRef"),
234
+ Effect.bind("core", ({ deferredRef }) => makeCore<R, E, A>(deferredRef, options)),
235
+ Effect.tap(({ core, deferredRef }) =>
236
+ Effect.forkIn(
237
+ ref.run(Sink.make(
238
+ (cause) => Effect.sync(() => deferredRef.done(Exit.failCause(cause))),
239
+ (value) => Effect.sync(() => deferredRef.done(Exit.succeed(value)))
240
+ )),
241
+ core.scope
242
+ )
243
+ ),
244
+ Effect.map(({ core }) =>
245
+ new DerivedImpl(
246
+ core,
247
+ persistCore(ref, core)
248
+ )
249
+ )
250
+ )
251
+ }
252
+
253
+ function persistCore<R, E, A, R2>(ref: RefSubject<R, E, A>, core: RefSubjectCore<R, E, A, R2>) {
254
+ // Log any errors that fail to persist, but don't fail the consumer
255
+ return Effect.ignoreLogged(Effect.provide(Effect.flatMap(core.deferredRef, (value) => set(ref, value)), core.context))
240
256
  }
241
257
 
242
258
  /**
243
- * Construct a RefSubject from any Fx value.
244
- *
245
- * @since 1.18.0
246
- * @category constructors
247
- */
248
- export function make<R, E, A>(
249
- fx: Effect.Effect<R, E, A>,
250
- eq?: Equivalence<A>
251
- ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A>>
252
- export function make<R, E, A>(
253
- fx: Fx.FxInput<R, E, A>,
254
- eq?: Equivalence<A>
255
- ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A>>
256
-
257
- export function make<R, E, A>(
258
- fx: Fx.FxInput<R, E, A>,
259
- eq?: Equivalence<A>
260
- ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A>> {
261
- return coreRefSubject.make(fx, eq)
259
+ * @since 1.20.0
260
+ */
261
+ export const make: {
262
+ <R, E, A>(
263
+ ref: RefSubject<R, E, A>,
264
+ options?: RefSubjectOptions<A>
265
+ ): Effect.Effect<R | Scope.Scope, never, RefSubject.Derived<never, E, A>>
266
+
267
+ <R, E, A>(
268
+ fxOrEffect: Fx<R, E, A> | Effect.Effect<R, E, A>,
269
+ options?: RefSubjectOptions<A>
270
+ ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A>>
271
+
272
+ <R, E, A>(
273
+ fxOrEffect: Fx<R, E, A> | Effect.Effect<R, E, A> | RefSubject<R, E, A>,
274
+ options?: RefSubjectOptions<A>
275
+ ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A> | RefSubject.Derived<never, E, A>>
276
+ } = function make<R, E, A>(
277
+ fxOrEffect: Fx<R, E, A> | Effect.Effect<R, E, A> | RefSubject<R, E, A>,
278
+ options?: RefSubjectOptions<A>
279
+ ): Effect.Effect<R | Scope.Scope, never, any> {
280
+ if (RefSubjectTypeId in fxOrEffect) return fromRefSubject(fxOrEffect as RefSubject<R, E, A>, options)
281
+ else if (TypeId in fxOrEffect) return fromFx(fxOrEffect, options)
282
+ else return fromEffect(fxOrEffect, options)
262
283
  }
263
284
 
264
285
  /**
265
- * Create a contextual wrapper around a RefSubject while maintaing the full API of
266
- * a Ref Subject.
267
- * @since 1.18.0
268
- * @category constructors
269
- */
270
- export function tagged<A>(defaultEq?: Equivalence<A>): {
271
- <const I extends C.IdentifierConstructor<any>>(
272
- identifier: (id: typeof C.id) => I
273
- ): RefSubject.Tagged<C.IdentifierOf<I>, never, A>
274
- <const I>(identifier: I | string): RefSubject.Tagged<C.IdentifierOf<I>, never, A>
275
- }
276
- export function tagged<E, A>(defaultEq?: Equivalence<A>): {
277
- <const I extends C.IdentifierConstructor<any>>(
278
- identifier: (id: typeof C.id) => I
279
- ): RefSubject.Tagged<C.IdentifierOf<I>, E, A>
280
- <const I>(identifier: I | string): RefSubject.Tagged<C.IdentifierOf<I>, E, A>
281
- }
282
-
283
- export function tagged(defaultEq?: Equivalence<any>): {
284
- <const I extends C.IdentifierConstructor<any>>(
285
- identifier: (id: typeof C.id) => I
286
- ): RefSubject.Tagged<C.IdentifierOf<I>, any, any> | RefSubject.Tagged<C.IdentifierOf<I>, never, any>
287
- <const I>(
288
- identifier: I | string
289
- ): RefSubject.Tagged<C.IdentifierOf<I>, any, any> | RefSubject.Tagged<C.IdentifierOf<I>, never, any>
290
- } {
291
- function makeTagged<const I extends C.IdentifierFactory<any>>(
292
- identifier: I
293
- ): RefSubject.Tagged<C.IdentifierOf<I>, any, any>
294
- function makeTagged<const I>(identifier: I): RefSubject.Tagged<C.IdentifierOf<I>, any, any>
295
- function makeTagged<const I>(identifier: I): RefSubject.Tagged<C.IdentifierOf<I>, any, any> {
296
- return new ContextImpl(C.Tagged<I, RefSubject<never, any, any>>(identifier), defaultEq) as any
297
- }
286
+ * @since 1.20.0
287
+ */
288
+ export function of<A, E = never>(
289
+ a: A,
290
+ options?: RefSubjectOptions<A>
291
+ ): Effect.Effect<Scope.Scope, never, RefSubject<never, E, A>> {
292
+ return Effect.acquireRelease(
293
+ withScopeAndFiberId(
294
+ (scope, id) =>
295
+ unsafeMake<E, A>({
296
+ id,
297
+ initial: Effect.succeed(a),
298
+ initialValue: a,
299
+ options,
300
+ scope
301
+ }),
302
+ options?.executionStrategy ?? ExecutionStrategy.sequential
303
+ ),
304
+ (ref) => ref.interrupt
305
+ )
306
+ }
298
307
 
299
- return makeTagged
308
+ const withScopeAndFiberId = <R, E, A>(
309
+ f: (scope: Scope.CloseableScope, id: FiberId.FiberId) => Effect.Effect<R, E, A>,
310
+ strategy: ExecutionStrategy.ExecutionStrategy
311
+ ) => Effect.fiberIdWith((id) => withScope((scope) => f(scope, id), strategy))
312
+
313
+ const emptyContext = C.empty()
314
+
315
+ /**
316
+ * @since 1.20.0
317
+ */
318
+ export function unsafeMake<E, A>(
319
+ params: {
320
+ readonly id: FiberId.FiberId
321
+ readonly initial: Effect.Effect<never, E, A>
322
+ readonly options?: RefSubjectOptions<A> | undefined
323
+ readonly scope: Scope.CloseableScope
324
+ readonly initialValue?: A
325
+ }
326
+ ): Effect.Effect<never, never, RefSubject<never, E, A>> {
327
+ const { id, initial, options, scope } = params
328
+ return Effect.suspend(() => {
329
+ const core = unsafeMakeCore(initial, id, emptyContext, scope, options)
330
+
331
+ // Sometimes we might be instantiating directly from a known value
332
+ // Here we seed the value and ensure the subject has it as well for re-broadcasting
333
+ if ("initialValue" in params) {
334
+ core.deferredRef.done(Exit.succeed(params.initialValue))
335
+ return Effect.map(core.subject.onSuccess(params.initialValue), () => new RefSubjectImpl(core))
336
+ }
337
+
338
+ return Effect.succeed(new RefSubjectImpl(core))
339
+ })
300
340
  }
301
341
 
302
- class ContextImpl<I, E, A> extends FxEffectBase<I, E, A, I, E, A> implements RefSubject<I, E, A> {
303
- readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
342
+ class RefSubjectImpl<R, E, A, R2> extends FxEffectBase<Exclude<R, R2> | Scope.Scope, E, A, Exclude<R, R2>, E, A>
343
+ implements RefSubject<Exclude<R, R2>, E, A>
344
+ {
304
345
  readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
346
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
347
+
348
+ readonly version: Effect.Effect<never, never, number>
349
+ readonly interrupt: Effect.Effect<Exclude<R, R2>, never, void>
350
+ readonly subscriberCount: Effect.Effect<Exclude<R, R2>, never, number>
305
351
 
306
- readonly version: RefSubject<I, E, A>["version"]
307
- readonly subscriberCount: RefSubject<I, E, A>["subscriberCount"]
308
- readonly get: RefSubject<I, E, A>["get"]
309
- readonly delete: RefSubject<I, E, A>["delete"]
310
- readonly interrupt: RefSubject<I, E, A>["interrupt"]
352
+ private readonly getSetDelete: GetSetDelete<Exclude<R, R2>, E, A>
311
353
 
312
- constructor(readonly tag: C.Tagged<I, RefSubject<never, E, A>>, readonly defaultEq?: Equivalence<A>) {
354
+ constructor(
355
+ private readonly core: RefSubjectCore<R, E, A, R2>
356
+ ) {
313
357
  super()
314
358
 
315
- this.version = tag.withEffect((ref) => ref.version)
316
- this.subscriberCount = tag.withEffect((ref) => ref.subscriberCount)
317
- this.get = tag.withEffect((ref) => ref.get)
318
- this.delete = tag.withEffect((ref) => ref.delete)
319
- this.interrupt = tag.withEffect((r) => r.interrupt)
359
+ this.version = Effect.sync(() => core.deferredRef.version)
360
+ this.interrupt = Effect.provide(interruptCore(core), core.context)
361
+ this.subscriberCount = Effect.provide(core.subject.subscriberCount, core.context)
362
+ this.getSetDelete = getSetDelete(core)
363
+
364
+ this.runUpdates = this.runUpdates.bind(this)
365
+ this.onSuccess = this.onSuccess.bind(this)
366
+ this.onFailure = this.onFailure.bind(this)
320
367
  }
321
368
 
322
- protected toFx(): Fx.Fx<I, E, A> {
323
- return fromFxEffect(this.tag)
369
+ run<R3>(sink: Sink.Sink<R3, E, A>): Effect.Effect<Exclude<R, R2> | R3 | Scope.Scope, never, unknown> {
370
+ return Effect.matchCauseEffect(this.toEffect(), {
371
+ onFailure: (cause) => sink.onFailure(cause),
372
+ onSuccess: () => Effect.provide(this.core.subject.run(sink), this.core.context)
373
+ })
324
374
  }
325
375
 
326
- protected toEffect(): Effect.Effect<I, E, A> {
327
- return this.get
376
+ runUpdates<R3, E3, B>(
377
+ run: (ref: GetSetDelete<Exclude<R, R2>, E, A>) => Effect.Effect<R3, E3, B>,
378
+ lock: boolean = true
379
+ ) {
380
+ return lock ? this.core.semaphore.withPermits(1)(run(this.getSetDelete)) : run(this.getSetDelete)
328
381
  }
329
382
 
330
- runUpdate: RefSubject<I, E, A>["runUpdate"] = (
331
- f,
332
- onInterrupt
333
- ) => this.tag.withEffect((ref) => ref.runUpdate(f, onInterrupt))
383
+ onSuccess(value: A): Effect.Effect<Exclude<R, R2>, never, unknown> {
384
+ return setCore(this.core, value)
385
+ }
334
386
 
335
- modifyEffect: <R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>) => Effect.Effect<I | R2, E | E2, B> = (
336
- f
337
- ) => this.tag.withEffect((ref) => ref.modifyEffect(f))
387
+ onFailure(cause: Cause.Cause<E>): Effect.Effect<Exclude<R, R2>, never, unknown> {
388
+ return onFailureCore(this.core, cause)
389
+ }
338
390
 
339
- modify: <B>(f: (a: A) => readonly [B, A]) => Effect.Effect<I, E, B> = (f) =>
340
- this.tag.withEffect((ref) => ref.modify(f))
391
+ toEffect(): Effect.Effect<Exclude<R, R2>, E, A> {
392
+ return getOrInitializeCore(this.core, true)
393
+ }
394
+ }
341
395
 
342
- updateEffect: <R2, E2>(f: (a: A) => Effect.Effect<R2, E2, A>) => Effect.Effect<I | R2, E | E2, A> = (f) =>
343
- this.tag.withEffect((ref) => ref.updateEffect(f))
396
+ class DerivedImpl<R, E, A, R2> extends RefSubjectImpl<R, E, A, R2> implements RefSubject.Derived<Exclude<R, R2>, E, A> {
397
+ constructor(
398
+ core: RefSubjectCore<R, E, A, R2>,
399
+ readonly persist: Effect.Effect<Exclude<R, R2>, never, void>
400
+ ) {
401
+ super(core)
402
+ }
403
+ }
344
404
 
345
- update: (f: (a: A) => A) => Effect.Effect<I, E, A> = (f) => this.tag.withEffect((ref) => ref.update(f))
405
+ /**
406
+ * @since 1.20.0
407
+ */
408
+ export const set: {
409
+ <A>(value: A): <R, E>(ref: RefSubject<R, E, A>) => Effect.Effect<R, E, A>
410
+ <R, E, A>(ref: RefSubject<R, E, A>, a: A): Effect.Effect<R, E, A>
411
+ } = dual(2, function set<R, E, A>(ref: RefSubject<R, E, A>, a: A): Effect.Effect<R, E, A> {
412
+ return ref.runUpdates((ref) => ref.set(a))
413
+ })
346
414
 
347
- set: (a: A) => Effect.Effect<I, never, A> = (a) => this.tag.withEffect((ref) => ref.set(a))
415
+ /**
416
+ * @since 1.20.0
417
+ */
418
+ export function reset<R, E, A>(ref: RefSubject<R, E, A>): Effect.Effect<R, E, Option.Option<A>> {
419
+ return ref.runUpdates((ref) => ref.delete)
420
+ }
348
421
 
349
- mapEffect: <R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, B>) => Computed<R2, E | E2, B> = (f) =>
350
- Computed(this as any, f)
422
+ /**
423
+ * @since 1.20.0
424
+ */
425
+ export {
426
+ /**
427
+ * @since 1.20.0
428
+ */
429
+ reset as delete
430
+ }
351
431
 
352
- map: <B>(f: (a: A) => B) => Computed<I, E, B> = (f) => Computed(this as any, (a: A) => Effect.sync(() => f(a)))
432
+ /**
433
+ * @since 1.20.0
434
+ */
435
+ export interface GetSetDelete<R, E, A> {
436
+ /**
437
+ * @since 1.20.0
438
+ */
439
+ readonly get: Effect.Effect<R, E, A>
440
+ /**
441
+ * @since 1.20.0
442
+ */
443
+ readonly set: (a: A) => Effect.Effect<R, never, A>
444
+ /**
445
+ * @since 1.20.0
446
+ */
447
+ readonly delete: Effect.Effect<R, E, Option.Option<A>>
448
+ }
353
449
 
354
- filterMapEffect: <R2, E2, B>(
355
- f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>
356
- ) => Filtered<R2, E | E2, B> = (f) => Filtered(this as any, f)
450
+ function getSetDelete<R, E, A, R2>(ref: RefSubjectCore<R, E, A, R2>): GetSetDelete<Exclude<R, R2>, E, A> {
451
+ return {
452
+ get: getOrInitializeCore(ref, false),
453
+ set: (a) => setCore(ref, a),
454
+ delete: deleteCore(ref)
455
+ }
456
+ }
357
457
 
358
- filterMap: <B>(f: (a: A) => Option.Option<B>) => Filtered<never, E, B> = (f) =>
359
- Filtered(this as any, (a: A) => Effect.sync(() => f(a)))
458
+ /**
459
+ * @since 1.20.0
460
+ */
461
+ export const updateEffect: {
462
+ <A, R2, E2>(
463
+ f: (value: A) => Effect.Effect<R2, E2, A>
464
+ ): <R, E>(ref: RefSubject<R, E, A>) => Effect.Effect<R | R2, E | E2, A>
465
+ <R, E, A, R2, E2>(
466
+ ref: RefSubject<R, E, A>,
467
+ f: (value: A) => Effect.Effect<R2, E2, A>
468
+ ): Effect.Effect<R | R2, E | E2, A>
469
+ } = dual(2, function updateEffect<R, E, A, R2, E2>(
470
+ ref: RefSubject<R, E, A>,
471
+ f: (value: A) => Effect.Effect<R2, E2, A>
472
+ ) {
473
+ return ref.runUpdates((ref) => Effect.flatMap(Effect.flatMap(ref.get, f), ref.set))
474
+ })
360
475
 
361
- filter: (f: (a: A) => boolean) => Filtered<I, E, A> = (f) =>
362
- this.filterMap((a) => f(a) ? Option.some(a) : Option.none())
476
+ /**
477
+ * @since 1.20.0
478
+ */
479
+ export const update: {
480
+ <A>(f: (value: A) => A): <R, E>(ref: RefSubject<R, E, A>) => Effect.Effect<R, E, A>
481
+ <R, E, A>(ref: RefSubject<R, E, A>, f: (value: A) => A): Effect.Effect<R, E, A>
482
+ } = dual(2, function update<R, E, A>(ref: RefSubject<R, E, A>, f: (value: A) => A) {
483
+ return updateEffect(ref, (value) => Effect.succeed(f(value)))
484
+ })
363
485
 
364
- filterEffect: <R2, E2>(f: (a: A) => Effect.Effect<R2, E2, boolean>) => Filtered<I | R2, E | E2, A> = (f) =>
365
- this.filterMapEffect((a) => Effect.map(f(a), (b) => b ? Option.some(a) : Option.none()))
486
+ /**
487
+ * @since 1.20.0
488
+ */
489
+ export const modifyEffect: {
490
+ <A, R2, E2, B>(
491
+ f: (value: A) => Effect.Effect<R2, E2, readonly [B, A]>
492
+ ): <R, E>(ref: RefSubject<R, E, A>) => Effect.Effect<R | R2, E | E2, B>
493
+ <R, E, A, R2, E2, B>(
494
+ ref: RefSubject<R, E, A>,
495
+ f: (value: A) => Effect.Effect<R2, E2, readonly [B, A]>
496
+ ): Effect.Effect<R | R2, E | E2, B>
497
+ } = dual(2, function modifyEffect<R, E, A, R2, E2, B>(
498
+ ref: RefSubject<R, E, A>,
499
+ f: (value: A) => Effect.Effect<R2, E2, readonly [B, A]>
500
+ ) {
501
+ return ref.runUpdates(
502
+ (ref) =>
503
+ Effect.flatMap(
504
+ ref.get,
505
+ (value) => Effect.flatMap(f(value), ([b, a]) => Effect.flatMap(ref.set(a), () => Effect.succeed(b)))
506
+ )
507
+ )
508
+ })
366
509
 
367
- skipRepeats: (eq?: Equivalence<A> | undefined) => Computed<I, E, A> = (eq = equals) =>
368
- fromTag(this.tag, (s) => s.skipRepeats(eq))
510
+ /**
511
+ * @since 1.20.0
512
+ */
513
+ export const modify: {
514
+ <A, B>(f: (value: A) => readonly [B, A]): <R, E>(ref: RefSubject<R, E, A>) => Effect.Effect<R, E, B>
515
+ <R, E, A, B>(ref: RefSubject<R, E, A>, f: (value: A) => readonly [B, A]): Effect.Effect<R, E, B>
516
+ } = dual(2, function modify<R, E, A, B>(ref: RefSubject<R, E, A>, f: (value: A) => readonly [B, A]) {
517
+ return modifyEffect(ref, (value) => Effect.succeed(f(value)))
518
+ })
369
519
 
370
- onFailure: (cause: Cause.Cause<E>) => Effect.Effect<I, never, unknown> = (cause) =>
371
- this.tag.withEffect((ref) => ref.onFailure(cause))
520
+ const isRefSubjectDataFirst = (args: IArguments) => isRefSubject(args[0])
372
521
 
373
- onSuccess: (value: A) => Effect.Effect<I, never, unknown> = (a) => this.tag.withEffect((ref) => ref.onSuccess(a))
522
+ /**
523
+ * @since 1.20.0
524
+ */
525
+ export const runUpdates: {
526
+ <R, E, A, R2, E2, B, R3 = never, E3 = never, C = never>(
527
+ f: (ref: GetSetDelete<R, E, A>) => Effect.Effect<R2, E2, B>,
528
+ options?:
529
+ | { readonly onInterrupt: (value: A) => Effect.Effect<R3, E3, C>; readonly value?: "initial" | "current" }
530
+ | undefined
531
+ ): (ref: RefSubject<R, E, A>) => Effect.Effect<R | R2 | R3, E | E2 | E3, B>
532
+
533
+ <R, E, A, R2, E2, B, R3 = never, E3 = never, C = never>(
534
+ ref: RefSubject<R, E, A>,
535
+ f: (ref: GetSetDelete<R, E, A>) => Effect.Effect<R2, E2, B>,
536
+ options?:
537
+ | { readonly onInterrupt: (value: A) => Effect.Effect<R3, E3, C>; readonly value?: "initial" | "current" }
538
+ | undefined
539
+ ): Effect.Effect<R | R2 | R3, E | E2 | E3, B>
540
+ } = dual(
541
+ isRefSubjectDataFirst,
542
+ function runUpdates<R, E, A, R2, E2, B, R3 = never, E3 = never, C = never>(
543
+ ref: RefSubject<R, E, A>,
544
+ f: (ref: GetSetDelete<R, E, A>) => Effect.Effect<R2, E2, B>,
545
+ options?: {
546
+ readonly onInterrupt: (value: A) => Effect.Effect<R3, E3, C>
547
+ readonly value?: "initial" | "current"
548
+ }
549
+ ) {
550
+ if (!options) {
551
+ return ref.runUpdates(f)
552
+ } else if (options.value === "initial") {
553
+ return ref.runUpdates((ref) =>
554
+ Effect.uninterruptibleMask((restore) =>
555
+ Effect.flatMap(
556
+ ref.get,
557
+ (initial) =>
558
+ f(ref).pipe(
559
+ restore,
560
+ Effect.tapErrorCause(Effect.unifiedFn((cause) =>
561
+ Cause.isInterruptedOnly(cause)
562
+ ? options.onInterrupt(initial)
563
+ : Effect.unit
564
+ ))
565
+ )
566
+ )
567
+ )
568
+ )
569
+ } else {
570
+ return ref.runUpdates((ref) =>
571
+ Effect.uninterruptibleMask((restore) =>
572
+ f(ref).pipe(
573
+ restore,
574
+ Effect.tapErrorCause(Effect.unifiedFn((cause) =>
575
+ Cause.isInterruptedOnly(cause)
576
+ ? Effect.flatMap(ref.get, options.onInterrupt)
577
+ : Effect.unit
578
+ ))
579
+ )
580
+ )
581
+ )
582
+ }
583
+ }
584
+ )
374
585
 
375
- make = <R>(fx: Fx.Fx<R, E, A>, eq?: Equivalence<A>): Layer.Layer<R, never, I> =>
376
- this.tag.scoped(make(fx, eq || this.defaultEq))
586
+ class RefSubjectCore<R, E, A, R2> {
587
+ constructor(
588
+ readonly initial: Effect.Effect<R, E, A>,
589
+ readonly subject: Subject.Subject<R, E, A>,
590
+ readonly context: C.Context<R2>,
591
+ readonly scope: Scope.CloseableScope,
592
+ readonly deferredRef: DeferredRef.DeferredRef<E, A>,
593
+ readonly semaphore: Effect.Semaphore
594
+ ) {}
595
+
596
+ public _fiber: Fiber.Fiber<E, A> | undefined = undefined
597
+ }
377
598
 
378
- of = (value: A, eq?: Equivalence<A>): Layer.Layer<never, never, I> => this.tag.scoped(of(value, eq))
599
+ function makeCore<R, E, A>(
600
+ initial: Effect.Effect<R, E, A>,
601
+ options?: RefSubjectOptions<A>
602
+ ) {
603
+ return Effect.context<R | Scope.Scope>().pipe(
604
+ Effect.bindTo("ctx"),
605
+ Effect.let("executionStrategy", () => options?.executionStrategy ?? ExecutionStrategy.parallel),
606
+ Effect.bind(
607
+ "scope",
608
+ ({ ctx, executionStrategy }) => Scope.fork(C.get(ctx, Scope.Scope), executionStrategy)
609
+ ),
610
+ Effect.bind(
611
+ "deferredRef",
612
+ () => DeferredRef.make<E, A>(getExitEquivalence(options?.eq ?? Equal.equals))
613
+ ),
614
+ Effect.let("subject", () => Subject.unsafeMake<E, A>(Math.max(1, options?.replay ?? 1))),
615
+ Effect.tap(({ scope, subject }) => Scope.addFinalizer(scope, subject.interrupt)),
616
+ Effect.map(({ ctx, deferredRef, scope, subject }) =>
617
+ new RefSubjectCore(
618
+ initial,
619
+ subject,
620
+ ctx,
621
+ scope,
622
+ deferredRef,
623
+ Effect.unsafeMakeSemaphore(1)
624
+ )
625
+ )
626
+ )
627
+ }
379
628
 
380
- provide = <R2>(fx: Fx.Fx<R2, E, A>, eq?: Equivalence<A>) => Effect.provide(this.make(fx, eq || this.defaultEq))
629
+ function unsafeMakeCore<R, E, A>(
630
+ initial: Effect.Effect<R, E, A>,
631
+ id: FiberId.FiberId,
632
+ ctx: C.Context<R>,
633
+ scope: Scope.CloseableScope,
634
+ options?: RefSubjectOptions<A>
635
+ ) {
636
+ return new RefSubjectCore(
637
+ initial,
638
+ Subject.unsafeMake<E, A>(Math.max(1, options?.replay ?? 1)),
639
+ ctx,
640
+ scope,
641
+ DeferredRef.unsafeMake(id, getExitEquivalence(options?.eq ?? Equal.equals)),
642
+ Effect.unsafeMakeSemaphore(1)
643
+ )
644
+ }
381
645
 
382
- provideFx = <R2>(fx: Fx.Fx<R2, E, A>, eq?: Equivalence<A>) => provide(this.make(fx, eq || this.defaultEq))
646
+ function getOrInitializeCore<R, E, A, R2>(
647
+ core: RefSubjectCore<R, E, A, R2>,
648
+ lockInitialize: boolean
649
+ ): Effect.Effect<Exclude<R, R2>, E, A> {
650
+ return Effect.suspend(() => {
651
+ if (core._fiber === undefined && Option.isNone(core.deferredRef.current)) {
652
+ return initializeCoreAndTap(core, lockInitialize)
653
+ } else {
654
+ return core.deferredRef
655
+ }
656
+ })
383
657
  }
384
658
 
385
- /**
386
- * Construct a RefSubject from any Fx value.
387
- *
388
- * @since 1.18.0
389
- * @category constructors
390
- */
391
- export function makeWithExtension<R, E, A, B>(
392
- fx: Effect.Effect<R, E, A>,
393
- f: (ref: RefSubject<never, E, A>) => B,
394
- eq?: Equivalence<A>
395
- ): Effect.Effect<R, never, RefSubject<never, E, A> & B>
396
- export function makeWithExtension<R, E, A, B>(
397
- fx: Fx.FxInput<R, E, A>,
398
- f: (ref: RefSubject<never, E, A>) => B,
399
- eq?: Equivalence<A>
400
- ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A> & B>
659
+ function initializeCoreEffect<R, E, A, R2>(
660
+ core: RefSubjectCore<R, E, A, R2>,
661
+ lock: boolean
662
+ ): Effect.Effect<Exclude<R, R2>, never, Fiber.Fiber<E, A>> {
663
+ const initialize = Effect.onExit(
664
+ Effect.provide(core.initial, core.context),
665
+ (exit) => {
666
+ core._fiber = undefined
667
+ core.deferredRef.done(exit)
668
+ return Effect.unit
669
+ }
670
+ )
401
671
 
402
- export function makeWithExtension<R, E, A, B>(
403
- fx: Fx.FxInput<R, E, A>,
404
- f: (ref: RefSubject<never, E, A>) => B,
405
- eq?: Equivalence<A>
406
- ): Effect.Effect<R | Scope.Scope, never, RefSubject<never, E, A> & B> {
407
- return coreRefSubject.makeWithExtension(fx, f, eq)
672
+ return Effect.flatMap(
673
+ Effect.forkIn(
674
+ lock && core.semaphore ? core.semaphore.withPermits(1)(initialize) : initialize,
675
+ core.scope
676
+ ),
677
+ (fiber) => Effect.sync(() => core._fiber = fiber)
678
+ )
408
679
  }
409
680
 
410
- /**
411
- * Construct a RefSubject with an initial value and the specified subject.
412
- * @since 1.18.0
413
- * @category constructors
414
- */
415
- export const unsafeMake: <R, E, A>(
416
- initial: Effect.Effect<R, E, A>,
417
- subject: Subject.Subject<R, E, A>,
418
- eq?: Equivalence<A>
419
- ) => RefSubject<R, E, A> = coreRefSubject.unsafeMake
681
+ function initializeCore<R, E, A, R2>(
682
+ core: RefSubjectCore<R, E, A, R2>,
683
+ lock: boolean
684
+ ): Effect.Effect<Exclude<R, R2>, never, Fiber.Fiber<E, A>> {
685
+ type Z = Effect.Effect<Exclude<R, R2>, never, Fiber.Fiber<E, A>>
420
686
 
421
- /**
422
- * Flatten an RefSubject of an Option into a Filtered.
423
- * @since 1.18.0
424
- * @category combinators
425
- */
426
- export const compact = <R, E, A>(refSubject: RefSubject<R, E, Option.Option<A>>): Filtered<R, E, A> =>
427
- refSubject.filterMap(identity)
687
+ const onSuccess = (a: A): Z => {
688
+ core.deferredRef.done(Exit.succeed(a))
689
+ return Effect.succeed(Fiber.succeed(a))
690
+ }
428
691
 
429
- /**
430
- * Split a RefSubject's into 2 Filtered values that track its errors and
431
- * success values separately.
432
- * @since 1.18.0
433
- * @category combinators
434
- */
435
- export const split = <R, E, A>(
436
- refSubject: RefSubject<R, E, A>
437
- ): readonly [Filtered<R, never, E>, Filtered<R, never, A>] => {
438
- const versioned = Versioned.transform(refSubject, exit, Effect.exit)
439
- const left = Filtered(versioned, getLeft)
440
- const right = Filtered(versioned, getRight)
692
+ const onCause = (cause: Cause.Cause<E>): Z => {
693
+ core.deferredRef.done(Exit.failCause(cause))
694
+ return Effect.succeed(Fiber.failCause(cause))
695
+ }
441
696
 
442
- return [left, right] as const
697
+ const onError = (e: E): Z => onCause(Cause.fail(e))
698
+
699
+ return matchEffectPrimitive(core.initial, {
700
+ Success: onSuccess,
701
+ Failure: onCause,
702
+ Some: onSuccess,
703
+ None: onError,
704
+ Left: onError,
705
+ Right: onSuccess,
706
+ Sync: (f) => onSuccess(f()),
707
+ Otherwise: () => initializeCoreEffect(core, lock)
708
+ })
443
709
  }
444
710
 
445
- const getLeft = <E, A>(exit: Exit.Exit<E, A>) =>
446
- Effect.succeed(
447
- Exit.match(exit, {
448
- onFailure: (cause) => Cause.failureOption(cause),
449
- onSuccess: () => Option.none()
450
- })
711
+ function initializeCoreAndTap<R, E, A, R2>(
712
+ core: RefSubjectCore<R, E, A, R2>,
713
+ lock: boolean
714
+ ): Effect.Effect<Exclude<R, R2>, E, A> {
715
+ return Effect.zipRight(
716
+ initializeCore(core, lock),
717
+ tapEventCore(core, core.deferredRef)
451
718
  )
719
+ }
452
720
 
453
- const getRight = <E, A>(exit: Exit.Exit<E, A>) =>
454
- Effect.succeed(
455
- Exit.match(exit, {
456
- onFailure: Option.none,
457
- onSuccess: Option.some
458
- })
459
- )
721
+ function setCore<R, E, A, R2>(core: RefSubjectCore<R, E, A, R2>, a: A): Effect.Effect<Exclude<R, R2>, never, A> {
722
+ const exit = Exit.succeed(a)
723
+
724
+ return Effect.suspend(() => {
725
+ if (core.deferredRef.done(exit)) {
726
+ // If the value changed, send an event
727
+ return Effect.as(sendEvent(core, exit), a)
728
+ } else {
729
+ // Otherwise, just return the current value
730
+ return Effect.succeed(a)
731
+ }
732
+ })
733
+ }
460
734
 
461
- /**
462
- * MakeRefSubject is a RefSubject factory function dervied from a Schema.
463
- * @since 1.18.0
464
- */
465
- export type MakeRefSubject<O> = {
466
- <R, E>(
467
- input: RefSubject<R, E, O>,
468
- eq?: Equivalence<O>
469
- ): Effect.Effect<R | Scope.Scope, never, ToDerived<R, E, O>>
735
+ function onFailureCore<R, E, A, R2>(core: RefSubjectCore<R, E, A, R2>, cause: Cause.Cause<E>) {
736
+ const exit = Exit.failCause(cause)
470
737
 
471
- <R, E>(input: Effect.Effect<R, E, O>, eq?: Equivalence<O>): Effect.Effect<R | Scope.Scope, never, ToRefSubject<E, O>>
738
+ return Effect.suspend(() => {
739
+ if (core.deferredRef.done(exit)) {
740
+ return sendEvent(core, exit)
741
+ } else {
742
+ return Effect.unit
743
+ }
744
+ })
745
+ }
472
746
 
473
- <R, E>(
474
- input: Stream.Stream<R, E, O>,
475
- eq?: Equivalence<O>
476
- ): Effect.Effect<R | Scope.Scope, never, ToRefSubject<E, O>>
747
+ function interruptCore<R, E, A, R2>(core: RefSubjectCore<R, E, A, R2>): Effect.Effect<R, never, void> {
748
+ return Effect.fiberIdWith((id) => {
749
+ core.deferredRef.reset()
477
750
 
478
- <R, E>(input: Fx.Fx<R, E, O>, eq?: Equivalence<O>): Effect.Effect<R | Scope.Scope, never, ToRefSubject<E, O>>
751
+ const closeScope = Scope.close(core.scope, Exit.interrupt(id))
752
+ const interruptFiber = core._fiber ? Fiber.interrupt(core._fiber) : Effect.unit
753
+ const interruptSubject = core.subject.interrupt
479
754
 
480
- <E>(input: Cause.Cause<E>, eq?: Equivalence<O>): Effect.Effect<Scope.Scope, never, ToRefSubject<E, O>>
755
+ return Effect.all([closeScope, interruptFiber, interruptSubject], { discard: true })
756
+ })
757
+ }
481
758
 
482
- <R, E>(
483
- input: Fx.FxInput<R, E, O>,
484
- eq?: Equivalence<O>
485
- ): Effect.Effect<R | Scope.Scope, never, ToRefSubject<E, O>>
759
+ function deleteCore<R, E, A, R2>(
760
+ core: RefSubjectCore<R, E, A, R2>
761
+ ): Effect.Effect<Exclude<R, R2>, E, Option.Option<A>> {
762
+ return Effect.suspend(() => {
763
+ const current = core.deferredRef.current
764
+ core.deferredRef.reset()
765
+
766
+ if (Option.isNone(current)) {
767
+ return Effect.succeed(Option.none())
768
+ }
769
+
770
+ return core.subject.subscriberCount.pipe(
771
+ Effect.provide(core.context),
772
+ Effect.flatMap(
773
+ (count: number) => count > 0 && !core._fiber ? initializeCore(core, false) : Effect.unit
774
+ ),
775
+ Effect.zipRight(Effect.asSome(current.value))
776
+ )
777
+ })
486
778
  }
487
779
 
488
- /**
489
- * Converts an error `E` and an output `O` into a RefSubject or a Record of RefSubjects if
490
- * the ouput value is a Record as well.
491
- * @since 1.18.0
492
- */
493
- export type ToRefSubject<E, O> = O extends Readonly<Record<PropertyKey, any>> ? {
494
- readonly [K in keyof O]: ToRefSubject<E, O[K]>
495
- } :
496
- RefSubject<never, E, O> // TODO: We should apply ParseErrors here too somehow
780
+ function tapEventCore<R, E, A, R2, R3>(
781
+ core: RefSubjectCore<R, E, A, R2>,
782
+ effect: Effect.Effect<R3, E, A>
783
+ ) {
784
+ return effect.pipe(
785
+ Effect.exit,
786
+ Effect.tap((exit) => sendEvent(core, exit)),
787
+ Effect.flatten
788
+ )
789
+ }
790
+
791
+ function sendEvent<R, E, A, R2>(
792
+ core: RefSubjectCore<R, E, A, R2>,
793
+ exit: Exit.Exit<E, A>
794
+ ): Effect.Effect<Exclude<R, R2>, never, unknown> {
795
+ if (Exit.isSuccess(exit)) {
796
+ return Effect.provide(core.subject.onSuccess(exit.value), core.context)
797
+ } else {
798
+ return Effect.provide(core.subject.onFailure(exit.cause), core.context)
799
+ }
800
+ }
497
801
 
498
802
  /**
499
- * Converts an error `E` and an output `O` into a RefSubject or a Record of RefSubjects if
500
- * the ouput value is a Record as well.
501
- * @since 1.18.0
803
+ * @since 1.20.0
502
804
  */
503
- export type ToDerived<R, E, O> = ToRefSubject<E, O> & {
504
- readonly persist: Effect.Effect<R, E, O>
505
- }
805
+ export const mapEffect: {
806
+ <A, R2, E2, B>(
807
+ f: (a: A) => Effect.Effect<R2, E2, B>
808
+ ): {
809
+ <R, E>(ref: RefSubject<R, E, A> | Computed<R, E, A>): Computed<R | R2, E | E2, B>
810
+ <R, E>(ref: Filtered<R, E, A>): Filtered<R | R2, E | E2, B>
811
+ <R0, E0, R, E, R2, E2, C>(
812
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
813
+ f: (a: A) => Effect.Effect<R2, E2, C>
814
+ ): Computed<R0 | R2, E0 | E | E2, C>
815
+ }
816
+
817
+ <R, E, A, R2, E2, B>(
818
+ ref: RefSubject<R, E, A> | Computed<R, E, A>,
819
+ f: (a: A) => Effect.Effect<R2, E2, B>
820
+ ): Computed<R | R2, E | E2, B>
821
+
822
+ <R, E, A, R2, E2, B>(
823
+ ref: Filtered<R, E, A>,
824
+ f: (a: A) => Effect.Effect<R2, E2, B>
825
+ ): Filtered<R | R2, E | E2, B>
826
+
827
+ <R0, E0, R, E, A, R2, E2, R3, E3, C>(
828
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
829
+ f: (a: A) => Effect.Effect<R3, E3, C>
830
+ ): Computed<R0 | R2 | R3 | Exclude<R, Scope.Scope>, E0 | E | E2 | E3, C>
831
+ } = dual(2, function mapEffect<R0, E0, R, E, A, R2, E2, R3, E3, C>(
832
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
833
+ f: (a: A) => Effect.Effect<R3, E3, C>
834
+ ):
835
+ | Computed<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, C>
836
+ | Filtered<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, C>
837
+ {
838
+ return FilteredTypeId in versioned
839
+ ? FilteredImpl.make(versioned, (a) => Effect.asSome(f(a)))
840
+ : ComputedImpl.make(versioned, f)
841
+ })
506
842
 
507
843
  /**
508
- * Derive a RefSubjectSchema using the "from" or "encoded" value represented by a Schema.
509
- * @since 1.18.0
844
+ * @since 1.20.0
510
845
  */
511
- export function deriveFromSchema<I, O>(schema: Schema.Schema<I, O>): MakeRefSubject<I> {
512
- return fromRefSubject(schema)
513
- }
846
+ export const map: {
847
+ <A, B>(f: (a: A) => B): {
848
+ <R, E>(ref: RefSubject<R, E, A>): Computed<R, E, B>
849
+ <R, E>(ref: Computed<R, E, A>): Computed<R, E, B>
850
+
851
+ <R, E>(ref: Filtered<R, E, A>): Filtered<R, E, B>
852
+
853
+ <R0, E0, R, E, R2, E2>(
854
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
855
+ f: (a: A) => B
856
+ ): Computed<R0 | R2, E0 | E | E2, B>
857
+ }
858
+
859
+ <R, E, A, B>(ref: RefSubject<R, E, A> | Computed<R, E, A>, f: (a: A) => B): Computed<R, E, B>
860
+ <R, E, A, B>(filtered: Filtered<R, E, A>, f: (a: A) => B): Filtered<R, E, B>
861
+
862
+ <R0, E0, R, E, A, R2, E2, B>(
863
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
864
+ f: (a: A) => B
865
+ ):
866
+ | Computed<R0 | R2 | Exclude<R, Scope.Scope>, E0 | E | E2, B>
867
+ | Filtered<R0 | R2 | Exclude<R, Scope.Scope>, E0 | E | E2, B>
868
+ } = dual(2, function map<R0, E0, R, E, A, R2, E2, B>(
869
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
870
+ f: (a: A) => B
871
+ ):
872
+ | Computed<R0 | Exclude<R, Scope.Scope> | R2, E0 | E | E2, B>
873
+ | Filtered<R0 | Exclude<R, Scope.Scope> | R2, E0 | E | E2, B>
874
+ {
875
+ return mapEffect(versioned, (a) => Effect.succeed(f(a)))
876
+ })
514
877
 
515
878
  /**
516
- * Derive a RefSubjectSchema using the "to" or "decoded" value represented by a Schema.
517
- * @since 1.18.0
879
+ * @since 1.20.0
518
880
  */
519
- export function deriveToSchema<I, O>(schema: Schema.Schema<I, O>): MakeRefSubject<O> {
520
- return toRefSubject(schema)
521
- }
881
+ export const filterMapEffect: {
882
+ <A, R2, E2, B>(
883
+ f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>
884
+ ): {
885
+ <R, E>(ref: RefSubject<R, E, A> | Computed<R, E, A>): Filtered<R | R2, E | E2, B>
886
+ <R, E>(ref: Filtered<R, E, A>): Filtered<R | R2, E | E2, B>
887
+ <R0, E0, R, E, R2, E2, B>(
888
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
889
+ f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>
890
+ ): Filtered<R0 | R2, E0 | E | E2, B>
891
+ }
892
+
893
+ <R, E, A, R2, E2, B>(
894
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>,
895
+ f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>
896
+ ): Filtered<R | R2, E | E2, B>
897
+ <R0, E0, R, E, A, R2, E2, B, R3, E3>(
898
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
899
+ f: (a: A) => Effect.Effect<R3, E3, Option.Option<B>>
900
+ ): Filtered<R0 | R2 | R3 | Exclude<R, Scope.Scope>, E0 | E | E2 | E3, B>
901
+ } = dual(2, function filterMapEffect<R0, E0, R, E, A, R2, E2, B, R3, E3>(
902
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
903
+ f: (a: A) => Effect.Effect<R3, E3, Option.Option<B>>
904
+ ): Filtered<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, B> {
905
+ return FilteredImpl.make(versioned, f)
906
+ })
522
907
 
523
908
  /**
524
- * @since 1.18.0
909
+ * @since 1.20.0
525
910
  */
526
- export const tuple: <const REFS extends ReadonlyArray<RefSubject.Any>>(
527
- ...refs: REFS
528
- ) => RefSubject<
529
- RefSubject.Context<REFS[number]>,
530
- RefSubject.Error<REFS[number]>,
531
- { readonly [K in keyof REFS]: RefSubject.Success<REFS[K]> }
532
- > = coreRefSubject.tuple
911
+ export const filterMap: {
912
+ <A, B>(f: (a: A) => Option.Option<B>): {
913
+ <R, E>(ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>): Filtered<R, E, B>
914
+ <R0, E0, R, E, R2, E2, B>(
915
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
916
+ f: (a: A) => Option.Option<B>
917
+ ): Filtered<R0 | R2, E0 | E | E2, B>
918
+ }
919
+
920
+ <R0, E0, R, E, A, R2, E2, B>(
921
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
922
+ f: (a: A) => Option.Option<B>
923
+ ): Filtered<R0 | R2 | Exclude<R, Scope.Scope>, E0 | E | E2, B>
924
+
925
+ <R, E, A, B>(
926
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>,
927
+ f: (a: A) => Option.Option<B>
928
+ ): Filtered<R, E, B>
929
+ } = dual(2, function filterMap<R0, E0, R, E, A, R2, E2, B>(
930
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
931
+ f: (a: A) => Option.Option<B>
932
+ ): Filtered<R0 | Exclude<R, Scope.Scope> | R2 | R2, E0 | E | E2, B> {
933
+ return FilteredImpl.make(versioned, (a) => Effect.succeed(f(a)))
934
+ })
533
935
 
534
936
  /**
535
- * @since 1.18.0
937
+ * @since 1.20.0
536
938
  */
537
- export const struct: <const REFS extends Readonly<Record<PropertyKey, RefSubject.Any>>>(
538
- refs: REFS
539
- ) => RefSubject<
540
- RefSubject.Context<REFS[string]>,
541
- RefSubject.Error<REFS[string]>,
542
- { readonly [K in keyof REFS]: RefSubject.Success<REFS[K]> }
543
- > = coreRefSubject.struct
939
+ export const compact: {
940
+ <R, E, A>(ref: RefSubject<R, E, Option.Option<A>> | Computed<R, E, Option.Option<A>>): Filtered<R, E, A>
941
+ <R, E, A>(ref: Filtered<R, E, Option.Option<A>>): Filtered<R, E, A>
942
+
943
+ <R0, E0, R, E, A, R2, E2>(
944
+ versioned: Versioned.Versioned<R0, E0, R, E, Option.Option<A>, R2, E2, Option.Option<A>>
945
+ ): Filtered<
946
+ R0 | R2 | Exclude<R, Scope.Scope>,
947
+ E0 | E | Exclude<E, Cause.NoSuchElementException> | Exclude<E2, Cause.NoSuchElementException>,
948
+ A
949
+ >
950
+ } = <R0, E0, R, E, A, R2, E2>(
951
+ versioned: Versioned.Versioned<R0, E0, R, E, Option.Option<A>, R2, E2, Option.Option<A>>
952
+ ): Filtered<R0 | R2 | Exclude<R, Scope.Scope>, E0 | E | Exclude<E | E2, Cause.NoSuchElementException>, A> =>
953
+ filterMap(versioned, identity) as any
544
954
 
545
955
  /**
546
- * @since 1.18.0
956
+ * @since 1.20.0
547
957
  */
548
- export function fromSubscriptionRef<A>(
549
- subscriptionRef: SubscriptionRef.SubscriptionRef<A>
550
- ): Effect.Effect<Scope.Scope, never, RefSubject<never, never, A>> {
551
- return coreRefSubject.make(fromStream(subscriptionRef.changes))
552
- }
958
+ export const filterEffect: {
959
+ <R, E, A, R2, E2>(
960
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>,
961
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
962
+ ): Filtered<R | R2, E | E2, A>
963
+ <R0, E0, R, E, A, R2, E2, R3, E3>(
964
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
965
+ f: (a: A) => Effect.Effect<R3, E3, boolean>
966
+ ): Filtered<R0 | R2 | R3 | Exclude<R, Scope.Scope>, E0 | E | E2 | E3, A>
967
+ } = dual(2, function filterEffect<R0, E0, R, E, A, R2, E2, R3, E3>(
968
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
969
+ f: (a: A) => Effect.Effect<R3, E3, boolean>
970
+ ): Filtered<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, A> {
971
+ return FilteredImpl.make(versioned, (a) => Effect.map(f(a), (b) => b ? Option.some(a) : Option.none()))
972
+ })
553
973
 
554
974
  /**
555
- * @since 1.18.0
975
+ * @since 1.20.0
556
976
  */
557
- export const transform: {
558
- <A, B>(from: (a: A) => B, to: (b: B) => A): <R, E>(ref: RefSubject<R, E, A>) => RefSubject<R, E, B>
559
- <R, E, A, B>(ref: RefSubject<R, E, A>, from: (a: A) => B, to: (b: B) => A): RefSubject<R, E, B>
560
- } = dual(3, function transform<R, E, A, B>(
561
- ref: RefSubject<R, E, A>,
562
- from: (a: A) => B,
563
- to: (b: B) => A
564
- ): RefSubject<R, E, B> {
565
- return new TransformImpl(ref, from, to)
977
+ export const filter: {
978
+ <A>(f: (a: A) => boolean): {
979
+ <R, E>(ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>): Filtered<R, E, A>
980
+ <R0, E0, R, E, R2, E2>(
981
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
982
+ f: (a: A) => boolean
983
+ ): Filtered<R0 | R2, E0 | E | E2, A>
984
+ }
985
+
986
+ <R, E, A>(ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>, f: (a: A) => boolean): Filtered<R, E, A>
987
+ <R0, E0, R, E, A, R2, E2, R3, E3>(
988
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
989
+ f: (a: A) => boolean
990
+ ): Filtered<R0 | R2 | R3 | Exclude<R, Scope.Scope>, E0 | E | E2 | E3, A>
991
+ } = dual(2, function filter<R0, E0, R, E, A, R2, E2, R3, E3>(
992
+ versioned: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
993
+ f: (a: A) => boolean
994
+ ): Filtered<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, A> {
995
+ return FilteredImpl.make(versioned, (a) => Effect.succeed(f(a) ? Option.some(a) : Option.none()))
566
996
  })
567
997
 
568
- class TransformImpl<R, E, A, B> extends FxEffectBase<R, E, B, R, E, B> implements RefSubject<R, E, B> {
569
- readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
998
+ class ComputedImpl<R0, E0, R, E, A, R2, E2, R3, E3, C> extends Versioned.VersionedTransform<
999
+ R0,
1000
+ E0,
1001
+ R,
1002
+ E,
1003
+ A,
1004
+ R2,
1005
+ E2,
1006
+ A,
1007
+ R0 | Exclude<R, Scope.Scope> | R2 | R3 | Scope.Scope,
1008
+ E0 | E | E2 | E3,
1009
+ C,
1010
+ R0 | Exclude<R, Scope.Scope> | R2 | R3,
1011
+ E0 | E | E2 | E3,
1012
+ C
1013
+ > implements Computed<R0 | Exclude<R, Scope.Scope> | R2 | R3, E0 | E | E2 | E3, C> {
570
1014
  readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
571
1015
 
572
- readonly version: RefSubject<R, E, B>["version"]
573
- readonly subscriberCount: RefSubject<R, E, B>["subscriberCount"]
574
- readonly get: RefSubject<R, E, B>["get"]
575
- readonly delete: RefSubject<R, E, B>["delete"]
576
- readonly interrupt: RefSubject<R, E, B>["interrupt"]
577
-
578
1016
  constructor(
579
- readonly ref: RefSubject<R, E, A>,
580
- readonly from: (a: A) => B,
581
- readonly to: (b: B) => A
1017
+ readonly input: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
1018
+ readonly f: (a: A) => Effect.Effect<R3, E3, C>
582
1019
  ) {
583
- super()
1020
+ super(
1021
+ input,
1022
+ (fx) =>
1023
+ share.hold(core.mapEffect(fx, f)) as Fx<
1024
+ R0 | Exclude<R, Scope.Scope> | R2 | R3 | Scope.Scope,
1025
+ E0 | E | E2 | E3,
1026
+ C
1027
+ >,
1028
+ Effect.flatMap(f)
1029
+ )
1030
+ }
584
1031
 
585
- this.version = ref.version
586
- this.subscriberCount = ref.subscriberCount
587
- this.get = Effect.map(ref.get, from)
588
- this.delete = Effect.map(ref.delete, Option.map(from))
1032
+ static make<R0, E0, R, E, A, R2, E2, R3, E3, C>(
1033
+ input: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
1034
+ f: (a: A) => Effect.Effect<R3, E3, C>
1035
+ ): Computed<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, C> {
1036
+ return new ComputedImpl(input, f)
1037
+ }
1038
+ }
1039
+
1040
+ class FilteredImpl<R0, E0, R, E, A, R2, E2, R3, E3, C> extends Versioned.VersionedTransform<
1041
+ R0,
1042
+ E0,
1043
+ R,
1044
+ E,
1045
+ A,
1046
+ R2,
1047
+ E2,
1048
+ A,
1049
+ Exclude<R, Scope.Scope> | R2 | R3 | Scope.Scope,
1050
+ E0 | E | E2 | E3,
1051
+ C,
1052
+ R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3,
1053
+ E0 | E | E2 | E3 | Cause.NoSuchElementException,
1054
+ C
1055
+ > implements Filtered<R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3, E0 | E | E2 | E3, C> {
1056
+ readonly [FilteredTypeId]: FilteredTypeId = FilteredTypeId
1057
+
1058
+ constructor(
1059
+ readonly input: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
1060
+ readonly f: (a: A) => Effect.Effect<R3, E3, Option.Option<C>>
1061
+ ) {
1062
+ super(
1063
+ input,
1064
+ (fx) => share.hold(core.filterMapEffect(fx, f) as any),
1065
+ (effect) => Effect.flatten(Effect.flatMap(effect, f))
1066
+ )
1067
+ }
1068
+
1069
+ static make<R0, E0, R, E, A, R2, E2, R3, E3, C>(
1070
+ input: Versioned.Versioned<R0, E0, R, E, A, R2, E2, A>,
1071
+ f: (a: A) => Effect.Effect<R3, E3, Option.Option<C>>
1072
+ ): Filtered<
1073
+ R0 | Exclude<R, Scope.Scope> | R2 | R3 | R2 | R3,
1074
+ E0 | E | Exclude<E2, Cause.NoSuchElementException> | E3,
1075
+ C
1076
+ > {
1077
+ return new FilteredImpl(input, f) as any
1078
+ }
1079
+
1080
+ asComputed(): Computed<R0 | R2 | R3 | Exclude<R, Scope.Scope>, E0 | E | E2 | E3, Option.Option<C>> {
1081
+ return ComputedImpl.make(this.input, this.f)
1082
+ }
1083
+ }
1084
+
1085
+ /**
1086
+ * @since 1.20.0
1087
+ */
1088
+ export const skipRepeatsWith: {
1089
+ <A>(eq: Equivalence.Equivalence<A>): {
1090
+ <R, E>(ref: RefSubject<R, E, A> | Computed<R, E, A>): Computed<R, E, A>
1091
+ <R, E>(ref: Filtered<R, E, A>): Filtered<R, E, A>
1092
+ }
1093
+
1094
+ <R, E, A>(
1095
+ ref: RefSubject<R, E, A> | Computed<R, E, A>,
1096
+ eq: Equivalence.Equivalence<A>
1097
+ ): Computed<R, E, A>
1098
+ <R, E, A>(
1099
+ ref: Filtered<R, E, A>,
1100
+ eq: Equivalence.Equivalence<A>
1101
+ ): Filtered<R, E, A>
1102
+
1103
+ <R, E, A>(
1104
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>,
1105
+ eq: Equivalence.Equivalence<A>
1106
+ ): Computed<R, E, A> | Filtered<R, E, A>
1107
+ } = dual(2, function skipRepeatsWith<R, E, A>(
1108
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>,
1109
+ eq: Equivalence.Equivalence<A>
1110
+ ): Computed<R, E, A> | Filtered<R, E, A> {
1111
+ const versioned = Versioned.transform(ref, (fx) => core.skipRepeatsWith(fx, eq), identity)
1112
+
1113
+ if (FilteredTypeId in ref) {
1114
+ return FilteredImpl.make(versioned, Effect.succeedSome)
1115
+ } else {
1116
+ return ComputedImpl.make(versioned, Effect.succeed) as any
1117
+ }
1118
+ })
1119
+
1120
+ /**
1121
+ * @since 1.20.0
1122
+ */
1123
+ export function skipRepeats<R, E, A>(
1124
+ ref: RefSubject<R, E, A> | Computed<R, E, A>
1125
+ ): Computed<R, E, A>
1126
+
1127
+ export function skipRepeats<R, E, A>(
1128
+ ref: Filtered<R, E, A>
1129
+ ): Filtered<R, E, A>
1130
+
1131
+ export function skipRepeats<R, E, A>(
1132
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>
1133
+ ): Computed<R, E, A> | Filtered<R, E, A>
1134
+
1135
+ export function skipRepeats<R, E, A>(
1136
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>
1137
+ ): Computed<R, E, A> | Filtered<R, E, A> {
1138
+ return skipRepeatsWith(ref, Equal.equals)
1139
+ }
1140
+
1141
+ /**
1142
+ * @since 1.20.0
1143
+ */
1144
+ export function transform<R, E, A, B>(
1145
+ ref: RefSubject<R, E, A>,
1146
+ from: (a: A) => B,
1147
+ to: (b: B) => A
1148
+ ): RefSubject<R, E, B> {
1149
+ return new RefSubjectTransform(ref, from, to)
1150
+ }
1151
+
1152
+ /**
1153
+ * @since 1.20.0
1154
+ */
1155
+ export function transformOrFail<R, E, R2, E2, A, R3, E3, B>(
1156
+ ref: RefSubject<R, E, A>,
1157
+ from: (a: A) => Effect.Effect<R2, E2, B>,
1158
+ to: (b: B) => Effect.Effect<R3, E3, A>
1159
+ ): RefSubject<R | R2 | R3, E | E2 | E3, B> {
1160
+ return new RefSubjectTransformEffect(ref, from, to)
1161
+ }
1162
+
1163
+ class RefSubjectTransform<R, E, A, B> extends FxEffectBase<R | Scope.Scope, E, B, R, E, B>
1164
+ implements RefSubject<R, E, B>
1165
+ {
1166
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1167
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
1168
+
1169
+ readonly version: Effect.Effect<R, E, number>
1170
+ readonly interrupt: Effect.Effect<R, never, void>
1171
+ readonly subscriberCount: Effect.Effect<R, never, number>
1172
+
1173
+ constructor(
1174
+ readonly ref: RefSubject<R, E, A>,
1175
+ readonly from: (a: A) => B,
1176
+ readonly to: (b: B) => A
1177
+ ) {
1178
+ super()
1179
+
1180
+ this.version = ref.version
589
1181
  this.interrupt = ref.interrupt
1182
+ this.subscriberCount = ref.subscriberCount
1183
+ }
1184
+
1185
+ run<R2 = never>(sink: Sink.Sink<R2, E, B>): Effect.Effect<R | Scope.Scope | R2, never, unknown> {
1186
+ return this.ref.run(Sink.map(sink, this.from))
1187
+ }
1188
+
1189
+ runUpdates<R2, E2, C>(
1190
+ run: (ref: GetSetDelete<R, E, B>) => Effect.Effect<R2, E2, C>
1191
+ ) {
1192
+ return this.ref.runUpdates((ref) =>
1193
+ run({
1194
+ get: Effect.map(ref.get, this.from),
1195
+ set: (b) => Effect.map(ref.set(this.to(b)), this.from),
1196
+ delete: Effect.map(ref.delete, Option.map(this.from))
1197
+ })
1198
+ )
1199
+ }
1200
+
1201
+ onFailure(cause: Cause.Cause<E>): Effect.Effect<R, never, unknown> {
1202
+ return this.ref.onFailure(cause)
590
1203
  }
591
1204
 
592
- protected toFx(): Fx.Fx<R, E, B> {
593
- return this.ref.map(this.from)
1205
+ onSuccess(value: B): Effect.Effect<R, never, unknown> {
1206
+ return this.ref.onSuccess(this.to(value))
594
1207
  }
595
1208
 
596
- protected toEffect(): Effect.Effect<R, E, B> {
597
- return this.ref.map(this.from)
1209
+ toEffect(): Effect.Effect<R, E, B> {
1210
+ return Effect.map(this.ref, this.from)
598
1211
  }
1212
+ }
599
1213
 
600
- set: RefSubject<R, E, B>["set"] = (b) => Effect.map(this.ref.set(this.to(b)), this.from)
601
- update: RefSubject<R, E, B>["update"] = (f) => Effect.map(this.ref.update((a) => this.to(f(this.from(a)))), this.from)
1214
+ class RefSubjectTransformEffect<R, E, A, R2, E2, B, R3, E3>
1215
+ extends FxEffectBase<R | R2 | R3 | Scope.Scope, E | E2 | E3, B, R | R2 | R3, E | E2, B>
1216
+ implements RefSubject<R | R2 | R3, E | E2 | E3, B>
1217
+ {
1218
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1219
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
602
1220
 
603
- updateEffect: RefSubject<R, E, B>["updateEffect"] = (f) =>
604
- Effect.map(this.ref.updateEffect((a) => Effect.map(f(this.from(a)), this.to)), this.from)
1221
+ readonly version: Effect.Effect<R, E, number>
1222
+ readonly interrupt: Effect.Effect<R, never, void>
1223
+ readonly subscriberCount: Effect.Effect<R, never, number>
1224
+ readonly subject: Subject.Subject<never, E | E2 | E3, B>
605
1225
 
606
- modifyEffect: RefSubject<R, E, B>["modifyEffect"] = (f) =>
607
- this.ref.modifyEffect((a) => Effect.map(f(this.from(a)), ([c, b]) => [c, this.to(b)] as const))
1226
+ constructor(
1227
+ readonly ref: RefSubject<R, E, A>,
1228
+ readonly from: (a: A) => Effect.Effect<R2, E2, B>,
1229
+ readonly to: (b: B) => Effect.Effect<R3, E3, A>
1230
+ ) {
1231
+ super()
608
1232
 
609
- modify: RefSubject<R, E, B>["modify"] = (f) =>
610
- this.ref.modify((a) => {
611
- const [c, b] = f(this.from(a))
612
- return [c, this.to(b)] as const
1233
+ this.version = ref.version
1234
+ this.interrupt = ref.interrupt
1235
+ this.subscriberCount = ref.subscriberCount
1236
+ this.subject = Subject.unsafeMake()
1237
+ }
1238
+
1239
+ run<R4 = never>(sink: Sink.Sink<R4, E | E2 | E3, B>): Effect.Effect<R | R2 | R3 | Scope.Scope | R4, never, unknown> {
1240
+ return core.merge(core.mapEffect(this.ref, this.from), this.subject).run(sink)
1241
+ }
1242
+
1243
+ runUpdates<R4, E4, C>(
1244
+ run: (ref: GetSetDelete<R | R2 | R3, E | E2 | E3, B>) => Effect.Effect<R4, E4, C>
1245
+ ) {
1246
+ return this.ref.runUpdates((ref) =>
1247
+ run({
1248
+ get: Effect.flatMap(ref.get, this.from),
1249
+ set: (b: B) =>
1250
+ Effect.matchCauseEffect(Effect.flatMap(this.to(b), ref.set), {
1251
+ onFailure: (cause) => Effect.as(this.subject.onFailure(cause), b),
1252
+ onSuccess: () => Effect.as(this.subject.onSuccess(b), b)
1253
+ }),
1254
+ delete: Effect.flatMap(
1255
+ ref.delete,
1256
+ Option.match({
1257
+ onNone: () => Effect.succeedNone,
1258
+ onSome: (b) => Effect.asSome(this.from(b))
1259
+ })
1260
+ )
1261
+ })
1262
+ )
1263
+ }
1264
+
1265
+ onFailure(cause: Cause.Cause<E | E2 | E3>): Effect.Effect<R, never, unknown> {
1266
+ return this.subject.onFailure(cause)
1267
+ }
1268
+
1269
+ onSuccess(value: B): Effect.Effect<R | R3, never, unknown> {
1270
+ return Effect.matchCauseEffect(this.to(value), {
1271
+ onFailure: (cause) => this.subject.onFailure(cause),
1272
+ onSuccess: (a) => this.ref.onSuccess(a)
613
1273
  })
1274
+ }
614
1275
 
615
- runUpdate: RefSubject<R, E, B>["runUpdate"] = (f) =>
616
- this.ref.runUpdate((get, set) => f(Effect.map(get, this.from), (b) => Effect.map(set(this.to(b)), this.from)))
1276
+ toEffect(): Effect.Effect<R | R2, E | E2, B> {
1277
+ return Effect.flatMap(this.ref, this.from)
1278
+ }
1279
+ }
617
1280
 
618
- mapEffect: RefSubject<R, E, B>["mapEffect"] = (f) => Computed(this, f)
1281
+ /**
1282
+ * @since 1.20.0
1283
+ */
1284
+ export function tuple<
1285
+ const Refs extends ReadonlyArray<RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>>
1286
+ >(refs: Refs): TupleFrom<Refs> {
1287
+ const kind = getRefKind(refs)
1288
+ switch (kind) {
1289
+ case "r":
1290
+ return makeTupleRef(refs as any) as TupleFrom<Refs>
1291
+ case "c":
1292
+ return makeTupleComputed(refs as any) as TupleFrom<Refs>
1293
+ case "f":
1294
+ return makeTupleFiltered(refs as any) as any as TupleFrom<Refs>
1295
+ }
1296
+ }
619
1297
 
620
- map: RefSubject<R, E, B>["map"] = (f) => this.mapEffect((b) => Effect.sync(() => f(b)))
1298
+ type RefKind = "r" | "c" | "f"
621
1299
 
622
- filterMapEffect: RefSubject<R, E, B>["filterMapEffect"] = (f) => Filtered(this, f)
1300
+ const join = (a: RefKind, b: RefKind) => {
1301
+ if (a === "r") return b
1302
+ if (b === "r") return a
1303
+ if (a === "f") return a
1304
+ if (b === "f") return b
1305
+ return "c"
1306
+ }
623
1307
 
624
- filterMap: RefSubject<R, E, B>["filterMap"] = (f) => Filtered(this, (a) => Effect.sync(() => f(a)))
1308
+ function getRefKind<
1309
+ const Refs extends ReadonlyArray<RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>>
1310
+ >(refs: Refs): RefKind {
1311
+ let kind: RefKind = "r"
1312
+
1313
+ for (const ref of refs) {
1314
+ if (FilteredTypeId in ref) {
1315
+ kind = "f"
1316
+ break
1317
+ } else if (!(RefSubjectTypeId in ref)) {
1318
+ kind = join(kind, "c")
1319
+ }
1320
+ }
625
1321
 
626
- filter: RefSubject<R, E, B>["filter"] = (f) => this.filterMap((a) => f(a) ? Option.some(a) : Option.none())
1322
+ return kind
1323
+ }
627
1324
 
628
- filterEffect: RefSubject<R, E, B>["filterEffect"] = (f) =>
629
- this.filterMapEffect((a) => Effect.map(f(a), (b) => b ? Option.some(a) : Option.none()))
1325
+ /**
1326
+ * @since 1.20.0
1327
+ */
1328
+ export type TupleFrom<
1329
+ Refs extends ReadonlyArray<RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>>
1330
+ > = {
1331
+ "c": [ComputedTupleFrom<Refs>] extends [Computed<infer R, infer E, infer A>] ? Computed<R, E, A> : never
1332
+ "f": [FilteredTupleFrom<Refs>] extends [Filtered<infer R, infer E, infer A>] ? Filtered<R, E, A> : never
1333
+ "r": [RefSubjectTupleFrom<Refs>] extends [RefSubject<infer R, infer E, infer A>] ? RefSubject<R, E, A> : never
1334
+ }[GetTupleKind<Refs>]
630
1335
 
631
- onSuccess: RefSubject<R, E, B>["onSuccess"] = (b) => this.ref.onSuccess(this.to(b))
1336
+ type Ref = RefSubject.Any | Computed.Any | Filtered.Any
632
1337
 
633
- onFailure: RefSubject<R, E, B>["onFailure"] = (b) => this.ref.onFailure(b)
1338
+ /**
1339
+ * @since 1.20.0
1340
+ */
1341
+ export type GetTupleKind<Refs extends ReadonlyArray<Ref>, Kind extends RefKind = "r"> = Refs extends
1342
+ readonly [infer Head extends Ref, ...infer Tail extends ReadonlyArray<Ref>] ?
1343
+ GetTupleKind<Tail, MergeKind<Kind, MatchKind<Head>>>
1344
+ : Kind
634
1345
 
635
- skipRepeats: (eq?: Equivalence<B> | undefined) => Computed<R, E, B> = (eq = equals) =>
636
- Computed<R, E, B, never, never, B>(
637
- Versioned.transformFx<R, never, R, E, B, R, E, B, R, E, B>(
638
- this,
639
- skipRepeatsWith(eq)
640
- ),
641
- Effect.succeed
1346
+ /**
1347
+ * @since 1.20.0
1348
+ */
1349
+ export type MatchKind<T extends Ref> = [T] extends [Filtered.Any] ? "f"
1350
+ : [T] extends [RefSubject.Any] ? "r"
1351
+ : "c"
1352
+
1353
+ type MergeKind<A extends RefKind, B extends RefKind> = A extends "f" ? A
1354
+ : B extends "f" ? B
1355
+ : A extends "r" ? B
1356
+ : B extends "r" ? A
1357
+ : "c"
1358
+
1359
+ type FilteredTupleFrom<
1360
+ Refs extends ReadonlyArray<RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>>
1361
+ > = Filtered<
1362
+ Effect.Effect.Context<Refs[number]>,
1363
+ Fx.Error<Refs[number]>,
1364
+ {
1365
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1366
+ }
1367
+ >
1368
+
1369
+ type ComputedTupleFrom<
1370
+ Refs extends ReadonlyArray<RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>>
1371
+ > = Computed<
1372
+ Effect.Effect.Context<Refs[number]>,
1373
+ Effect.Effect.Error<Refs[number]>,
1374
+ {
1375
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1376
+ }
1377
+ >
1378
+
1379
+ type RefSubjectTupleFrom<
1380
+ Refs extends ReadonlyArray<RefSubject<any, any, any> | Computed<any, any, any> | Filtered<any, any, any>>
1381
+ > = RefSubject<
1382
+ Effect.Effect.Context<Refs[number]>,
1383
+ Effect.Effect.Error<Refs[number]>,
1384
+ {
1385
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1386
+ }
1387
+ >
1388
+
1389
+ function makeTupleRef<
1390
+ const Refs extends ReadonlyArray<RefSubject<any, any, any>>
1391
+ >(refs: Refs): RefSubjectTupleFrom<Refs> {
1392
+ return new RefSubjectTuple(refs)
1393
+ }
1394
+
1395
+ class RefSubjectTuple<
1396
+ const Refs extends ReadonlyArray<RefSubject<any, any, any>>
1397
+ > extends FxEffectBase<
1398
+ Effect.Effect.Context<Refs[number]>,
1399
+ Effect.Effect.Error<Refs[number]>,
1400
+ {
1401
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1402
+ },
1403
+ Effect.Effect.Context<Refs[number]>,
1404
+ Effect.Effect.Error<Refs[number]>,
1405
+ {
1406
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1407
+ }
1408
+ > implements RefSubjectTupleFrom<Refs> {
1409
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1410
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
1411
+
1412
+ readonly version: Effect.Effect<Effect.Effect.Context<Refs[number]>, Effect.Effect.Error<Refs[number]>, number>
1413
+ readonly interrupt: Effect.Effect<Effect.Effect.Context<Refs[number]>, never, void>
1414
+ readonly subscriberCount: Effect.Effect<Effect.Effect.Context<Refs[number]>, never, number>
1415
+
1416
+ private versioned: Versioned.Versioned<
1417
+ Effect.Effect.Context<Refs[number]>,
1418
+ Effect.Effect.Error<Refs[number]>,
1419
+ Effect.Effect.Context<Refs[number]>,
1420
+ Effect.Effect.Error<Refs[number]>,
1421
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> },
1422
+ Effect.Effect.Context<Refs[number]>,
1423
+ Effect.Effect.Error<Refs[number]>,
1424
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1425
+ >
1426
+
1427
+ private getSetDelete: GetSetDelete<
1428
+ Effect.Effect.Context<Refs[number]>,
1429
+ Effect.Effect.Error<Refs[number]>,
1430
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1431
+ >
1432
+
1433
+ constructor(
1434
+ readonly refs: Refs
1435
+ ) {
1436
+ super()
1437
+
1438
+ this.versioned = Versioned.tuple(refs) as any
1439
+ this.version = this.versioned.version
1440
+ this.interrupt = Effect.all(refs.map((r) => r.interrupt), UNBOUNDED)
1441
+ this.subscriberCount = Effect.map(
1442
+ Effect.all(refs.map((r) => r.subscriberCount), UNBOUNDED),
1443
+ ReadonlyArray.reduce(0, sum)
1444
+ )
1445
+
1446
+ this.getSetDelete = {
1447
+ get: this.versioned,
1448
+ set: (a) => Effect.all(refs.map((r, i) => set(r, a[i])), UNBOUNDED) as any,
1449
+ delete: Effect.map(Effect.all(refs.map((r) => reset(r)), UNBOUNDED), Option.all) as any
1450
+ }
1451
+
1452
+ this.runUpdates = this.runUpdates.bind(this)
1453
+ this.onFailure = this.onFailure.bind(this)
1454
+ this.onSuccess = this.onSuccess.bind(this)
1455
+ }
1456
+
1457
+ run<R2 = never>(
1458
+ sink: Sink.Sink<
1459
+ R2,
1460
+ Effect.Effect.Error<Refs[number]>,
1461
+ {
1462
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1463
+ }
1464
+ >
1465
+ ): Effect.Effect<Effect.Effect.Context<Refs[number]> | R2, never, unknown> {
1466
+ return this.versioned.run(sink)
1467
+ }
1468
+
1469
+ toEffect(): Effect.Effect<
1470
+ Effect.Effect.Context<Refs[number]>,
1471
+ Effect.Effect.Error<Refs[number]>,
1472
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1473
+ > {
1474
+ return this.versioned
1475
+ }
1476
+
1477
+ runUpdates<R2, E2, C>(
1478
+ run: (
1479
+ ref: GetSetDelete<
1480
+ Effect.Effect.Context<Refs[number]>,
1481
+ Effect.Effect.Error<Refs[number]>,
1482
+ {
1483
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1484
+ }
1485
+ >
1486
+ ) => Effect.Effect<R2, E2, C>
1487
+ ) {
1488
+ return run(this.getSetDelete)
1489
+ }
1490
+
1491
+ onFailure(
1492
+ cause: Cause.Cause<Effect.Effect.Error<Refs[number]>>
1493
+ ): Effect.Effect<Effect.Effect.Context<Refs[number]>, never, unknown> {
1494
+ return Effect.all(this.refs.map((ref) => ref.onFailure(cause)))
1495
+ }
1496
+
1497
+ onSuccess(
1498
+ value: { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1499
+ ): Effect.Effect<Effect.Effect.Context<Refs[number]>, never, unknown> {
1500
+ return Effect.catchAllCause(this.getSetDelete.set(value), (c) => this.onFailure(c))
1501
+ }
1502
+ }
1503
+
1504
+ function makeTupleComputed<
1505
+ const Refs extends ReadonlyArray<Computed<any, any, any>>
1506
+ >(refs: Refs): ComputedTupleFrom<Refs> {
1507
+ return new ComputedImpl(Versioned.tuple(refs) as any, Effect.succeed) as any
1508
+ }
1509
+
1510
+ function makeTupleFiltered<
1511
+ const Refs extends ReadonlyArray<Computed<any, any, any> | Filtered<any, any, any>>
1512
+ >(refs: Refs): FilteredTupleFrom<Refs> {
1513
+ return new FilteredImpl(Versioned.tuple(refs) as any, Effect.succeedSome) as any
1514
+ }
1515
+
1516
+ /**
1517
+ * @since 1.20.0
1518
+ */
1519
+ export function struct<
1520
+ const Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>
1521
+ >(refs: Refs): StructFrom<Refs> {
1522
+ const kind = getRefKind(Object.values(refs))
1523
+ switch (kind) {
1524
+ case "r":
1525
+ return makeStructRef(refs as any) as StructFrom<Refs>
1526
+ case "c":
1527
+ return makeStructComputed(refs as any) as StructFrom<Refs>
1528
+ case "f":
1529
+ return makeStructFiltered(refs as any) as any as StructFrom<Refs>
1530
+ }
1531
+ }
1532
+
1533
+ function makeStructRef<
1534
+ const Refs extends Readonly<Record<string, RefSubject.Any>>
1535
+ >(refs: Refs): RefSubjectStructFrom<Refs> {
1536
+ return new RefSubjectStruct(refs)
1537
+ }
1538
+
1539
+ class RefSubjectStruct<
1540
+ const Refs extends Readonly<Record<string, RefSubject.Any>>
1541
+ > extends FxEffectBase<
1542
+ Effect.Effect.Context<Refs[keyof Refs]> | Scope.Scope,
1543
+ Effect.Effect.Error<Refs[keyof Refs]>,
1544
+ {
1545
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1546
+ },
1547
+ Effect.Effect.Context<Refs[keyof Refs]>,
1548
+ Effect.Effect.Error<Refs[keyof Refs]>,
1549
+ {
1550
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1551
+ }
1552
+ > implements
1553
+ RefSubject<
1554
+ Effect.Effect.Context<Refs[keyof Refs]>,
1555
+ Effect.Effect.Error<Refs[keyof Refs]>,
1556
+ {
1557
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1558
+ }
1559
+ >
1560
+ {
1561
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1562
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
1563
+
1564
+ readonly version: Effect.Effect<
1565
+ Effect.Effect.Context<Refs[keyof Refs]>,
1566
+ Effect.Effect.Error<Refs[keyof Refs]>,
1567
+ number
1568
+ >
1569
+ readonly interrupt: Effect.Effect<Effect.Effect.Context<Refs[keyof Refs]>, never, void>
1570
+ readonly subscriberCount: Effect.Effect<Effect.Effect.Context<Refs[keyof Refs]>, never, number>
1571
+
1572
+ private versioned: Versioned.Versioned<
1573
+ Effect.Effect.Context<Refs[keyof Refs]>,
1574
+ Effect.Effect.Error<Refs[keyof Refs]>,
1575
+ Effect.Effect.Context<Refs[keyof Refs]>,
1576
+ Effect.Effect.Error<Refs[keyof Refs]>,
1577
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> },
1578
+ Effect.Effect.Context<Refs[keyof Refs]>,
1579
+ Effect.Effect.Error<Refs[keyof Refs]>,
1580
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1581
+ >
1582
+
1583
+ private getSetDelete: GetSetDelete<
1584
+ Effect.Effect.Context<Refs[keyof Refs]>,
1585
+ Effect.Effect.Error<Refs[keyof Refs]>,
1586
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1587
+ >
1588
+
1589
+ constructor(
1590
+ readonly refs: Refs
1591
+ ) {
1592
+ super()
1593
+
1594
+ this.versioned = Versioned.struct(refs) as any
1595
+ this.version = this.versioned.version
1596
+ this.interrupt = Effect.all(Object.values(refs).map((r) => r.interrupt), UNBOUNDED)
1597
+ this.subscriberCount = Effect.map(
1598
+ Effect.all(Object.values(refs).map((r) => r.subscriberCount), UNBOUNDED),
1599
+ ReadonlyArray.reduce(0, sum)
642
1600
  )
1601
+
1602
+ this.getSetDelete = {
1603
+ get: this.versioned,
1604
+ set: (a) => Effect.all(Object.keys(refs).map((k) => set(refs[k] as any, a[k])), UNBOUNDED) as any,
1605
+ delete: Effect.map(Effect.all(Object.values(refs).map((r) => reset(r as any)), UNBOUNDED), Option.all) as any
1606
+ }
1607
+
1608
+ this.runUpdates = this.runUpdates.bind(this)
1609
+ this.onFailure = this.onFailure.bind(this)
1610
+ this.onSuccess = this.onSuccess.bind(this)
1611
+ }
1612
+
1613
+ run<R3 = never>(
1614
+ sink: Sink.Sink<
1615
+ R3,
1616
+ Effect.Effect.Error<Refs[keyof Refs]>,
1617
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1618
+ >
1619
+ ): Effect.Effect<Effect.Effect.Context<Refs[keyof Refs]> | R3, never, unknown> {
1620
+ return this.versioned.run(sink)
1621
+ }
1622
+
1623
+ toEffect(): Effect.Effect<
1624
+ Effect.Effect.Context<Refs[keyof Refs]>,
1625
+ Effect.Effect.Error<Refs[keyof Refs]>,
1626
+ { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1627
+ > {
1628
+ return this.versioned
1629
+ }
1630
+
1631
+ runUpdates<R2, E2, C>(
1632
+ run: (
1633
+ ref: GetSetDelete<
1634
+ Effect.Effect.Context<Refs[keyof Refs]>,
1635
+ Effect.Effect.Error<Refs[keyof Refs]>,
1636
+ {
1637
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1638
+ }
1639
+ >
1640
+ ) => Effect.Effect<R2, E2, C>
1641
+ ) {
1642
+ return run(this.getSetDelete)
1643
+ }
1644
+
1645
+ onFailure(
1646
+ cause: Cause.Cause<Effect.Effect.Error<Refs[keyof Refs]>>
1647
+ ): Effect.Effect<Effect.Effect.Context<Refs[keyof Refs]>, never, unknown> {
1648
+ return Effect.all(Object.values(this.refs).map((ref) => ref.onFailure(cause as any)))
1649
+ }
1650
+
1651
+ onSuccess(
1652
+ value: { readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]> }
1653
+ ): Effect.Effect<Effect.Effect.Context<Refs[keyof Refs]>, never, unknown> {
1654
+ return Effect.catchAllCause(this.getSetDelete.set(value), (c) => this.onFailure(c))
1655
+ }
1656
+ }
1657
+
1658
+ function makeStructComputed<
1659
+ const Refs extends Readonly<Record<string, Computed<any, any, any>>>
1660
+ >(refs: Refs): ComputedStructFrom<Refs> {
1661
+ return new ComputedImpl(Versioned.struct(refs) as any, Effect.succeed) as any
1662
+ }
1663
+
1664
+ function makeStructFiltered<
1665
+ const Refs extends Readonly<Record<string, Computed<any, any, any> | Filtered<any, any, any>>>
1666
+ >(refs: Refs): FilteredStructFrom<Refs> {
1667
+ return new FilteredImpl(Versioned.struct(refs) as any, Effect.succeedSome) as any
1668
+ }
1669
+
1670
+ type StructFrom<
1671
+ Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>
1672
+ > = {
1673
+ "c": [ComputedStructFrom<Refs>] extends [Computed<infer R, infer E, infer A>] ? Computed<R, E, A> : never
1674
+ "f": [FilteredStructFrom<Refs>] extends [Filtered<infer R, infer E, infer A>] ? Filtered<R, E, A> : never
1675
+ "r": [RefSubjectStructFrom<Refs>] extends [RefSubject<infer R, infer E, infer A>] ? RefSubject<R, E, A> : never
1676
+ }[GetStructKind<Refs>]
1677
+
1678
+ /**
1679
+ * @since 1.20.0
1680
+ */
1681
+ export type GetStructKind<
1682
+ Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>
1683
+ > = MergeKinds<
1684
+ UnionToTuple<
1685
+ {
1686
+ [K in keyof Refs]: MatchKind<Refs[K]>
1687
+ }[keyof Refs]
1688
+ >
1689
+ >
1690
+
1691
+ type MergeKinds<Kinds extends ReadonlyArray<any>> = Kinds extends
1692
+ readonly [infer Head extends RefKind, ...infer Tail extends ReadonlyArray<RefKind>] ?
1693
+ MergeKind<Head, MergeKinds<Tail>>
1694
+ : "r"
1695
+
1696
+ type FilteredStructFrom<
1697
+ Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>
1698
+ > = Filtered<
1699
+ Effect.Effect.Context<Refs[keyof Refs]>,
1700
+ Fx.Error<Refs[keyof Refs]>,
1701
+ {
1702
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1703
+ }
1704
+ >
1705
+
1706
+ type ComputedStructFrom<
1707
+ Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>
1708
+ > = Computed<
1709
+ Effect.Effect.Context<Refs[keyof Refs]>,
1710
+ Effect.Effect.Error<Refs[keyof Refs]>,
1711
+ {
1712
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1713
+ }
1714
+ >
1715
+
1716
+ type RefSubjectStructFrom<
1717
+ Refs extends Readonly<Record<string, RefSubject.Any | Computed.Any | Filtered.Any>>
1718
+ > = RefSubject<
1719
+ Effect.Effect.Context<Refs[keyof Refs]>,
1720
+ Effect.Effect.Error<Refs[keyof Refs]>,
1721
+ {
1722
+ readonly [K in keyof Refs]: Effect.Effect.Success<Refs[K]>
1723
+ }
1724
+ >
1725
+
1726
+ /**
1727
+ * @since 1.20.0
1728
+ */
1729
+ export function tagged<E, A>(replay?: number): {
1730
+ <const I extends C.IdentifierFactory<any>>(identifier: I): RefSubject.Tagged<C.IdentifierOf<I>, E, A>
1731
+ <const I>(identifier: I): RefSubject.Tagged<C.IdentifierOf<I>, E, A>
1732
+ } {
1733
+ return <const I>(identifier: I) => new RefSubjectTagged(C.Tagged<I, RefSubject<never, E, A>>(identifier), replay)
1734
+ }
1735
+
1736
+ class RefSubjectTagged<I, E, A> extends FxEffectBase<
1737
+ I | Scope.Scope,
1738
+ E,
1739
+ A,
1740
+ I,
1741
+ E,
1742
+ A
1743
+ > implements RefSubject.Tagged<I, E, A> {
1744
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1745
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
1746
+
1747
+ readonly version: Effect.Effect<I, E, number>
1748
+ readonly interrupt: Effect.Effect<I, never, void>
1749
+ readonly subscriberCount: Effect.Effect<I, never, number>
1750
+
1751
+ constructor(
1752
+ readonly tag: C.Tagged<I, RefSubject<never, E, A>>,
1753
+ readonly replay: number = 0
1754
+ ) {
1755
+ super()
1756
+
1757
+ this.version = tag.withEffect((ref) => ref.version)
1758
+ this.interrupt = tag.withEffect((ref) => ref.interrupt)
1759
+ this.subscriberCount = tag.withEffect((ref) => ref.subscriberCount)
1760
+
1761
+ this.runUpdates = this.runUpdates.bind(this)
1762
+ this.onFailure = this.onFailure.bind(this)
1763
+ this.onSuccess = this.onSuccess.bind(this)
1764
+ }
1765
+
1766
+ run<R2 = never>(
1767
+ sink: Sink.Sink<R2, E, A>
1768
+ ): Effect.Effect<I | R2 | Scope.Scope, never, unknown> {
1769
+ return this.tag.withEffect((ref) => ref.run(sink))
1770
+ }
1771
+
1772
+ toEffect(): Effect.Effect<I, E, A> {
1773
+ return this.tag.withEffect((ref) => ref)
1774
+ }
1775
+
1776
+ runUpdates<R2, E2, C>(
1777
+ run: (ref: GetSetDelete<I, E, A>) => Effect.Effect<R2, E2, C>
1778
+ ): Effect.Effect<I | R2, E2, C> {
1779
+ return this.tag.withEffect((ref) => ref.runUpdates(run))
1780
+ }
1781
+
1782
+ onFailure(cause: Cause.Cause<E>): Effect.Effect<I, never, unknown> {
1783
+ return this.tag.withEffect((ref) => ref.onFailure(cause))
1784
+ }
1785
+
1786
+ onSuccess(value: A): Effect.Effect<I, never, unknown> {
1787
+ return this.tag.withEffect((ref) => ref.onSuccess(value))
1788
+ }
1789
+
1790
+ make = <R>(fxOrEffect: Fx<R, E, A> | Effect.Effect<R, E, A>): Layer.Layer<R, never, I> =>
1791
+ this.tag.scoped(make(fxOrEffect))
1792
+ }
1793
+
1794
+ /**
1795
+ * @since 1.20.0
1796
+ */
1797
+ export function fromTag<I, S, R, E, A>(
1798
+ tag: C.Tag<I, S>,
1799
+ f: (s: S) => RefSubject<R, E, A>
1800
+ ): RefSubject<I | R, E, A> {
1801
+ return new RefSubjectFromTag(tag, f)
1802
+ }
1803
+
1804
+ class RefSubjectFromTag<I, S, R, E, A> extends FxEffectBase<
1805
+ I | R | Scope.Scope,
1806
+ E,
1807
+ A,
1808
+ I | R,
1809
+ E,
1810
+ A
1811
+ > implements RefSubject<I | R, E, A> {
1812
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1813
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
1814
+
1815
+ readonly version: Effect.Effect<I | R, E, number>
1816
+ readonly interrupt: Effect.Effect<I | R, never, void>
1817
+ readonly subscriberCount: Effect.Effect<I | R, never, number>
1818
+
1819
+ private _get: Effect.Effect<I, never, RefSubject<R, E, A>>
1820
+ private _fx: Fx<I | R | Scope.Scope, E, A>
1821
+
1822
+ constructor(
1823
+ readonly tag: C.Tag<I, S>,
1824
+ readonly f: (s: S) => RefSubject<R, E, A>
1825
+ ) {
1826
+ super()
1827
+
1828
+ this._get = Effect.map(tag, f)
1829
+ this._fx = core.fromFxEffect(this._get)
1830
+
1831
+ this.version = Effect.flatMap(this._get, (ref) => ref.version)
1832
+ this.interrupt = Effect.flatMap(this._get, (ref) => ref.interrupt)
1833
+ this.subscriberCount = Effect.flatMap(this._get, (ref) => ref.subscriberCount)
1834
+ }
1835
+
1836
+ run<R3>(sink: Sink.Sink<R3, E, A>): Effect.Effect<I | R | R3 | Scope.Scope, never, unknown> {
1837
+ return this._fx.run(sink)
1838
+ }
1839
+
1840
+ toEffect(): Effect.Effect<I | R, E, A> {
1841
+ return Effect.flatten(this._get)
1842
+ }
1843
+
1844
+ runUpdates<R2, E2, C>(
1845
+ run: (ref: GetSetDelete<I | R, E, A>) => Effect.Effect<R2, E2, C>
1846
+ ): Effect.Effect<I | R | R2, E2, C> {
1847
+ return Effect.flatMap(this._get, (ref) => ref.runUpdates(run))
1848
+ }
1849
+
1850
+ onFailure(cause: Cause.Cause<E>): Effect.Effect<I | R, never, unknown> {
1851
+ return Effect.flatMap(this._get, (ref) => ref.onFailure(cause))
1852
+ }
1853
+
1854
+ onSuccess(value: A): Effect.Effect<I | R, never, unknown> {
1855
+ return Effect.flatMap(this._get, (ref) => ref.onSuccess(value))
1856
+ }
1857
+ }
1858
+
1859
+ /**
1860
+ * @since 1.20.0
1861
+ */
1862
+ export function isRefSubject<R, E, A>(u: unknown): u is RefSubject<R, E, A>
1863
+ export function isRefSubject(u: unknown): u is RefSubject.Any
1864
+ export function isRefSubject(u: unknown): u is RefSubject.Any {
1865
+ return isObjectLike(u) && RefSubjectTypeId in u
1866
+ }
1867
+
1868
+ /**
1869
+ * @since 1.20.0
1870
+ */
1871
+ export function isComputed<R, E, A>(u: unknown): u is Computed<R, E, A>
1872
+ export function isComputed(u: unknown): u is Computed.Any
1873
+ export function isComputed(u: unknown): u is Computed.Any {
1874
+ return isObjectLike(u) && ComputedTypeId in u
1875
+ }
1876
+
1877
+ /**
1878
+ * @since 1.20.0
1879
+ */
1880
+ export function isFiltered<R, E, A>(u: unknown): u is Filtered<R, E, A>
1881
+ export function isFiltered(u: unknown): u is Filtered.Any
1882
+ export function isFiltered(u: unknown): u is Filtered.Any {
1883
+ return isObjectLike(u) && FilteredTypeId in u
1884
+ }
1885
+
1886
+ /**
1887
+ * @since 1.20.0
1888
+ */
1889
+ export function isDerived<R, E, A>(u: unknown): u is RefSubject.Derived<R, E, A>
1890
+ export function isDerived(u: unknown): u is RefSubject.Derived<unknown, unknown, unknown>
1891
+ export function isDerived(u: unknown): u is RefSubject.Derived<unknown, unknown, unknown> {
1892
+ return isRefSubject(u) && "persist" in u
1893
+ }
1894
+
1895
+ function isObjectLike(u: unknown): u is object {
1896
+ if (u == null) return false
1897
+
1898
+ const type = typeof u
1899
+
1900
+ return (type === "object" && !Array.isArray(u)) || type === "function"
1901
+ }
1902
+
1903
+ /**
1904
+ * @since 1.20.0
1905
+ */
1906
+ export function computedFromTag<I, S, R, E, A>(
1907
+ tag: C.Tag<I, S>,
1908
+ f: (s: S) => Computed<R, E, A>
1909
+ ): Computed<I | R, E, A> {
1910
+ return new ComputedFromTag(tag, f)
1911
+ }
1912
+
1913
+ class ComputedFromTag<I, S, R, E, A> extends FxEffectBase<
1914
+ I | R | Scope.Scope,
1915
+ E,
1916
+ A,
1917
+ I | R,
1918
+ E,
1919
+ A
1920
+ > implements Computed<I | R, E, A> {
1921
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
1922
+
1923
+ readonly version: Effect.Effect<I | R, E, number>
1924
+
1925
+ private _get: Effect.Effect<I, never, Computed<R, E, A>>
1926
+
1927
+ constructor(
1928
+ readonly tag: C.Tag<I, S>,
1929
+ readonly f: (s: S) => Computed<R, E, A>
1930
+ ) {
1931
+ super()
1932
+
1933
+ this._get = Effect.map(tag, f)
1934
+ this.version = Effect.flatMap(this._get, (ref) => ref.version)
1935
+ }
1936
+
1937
+ run<R3>(sink: Sink.Sink<R3, E, A>): Effect.Effect<I | R | Scope.Scope | R3, never, unknown> {
1938
+ return Effect.flatMap(this._get, (ref) => ref.run(sink))
1939
+ }
1940
+
1941
+ toEffect(): Effect.Effect<I | R, E, A> {
1942
+ return Effect.flatten(this._get)
1943
+ }
1944
+ }
1945
+
1946
+ /**
1947
+ * @since 1.20.0
1948
+ */
1949
+ export function filteredFromTag<I, S, R, E, A>(
1950
+ tag: C.Tag<I, S>,
1951
+ f: (s: S) => Filtered<R, E, A>
1952
+ ): Filtered<I | R, E, A> {
1953
+ return new FilteredFromTag(tag, f)
1954
+ }
1955
+
1956
+ class FilteredFromTag<I, S, R, E, A> extends FxEffectBase<
1957
+ I | R | Scope.Scope,
1958
+ E,
1959
+ A,
1960
+ I | R,
1961
+ E | Cause.NoSuchElementException,
1962
+ A
1963
+ > implements Filtered<I | R, E, A> {
1964
+ readonly [FilteredTypeId]: FilteredTypeId = FilteredTypeId
1965
+
1966
+ readonly version: Effect.Effect<I | R, E, number>
1967
+
1968
+ private _get: Effect.Effect<I, never, Filtered<R, E, A>>
1969
+
1970
+ constructor(
1971
+ readonly tag: C.Tag<I, S>,
1972
+ readonly f: (s: S) => Filtered<R, E, A>
1973
+ ) {
1974
+ super()
1975
+
1976
+ this._get = Effect.map(tag, f)
1977
+ this.version = Effect.flatMap(this._get, (ref) => ref.version)
1978
+ }
1979
+
1980
+ run<R3>(sink: Sink.Sink<R3, E, A>): Effect.Effect<I | R | Scope.Scope | R3, never, unknown> {
1981
+ return Effect.flatMap(this._get, (ref) => ref.run(sink))
1982
+ }
1983
+
1984
+ toEffect(): Effect.Effect<I | R, E | Cause.NoSuchElementException, A> {
1985
+ return Effect.flatten(this._get)
1986
+ }
1987
+
1988
+ asComputed(): Computed<I | R, E, Option.Option<A>> {
1989
+ return new ComputedFromTag(this.tag, (s) => this.f(s).asComputed())
1990
+ }
1991
+ }
1992
+
1993
+ /**
1994
+ * @since 1.20.0
1995
+ */
1996
+ export const provide: {
1997
+ <S>(context: C.Context<S> | Runtime.Runtime<S>): {
1998
+ <R, E, A>(filtered: Filtered<R, E, A>): Filtered<Exclude<R, S>, E, A>
1999
+ <R, E, A>(computed: Computed<R, E, A>): Computed<Exclude<R, S>, E, A>
2000
+ <R, E, A>(ref: RefSubject<R, E, A>): RefSubject<Exclude<R, S>, E, A>
2001
+ }
2002
+
2003
+ <R2, S>(layer: Layer.Layer<R2, never, S>): {
2004
+ <R, E, A>(filtered: Filtered<R, E, A>): Filtered<Exclude<R, S> | R2, E, A>
2005
+ <R, E, A>(computed: Computed<R, E, A>): Computed<Exclude<R, S> | R2, E, A>
2006
+ <R, E, A>(ref: RefSubject<R, E, A>): RefSubject<Exclude<R, S> | R2, E, A>
2007
+ }
2008
+
2009
+ <R, E, A, S>(
2010
+ filtered: Filtered<R, E, A>,
2011
+ context: C.Context<S> | Runtime.Runtime<S>
2012
+ ): Filtered<Exclude<R, S>, E, A>
2013
+ <R, E, A, S>(
2014
+ computed: Computed<R, E, A>,
2015
+ context: C.Context<S> | Runtime.Runtime<S>
2016
+ ): Computed<Exclude<R, S>, E, A>
2017
+ <R, E, A, S>(
2018
+ ref: RefSubject<R, E, A>,
2019
+ context: C.Context<S> | Runtime.Runtime<S>
2020
+ ): RefSubject<Exclude<R, S>, E, A>
2021
+
2022
+ <R, E, A, R2, S>(filtered: Filtered<R, E, A>, layer: Layer.Layer<R2, never, S>): Filtered<Exclude<R, S> | R2, E, A>
2023
+ <R, E, A, R2, S>(computed: Computed<R, E, A>, layer: Layer.Layer<R2, never, S>): Computed<Exclude<R, S> | R2, E, A>
2024
+ <R, E, A, R2, S>(ref: RefSubject<R, E, A>, layer: Layer.Layer<R2, never, S>): RefSubject<Exclude<R, S> | R2, E, A>
2025
+ } = dual(2, function provide<R, E, A, R2 = never, S = never>(
2026
+ ref: RefSubject<R, E, A> | Computed<R, E, A> | Filtered<R, E, A>,
2027
+ providing: Layer.Layer<R2, never, S> | C.Context<S> | Runtime.Runtime<S>
2028
+ ) {
2029
+ const layer = Layer.isLayer(providing)
2030
+ ? providing as Layer.Layer<R2, never, S>
2031
+ : C.isContext(providing)
2032
+ ? Layer.succeedContext(providing)
2033
+ : runtimeToLayer(providing as Runtime.Runtime<S>)
2034
+
2035
+ if (isComputed(ref)) {
2036
+ return ComputedImpl.make(Versioned.provide(ref, layer), Effect.succeed) as any
2037
+ } else if (isFiltered(ref)) {
2038
+ return FilteredImpl.make(Versioned.provide(ref, layer), Effect.succeedSome) as any
2039
+ } else {
2040
+ return new RefSubjectProvide(ref, layer)
2041
+ }
2042
+ })
2043
+
2044
+ class RefSubjectProvide<R, E, A, R2, S> extends FxEffectBase<
2045
+ Exclude<R, S> | R2 | Scope.Scope,
2046
+ E,
2047
+ A,
2048
+ Exclude<R, S> | R2,
2049
+ E,
2050
+ A
2051
+ > {
2052
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
2053
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
2054
+
2055
+ readonly interrupt: Effect.Effect<Exclude<R, S> | R2, never, void>
2056
+ readonly subscriberCount: Effect.Effect<Exclude<R, S> | R2, never, number>
2057
+
2058
+ constructor(
2059
+ readonly ref: RefSubject<R, E, A>,
2060
+ readonly layer: Layer.Layer<R2, never, S>
2061
+ ) {
2062
+ super()
2063
+
2064
+ this.interrupt = Effect.provide(ref.interrupt, layer)
2065
+ this.subscriberCount = Effect.provide(ref.subscriberCount, layer)
2066
+ }
2067
+
2068
+ run<R3>(
2069
+ sink: Sink.Sink<R3, E, A>
2070
+ ): Effect.Effect<R2 | Scope.Scope | Exclude<Scope.Scope, S> | Exclude<R, S> | Exclude<R3, S>, never, unknown> {
2071
+ return Effect.provide(this.ref.run(sink), this.layer)
2072
+ }
2073
+
2074
+ toEffect(): Effect.Effect<Exclude<R, S> | R2, E, A> {
2075
+ return Effect.provide(this.ref, this.layer)
2076
+ }
2077
+ }
2078
+
2079
+ /**
2080
+ * Set the value to true
2081
+ * @since 1.18.0
2082
+ */
2083
+ export const asTrue: <R, E>(ref: RefSubject<R, E, boolean>) => Effect.Effect<R, E, boolean> = <R, E>(
2084
+ ref: RefSubject<R, E, boolean>
2085
+ ) => set(ref, true)
2086
+
2087
+ /**
2088
+ * Set the value to false
2089
+ * @since 1.18.0
2090
+ */
2091
+ export const asFalse: <R, E>(ref: RefSubject<R, E, boolean>) => Effect.Effect<R, E, boolean> = <R, E>(
2092
+ ref: RefSubject<R, E, boolean>
2093
+ ) => set(ref, false)
2094
+
2095
+ /**
2096
+ * Toggle the boolean value between true and false
2097
+ * @since 1.18.0
2098
+ */
2099
+ export const toggle: <R, E>(ref: RefSubject<R, E, boolean>) => Effect.Effect<R, E, boolean> = <R, E>(
2100
+ ref: RefSubject<R, E, boolean>
2101
+ ) => update(ref, Boolean.not)
2102
+
2103
+ const add = (x: number): number => x + 1
2104
+
2105
+ /**
2106
+ * Set the value to true
2107
+ * @since 1.18.0
2108
+ */
2109
+ export const increment: <R, E>(ref: RefSubject<R, E, number>) => Effect.Effect<R, E, number> = <R, E>(
2110
+ ref: RefSubject<R, E, number>
2111
+ ) => update(ref, add)
2112
+
2113
+ const sub = (x: number): number => x - 1
2114
+
2115
+ /**
2116
+ * Set the value to false
2117
+ * @since 1.18.0
2118
+ */
2119
+ export const decrement: <R, E>(ref: RefSubject<R, E, number>) => Effect.Effect<R, E, number> = <R, E>(
2120
+ ref: RefSubject<R, E, number>
2121
+ ) => update(ref, sub)
2122
+
2123
+ /**
2124
+ * @since 1.20.0
2125
+ */
2126
+ export const slice: {
2127
+ (drop: number, take: number): <R, E, A>(ref: RefSubject<R, E, A>) => RefSubject<R, E, A>
2128
+ <R, E, A>(ref: RefSubject<R, E, A>, drop: number, take: number): RefSubject<R, E, A>
2129
+ } = dual(
2130
+ 3,
2131
+ function slice<R, E, A>(ref: RefSubject<R, E, A>, drop: number, take: number): RefSubject<R, E, A> {
2132
+ return new RefSubjectSlice(ref, drop, take)
2133
+ }
2134
+ )
2135
+
2136
+ /**
2137
+ * @since 1.20.0
2138
+ */
2139
+ export const drop: {
2140
+ (drop: number): <R, E, A>(ref: RefSubject<R, E, A>) => RefSubject<R, E, A>
2141
+ <R, E, A>(ref: RefSubject<R, E, A>, drop: number): RefSubject<R, E, A>
2142
+ } = dual(2, function drop<R, E, A>(ref: RefSubject<R, E, A>, drop: number): RefSubject<R, E, A> {
2143
+ return slice(ref, drop, Infinity)
2144
+ })
2145
+
2146
+ /**
2147
+ * @since 1.20.0
2148
+ */
2149
+ export const take: {
2150
+ (take: number): <R, E, A>(ref: RefSubject<R, E, A>) => RefSubject<R, E, A>
2151
+ <R, E, A>(ref: RefSubject<R, E, A>, take: number): RefSubject<R, E, A>
2152
+ } = dual(2, function take<R, E, A>(ref: RefSubject<R, E, A>, take: number): RefSubject<R, E, A> {
2153
+ return slice(ref, 0, take)
2154
+ })
2155
+
2156
+ class RefSubjectSlice<R, E, A> extends FxEffectBase<R | Scope.Scope, E, A, R, E, A> implements RefSubject<R, E, A> {
2157
+ readonly [ComputedTypeId]: ComputedTypeId = ComputedTypeId
2158
+ readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
2159
+
2160
+ readonly version: Effect.Effect<R, E, number>
2161
+ readonly interrupt: Effect.Effect<R, never, void>
2162
+ readonly subscriberCount: Effect.Effect<R, never, number>
2163
+ private _fx: Fx<Scope.Scope | R, E, A>
2164
+
2165
+ constructor(
2166
+ readonly ref: RefSubject<R, E, A>,
2167
+ readonly drop: number,
2168
+ readonly take: number
2169
+ ) {
2170
+ super()
2171
+
2172
+ this.version = ref.version
2173
+ this.interrupt = ref.interrupt
2174
+ this.subscriberCount = ref.subscriberCount
2175
+ this._fx = share.hold(core.slice(ref, drop, take))
2176
+ this._effect = ref
2177
+ }
2178
+
2179
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2 | Scope.Scope, never, unknown> {
2180
+ return this._fx.run(sink)
2181
+ }
2182
+
2183
+ toEffect(): Effect.Effect<R, E, A> {
2184
+ return this.ref
2185
+ }
2186
+
2187
+ runUpdates<R2, E2, C>(
2188
+ run: (ref: GetSetDelete<R, E, A>) => Effect.Effect<R2, E2, C>
2189
+ ): Effect.Effect<R | R2, E2, C> {
2190
+ return this.ref.runUpdates(run)
2191
+ }
2192
+
2193
+ onFailure(cause: Cause.Cause<E>): Effect.Effect<R, never, unknown> {
2194
+ return this.ref.onFailure(cause)
2195
+ }
2196
+
2197
+ onSuccess(value: A): Effect.Effect<R, never, unknown> {
2198
+ return this.ref.onSuccess(value)
2199
+ }
643
2200
  }