@typed/fx 1.12.6 → 1.14.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 (610) hide show
  1. package/dist/Computed.d.ts +42 -0
  2. package/dist/Computed.d.ts.map +1 -0
  3. package/dist/Computed.js +39 -0
  4. package/dist/Computed.js.map +1 -0
  5. package/dist/Filtered.d.ts +34 -0
  6. package/dist/Filtered.d.ts.map +1 -0
  7. package/dist/Filtered.js +40 -0
  8. package/dist/Filtered.js.map +1 -0
  9. package/dist/Fx.d.ts +2 -3
  10. package/dist/Fx.d.ts.map +1 -1
  11. package/dist/Fx.js +11 -26
  12. package/dist/Fx.js.map +1 -1
  13. package/dist/RefArray.d.ts +116 -0
  14. package/dist/RefArray.d.ts.map +1 -0
  15. package/dist/RefArray.js +67 -0
  16. package/dist/RefArray.js.map +1 -0
  17. package/dist/RefSubject.d.ts +25 -21
  18. package/dist/RefSubject.d.ts.map +1 -1
  19. package/dist/RefSubject.js +356 -248
  20. package/dist/RefSubject.js.map +1 -1
  21. package/dist/RefTransform.d.ts +51 -0
  22. package/dist/RefTransform.d.ts.map +1 -0
  23. package/dist/RefTransform.js +69 -0
  24. package/dist/RefTransform.js.map +1 -0
  25. package/dist/Subject.d.ts +1 -1
  26. package/dist/Subject.d.ts.map +1 -1
  27. package/dist/Subject.js +4 -4
  28. package/dist/Subject.js.map +1 -1
  29. package/dist/at.d.ts +1 -1
  30. package/dist/at.d.ts.map +1 -1
  31. package/dist/at.js +1 -1
  32. package/dist/at.js.map +1 -1
  33. package/dist/catchAllCause.d.ts +8 -1
  34. package/dist/catchAllCause.d.ts.map +1 -1
  35. package/dist/catchAllCause.js +23 -3
  36. package/dist/catchAllCause.js.map +1 -1
  37. package/dist/cjs/Computed.d.ts +42 -0
  38. package/dist/cjs/Computed.d.ts.map +1 -0
  39. package/dist/cjs/Computed.js +66 -0
  40. package/dist/cjs/Computed.js.map +1 -0
  41. package/dist/cjs/Filtered.d.ts +34 -0
  42. package/dist/cjs/Filtered.d.ts.map +1 -0
  43. package/dist/cjs/Filtered.js +67 -0
  44. package/dist/cjs/Filtered.js.map +1 -0
  45. package/dist/cjs/Fx.d.ts +2 -3
  46. package/dist/cjs/Fx.d.ts.map +1 -1
  47. package/dist/cjs/Fx.js +13 -28
  48. package/dist/cjs/Fx.js.map +1 -1
  49. package/dist/cjs/RefArray.d.ts +116 -0
  50. package/dist/cjs/RefArray.d.ts.map +1 -0
  51. package/dist/cjs/RefArray.js +97 -0
  52. package/dist/cjs/RefArray.js.map +1 -0
  53. package/dist/cjs/RefSubject.d.ts +25 -21
  54. package/dist/cjs/RefSubject.d.ts.map +1 -1
  55. package/dist/cjs/RefSubject.js +363 -251
  56. package/dist/cjs/RefSubject.js.map +1 -1
  57. package/dist/cjs/RefTransform.d.ts +51 -0
  58. package/dist/cjs/RefTransform.d.ts.map +1 -0
  59. package/dist/cjs/RefTransform.js +96 -0
  60. package/dist/cjs/RefTransform.js.map +1 -0
  61. package/dist/cjs/Subject.d.ts +1 -1
  62. package/dist/cjs/Subject.d.ts.map +1 -1
  63. package/dist/cjs/Subject.js +27 -4
  64. package/dist/cjs/Subject.js.map +1 -1
  65. package/dist/cjs/at.d.ts +1 -1
  66. package/dist/cjs/at.d.ts.map +1 -1
  67. package/dist/cjs/at.js +25 -2
  68. package/dist/cjs/at.js.map +1 -1
  69. package/dist/cjs/catchAllCause.d.ts +8 -1
  70. package/dist/cjs/catchAllCause.d.ts.map +1 -1
  71. package/dist/cjs/catchAllCause.js +48 -3
  72. package/dist/cjs/catchAllCause.js.map +1 -1
  73. package/dist/cjs/combineAll.d.ts.map +1 -1
  74. package/dist/cjs/combineAll.js +29 -6
  75. package/dist/cjs/combineAll.js.map +1 -1
  76. package/dist/cjs/combineAllDiscard.d.ts.map +1 -1
  77. package/dist/cjs/combineAllDiscard.js +28 -5
  78. package/dist/cjs/combineAllDiscard.js.map +1 -1
  79. package/dist/cjs/continueWith.d.ts +1 -1
  80. package/dist/cjs/continueWith.d.ts.map +1 -1
  81. package/dist/cjs/continueWith.js +25 -2
  82. package/dist/cjs/continueWith.js.map +1 -1
  83. package/dist/cjs/data-first.d.ts +10 -0
  84. package/dist/cjs/data-first.d.ts.map +1 -1
  85. package/dist/cjs/data-first.js +10 -0
  86. package/dist/cjs/data-first.js.map +1 -1
  87. package/dist/cjs/debounce.d.ts +1 -1
  88. package/dist/cjs/debounce.d.ts.map +1 -1
  89. package/dist/cjs/debounce.js +25 -2
  90. package/dist/cjs/debounce.js.map +1 -1
  91. package/dist/cjs/delay.d.ts.map +1 -1
  92. package/dist/cjs/delay.js +25 -2
  93. package/dist/cjs/delay.js.map +1 -1
  94. package/dist/cjs/empty.js +1 -1
  95. package/dist/cjs/empty.js.map +1 -1
  96. package/dist/cjs/exhaustMap.d.ts +1 -1
  97. package/dist/cjs/exhaustMap.d.ts.map +1 -1
  98. package/dist/cjs/exhaustMap.js.map +1 -1
  99. package/dist/cjs/exhaustMapCause.d.ts +2 -1
  100. package/dist/cjs/exhaustMapCause.d.ts.map +1 -1
  101. package/dist/cjs/exhaustMapCause.js +26 -2
  102. package/dist/cjs/exhaustMapCause.js.map +1 -1
  103. package/dist/cjs/exhaustMapLatest.d.ts +1 -1
  104. package/dist/cjs/exhaustMapLatest.d.ts.map +1 -1
  105. package/dist/cjs/exhaustMapLatest.js.map +1 -1
  106. package/dist/cjs/exhaustMapLatestCause.d.ts +2 -1
  107. package/dist/cjs/exhaustMapLatestCause.d.ts.map +1 -1
  108. package/dist/cjs/exhaustMapLatestCause.js +26 -2
  109. package/dist/cjs/exhaustMapLatestCause.js.map +1 -1
  110. package/dist/cjs/failCause.d.ts +1 -0
  111. package/dist/cjs/failCause.d.ts.map +1 -1
  112. package/dist/cjs/failCause.js +5 -1
  113. package/dist/cjs/failCause.js.map +1 -1
  114. package/dist/cjs/filter.d.ts.map +1 -1
  115. package/dist/cjs/filter.js +25 -2
  116. package/dist/cjs/filter.js.map +1 -1
  117. package/dist/cjs/filterMap.d.ts +1 -1
  118. package/dist/cjs/filterMap.d.ts.map +1 -1
  119. package/dist/cjs/filterMap.js +26 -2
  120. package/dist/cjs/filterMap.js.map +1 -1
  121. package/dist/cjs/flatMap.d.ts +1 -1
  122. package/dist/cjs/flatMap.d.ts.map +1 -1
  123. package/dist/cjs/flatMap.js.map +1 -1
  124. package/dist/cjs/fromArray.d.ts.map +1 -1
  125. package/dist/cjs/fromArray.js +27 -4
  126. package/dist/cjs/fromArray.js.map +1 -1
  127. package/dist/cjs/fromDequeue.d.ts +5 -0
  128. package/dist/cjs/fromDequeue.d.ts.map +1 -0
  129. package/dist/cjs/fromDequeue.js +49 -0
  130. package/dist/cjs/fromDequeue.js.map +1 -0
  131. package/dist/cjs/fromEffect.d.ts +1 -1
  132. package/dist/cjs/fromEffect.d.ts.map +1 -1
  133. package/dist/cjs/fromEffect.js +33 -2
  134. package/dist/cjs/fromEffect.js.map +1 -1
  135. package/dist/cjs/fromEmitter.d.ts +2 -2
  136. package/dist/cjs/fromEmitter.d.ts.map +1 -1
  137. package/dist/cjs/fromEmitter.js +35 -11
  138. package/dist/cjs/fromEmitter.js.map +1 -1
  139. package/dist/cjs/fromFxEffect.d.ts +1 -1
  140. package/dist/cjs/fromFxEffect.d.ts.map +1 -1
  141. package/dist/cjs/fromFxEffect.js +25 -2
  142. package/dist/cjs/fromFxEffect.js.map +1 -1
  143. package/dist/cjs/fromHub.d.ts +5 -0
  144. package/dist/cjs/fromHub.d.ts.map +1 -0
  145. package/dist/cjs/fromHub.js +34 -0
  146. package/dist/cjs/fromHub.js.map +1 -0
  147. package/dist/cjs/fromIterable.d.ts.map +1 -1
  148. package/dist/cjs/fromIterable.js +27 -4
  149. package/dist/cjs/fromIterable.js.map +1 -1
  150. package/dist/cjs/fromStream.d.ts +4 -0
  151. package/dist/cjs/fromStream.d.ts.map +1 -0
  152. package/dist/cjs/fromStream.js +34 -0
  153. package/dist/cjs/fromStream.js.map +1 -0
  154. package/dist/cjs/gen.d.ts +1 -1
  155. package/dist/cjs/gen.d.ts.map +1 -1
  156. package/dist/cjs/gen.js +25 -2
  157. package/dist/cjs/gen.js.map +1 -1
  158. package/dist/cjs/helpers.d.ts +5 -3
  159. package/dist/cjs/helpers.d.ts.map +1 -1
  160. package/dist/cjs/helpers.js +59 -72
  161. package/dist/cjs/helpers.js.map +1 -1
  162. package/dist/cjs/hold.d.ts +5 -5
  163. package/dist/cjs/hold.d.ts.map +1 -1
  164. package/dist/cjs/hold.js +32 -11
  165. package/dist/cjs/hold.js.map +1 -1
  166. package/dist/cjs/index.d.ts +43 -2
  167. package/dist/cjs/index.d.ts.map +1 -1
  168. package/dist/cjs/index.js +185 -119
  169. package/dist/cjs/index.js.map +1 -1
  170. package/dist/cjs/keyed.d.ts.map +1 -1
  171. package/dist/cjs/keyed.js +32 -41
  172. package/dist/cjs/keyed.js.map +1 -1
  173. package/dist/cjs/map.d.ts.map +1 -1
  174. package/dist/cjs/map.js +25 -2
  175. package/dist/cjs/map.js.map +1 -1
  176. package/dist/cjs/mergeAll.d.ts.map +1 -1
  177. package/dist/cjs/mergeAll.js +28 -3
  178. package/dist/cjs/mergeAll.js.map +1 -1
  179. package/dist/cjs/mergeBufferConcurrently.d.ts +8 -0
  180. package/dist/cjs/mergeBufferConcurrently.d.ts.map +1 -0
  181. package/dist/cjs/mergeBufferConcurrently.js +95 -0
  182. package/dist/cjs/mergeBufferConcurrently.js.map +1 -0
  183. package/dist/cjs/mergeConcurrently.d.ts +3 -0
  184. package/dist/cjs/mergeConcurrently.d.ts.map +1 -0
  185. package/dist/cjs/mergeConcurrently.js +69 -0
  186. package/dist/cjs/mergeConcurrently.js.map +1 -0
  187. package/dist/cjs/multicast.d.ts +10 -8
  188. package/dist/cjs/multicast.d.ts.map +1 -1
  189. package/dist/cjs/multicast.js +43 -19
  190. package/dist/cjs/multicast.js.map +1 -1
  191. package/dist/cjs/never.d.ts.map +1 -1
  192. package/dist/cjs/never.js +25 -2
  193. package/dist/cjs/never.js.map +1 -1
  194. package/dist/cjs/observe.d.ts +4 -1
  195. package/dist/cjs/observe.d.ts.map +1 -1
  196. package/dist/cjs/observe.js +40 -10
  197. package/dist/cjs/observe.js.map +1 -1
  198. package/dist/cjs/onExit.d.ts +5 -0
  199. package/dist/cjs/onExit.d.ts.map +1 -0
  200. package/dist/cjs/onExit.js +33 -0
  201. package/dist/cjs/onExit.js.map +1 -0
  202. package/dist/cjs/onInterrupt.d.ts +1 -1
  203. package/dist/cjs/onInterrupt.d.ts.map +1 -1
  204. package/dist/cjs/onInterrupt.js +25 -2
  205. package/dist/cjs/onInterrupt.js.map +1 -1
  206. package/dist/cjs/orElse.d.ts +4 -0
  207. package/dist/cjs/orElse.d.ts.map +1 -0
  208. package/dist/cjs/orElse.js +34 -0
  209. package/dist/cjs/orElse.js.map +1 -0
  210. package/dist/cjs/promise.d.ts.map +1 -1
  211. package/dist/cjs/promise.js +36 -13
  212. package/dist/cjs/promise.js.map +1 -1
  213. package/dist/cjs/provide.d.ts +3 -2
  214. package/dist/cjs/provide.d.ts.map +1 -1
  215. package/dist/cjs/provide.js +34 -7
  216. package/dist/cjs/provide.js.map +1 -1
  217. package/dist/cjs/reduce.d.ts +2 -1
  218. package/dist/cjs/reduce.d.ts.map +1 -1
  219. package/dist/cjs/reduce.js +26 -3
  220. package/dist/cjs/reduce.js.map +1 -1
  221. package/dist/cjs/scan.d.ts.map +1 -1
  222. package/dist/cjs/scan.js +26 -3
  223. package/dist/cjs/scan.js.map +1 -1
  224. package/dist/cjs/scoped.d.ts +1 -1
  225. package/dist/cjs/scoped.d.ts.map +1 -1
  226. package/dist/cjs/scoped.js +25 -2
  227. package/dist/cjs/scoped.js.map +1 -1
  228. package/dist/cjs/skipRepeats.d.ts +1 -1
  229. package/dist/cjs/skipRepeats.d.ts.map +1 -1
  230. package/dist/cjs/skipRepeats.js +34 -9
  231. package/dist/cjs/skipRepeats.js.map +1 -1
  232. package/dist/cjs/skipWhile.d.ts.map +1 -1
  233. package/dist/cjs/skipWhile.js +27 -4
  234. package/dist/cjs/skipWhile.js.map +1 -1
  235. package/dist/cjs/slice.d.ts.map +1 -1
  236. package/dist/cjs/slice.js +29 -6
  237. package/dist/cjs/slice.js.map +1 -1
  238. package/dist/cjs/snapshotEffect.d.ts +1 -1
  239. package/dist/cjs/snapshotEffect.d.ts.map +1 -1
  240. package/dist/cjs/snapshotEffect.js +36 -10
  241. package/dist/cjs/snapshotEffect.js.map +1 -1
  242. package/dist/cjs/struct.d.ts +5 -0
  243. package/dist/cjs/struct.d.ts.map +1 -0
  244. package/dist/cjs/struct.js +10 -0
  245. package/dist/cjs/struct.js.map +1 -0
  246. package/dist/cjs/switchMap.d.ts +1 -1
  247. package/dist/cjs/switchMap.d.ts.map +1 -1
  248. package/dist/cjs/switchMap.js.map +1 -1
  249. package/dist/cjs/switchMapCause.d.ts +3 -1
  250. package/dist/cjs/switchMapCause.d.ts.map +1 -1
  251. package/dist/cjs/switchMapCause.js +38 -3
  252. package/dist/cjs/switchMapCause.js.map +1 -1
  253. package/dist/cjs/switchMatch.d.ts +2 -1
  254. package/dist/cjs/switchMatch.d.ts.map +1 -1
  255. package/dist/cjs/switchMatch.js +26 -2
  256. package/dist/cjs/switchMatch.js.map +1 -1
  257. package/dist/cjs/takeWhile.d.ts.map +1 -1
  258. package/dist/cjs/takeWhile.js +27 -4
  259. package/dist/cjs/takeWhile.js.map +1 -1
  260. package/dist/cjs/tap.d.ts +1 -1
  261. package/dist/cjs/tap.d.ts.map +1 -1
  262. package/dist/cjs/tap.js +26 -3
  263. package/dist/cjs/tap.js.map +1 -1
  264. package/dist/cjs/tapCause.d.ts +2 -1
  265. package/dist/cjs/tapCause.d.ts.map +1 -1
  266. package/dist/cjs/tapCause.js +32 -5
  267. package/dist/cjs/tapCause.js.map +1 -1
  268. package/dist/cjs/test-utils.d.ts +1 -1
  269. package/dist/cjs/test-utils.d.ts.map +1 -1
  270. package/dist/cjs/test-utils.js +33 -8
  271. package/dist/cjs/test-utils.js.map +1 -1
  272. package/dist/cjs/throttle.d.ts +1 -1
  273. package/dist/cjs/throttle.d.ts.map +1 -1
  274. package/dist/cjs/throttle.js +25 -2
  275. package/dist/cjs/throttle.js.map +1 -1
  276. package/dist/cjs/toArray.d.ts +1 -1
  277. package/dist/cjs/toArray.d.ts.map +1 -1
  278. package/dist/cjs/toArray.js +26 -4
  279. package/dist/cjs/toArray.js.map +1 -1
  280. package/dist/cjs/toChunk.d.ts +2 -1
  281. package/dist/cjs/toChunk.d.ts.map +1 -1
  282. package/dist/cjs/toChunk.js +28 -4
  283. package/dist/cjs/toChunk.js.map +1 -1
  284. package/dist/cjs/toEnqueue.d.ts +6 -0
  285. package/dist/cjs/toEnqueue.d.ts.map +1 -0
  286. package/dist/cjs/toEnqueue.js +9 -0
  287. package/dist/cjs/toEnqueue.js.map +1 -0
  288. package/dist/cjs/toReadonlyArray.d.ts +1 -1
  289. package/dist/cjs/toReadonlyArray.d.ts.map +1 -1
  290. package/dist/cjs/toStream.d.ts +4 -0
  291. package/dist/cjs/toStream.d.ts.map +1 -0
  292. package/dist/cjs/toStream.js +35 -0
  293. package/dist/cjs/toStream.js.map +1 -0
  294. package/dist/combineAll.d.ts.map +1 -1
  295. package/dist/combineAll.js +5 -5
  296. package/dist/combineAll.js.map +1 -1
  297. package/dist/combineAllDiscard.d.ts.map +1 -1
  298. package/dist/combineAllDiscard.js +5 -5
  299. package/dist/combineAllDiscard.js.map +1 -1
  300. package/dist/continueWith.d.ts +1 -1
  301. package/dist/continueWith.d.ts.map +1 -1
  302. package/dist/continueWith.js +1 -1
  303. package/dist/continueWith.js.map +1 -1
  304. package/dist/data-first.d.ts +10 -0
  305. package/dist/data-first.d.ts.map +1 -1
  306. package/dist/data-first.js +10 -0
  307. package/dist/data-first.js.map +1 -1
  308. package/dist/debounce.d.ts +1 -1
  309. package/dist/debounce.d.ts.map +1 -1
  310. package/dist/debounce.js +1 -1
  311. package/dist/debounce.js.map +1 -1
  312. package/dist/delay.d.ts.map +1 -1
  313. package/dist/delay.js +1 -1
  314. package/dist/delay.js.map +1 -1
  315. package/dist/empty.js +1 -1
  316. package/dist/empty.js.map +1 -1
  317. package/dist/exhaustMap.d.ts +1 -1
  318. package/dist/exhaustMap.d.ts.map +1 -1
  319. package/dist/exhaustMap.js.map +1 -1
  320. package/dist/exhaustMapCause.d.ts +2 -1
  321. package/dist/exhaustMapCause.d.ts.map +1 -1
  322. package/dist/exhaustMapCause.js +3 -2
  323. package/dist/exhaustMapCause.js.map +1 -1
  324. package/dist/exhaustMapLatest.d.ts +1 -1
  325. package/dist/exhaustMapLatest.d.ts.map +1 -1
  326. package/dist/exhaustMapLatest.js.map +1 -1
  327. package/dist/exhaustMapLatestCause.d.ts +2 -1
  328. package/dist/exhaustMapLatestCause.d.ts.map +1 -1
  329. package/dist/exhaustMapLatestCause.js +3 -2
  330. package/dist/exhaustMapLatestCause.js.map +1 -1
  331. package/dist/failCause.d.ts +1 -0
  332. package/dist/failCause.d.ts.map +1 -1
  333. package/dist/failCause.js +3 -0
  334. package/dist/failCause.js.map +1 -1
  335. package/dist/filter.d.ts.map +1 -1
  336. package/dist/filter.js +2 -2
  337. package/dist/filter.js.map +1 -1
  338. package/dist/filterMap.d.ts +1 -1
  339. package/dist/filterMap.d.ts.map +1 -1
  340. package/dist/filterMap.js +3 -2
  341. package/dist/filterMap.js.map +1 -1
  342. package/dist/flatMap.d.ts +1 -1
  343. package/dist/flatMap.d.ts.map +1 -1
  344. package/dist/flatMap.js.map +1 -1
  345. package/dist/fromArray.d.ts.map +1 -1
  346. package/dist/fromArray.js +2 -2
  347. package/dist/fromArray.js.map +1 -1
  348. package/dist/fromDequeue.d.ts +5 -0
  349. package/dist/fromDequeue.d.ts.map +1 -0
  350. package/dist/fromDequeue.js +21 -0
  351. package/dist/fromDequeue.js.map +1 -0
  352. package/dist/fromEffect.d.ts +1 -1
  353. package/dist/fromEffect.d.ts.map +1 -1
  354. package/dist/fromEffect.js +11 -3
  355. package/dist/fromEffect.js.map +1 -1
  356. package/dist/fromEmitter.d.ts +2 -2
  357. package/dist/fromEmitter.d.ts.map +1 -1
  358. package/dist/fromEmitter.js +7 -6
  359. package/dist/fromEmitter.js.map +1 -1
  360. package/dist/fromFxEffect.d.ts +1 -1
  361. package/dist/fromFxEffect.d.ts.map +1 -1
  362. package/dist/fromFxEffect.js +2 -2
  363. package/dist/fromFxEffect.js.map +1 -1
  364. package/dist/fromHub.d.ts +5 -0
  365. package/dist/fromHub.d.ts.map +1 -0
  366. package/dist/fromHub.js +7 -0
  367. package/dist/fromHub.js.map +1 -0
  368. package/dist/fromIterable.d.ts.map +1 -1
  369. package/dist/fromIterable.js +2 -2
  370. package/dist/fromIterable.js.map +1 -1
  371. package/dist/fromStream.d.ts +4 -0
  372. package/dist/fromStream.d.ts.map +1 -0
  373. package/dist/fromStream.js +7 -0
  374. package/dist/fromStream.js.map +1 -0
  375. package/dist/gen.d.ts +1 -1
  376. package/dist/gen.d.ts.map +1 -1
  377. package/dist/gen.js +1 -1
  378. package/dist/gen.js.map +1 -1
  379. package/dist/helpers.d.ts +5 -3
  380. package/dist/helpers.d.ts.map +1 -1
  381. package/dist/helpers.js +34 -70
  382. package/dist/helpers.js.map +1 -1
  383. package/dist/hold.d.ts +5 -5
  384. package/dist/hold.d.ts.map +1 -1
  385. package/dist/hold.js +3 -5
  386. package/dist/hold.js.map +1 -1
  387. package/dist/index.d.ts +43 -2
  388. package/dist/index.d.ts.map +1 -1
  389. package/dist/index.js +132 -116
  390. package/dist/index.js.map +1 -1
  391. package/dist/keyed.d.ts.map +1 -1
  392. package/dist/keyed.js +33 -42
  393. package/dist/keyed.js.map +1 -1
  394. package/dist/map.d.ts.map +1 -1
  395. package/dist/map.js +1 -1
  396. package/dist/map.js.map +1 -1
  397. package/dist/mergeAll.d.ts.map +1 -1
  398. package/dist/mergeAll.js +4 -2
  399. package/dist/mergeAll.js.map +1 -1
  400. package/dist/mergeBufferConcurrently.d.ts +8 -0
  401. package/dist/mergeBufferConcurrently.d.ts.map +1 -0
  402. package/dist/mergeBufferConcurrently.js +68 -0
  403. package/dist/mergeBufferConcurrently.js.map +1 -0
  404. package/dist/mergeConcurrently.d.ts +3 -0
  405. package/dist/mergeConcurrently.d.ts.map +1 -0
  406. package/dist/mergeConcurrently.js +42 -0
  407. package/dist/mergeConcurrently.js.map +1 -0
  408. package/dist/multicast.d.ts +10 -8
  409. package/dist/multicast.d.ts.map +1 -1
  410. package/dist/multicast.js +17 -16
  411. package/dist/multicast.js.map +1 -1
  412. package/dist/never.d.ts.map +1 -1
  413. package/dist/never.js +2 -2
  414. package/dist/never.js.map +1 -1
  415. package/dist/observe.d.ts +4 -1
  416. package/dist/observe.d.ts.map +1 -1
  417. package/dist/observe.js +12 -7
  418. package/dist/observe.js.map +1 -1
  419. package/dist/onExit.d.ts +5 -0
  420. package/dist/onExit.d.ts.map +1 -0
  421. package/dist/onExit.js +6 -0
  422. package/dist/onExit.js.map +1 -0
  423. package/dist/onInterrupt.d.ts +1 -1
  424. package/dist/onInterrupt.d.ts.map +1 -1
  425. package/dist/onInterrupt.js +1 -1
  426. package/dist/onInterrupt.js.map +1 -1
  427. package/dist/orElse.d.ts +4 -0
  428. package/dist/orElse.d.ts.map +1 -0
  429. package/dist/orElse.js +7 -0
  430. package/dist/orElse.js.map +1 -0
  431. package/dist/promise.d.ts.map +1 -1
  432. package/dist/promise.js +5 -5
  433. package/dist/promise.js.map +1 -1
  434. package/dist/provide.d.ts +3 -2
  435. package/dist/provide.d.ts.map +1 -1
  436. package/dist/provide.js +8 -4
  437. package/dist/provide.js.map +1 -1
  438. package/dist/reduce.d.ts +2 -1
  439. package/dist/reduce.d.ts.map +1 -1
  440. package/dist/reduce.js +1 -1
  441. package/dist/reduce.js.map +1 -1
  442. package/dist/scan.d.ts.map +1 -1
  443. package/dist/scan.js +1 -1
  444. package/dist/scan.js.map +1 -1
  445. package/dist/scoped.d.ts +1 -1
  446. package/dist/scoped.d.ts.map +1 -1
  447. package/dist/scoped.js +1 -1
  448. package/dist/scoped.js.map +1 -1
  449. package/dist/skipRepeats.d.ts +1 -1
  450. package/dist/skipRepeats.d.ts.map +1 -1
  451. package/dist/skipRepeats.js +6 -7
  452. package/dist/skipRepeats.js.map +1 -1
  453. package/dist/skipWhile.d.ts.map +1 -1
  454. package/dist/skipWhile.js +2 -2
  455. package/dist/skipWhile.js.map +1 -1
  456. package/dist/slice.d.ts.map +1 -1
  457. package/dist/slice.js +4 -4
  458. package/dist/slice.js.map +1 -1
  459. package/dist/snapshotEffect.d.ts +1 -1
  460. package/dist/snapshotEffect.d.ts.map +1 -1
  461. package/dist/snapshotEffect.js +4 -1
  462. package/dist/snapshotEffect.js.map +1 -1
  463. package/dist/struct.d.ts +5 -0
  464. package/dist/struct.d.ts.map +1 -0
  465. package/dist/struct.js +6 -0
  466. package/dist/struct.js.map +1 -0
  467. package/dist/switchMap.d.ts +1 -1
  468. package/dist/switchMap.d.ts.map +1 -1
  469. package/dist/switchMap.js.map +1 -1
  470. package/dist/switchMapCause.d.ts +3 -1
  471. package/dist/switchMapCause.d.ts.map +1 -1
  472. package/dist/switchMapCause.js +13 -2
  473. package/dist/switchMapCause.js.map +1 -1
  474. package/dist/switchMatch.d.ts +2 -1
  475. package/dist/switchMatch.d.ts.map +1 -1
  476. package/dist/switchMatch.js +3 -2
  477. package/dist/switchMatch.js.map +1 -1
  478. package/dist/takeWhile.d.ts.map +1 -1
  479. package/dist/takeWhile.js +2 -2
  480. package/dist/takeWhile.js.map +1 -1
  481. package/dist/tap.d.ts +1 -1
  482. package/dist/tap.d.ts.map +1 -1
  483. package/dist/tap.js +2 -2
  484. package/dist/tap.js.map +1 -1
  485. package/dist/tapCause.d.ts +2 -1
  486. package/dist/tapCause.d.ts.map +1 -1
  487. package/dist/tapCause.js +7 -3
  488. package/dist/tapCause.js.map +1 -1
  489. package/dist/test-utils.d.ts +1 -1
  490. package/dist/test-utils.d.ts.map +1 -1
  491. package/dist/test-utils.js +5 -3
  492. package/dist/test-utils.js.map +1 -1
  493. package/dist/throttle.d.ts +1 -1
  494. package/dist/throttle.d.ts.map +1 -1
  495. package/dist/throttle.js +1 -1
  496. package/dist/throttle.js.map +1 -1
  497. package/dist/toArray.d.ts +1 -1
  498. package/dist/toArray.d.ts.map +1 -1
  499. package/dist/toArray.js +3 -4
  500. package/dist/toArray.js.map +1 -1
  501. package/dist/toChunk.d.ts +2 -1
  502. package/dist/toChunk.d.ts.map +1 -1
  503. package/dist/toChunk.js +2 -1
  504. package/dist/toChunk.js.map +1 -1
  505. package/dist/toEnqueue.d.ts +6 -0
  506. package/dist/toEnqueue.d.ts.map +1 -0
  507. package/dist/toEnqueue.js +5 -0
  508. package/dist/toEnqueue.js.map +1 -0
  509. package/dist/toReadonlyArray.d.ts +1 -1
  510. package/dist/toReadonlyArray.d.ts.map +1 -1
  511. package/dist/toStream.d.ts +4 -0
  512. package/dist/toStream.d.ts.map +1 -0
  513. package/dist/toStream.js +8 -0
  514. package/dist/toStream.js.map +1 -0
  515. package/dist/tsconfig.cjs.build.tsbuildinfo +1 -1
  516. package/package.json +5 -5
  517. package/src/Computed.ts +114 -0
  518. package/src/Filtered.ts +112 -0
  519. package/src/Fx.ts +17 -42
  520. package/src/RefArray.ts +226 -0
  521. package/src/RefSubject.test.ts +72 -7
  522. package/src/RefSubject.ts +606 -583
  523. package/src/RefTransform.ts +134 -0
  524. package/src/Subject.ts +6 -14
  525. package/src/at.ts +3 -2
  526. package/src/catchAllCause.test.ts +1 -1
  527. package/src/catchAllCause.ts +46 -3
  528. package/src/combineAll.ts +18 -14
  529. package/src/combineAllDiscard.ts +18 -14
  530. package/src/continueWith.ts +2 -1
  531. package/src/data-first.ts +10 -0
  532. package/src/debounce.test.ts +1 -1
  533. package/src/debounce.ts +3 -2
  534. package/src/delay.test.ts +1 -1
  535. package/src/delay.ts +1 -1
  536. package/src/empty.ts +1 -1
  537. package/src/exhaustMap.test.ts +1 -1
  538. package/src/exhaustMap.ts +2 -1
  539. package/src/exhaustMapCause.test.ts +1 -1
  540. package/src/exhaustMapCause.ts +4 -2
  541. package/src/exhaustMapLatest.test.ts +1 -1
  542. package/src/exhaustMapLatest.ts +2 -1
  543. package/src/exhaustMapLatestCause.test.ts +1 -1
  544. package/src/exhaustMapLatestCause.ts +4 -2
  545. package/src/failCause.test.ts +2 -1
  546. package/src/failCause.ts +4 -0
  547. package/src/filter.ts +2 -4
  548. package/src/filterMap.ts +11 -2
  549. package/src/flatMap.test.ts +1 -1
  550. package/src/flatMap.ts +2 -1
  551. package/src/fromArray.ts +3 -2
  552. package/src/fromDequeue.ts +39 -0
  553. package/src/fromEffect.test.ts +2 -1
  554. package/src/fromEffect.ts +14 -3
  555. package/src/fromEmitter.test.ts +2 -1
  556. package/src/fromEmitter.ts +8 -12
  557. package/src/fromFxEffect.test.ts +2 -1
  558. package/src/fromFxEffect.ts +5 -2
  559. package/src/fromHub.ts +10 -0
  560. package/src/fromIterable.ts +3 -2
  561. package/src/gen.test.ts +2 -1
  562. package/src/gen.ts +2 -1
  563. package/src/helpers.ts +79 -108
  564. package/src/hold.test.ts +1 -1
  565. package/src/hold.ts +4 -8
  566. package/src/index.ts +580 -609
  567. package/src/keyed.ts +82 -81
  568. package/src/map.ts +2 -1
  569. package/src/mergeAll.ts +12 -6
  570. package/src/mergeBufferConcurrently.test.ts +37 -0
  571. package/src/mergeBufferConcurrently.ts +105 -0
  572. package/src/mergeConcurrently.test.ts +20 -0
  573. package/src/mergeConcurrently.ts +57 -0
  574. package/src/multicast.test.ts +2 -1
  575. package/src/multicast.ts +34 -24
  576. package/src/never.ts +3 -2
  577. package/src/observe.ts +20 -9
  578. package/src/onExit.ts +13 -0
  579. package/src/onInterrupt.ts +1 -1
  580. package/src/orElse.ts +16 -0
  581. package/src/promise.ts +6 -5
  582. package/src/provide.ts +14 -10
  583. package/src/reduce.ts +3 -1
  584. package/src/scan.ts +2 -1
  585. package/src/scoped.ts +3 -1
  586. package/src/skipRepeats.ts +7 -8
  587. package/src/skipWhile.ts +2 -2
  588. package/src/slice.ts +5 -4
  589. package/src/snapshotEffect.ts +5 -1
  590. package/src/struct.ts +18 -0
  591. package/src/switchMap.test.ts +1 -1
  592. package/src/switchMap.ts +2 -1
  593. package/src/switchMapCause.test.ts +1 -1
  594. package/src/switchMapCause.ts +20 -2
  595. package/src/switchMatch.test.ts +1 -1
  596. package/src/switchMatch.ts +4 -2
  597. package/src/takeWhile.ts +3 -3
  598. package/src/tap.ts +7 -2
  599. package/src/tapCause.ts +10 -7
  600. package/src/test-utils.ts +5 -3
  601. package/src/throttle.test.ts +1 -1
  602. package/src/throttle.ts +3 -1
  603. package/src/toArray.ts +6 -5
  604. package/src/toChunk.ts +2 -1
  605. package/src/toEnqueue.ts +13 -0
  606. package/src/toReadonlyArray.ts +1 -1
  607. package/tsconfig.build.json +2 -1
  608. package/tsconfig.build.tsbuildinfo +1 -1
  609. package/vite.config.js +3 -0
  610. package/src/externals.ts +0 -18
package/src/RefSubject.ts CHANGED
@@ -1,31 +1,47 @@
1
- import type { Trace } from '@effect/data/Debug'
2
- import { methodWithTrace } from '@effect/data/Debug'
3
- import { equals } from '@effect/data/Equal'
1
+ import * as Context from '@effect/data/Context'
4
2
  import * as Equal from '@effect/data/Equal'
5
3
  import { identity, pipe } from '@effect/data/Function'
6
4
  import * as Hash from '@effect/data/Hash'
7
- import * as RR from '@effect/data/ReadonlyRecord'
8
- import * as Equivalence from '@effect/data/typeclass/Equivalence'
9
-
10
- import { Fx, Sink, isFx, Traced, FxTypeId } from './Fx.js'
11
- import type { Subject } from './Subject.js'
5
+ import * as MutableRef from '@effect/data/MutableRef'
6
+ import * as Option from '@effect/data/Option'
7
+ import { Pipeable, pipeArguments } from '@effect/data/Pipeable'
8
+ import * as Equivalence from '@effect/data/Equivalence'
9
+ import * as Deferred from '@effect/io/Deferred'
10
+ import * as Effect from '@effect/io/Effect'
11
+ import * as Fiber from '@effect/io/Fiber'
12
+ import * as Scope from '@effect/io/Scope'
13
+ import fastDeepEqual from 'fast-deep-equal'
14
+
15
+ import { Computed, ComputedImpl, ComputedTypeId } from './Computed.js'
16
+ import { FilteredImpl } from './Filtered.js'
17
+ import { Fx, FxTypeId, Sink, isFx } from './Fx.js'
18
+ import { RefTransform, RefTransformImpl } from './RefTransform.js'
19
+ import { Subject } from './Subject.js'
12
20
  import { combineAll } from './combineAll.js'
13
- import type { Context } from './externals.js'
14
- import { Effect, Fiber, MutableRef, Option } from './externals.js'
15
21
  import { HoldFx } from './hold.js'
16
- import { map } from './map.js'
17
- import { multicast } from './multicast.js'
18
22
  import { never } from './never.js'
19
- import { switchMapEffect } from './switchMap.js'
23
+ import { drain } from './observe.js'
24
+ import { struct } from './struct.js'
25
+ import { switchMatchCauseEffect } from './switchMatch.js'
26
+
27
+ const unboundedConcurrency = { concurrency: 'unbounded' } as const
28
+
29
+ const refVariance = {
30
+ _R: identity,
31
+ _E: identity,
32
+ _A: identity,
33
+ }
20
34
 
21
- export const RefSubjectTypeId = Symbol.for('./RefSubject')
35
+ export const RefSubjectTypeId = Symbol.for('@typed/fx/RefSubject')
22
36
  export type RefSubjectTypeId = typeof RefSubjectTypeId
23
37
 
24
- export interface RefSubject<in out E, in out A> extends Subject<E, A>, Effect.Effect<never, E, A> {
38
+ export interface RefSubject<in out E, in out A>
39
+ extends Subject<E, A>,
40
+ Computed<never, E, A>,
41
+ Pipeable {
25
42
  readonly [RefSubjectTypeId]: RefSubjectTypeId
26
43
 
27
44
  readonly eq: Equivalence.Equivalence<A>
28
- readonly get: Effect.Effect<never, E, A>
29
45
 
30
46
  readonly modifyEffect: <R2, E2, B>(
31
47
  f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>,
@@ -39,57 +55,75 @@ export interface RefSubject<in out E, in out A> extends Subject<E, A>, Effect.Ef
39
55
 
40
56
  readonly update: (f: (a: A) => A) => Effect.Effect<never, E, A>
41
57
 
42
- readonly set: (a: A) => Effect.Effect<never, E, A>
58
+ readonly set: (a: A) => Effect.Effect<never, never, A>
43
59
 
44
60
  readonly delete: Effect.Effect<never, E, Option.Option<A>>
45
61
 
46
- readonly mapEffect: <R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, B>) => Computed<R2, E | E2, B>
47
-
48
- readonly map: <B>(f: (a: A) => B) => Computed<never, E, B>
62
+ /**
63
+ * The current version of the RefSubject, starting with 0, 1 when initialized,
64
+ * and incremented each time the value is updated.
65
+ */
66
+ readonly version: () => number
49
67
  }
50
68
 
51
- export interface Computed<R, E, A> extends Fx<R, E, A>, Effect.Effect<R, E, A> {
52
- readonly get: Effect.Effect<R, E, A>
53
-
54
- readonly mapEffect: <R2, E2, B>(
55
- f: (a: A) => Effect.Effect<R2, E2, B>,
56
- ) => Computed<R | R2, E | E2, B>
57
-
58
- readonly map: <B>(f: (a: A) => B) => Computed<R, E, B>
59
- }
69
+ type Lock = <R2, E2, B>(effect: Effect.Effect<R2, E2, B>) => Effect.Effect<R2, E2, B>
60
70
 
61
71
  export function makeRef<R, E, A>(
62
72
  effect: Effect.Effect<R, E, A>,
63
- eq: Equivalence.Equivalence<A> = equals,
64
- ): Effect.Effect<R, never, RefSubject<E, A>> {
65
- return Effect.contextWith(
66
- (ctx: Context.Context<R>) => new RefSubjectImpl(Effect.provideContext(effect, ctx), eq),
73
+ eq?: Equivalence.Equivalence<A>,
74
+ ): Effect.Effect<R | Scope.Scope, never, RefSubject<E, A>> {
75
+ return Effect.contextWithEffect((context) =>
76
+ Effect.suspend(() => {
77
+ const ref = RefSubject.unsafeMake(
78
+ Effect.provideContext(effect, context),
79
+ Context.get(context, Scope.Scope),
80
+ eq,
81
+ )
82
+
83
+ return Effect.as(
84
+ Effect.addFinalizer(() => ref.end()),
85
+ ref,
86
+ )
87
+ }),
67
88
  )
68
89
  }
69
90
 
70
91
  export namespace RefSubject {
71
92
  export type Any = RefSubject<any, any> | RefSubject<never, any>
72
93
 
73
- export function tuple<S extends ReadonlyArray<Any>>(
74
- ...subjects: S
94
+ export function unsafeMake<E, A>(
95
+ initial: Effect.Effect<never, E, A>,
96
+ scope: Scope.Scope,
97
+ eq: Equivalence.Equivalence<A> = fastDeepEqual,
98
+ ): RefSubject<E, A> {
99
+ return makeRefFromPrimitive(unsafeMakeRefPrimitive(initial, scope, eq))
100
+ }
101
+
102
+ export function tuple<const Refs extends readonly Any[]>(
103
+ ...refs: Refs
75
104
  ): RefSubject<
76
- Fx.ErrorsOf<S[number]>,
105
+ Fx.ErrorsOf<Refs[number]>,
77
106
  {
78
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
107
+ readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]>
79
108
  }
80
109
  > {
81
- return new TupleRefSubjectImpl(subjects)
110
+ return makeRefFromPrimitive<
111
+ Fx.ErrorsOf<Refs[number]>,
112
+ {
113
+ readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]>
114
+ }
115
+ >(tupleRefPrimitive<Refs>(refs))
82
116
  }
83
117
 
84
- export function struct<S extends RR.ReadonlyRecord<Any>>(
85
- subjects: S,
118
+ export function struct<const Refs extends Readonly<Record<string, Any>>>(
119
+ refs: Refs,
86
120
  ): RefSubject<
87
- Fx.ErrorsOf<S[keyof S]>,
121
+ Fx.ErrorsOf<Refs[string]>,
88
122
  {
89
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
123
+ readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]>
90
124
  }
91
125
  > {
92
- return new StructRefSubjectImpl(subjects)
126
+ return makeRefFromPrimitive(structRefPrimitive<Refs>(refs))
93
127
  }
94
128
 
95
129
  export function all<S extends ReadonlyArray<Any>>(
@@ -101,7 +135,16 @@ export namespace RefSubject {
101
135
  }
102
136
  >
103
137
 
104
- export function all<S extends RR.ReadonlyRecord<Any>>(
138
+ export function all<S extends ReadonlyArray<Any>>(
139
+ ...subjects: S
140
+ ): RefSubject<
141
+ Fx.ErrorsOf<S[number]>,
142
+ {
143
+ readonly [K in keyof S]: Fx.OutputOf<S[K]>
144
+ }
145
+ >
146
+
147
+ export function all<S extends Readonly<Record<string, Any>>>(
105
148
  subjects: S,
106
149
  ): RefSubject<
107
150
  Fx.ErrorsOf<S[string]>,
@@ -110,643 +153,623 @@ export namespace RefSubject {
110
153
  }
111
154
  >
112
155
 
113
- export function all(subjects: any): any {
114
- return (Array.isArray(subjects) ? tuple(...subjects) : struct(subjects)) as any
115
- }
156
+ export function all(...subjects: any): any {
157
+ /// MUST be a tuple if more than one argument
158
+ if (subjects.length > 1) {
159
+ return tuple(...subjects)
160
+ }
116
161
 
117
- export function unsafeMake<E, A>(
118
- get: Effect.Effect<never, E, A>,
119
- eq: Equivalence.Equivalence<A> = equals,
120
- ): RefSubject<E, A> {
121
- return new RefSubjectImpl(get, eq)
162
+ // Otherwise a single param is either a tuple or a struct
163
+ const singleParam = subjects[0]
164
+
165
+ if (Array.isArray(singleParam)) {
166
+ return tuple(...singleParam)
167
+ }
168
+
169
+ return struct(singleParam)
122
170
  }
123
171
  }
124
172
 
125
- const refSubjectVariant = {
126
- _R: identity,
127
- _E: identity,
128
- _A: identity,
173
+ export function isRefSubject<E, A>(u: unknown): u is RefSubject<E, A> {
174
+ return isFx<never, E, A>(u) && RefSubjectTypeId in u
129
175
  }
130
176
 
131
- class RefSubjectImpl<E, A> extends HoldFx<never, E, A> implements RefSubject<E, A> {
132
- readonly _tag = 'Commit'
133
- public i2: any = undefined
134
- public trace: Trace = undefined;
135
-
136
- readonly [Effect.EffectTypeId] = refSubjectVariant;
137
- readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
138
-
139
- readonly lock = Effect.unsafeMakeSemaphore(1).withPermits(1)
140
- readonly initializeFiber: MutableRef.MutableRef<Option.Option<Fiber.RuntimeFiber<E, A>>> =
141
- MutableRef.make(Option.none())
177
+ // Internals for RefSubject
142
178
 
143
- readonly eq: Equivalence.Equivalence<A>
144
-
145
- constructor(readonly i0: Effect.Effect<never, E, A>, readonly i1: Equivalence.Equivalence<A>) {
146
- super(never<E, A>())
179
+ function makeGetFromContext<E, A>(ctx: RefSubjectContext<E, A>): RefSubject<E, A>['get'] {
180
+ return Effect.suspend(() => {
181
+ const current = MutableRef.get(ctx.currentRef)
147
182
 
148
- this.modifyEffect = this.modifyEffect.bind(this)
149
- this.eq = i1
150
- }
183
+ if (Option.isSome(current)) {
184
+ return Effect.succeed(current.value)
185
+ }
151
186
 
152
- run<R2>(sink: Sink<R2, E, A>) {
153
- return Effect.suspend(() => {
154
- const current = MutableRef.get(this.current)
187
+ const fiber = MutableRef.get(ctx.initializingFiberRef)
155
188
 
156
- if (Option.isNone(current)) {
157
- return pipe(
158
- this.get,
159
- Effect.catchAllCause(sink.error),
160
- Effect.flatMap(() => super.run(sink)),
161
- )
162
- }
189
+ if (Option.isSome(fiber)) {
190
+ return Fiber.join(fiber.value)
191
+ }
163
192
 
164
- return super.run(sink)
165
- })
166
- }
193
+ return Effect.tap(ctx.lock(initializeFromContext(ctx)), (a) => ctx.hold.event(a))
194
+ })
195
+ }
167
196
 
168
- readonly event: RefSubject<E, A>['event'] = methodWithTrace(
169
- (trace) => (a: A) => Effect.catchAllCause(this.set(a), this.error).traced(trace),
197
+ function initializeFromContext<E, A>(ctx: RefSubjectContext<E, A>): Effect.Effect<never, E, A> {
198
+ return Effect.uninterruptibleMask((restore) =>
199
+ Effect.flatMap(Effect.forkIn(restore(ctx.initial), ctx.scope), (fiber) => {
200
+ MutableRef.set(ctx.initializingFiberRef, Option.some(fiber))
201
+
202
+ return Effect.tap(Fiber.join(fiber), (a) =>
203
+ Effect.sync(() => {
204
+ MutableRef.increment(ctx.version)
205
+ MutableRef.set(ctx.currentRef, Option.some(a))
206
+ MutableRef.set(ctx.initializingFiberRef, Option.none())
207
+ }),
208
+ )
209
+ }),
170
210
  )
211
+ }
171
212
 
172
- readonly end = methodWithTrace(
173
- (trace) => () =>
174
- Effect.suspend(() =>
175
- Effect.zipPar(this.interruptFibers(), this.interruptInitializeFiber()),
176
- ).traced(trace),
177
- )
213
+ function makeRefMethods<E, A>(
214
+ primitive: RefPrimitive<E, A>,
215
+ ): Pick<RefSubject<E, A>, 'modify' | 'updateEffect' | 'update'> {
216
+ const modify = makeModify<E, A>(primitive.modifyEffect)
217
+ const updateEffect = makeUpdateEffect<E, A>(primitive.modifyEffect)
218
+ const update = makeUpdate<E, A>(updateEffect)
219
+
220
+ return {
221
+ modify,
222
+ updateEffect,
223
+ update,
224
+ } as const
225
+ }
178
226
 
179
- protected interruptFibers() {
180
- return this.fiber ? Fiber.interrupt(this.fiber) : Effect.unit()
181
- }
227
+ function makeModifyEffectFromContext<E, A>(
228
+ get: RefSubject<E, A>['get'],
229
+ ctx: RefSubjectContext<E, A>,
230
+ ): RefSubject<E, A>['modifyEffect'] {
231
+ return (f) =>
232
+ Effect.flatMap(get, (a1) =>
233
+ ctx.lock(
234
+ Effect.flatMap(f(a1), ([b, a2]) =>
235
+ Effect.suspend(() => {
236
+ MutableRef.set(ctx.currentRef, Option.some(a2))
182
237
 
183
- protected interruptInitializeFiber() {
184
- const fiber = MutableRef.get(this.initializeFiber)
185
- if (Option.isSome(fiber)) {
186
- return Fiber.interrupt(fiber.value)
187
- }
238
+ if (ctx.eq(a1, a2)) {
239
+ return Effect.succeed(b)
240
+ }
188
241
 
189
- return Effect.unit()
190
- }
242
+ MutableRef.increment(ctx.version)
191
243
 
192
- readonly get: RefSubject<E, A>['get'] = Effect.suspend(() =>
193
- pipe(
194
- MutableRef.get(this.current),
195
- Option.match(
196
- () =>
197
- pipe(
198
- MutableRef.get(this.initializeFiber),
199
- Option.match(
200
- () =>
201
- this.lock(
202
- Effect.uninterruptibleMask((restore) =>
203
- pipe(
204
- Effect.forkDaemon(restore(this.i0)),
205
- Effect.tap((fiber) =>
206
- Effect.sync(() => MutableRef.set(this.initializeFiber, Option.some(fiber))),
207
- ),
208
- Effect.flatMap(Fiber.join),
209
- Effect.tap((a) =>
210
- Effect.suspend(() => {
211
- MutableRef.set(this.current, Option.some(a))
212
- MutableRef.set(this.initializeFiber, Option.none())
213
-
214
- return super.event(a)
215
- }),
216
- ),
217
- ),
218
- ),
219
- ),
220
- Fiber.join,
221
- ),
222
- ),
223
- Effect.succeed,
244
+ return Effect.as(ctx.hold.event(a2), b)
245
+ }),
246
+ ),
224
247
  ),
225
- ),
226
- )
227
-
228
- modifyEffect<R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>) {
229
- return methodWithTrace(
230
- (trace) =>
231
- <R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>) =>
232
- Effect.flatMap(this.get, (a1) =>
233
- this.lock(
234
- Effect.flatMap(f(a1), ([b, a2]) =>
235
- Effect.suspend(() => {
236
- MutableRef.set(this.current, Option.some(a2))
237
-
238
- if (this.i1(a1, a2)) {
239
- return Effect.succeed(b)
240
- }
241
-
242
- return Effect.as(super.event(a2), b)
243
- }),
244
- ),
245
- ),
246
- ).traced(trace),
247
- )(f)
248
- }
248
+ )
249
+ }
249
250
 
250
- readonly modify: RefSubject<E, A>['modify'] = (f) =>
251
- this.modifyEffect((a) => Effect.sync(() => f(a)))
251
+ function makeModify<E, A>(
252
+ modifyEffect: RefSubject<E, A>['modifyEffect'],
253
+ ): RefSubject<E, A>['modify'] {
254
+ return (f) => modifyEffect((a) => Effect.sync(() => f(a)))
255
+ }
252
256
 
253
- readonly updateEffect: RefSubject<E, A>['updateEffect'] = (f) =>
254
- this.modifyEffect((a) => Effect.map(f(a), (a) => [a, a]))
257
+ function makeUpdateEffect<E, A>(
258
+ modifyEffect: RefSubject<E, A>['modifyEffect'],
259
+ ): RefSubject<E, A>['updateEffect'] {
260
+ return (f) => modifyEffect((a) => Effect.map(f(a), (a) => [a, a]))
261
+ }
255
262
 
256
- readonly update: RefSubject<E, A>['update'] = (f) =>
257
- this.updateEffect((a) => Effect.sync(() => f(a)))
263
+ function makeUpdate<E, A>(
264
+ updateEffect: RefSubject<E, A>['updateEffect'],
265
+ ): RefSubject<E, A>['update'] {
266
+ return (f) => updateEffect((a) => Effect.sync(() => f(a)))
267
+ }
258
268
 
259
- readonly set: RefSubject<E, A>['set'] = (a) => this.update(() => a)
269
+ function makeSetFromContext<E, A>(ctx: RefSubjectContext<E, A>): RefSubject<E, A>['set'] {
270
+ return (a: A) =>
271
+ Effect.suspend(() => {
272
+ const fiber = MutableRef.get(ctx.initializingFiberRef)
273
+
274
+ return pipe(
275
+ fiber,
276
+ Option.match({ onNone: () => Effect.unit, onSome: Fiber.await }),
277
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
278
+ Effect.flatMap((_: unknown) => {
279
+ const current = MutableRef.get(ctx.currentRef)
280
+
281
+ MutableRef.set(ctx.currentRef, Option.some(a))
282
+
283
+ // Only emit if the value has changed
284
+ if (Option.isNone(current) || (Option.isSome(current) && !ctx.eq(current.value, a))) {
285
+ // Increment the version
286
+ MutableRef.increment(ctx.version)
287
+ return Effect.as(ctx.hold.event(a), a)
288
+ }
289
+
290
+ return Effect.succeed(a)
291
+ }),
292
+ )
293
+ })
294
+ }
260
295
 
261
- readonly delete: RefSubject<E, A>['delete'] = Effect.suspend(() => {
262
- const current = MutableRef.get(this.current)
296
+ function makeDeleteFromContext<E, A>(ctx: RefSubjectContext<E, A>): RefSubject<E, A>['delete'] {
297
+ return Effect.sync(() => {
298
+ const current = MutableRef.get(ctx.currentRef)
263
299
 
264
300
  if (Option.isSome(current)) {
265
- MutableRef.set(this.current, Option.none())
301
+ MutableRef.set(ctx.version, 0)
302
+ MutableRef.set(ctx.currentRef, Option.none())
266
303
  }
267
304
 
268
- return Effect.succeed<Option.Option<A>>(current)
305
+ return current
269
306
  })
307
+ }
270
308
 
271
- readonly mapEffect: RefSubject<E, A>['mapEffect'] = <R2, E2, B>(
272
- f: (a: A) => Effect.Effect<R2, E2, B>,
273
- ) => new ComputedImpl<never, E, A, R2, E2, B>(this, f)
274
-
275
- readonly map: RefSubject<E, A>['map'] = (f) => this.mapEffect((a) => Effect.sync(() => f(a)));
309
+ function makeEndFromContext<E, A>(ctx: RefSubjectContext<E, A>): RefSubject<E, A>['end'] {
310
+ return () =>
311
+ Effect.suspend(() => {
312
+ MutableRef.set(ctx.version, 0)
276
313
 
277
- [Equal.symbol](that: unknown) {
278
- return this === that
279
- }
314
+ const fibers = [
315
+ ctx.hold.fiber || Fiber.unit,
316
+ Option.getOrElse(MutableRef.get(ctx.initializingFiberRef), () => Fiber.unit),
317
+ ]
280
318
 
281
- [Hash.symbol]() {
282
- return Hash.random(this)
283
- }
319
+ return Fiber.interruptAll(fibers)
320
+ })
321
+ }
284
322
 
285
- traced(trace: Trace): Effect.Effect<never, E, A> {
286
- if (trace) {
287
- const traced = new RefSubjectImpl(this.i0, this.i1)
288
- traced.trace = trace
289
- return traced
290
- }
323
+ function makeFiltered<E, A>(
324
+ f: () => RefSubject<E, A>,
325
+ ): Pick<
326
+ RefSubject<E, A>,
327
+ 'filterMapEffect' | 'filterMap' | 'filterEffect' | 'filter' | 'filterNotEffect' | 'filterNot'
328
+ > {
329
+ const get = makeMemoizedGet(f)
291
330
 
292
- return this
331
+ function filterMapEffect<R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>) {
332
+ return new FilteredImpl(get(), f)
293
333
  }
294
334
 
295
- commit(): Effect.Effect<never, E, A> {
296
- return this.get.traced(this.trace)
335
+ function filterMap<B>(f: (a: A) => Option.Option<B>) {
336
+ return filterMapEffect((a) => Effect.sync(() => f(a)))
297
337
  }
298
- }
299
338
 
300
- class TupleRefSubjectImpl<S extends ReadonlyArray<RefSubject.Any>>
301
- extends HoldFx<
302
- never,
303
- Fx.ErrorsOf<S[number]>,
304
- {
305
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
306
- }
307
- >
308
- implements
309
- RefSubject<
310
- Fx.ErrorsOf<S[number]>,
311
- {
312
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
313
- }
314
- >
315
- {
316
- readonly _tag = 'Commit'
317
- public trace: Trace = undefined;
318
-
319
- readonly [Effect.EffectTypeId] = refSubjectVariant;
320
- readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
321
-
322
- readonly i1: Equivalence.Equivalence<{ readonly [K in keyof S]: Fx.OutputOf<S[K]> }>
323
- public i2: any = undefined
324
-
325
- readonly lock = Effect.unsafeMakeSemaphore(1).withPermits(1)
326
-
327
- readonly eq: Equivalence.Equivalence<{ readonly [K in keyof S]: Fx.OutputOf<S[K]> }>
328
-
329
- constructor(readonly i0: S) {
330
- super(combineAll(...i0) as any)
331
-
332
- this.i1 = this.eq = Equivalence.tuple(...i0.map((s) => s.eq)) as Equivalence.Equivalence<{
333
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
334
- }>
339
+ function filterEffect<R2, E2>(f: (a: A) => Effect.Effect<R2, E2, boolean>) {
340
+ return filterMapEffect((a) => Effect.map(f(a), (b) => (b ? Option.some(a) : Option.none())))
335
341
  }
336
342
 
337
- end() {
338
- return Effect.allPar(this.i0.map((s) => s.end()))
343
+ function filter(f: (a: A) => boolean) {
344
+ return filterEffect((a) => Effect.sync(() => f(a)))
339
345
  }
340
346
 
341
- readonly get: RefSubject<
342
- Fx.ErrorsOf<S[number]>,
343
- {
344
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
345
- }
346
- >['get'] = Effect.suspend(
347
- () =>
348
- Effect.allPar(this.i0.map((s) => s.get)) as Effect.Effect<
349
- never,
350
- Fx.ErrorsOf<S[number]>,
351
- {
352
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
353
- }
354
- >,
355
- )
356
-
357
- modifyEffect<R2, E2, B>(
358
- f: (a: {
359
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
360
- }) => Effect.Effect<R2, E2, readonly [B, { readonly [K in keyof S]: Fx.OutputOf<S[K]> }]>,
361
- ) {
362
- const { current, i0 } = this
347
+ function filterNotEffect<R2, E2>(f: (a: A) => Effect.Effect<R2, E2, boolean>) {
348
+ return filterEffect((a) => Effect.map(f(a), (b) => !b))
349
+ }
363
350
 
364
- return pipe(
365
- this.get,
366
- Effect.flatMap((a) =>
367
- this.lock(
368
- Effect.gen(function* ($) {
369
- const [b, a2] = yield* $(f(a))
351
+ function filterNot(f: (a: A) => boolean) {
352
+ return filterNotEffect((a) => Effect.sync(() => f(a)))
353
+ }
370
354
 
371
- MutableRef.set(current, Option.some(a2))
355
+ return {
356
+ filterMapEffect,
357
+ filterMap,
358
+ filterEffect,
359
+ filter,
360
+ filterNotEffect,
361
+ filterNot,
362
+ } as const
363
+ }
372
364
 
373
- yield* $(Effect.allPar(i0.map((s, i) => s.set(a2[i]))))
365
+ function makeComputedMethods<E, A>(
366
+ f: () => RefSubject<E, A>,
367
+ ): Pick<RefSubject<E, A>, 'mapEffect' | 'map'> {
368
+ const get = makeMemoizedGet(f)
374
369
 
375
- return b
376
- }),
377
- ),
378
- ),
379
- )
370
+ function mapEffect<R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, B>): Computed<R2, E | E2, B> {
371
+ return new ComputedImpl(get(), f)
380
372
  }
381
373
 
382
- readonly modify: RefSubject<
383
- Fx.ErrorsOf<S[number]>,
384
- {
385
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
386
- }
387
- >['modify'] = (f) => this.modifyEffect((a) => Effect.sync(() => f(a)))
388
-
389
- readonly updateEffect: RefSubject<
390
- Fx.ErrorsOf<S[number]>,
391
- {
392
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
393
- }
394
- >['updateEffect'] = (f) => this.modifyEffect((a) => Effect.map(f(a), (a) => [a, a]))
395
-
396
- readonly update: RefSubject<
397
- Fx.ErrorsOf<S[number]>,
398
- {
399
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
400
- }
401
- >['update'] = (f) => this.updateEffect((a) => Effect.sync(() => f(a)))
374
+ function map<B>(f: (a: A) => B): Computed<never, E, B> {
375
+ return mapEffect((a) => Effect.sync(() => f(a)))
376
+ }
402
377
 
403
- readonly set: RefSubject<
404
- Fx.ErrorsOf<S[number]>,
405
- {
406
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
407
- }
408
- >['set'] = (a) => this.update(() => a)
378
+ return {
379
+ mapEffect,
380
+ map,
381
+ } as const
382
+ }
409
383
 
410
- readonly delete: RefSubject<
411
- Fx.ErrorsOf<S[number]>,
412
- {
413
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
414
- }
415
- >['delete'] = Effect.suspend(() => {
416
- const current = MutableRef.get(this.current)
384
+ function makeTransformMethods<E, A>(
385
+ f: () => RefSubject<E, A>,
386
+ ): Pick<RefSubject<E, A>, 'transformBoth' | 'transform' | 'transformGet'> {
387
+ const get = makeMemoizedGet(f)
417
388
 
418
- if (Option.isSome(current)) {
419
- MutableRef.set(this.current, Option.none())
420
- }
389
+ function transformBoth<R3, E3, C, R4, E4, D>(
390
+ f: (fx: Fx<never, E, A>) => Fx<R3, E3, C>,
391
+ g: (effect: Effect.Effect<never, E, A>) => Effect.Effect<R4, E4, D>,
392
+ ): RefTransform<R3, E3, C, R4, E4, D> {
393
+ return new RefTransformImpl(get(), f, g)
394
+ }
421
395
 
422
- return Effect.succeed<
423
- Option.Option<{
424
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
425
- }>
426
- >(current)
427
- })
396
+ function transform<R3, E3, C>(
397
+ f: (fx: Fx<never, E, A>) => Fx<R3, E3, C>,
398
+ ): RefTransform<R3, E3, C, never, E, A> {
399
+ return transformBoth(f, identity)
400
+ }
428
401
 
429
- readonly mapEffect: RefSubject<
430
- Fx.ErrorsOf<S[number]>,
431
- {
432
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
433
- }
434
- >['mapEffect'] = <R2, E2, B>(
435
- f: (a: {
436
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
437
- }) => Effect.Effect<R2, E2, B>,
438
- ) =>
439
- new ComputedImpl<
440
- never,
441
- Fx.ErrorsOf<S[number]>,
442
- {
443
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
444
- },
445
- R2,
446
- E2,
447
- B
448
- >(this, f)
402
+ function transformGet<R3, E3, C>(
403
+ f: (effect: Effect.Effect<never, E, A>) => Effect.Effect<R3, E3, C>,
404
+ ): RefTransform<never, E, A, R3, E3, C> {
405
+ return transformBoth(identity, f)
406
+ }
449
407
 
450
- readonly map: RefSubject<
451
- Fx.ErrorsOf<S[number]>,
452
- {
453
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
454
- }
455
- >['map'] = (f) => this.mapEffect((a) => Effect.sync(() => f(a)));
408
+ return {
409
+ transformBoth,
410
+ transform,
411
+ transformGet,
412
+ } as const
413
+ }
456
414
 
415
+ const placeholders = {
416
+ _tag: 'Commit',
417
+ [Effect.EffectTypeId]: refVariance,
418
+ i0: undefined,
419
+ i1: undefined,
420
+ i2: undefined,
457
421
  [Equal.symbol](that: unknown) {
458
422
  return this === that
459
- }
460
-
423
+ },
461
424
  [Hash.symbol]() {
462
425
  return Hash.random(this)
463
- }
426
+ },
427
+ pipe() {
428
+ // eslint-disable-next-line prefer-rest-params
429
+ return pipeArguments(this, arguments)
430
+ },
431
+ }
464
432
 
465
- traced(trace: Trace): Effect.Effect<
466
- never,
467
- Fx.ErrorsOf<S[number]>,
433
+ function makeEffectMethods<E, A>(
434
+ get: RefSubject<E, A>['get'],
435
+ ): Pick<RefSubject<E, A>, Extract<keyof Effect.Effect<never, E, A>, keyof RefSubject<E, A>>> {
436
+ return Object.assign(
468
437
  {
469
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
470
- }
471
- > {
472
- if (trace) {
473
- const traced = new TupleRefSubjectImpl(this.i0)
474
- traced.trace = trace
475
- return traced
476
- }
438
+ commit() {
439
+ return get
440
+ },
441
+ } as const,
442
+ placeholders,
443
+ ) as any
444
+ }
477
445
 
478
- return this
479
- }
446
+ function makeMemoizedGet<A>(f: () => A) {
447
+ let memoized: Option.Option<A> = Option.none()
480
448
 
481
- commit(): Effect.Effect<
482
- never,
483
- Fx.ErrorsOf<S[number]>,
484
- {
485
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
449
+ return () => {
450
+ if (Option.isNone(memoized)) {
451
+ memoized = Option.some(f())
486
452
  }
487
- > {
488
- return this.get.traced(this.trace)
453
+
454
+ return (memoized as Option.Some<A>).value
489
455
  }
490
456
  }
491
457
 
492
- class StructRefSubjectImpl<S extends RR.ReadonlyRecord<RefSubject.Any>>
493
- extends HoldFx<
494
- never,
495
- Fx.ErrorsOf<S[number]>,
496
- {
497
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
498
- }
499
- >
500
- implements
501
- RefSubject<
502
- Fx.ErrorsOf<S[number]>,
503
- {
504
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
505
- }
506
- >
507
- {
508
- readonly _tag = 'Commit'
509
- public trace: Trace = undefined;
510
-
511
- readonly [Effect.EffectTypeId] = refSubjectVariant;
512
- readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
458
+ type RefSubjectContext<E, A> = {
459
+ initial: Effect.Effect<never, E, A>
460
+ currentRef: MutableRef.MutableRef<Option.Option<A>>
461
+ initializingFiberRef: MutableRef.MutableRef<Option.Option<Fiber.RuntimeFiber<E, A>>>
462
+ lock: Lock
463
+ scope: Scope.Scope
464
+ eq: Equivalence.Equivalence<A>
465
+ hold: HoldFx<never, E, A>
466
+ version: MutableRef.MutableRef<number>
467
+ }
513
468
 
514
- readonly i1: Equivalence.Equivalence<{ readonly [K in keyof S]: Fx.OutputOf<S[K]> }>
515
- public i2: any = undefined
469
+ function makeRefSubjectContext<E, A>(
470
+ initial: Effect.Effect<never, E, A>,
471
+ scope: Scope.Scope,
472
+ eq: Equivalence.Equivalence<A>,
473
+ ) {
474
+ const hold = new HoldFx(never<E, A>())
475
+ const ctx: RefSubjectContext<E, A> = {
476
+ initial,
477
+ currentRef: hold.current,
478
+ initializingFiberRef: MutableRef.make(Option.none()),
479
+ lock: Effect.unsafeMakeSemaphore(1).withPermits(1),
480
+ scope,
481
+ eq,
482
+ hold,
483
+ version: MutableRef.make(0),
484
+ }
485
+
486
+ return ctx
487
+ }
516
488
 
517
- readonly lock = Effect.unsafeMakeSemaphore(1).withPermits(1)
489
+ function unsafeMakeRefPrimitive<E, A>(
490
+ initial: Effect.Effect<never, E, A>,
491
+ scope: Scope.Scope,
492
+ eq: Equivalence.Equivalence<A>,
493
+ ): RefPrimitive<E, A> {
494
+ const ctx = makeRefSubjectContext(initial, scope, eq)
495
+ const get = makeGetFromContext(ctx)
496
+ const set = makeSetFromContext(ctx)
518
497
 
519
- readonly eq: Equivalence.Equivalence<{ readonly [K in keyof S]: Fx.OutputOf<S[K]> }>
498
+ function run<R2>(sink: Sink<R2, E, A>) {
499
+ return Effect.suspend(() => {
500
+ const current = MutableRef.get(ctx.hold.current)
520
501
 
521
- constructor(readonly i0: S) {
522
- super(
523
- map(
524
- combineAll(...Object.entries(i0).map(([k, s]) => map(s, (x) => [k, x]))),
525
- Object.fromEntries,
526
- ) as any,
527
- )
502
+ if (Option.isNone(current)) {
503
+ return pipe(
504
+ primitive.get,
505
+ Effect.catchAllCause(sink.error),
506
+ Effect.flatMap(() => ctx.hold.run(sink)),
507
+ )
508
+ }
528
509
 
529
- this.i1 = this.eq = Equivalence.struct(RR.map(i0, (s) => s.eq)) as Equivalence.Equivalence<{
530
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
531
- }>
510
+ return ctx.hold.run(sink)
511
+ })
532
512
  }
533
513
 
534
- end() {
535
- return Effect.allPar(RR.map(this.i0, (s) => s.end()))
514
+ const primitive: RefPrimitive<E, A> = {
515
+ delete: makeDeleteFromContext(ctx),
516
+ end: makeEndFromContext(ctx),
517
+ eq,
518
+ error: (cause) => ctx.hold.error(cause),
519
+ event: set,
520
+ get,
521
+ modifyEffect: makeModifyEffectFromContext(get, ctx),
522
+ run,
523
+ set,
524
+ version: ctx.version,
536
525
  }
537
526
 
538
- readonly get: RefSubject<
539
- Fx.ErrorsOf<S[number]>,
540
- {
541
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
542
- }
543
- >['get'] = Effect.suspend(
544
- () =>
545
- Effect.allPar(RR.map(this.i0, (s) => s.get)) as Effect.Effect<
546
- never,
547
- Fx.ErrorsOf<S[number]>,
548
- {
549
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
550
- }
551
- >,
552
- )
553
-
554
- modifyEffect<R2, E2, B>(
555
- f: (a: {
556
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
557
- }) => Effect.Effect<R2, E2, readonly [B, { readonly [K in keyof S]: Fx.OutputOf<S[K]> }]>,
558
- ) {
559
- const { current, i0: subjects } = this
560
-
561
- return pipe(
562
- this.get,
563
- Effect.flatMap((a) =>
564
- this.lock(
565
- Effect.gen(function* ($) {
566
- const [b, a2] = yield* $(f(a))
527
+ return primitive
528
+ }
567
529
 
568
- MutableRef.set(current, Option.some(a2))
530
+ function makeRefFromPrimitive<E, A>(primitive: RefPrimitive<E, A>): RefSubject<E, A> {
531
+ const ref: RefSubject<E, A> = {
532
+ [FxTypeId]: refVariance,
533
+ [RefSubjectTypeId]: RefSubjectTypeId,
534
+ [ComputedTypeId]: ComputedTypeId,
535
+ ...primitive,
536
+ ...makeRefMethods(primitive),
537
+ ...makeEffectMethods(primitive.get),
538
+ ...makeFiltered(() => ref),
539
+ ...makeComputedMethods(() => ref),
540
+ ...makeTransformMethods(() => ref),
541
+ version() {
542
+ return MutableRef.get(primitive.version)
543
+ },
544
+ }
545
+
546
+ return ref
547
+ }
569
548
 
570
- yield* $(Effect.allPar(RR.map(subjects, (s, i) => s.set(a2[i]))))
549
+ // Base Ref which provides all functionality that can otherwise be derived
550
+ // using makeRefFromPrimitive
551
+ interface RefPrimitive<E, A> {
552
+ // Fx
553
+ run: RefSubject<E, A>['run']
554
+
555
+ // Subject
556
+ event: RefSubject<E, A>['event']
557
+ error: RefSubject<E, A>['error']
558
+ end: RefSubject<E, A>['end']
559
+
560
+ // Ref
561
+ eq: RefSubject<E, A>['eq']
562
+ get: RefSubject<E, A>['get']
563
+ modifyEffect: RefSubject<E, A>['modifyEffect']
564
+ set: RefSubject<E, A>['set']
565
+ delete: RefSubject<E, A>['delete']
566
+
567
+ // Primitive
568
+ version: MutableRef.MutableRef<number>
569
+ }
571
570
 
572
- return b
573
- }),
574
- ),
571
+ // Internals for RefSubject.tuple
572
+
573
+ function tupleRefPrimitive<const Refs extends ReadonlyArray<RefSubject.Any>>(
574
+ refs: Refs,
575
+ ): RefPrimitive<Fx.ErrorsOf<Refs[number]>, { readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]> }> {
576
+ type _E = Fx.ErrorsOf<Refs[number]>
577
+ type _A = { readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]> }
578
+
579
+ const hold = new HoldFx(combineAll(...refs) as any as Fx<never, _E, _A>)
580
+ const eq = Equivalence.tuple(...refs.map((ref) => ref.eq))
581
+ const get = Effect.all(
582
+ refs.map((ref) => ref.get),
583
+ unboundedConcurrency,
584
+ ) as Effect.Effect<never, _E, _A>
585
+
586
+ const primitive: RefPrimitive<_E, _A> = {
587
+ delete: Effect.map(
588
+ Effect.all(
589
+ refs.map((ref) => ref.delete),
590
+ { concurrency: 'unbounded' },
575
591
  ),
576
- )
577
- }
578
-
579
- readonly modify: RefSubject<
580
- Fx.ErrorsOf<S[number]>,
581
- {
582
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
583
- }
584
- >['modify'] = (f) => this.modifyEffect((a) => Effect.sync(() => f(a)))
585
-
586
- readonly updateEffect: RefSubject<
587
- Fx.ErrorsOf<S[number]>,
588
- {
589
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
590
- }
591
- >['updateEffect'] = (f) => this.modifyEffect((a) => Effect.map(f(a), (a) => [a, a]))
592
-
593
- readonly update: RefSubject<
594
- Fx.ErrorsOf<S[number]>,
595
- {
596
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
597
- }
598
- >['update'] = (f) => this.updateEffect((a) => Effect.sync(() => f(a)))
599
-
600
- readonly set: RefSubject<
601
- Fx.ErrorsOf<S[number]>,
602
- {
603
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
604
- }
605
- >['set'] = (a) => this.update(() => a)
606
-
607
- readonly delete: RefSubject<
608
- Fx.ErrorsOf<S[number]>,
609
- {
610
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
611
- }
612
- >['delete'] = Effect.suspend(() => {
613
- const current = MutableRef.get(this.current)
614
-
615
- if (Option.isSome(current)) {
616
- MutableRef.set(this.current, Option.none())
617
- }
618
-
619
- return Effect.succeed<
620
- Option.Option<{
621
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
622
- }>
623
- >(current)
624
- })
625
-
626
- readonly mapEffect: RefSubject<
627
- Fx.ErrorsOf<S[number]>,
628
- {
629
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
630
- }
631
- >['mapEffect'] = <R2, E2, B>(
632
- f: (a: {
633
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
634
- }) => Effect.Effect<R2, E2, B>,
635
- ) =>
636
- new ComputedImpl<
637
- never,
638
- Fx.ErrorsOf<S[number]>,
639
- {
640
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
641
- },
642
- R2,
643
- E2,
644
- B
645
- >(this, f)
646
-
647
- readonly map: RefSubject<
648
- Fx.ErrorsOf<S[number]>,
649
- {
650
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
651
- }
652
- >['map'] = (f) => this.mapEffect((a) => Effect.sync(() => f(a)));
653
-
654
- [Equal.symbol](that: unknown) {
655
- return this === that
656
- }
657
-
658
- [Hash.symbol]() {
659
- return Hash.random(this)
660
- }
592
+ (values) => Option.all(values),
593
+ ) as Effect.Effect<never, _E, Option.Option<_A>>,
594
+ end: () =>
595
+ Effect.all(
596
+ refs.map((ref) => ref.end()),
597
+ unboundedConcurrency,
598
+ ),
599
+ eq,
600
+ error: (error) => hold.error(error),
601
+ event: (value) =>
602
+ Effect.all(
603
+ value.map((v, i) => refs[i].event(v)),
604
+ unboundedConcurrency,
605
+ ),
606
+ get,
607
+ modifyEffect: makeModifyEffectTuple(refs, get, eq),
608
+ run: (sink) => hold.run(sink),
609
+ set: (value) =>
610
+ Effect.all(
611
+ value.map((v, i) => refs[i].set(v)),
612
+ unboundedConcurrency,
613
+ ) as Effect.Effect<never, never, _A>,
614
+ version: MutableRef.make(0),
615
+ }
616
+
617
+ return primitive
618
+ }
661
619
 
662
- traced(trace: Trace): Effect.Effect<
663
- never,
664
- Fx.ErrorsOf<S[number]>,
665
- {
666
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
667
- }
668
- > {
669
- if (trace) {
670
- const traced = new StructRefSubjectImpl(this.i0)
671
- traced.trace = trace
672
- return traced
673
- }
620
+ function makeModifyEffectTuple<
621
+ const Refs extends ReadonlyArray<RefSubject.Any>,
622
+ E,
623
+ A extends readonly any[],
624
+ >(
625
+ refs: Refs,
626
+ get: Effect.Effect<never, E, A>,
627
+ eq: Equivalence.Equivalence<A>,
628
+ ): RefSubject<E, A>['modifyEffect'] {
629
+ return <R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>) => {
630
+ return Effect.gen(function* ($) {
631
+ const current = yield* $(get)
632
+ const [b, a] = yield* $(f(current))
633
+
634
+ if (eq(a, current)) {
635
+ return b
636
+ }
674
637
 
675
- return this
676
- }
638
+ yield* $(
639
+ Effect.all(
640
+ refs.map((ref, i) => ref.set(a[i])),
641
+ unboundedConcurrency,
642
+ ),
643
+ )
677
644
 
678
- commit(): Effect.Effect<
679
- never,
680
- Fx.ErrorsOf<S[number]>,
681
- {
682
- readonly [K in keyof S]: Fx.OutputOf<S[K]>
683
- }
684
- > {
685
- return this.get.traced(this.trace)
645
+ return b
646
+ })
686
647
  }
687
648
  }
688
649
 
689
- class ComputedImpl<R, E, A, R2, E2, B> implements Computed<R | R2, E | E2, B> {
690
- readonly [FxTypeId] = {
691
- _R: identity,
692
- _E: identity,
693
- _A: identity,
694
- }
695
-
696
- readonly _tag = 'Commit'
697
- public trace: Trace = undefined;
650
+ function structRefPrimitive<const Refs extends Readonly<Record<string, RefSubject.Any>>>(
651
+ refs: Refs,
652
+ ): RefPrimitive<Fx.ErrorsOf<Refs[string]>, { readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]> }> {
653
+ type _E = Fx.ErrorsOf<Refs[string]>
654
+ type _A = { readonly [K in keyof Refs]: Fx.OutputOf<Refs[K]> }
655
+
656
+ const hold = new HoldFx(struct(refs)) as HoldFx<never, _E, _A>
657
+ const eq = Equivalence.struct(mapRecord(refs, (ref) => ref.eq))
658
+ const get = Effect.all(
659
+ mapRecord(refs, (ref) => ref.get),
660
+ unboundedConcurrency,
661
+ ) as Effect.Effect<never, _E, _A>
662
+
663
+ const primitive: RefPrimitive<_E, _A> = {
664
+ delete: Effect.map(
665
+ Effect.all(
666
+ mapRecord(refs, (ref) => ref.delete),
667
+ unboundedConcurrency,
668
+ ),
669
+ (values) => Option.all(values),
670
+ ) as Effect.Effect<never, _E, Option.Option<_A>>,
671
+ end: () =>
672
+ Effect.all(
673
+ mapRecord(refs, (ref) => ref.end()),
674
+ unboundedConcurrency,
675
+ ),
676
+ eq,
677
+ error: (error) => hold.error(error),
678
+ event: (value) =>
679
+ Effect.all(
680
+ mapRecord(value, (v, i) => refs[i].event(v)),
681
+ unboundedConcurrency,
682
+ ),
683
+ get,
684
+ modifyEffect: makeModifyEffectStruct(refs, get, eq),
685
+ run: (sink) => hold.run(sink),
686
+ set: (value) =>
687
+ Effect.all(
688
+ mapRecord(value, (v, i) => refs[i].set(v)),
689
+ unboundedConcurrency,
690
+ ) as Effect.Effect<never, never, _A>,
691
+ version: MutableRef.make(0),
692
+ }
693
+
694
+ return primitive
695
+ }
698
696
 
699
- readonly [Effect.EffectTypeId] = refSubjectVariant;
700
- readonly [RefSubjectTypeId]: RefSubjectTypeId = RefSubjectTypeId
697
+ function makeModifyEffectStruct<
698
+ const Refs extends Readonly<Record<string, RefSubject.Any>>,
699
+ E,
700
+ A extends Readonly<Record<string, any>>,
701
+ >(
702
+ refs: Refs,
703
+ get: Effect.Effect<never, E, A>,
704
+ eq: Equivalence.Equivalence<A>,
705
+ ): RefSubject<E, A>['modifyEffect'] {
706
+ return <R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, readonly [B, A]>) => {
707
+ return Effect.gen(function* ($) {
708
+ const current = yield* $(get)
709
+ const [b, a] = yield* $(f(current))
710
+
711
+ if (eq(a, current)) {
712
+ return b
713
+ }
701
714
 
702
- readonly i2: Fx<R | R2, E | E2, B>
715
+ yield* $(
716
+ Effect.all(
717
+ mapRecord(refs, (ref, i) => ref.set(a[i])),
718
+ unboundedConcurrency,
719
+ ),
720
+ )
703
721
 
704
- constructor(readonly i0: Computed<R, E, A>, readonly i1: (a: A) => Effect.Effect<R2, E2, B>) {
705
- // Create a stable reference to derived Fx
706
- this.i2 = multicast(switchMapEffect(this.i0, this.i1))
722
+ return b
723
+ })
707
724
  }
725
+ }
708
726
 
709
- run<R3>(sink: Sink<R3, E | E2, B>) {
710
- return this.i2.run(sink)
711
- }
727
+ function mapRecord<K extends string, A, B>(
728
+ record: Readonly<Record<K, A>>,
729
+ f: (a: A, k: K) => B,
730
+ ): { readonly [_ in K]: B } {
731
+ const result: Record<K, B> = {} as any
712
732
 
713
- addTrace(trace: Trace): Fx<R | R2, E | E2, B> {
714
- return Traced<R | R2, E | E2, B>(this, trace)
733
+ for (const k in record) {
734
+ result[k] = f(record[k], k)
715
735
  }
716
736
 
717
- readonly get = Effect.flatMap(this.i0.get, this.i1)
718
-
719
- readonly mapEffect: Computed<R | R2, E | E2, B>['mapEffect'] = <R3, E3, C>(
720
- f: (b: B) => Effect.Effect<R3, E3, C>,
721
- ): Computed<R | R2 | R3, E | E2 | E3, C> =>
722
- new ComputedImpl(this.i0, (a) => Effect.flatMap(this.i1(a), f))
723
-
724
- readonly map: Computed<R | R2, E | E2, B>['map'] = <C>(f: (b: B) => C) =>
725
- this.mapEffect((a) => Effect.sync(() => f(a)));
737
+ return result
738
+ }
726
739
 
727
- [Equal.symbol](that: unknown) {
728
- return this === that
729
- }
740
+ export function asRef<R, E, A>(fx: Fx<R, E, A>) {
741
+ return Effect.flatMap(Deferred.make<E, A>(), (deferred) =>
742
+ Effect.flatMap(makeRef(Deferred.await(deferred)), (ref) => {
743
+ const onValue = (value: A) =>
744
+ Effect.flatMap(Deferred.succeed(deferred, value), (closed) =>
745
+ closed ? Effect.unit : ref.set(value),
746
+ )
730
747
 
731
- [Hash.symbol]() {
732
- return Hash.random(this)
733
- }
748
+ return Effect.as(
749
+ Effect.forkScoped(
750
+ Effect.catchAllCause(drain(switchMatchCauseEffect(fx, ref.error, onValue)), ref.error),
751
+ ),
752
+ ref,
753
+ )
754
+ }),
755
+ )
734
756
 
735
- traced(trace: Trace): Effect.Effect<R | R2, E | E2, B> {
736
- if (trace) {
737
- const traced = new ComputedImpl(this.i0, this.i1)
738
- traced.trace = trace
739
- return traced
740
- }
757
+ return Effect.gen(function* ($) {
758
+ const deferred = yield* $(Deferred.make<E, A>())
759
+ const ref = yield* $(makeRef(Deferred.await(deferred)))
741
760
 
742
- return this
743
- }
761
+ const onValue = (value: A) =>
762
+ Effect.flatMap(Deferred.succeed(deferred, value), (closed) =>
763
+ closed ? Effect.unit : ref.set(value),
764
+ )
744
765
 
745
- commit(): Effect.Effect<R | R2, E | E2, B> {
746
- return this.get.traced(this.trace)
747
- }
748
- }
766
+ yield* $(
767
+ switchMatchCauseEffect(fx, ref.error, onValue),
768
+ drain,
769
+ Effect.catchAllCause(ref.error),
770
+ Effect.forkScoped,
771
+ )
749
772
 
750
- export function isRefSubject<E, A>(u: unknown): u is RefSubject<E, A> {
751
- return isFx<never, E, A>(u) && RefSubjectTypeId in u && u[RefSubjectTypeId] === RefSubjectTypeId
773
+ return ref
774
+ })
752
775
  }