@typed/fx 1.18.4 → 1.20.0

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