@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
@@ -1,2198 +1,2739 @@
1
- import type { Exit } from "effect"
2
- import {
3
- Cause,
4
- Chunk,
5
- Deferred,
6
- Effect,
7
- Effectable,
8
- Either,
9
- Equal,
10
- Fiber,
11
- Layer,
12
- Option,
13
- Ref,
14
- Scope,
15
- Stream,
16
- SynchronizedRef
1
+ import * as Context from "@typed/context"
2
+ import type {
3
+ ConfigProvider,
4
+ Duration,
5
+ Equivalence,
6
+ FiberId,
7
+ FiberRef,
8
+ HashSet,
9
+ Queue,
10
+ Request,
11
+ Runtime,
12
+ Schedule,
13
+ Scheduler
17
14
  } from "effect"
18
-
19
- import { dual, identity } from "effect/Function"
20
-
21
- import { type Context, isContext, type Tag } from "@typed/context"
22
- import * as Schedule from "effect/Schedule"
15
+ import * as Boolean from "effect/Boolean"
16
+ import * as Cause from "effect/Cause"
17
+ import * as Clock from "effect/Clock"
18
+ import * as Deferred from "effect/Deferred"
19
+ import * as Effect from "effect/Effect"
20
+ import * as Either from "effect/Either"
21
+ import * as Equal from "effect/Equal"
22
+ import * as ExecutionStrategy from "effect/ExecutionStrategy"
23
+ import * as Exit from "effect/Exit"
24
+ import * as Fiber from "effect/Fiber"
25
+ import { constFalse, constTrue } from "effect/Function"
26
+ import * as Layer from "effect/Layer"
27
+ import * as Option from "effect/Option"
28
+ import * as Predicate from "effect/Predicate"
29
+ import * as Ref from "effect/Ref"
30
+ import * as Scope from "effect/Scope"
31
+ import * as Tracer from "effect/Tracer"
32
+ import type { FlattenStrategy, Fx, FxFork, MergeStrategy } from "../Fx.js"
33
+ import * as Sink from "../Sink.js"
34
+ import type { Bounds } from "./bounds.js"
35
+ import { boundsFrom, isInfiniteBounds, isNilBounds, mergeBounds } from "./bounds.js"
36
+ import * as EffectLoopOp from "./effect-loop-operator.js"
37
+ import * as EffectOp from "./effect-operator.js"
38
+ import * as EffectProducer from "./effect-producer.js"
23
39
  import {
24
- compileEffectLoop,
25
- FilterEffect,
26
- FilterMapEffect,
27
- liftSyncOperator,
28
- MapEffect,
29
- TapEffect
30
- } from "./effect-operator.js"
31
- import * as helpers from "./helpers.js"
40
+ adjustTime,
41
+ matchEffectPrimitive,
42
+ tupleSink,
43
+ withBuffers,
44
+ withFlattenStrategy,
45
+ withScopedFork
46
+ } from "./helpers.js"
47
+ import * as SyncLoopOp from "./loop-operator.js"
48
+ import * as Op from "./operator.js"
49
+ import { EffectBase, FxBase } from "./protos.js"
32
50
  import * as Provide from "./provide.js"
33
- import * as strategies from "./strategies.js"
34
- import { compileSyncReducer, Filter, FilterMap, Map } from "./sync-operator.js"
51
+ import { Bounded, Exhaust, ExhaustLatest, Ordered, Switch, Unbounded, Unordered } from "./strategies.js"
52
+ import * as SyncOp from "./sync-operator.js"
53
+ import * as SyncProducer from "./sync-producer.js"
54
+
55
+ const DISCARD = { discard: true } as const
56
+ const UNBOUNDED = { concurrency: "unbounded" } as const
57
+
58
+ // TODO: Optimizations for take/drop and variants
59
+ // TODO: Slice optimizations on synchronous producers
60
+ // TODO: Error/Cause operator fusion
61
+ // TODO: Double-check other optimiation opportunities
62
+ // TODO: expose FxBase and FxEffectBase
63
+
64
+ export function make<A>(
65
+ run: (sink: Sink.Sink<never, never, A>) => Effect.Effect<never, never, unknown>
66
+ ): Fx<never, never, A>
67
+ export function make<E, A>(run: (sink: Sink.Sink<never, E, A>) => Effect.Effect<never, never, unknown>): Fx<never, E, A>
68
+ export function make<R, E, A>(run: (sink: Sink.Sink<never, E, A>) => Effect.Effect<R, never, unknown>): Fx<R, E, A>
69
+ export function make<R, E, A>(run: (sink: Sink.Sink<never, E, A>) => Effect.Effect<R, never, unknown>): Fx<R, E, A> {
70
+ return new Make(run)
71
+ }
35
72
 
36
- import type { DurationInput } from "effect/Duration"
37
- import type { Equivalence } from "effect/Equivalence"
38
- import type { Runtime } from "effect/Runtime"
39
- import * as Emitter from "../Emitter.js"
40
- import type {
41
- FlattenStrategy,
42
- Fx,
43
- FxInput,
44
- MergeStrategy,
45
- WithEarlyExitParams,
46
- WithFlattenStrategyParams,
47
- WithScopedForkParams
48
- } from "../Fx.js"
49
- import * as Sink from "../Sink.js"
50
- import { type Bounds, boundsFrom, mergeBounds } from "./bounds.js"
51
- import { type InternalEffect, matchEffectPrimitive } from "./effect-primitive.js"
52
- import {
53
- Empty,
54
- Fail,
55
- FromIterable,
56
- FromSink,
57
- Never,
58
- Succeed,
59
- Suspend,
60
- Sync,
61
- ToFx,
62
- Transformer,
63
- TransformerCause,
64
- TransformerEffect,
65
- WithEarlyExit,
66
- WithFlattenStrategy,
67
- WithScopedFork
68
- } from "./fx-primitive.js"
69
- import { adjustTime } from "./helpers.js"
70
- import { matchFxInput } from "./matchers.js"
71
- import { OnceEffect } from "./protos.js"
72
- import { run } from "./run.js"
73
+ class Make<R, E, A> extends FxBase<R, E, A> {
74
+ constructor(readonly _run: Fx<R, E, A>["run"]) {
75
+ super()
76
+ }
73
77
 
74
- const constUnit = () => Effect.unit
78
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
79
+ return Effect.contextWithEffect((ctx) => this._run(Sink.provide(sink, ctx)))
80
+ }
81
+ }
75
82
 
76
- class Merge<R, E, A> extends ToFx<R, E, A> {
77
- constructor(readonly i0: ReadonlyArray<Fx<R, E, A>>, readonly i1: MergeStrategy) {
78
- super(i0, i1)
83
+ class Producer<A> extends FxBase<never, never, A> {
84
+ constructor(readonly i0: SyncProducer.SyncProducer<A>) {
85
+ super()
79
86
  }
80
87
 
81
- static make<R, E, A>(fx: ReadonlyArray<Fx<R, E, A>>, strategy: MergeStrategy): Fx<R, E, A> {
82
- // TODO: Flatten nested Merges
88
+ run<R2>(sink: Sink.Sink<R2, never, A>): Effect.Effect<R2, never, unknown> {
89
+ return SyncProducer.runSink(this.i0, sink)
90
+ }
91
+ }
92
+ /**
93
+ * @internal
94
+ */
95
+ export function isProducer<R, E, A>(fx: Fx<R, E, A>): fx is Producer<A> {
96
+ return fx.constructor === Producer
97
+ }
83
98
 
84
- if (fx.length === 0) return empty
85
- const nonEmptyFx = fx.filter((fx) => !(fx instanceof Empty))
99
+ export const succeed = <A>(value: A): Fx<never, never, A> => new Producer(SyncProducer.Success(value))
86
100
 
87
- if (nonEmptyFx.length === 0) return empty
88
- if (nonEmptyFx.length === 1) return nonEmptyFx[0]
101
+ export const fromSync = <A>(f: () => A): Fx<never, never, A> => new Producer(SyncProducer.FromSync(f))
89
102
 
90
- const neverIndex = nonEmptyFx.findIndex((fx) => fx instanceof Never)
103
+ export const fromArray = <const A extends ReadonlyArray<any>>(array: A): Fx<never, never, A[number]> =>
104
+ new Producer(SyncProducer.FromArray(array))
91
105
 
92
- if (neverIndex === -1) return new Merge(nonEmptyFx, strategy)
106
+ export const fromIterable = <A>(iterable: Iterable<A>): Fx<never, never, A> =>
107
+ new Producer(SyncProducer.FromIterable(iterable))
93
108
 
94
- switch (strategy._tag) {
95
- case "Switch":
96
- case "Ordered":
97
- // Will only emit up to the first Never
98
- return new Merge(nonEmptyFx.slice(0, neverIndex + 1), strategy)
99
- // No use creating fibers for Fx that don't emit
100
- case "Unordered":
101
- return new Merge(nonEmptyFx, strategy)
102
- }
109
+ class ProducerEffect<R, E, A> extends FxBase<R, E, A> {
110
+ constructor(readonly i0: EffectProducer.EffectProducer<R, E, A>) {
111
+ super()
103
112
  }
104
113
 
105
- toFx(): Fx<R, E, A> {
106
- const { i0, i1 } = this
114
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
115
+ return EffectProducer.runSink(this.i0, sink)
116
+ }
117
+ }
107
118
 
108
- switch (i1._tag) {
109
- case "Ordered": {
110
- const concurrency = i1.concurrency === Infinity ? "unbounded" : i1.concurrency
119
+ /**
120
+ * @internal
121
+ */
122
+ export function isProducerEffect<R, E, A>(fx: Fx<R, E, A>): fx is ProducerEffect<R, E, A> {
123
+ return fx.constructor === ProducerEffect
124
+ }
111
125
 
112
- return fromSink((sink) => (
113
- Effect.flatMap(helpers.withBuffers(i0.length, sink), (buffers) =>
114
- Effect.all(
115
- i0.map((fx, i) =>
116
- Effect.flatMap(
117
- run(
118
- fx,
119
- Sink.WithContext(
120
- (cause) => Cause.isInterruptedOnly(cause) ? Effect.unit : sink.onFailure(cause),
121
- (a) => buffers.onSuccess(i, a)
122
- )
123
- ),
124
- () => buffers.onEnd(i)
125
- )
126
- ),
127
- {
128
- concurrency
129
- }
130
- ))
131
- ))
132
- }
133
- case "Switch":
134
- return fromSink((sink) => Effect.all(i0.map((fx) => run(fx, sink)), { concurrency: 1 }))
135
- case "Unordered":
136
- return fromSink((sink) =>
137
- Effect.all(i0.map((fx) => run(fx, sink)), {
138
- concurrency: i1.concurrency === Infinity ? "unbounded" : i1.concurrency
139
- })
140
- )
141
- }
126
+ export const fromEffect = <R, E, A>(effect: Effect.Effect<R, E, A>): Fx<R, E, A> =>
127
+ matchEffectPrimitive<R, E, A, Fx<R, E, A>>(effect, {
128
+ // Match over Effect primitives and return Fx primitives to allow fusion to take place
129
+ Success: succeed,
130
+ Failure: failCause,
131
+ Sync: fromSync,
132
+ Left: fail,
133
+ Right: succeed,
134
+ Some: succeed,
135
+ None: fail,
136
+ Otherwise: (effect) => new ProducerEffect(EffectProducer.FromEffect(effect))
137
+ })
138
+
139
+ export const fromScheduled = <R, E, I, R2, O>(
140
+ input: Effect.Effect<R, E, I>,
141
+ schedule: Schedule.Schedule<R2, I, O>
142
+ ): Fx<R | R2, E, O> => new ProducerEffect(EffectProducer.FromScheduled(input, schedule))
143
+
144
+ export const schedule = <R, E, A, R2, O>(
145
+ input: Effect.Effect<R, E, A>,
146
+ schedule: Schedule.Schedule<R2, unknown, O>
147
+ ): Fx<R | R2, E, A> => new ProducerEffect(EffectProducer.Scheduled(input, schedule))
148
+
149
+ class FailCause<E> extends FxBase<never, E, never> {
150
+ constructor(readonly i0: Cause.Cause<E>) {
151
+ super()
152
+ }
153
+
154
+ run<R2>(sink: Sink.Sink<R2, E, never>): Effect.Effect<R2, never, unknown> {
155
+ return sink.onFailure(this.i0)
142
156
  }
143
157
  }
144
158
 
145
- class Slice<R, E, A> extends ToFx<R, E, A> {
146
- constructor(
147
- readonly i0: Fx<R, E, A>,
148
- readonly i1: Bounds
149
- ) {
150
- super(i0, i1)
159
+ /**
160
+ * @internal
161
+ */
162
+ export function isFailCause<R, E, A>(fx: Fx<R, E, A>): fx is FailCause<E> {
163
+ return fx.constructor === FailCause
164
+ }
165
+
166
+ export const failCause = <E>(cause: Cause.Cause<E>): Fx<never, E, never> => new FailCause(cause)
167
+
168
+ export const fail = <E>(error: E): Fx<never, E, never> => failCause(Cause.fail(error))
169
+
170
+ export const die = (error: unknown): Fx<never, never, never> => failCause(Cause.die(error))
171
+
172
+ class Transformer<R, E, A> extends FxBase<R, E, A> {
173
+ constructor(readonly i0: Fx<R, E, any>, readonly i1: Op.Operator) {
174
+ super()
151
175
  }
152
176
 
153
- static make<R, E, A>(fx: Fx<R, E, A>, bounds: Bounds): Fx<R, E, A> {
154
- if (fx instanceof Slice) {
155
- return new Slice(fx.i0, mergeBounds(fx.i1, bounds))
156
- } else if (fx instanceof Transformer && fx.i1._tag === "Map") {
157
- return new Transformer(Slice.make(fx.i0, bounds), fx.i1)
177
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
178
+ return this.i0.run(Op.compileOperatorSink(this.i1, sink))
179
+ }
180
+
181
+ static make<R, E, A, R2, E2, B>(fx: Fx<R, E, A>, operator: Op.Operator): Fx<R | R2, E | E2, B> {
182
+ if (isEmpty(fx) || isNever(fx)) return fx
183
+ else if (isProducer(fx)) {
184
+ return new ProducerSyncTransformer(fx.i0, operator)
185
+ } else if (isTransformer(fx)) {
186
+ return new Transformer(fx.i0, Op.fuseOperators(fx.i1, operator))
187
+ } else if (isProducerSyncTransformer(fx)) {
188
+ return new ProducerSyncTransformer(fx.i0, Op.fuseOperators(fx.i1, operator))
189
+ } else if (isProducerEffect(fx)) {
190
+ return new ProducerEffectTransformer(fx.i0, operator)
191
+ } else if (isProducerEffectTransformer(fx)) {
192
+ return new ProducerEffectTransformer(fx.i0, Op.fuseOperators(fx.i1, operator))
193
+ } else if (isSuspend(fx)) {
194
+ return new SuspendedTransformer(fx.i0, operator)
195
+ } else if (isSuspendedTransformer(fx)) {
196
+ return new SuspendedTransformer(fx.i0, Op.fuseOperators(fx.i1, operator))
197
+ } else if (isFailCause(fx)) {
198
+ return fx
158
199
  } else {
159
- return new Slice(fx, bounds)
200
+ return new Transformer<R, E, B>(fx, operator)
160
201
  }
161
202
  }
203
+ }
162
204
 
163
- toFx(): Fx<R, E, A> {
164
- const fx = this.i0
165
- const { max, min } = this.i1
166
-
167
- return withEarlyExit(({ sink }) =>
168
- Effect.suspend(() => {
169
- let toSkip = min
170
- let toTake = max
171
-
172
- return run(
173
- fx,
174
- Sink.WithContext(sink.onFailure, (a) =>
175
- Effect.suspend(() => {
176
- if (toSkip > 0) {
177
- toSkip -= 1
178
- return Effect.unit
179
- } else if (toTake > 0) {
180
- toTake -= 1
181
- return Effect.flatMap(sink.onSuccess(a), () => toTake <= 0 ? sink.earlyExit : Effect.unit)
182
- } else {
183
- return sink.earlyExit
184
- }
185
- }))
186
- )
187
- })
188
- )
189
- }
205
+ /**
206
+ * @internal
207
+ */
208
+ export function isTransformer<R, E, A>(fx: Fx<R, E, A>): fx is Transformer<R, E, A> {
209
+ return fx.constructor === Transformer
190
210
  }
191
211
 
192
- class Loop<R, E, A, B, C> extends ToFx<R, E, C> {
193
- constructor(
194
- readonly i0: Fx<R, E, A>,
195
- readonly i1: (b: B, a: A) => readonly [C, B],
196
- readonly i2: B
197
- ) {
198
- super(i0, i1, i2)
212
+ class ProducerSyncTransformer<R, E, A> extends FxBase<R, E, A> implements Fx<R, E, A> {
213
+ constructor(readonly i0: SyncProducer.SyncProducer<any>, readonly i1: Op.Operator) {
214
+ super()
199
215
  }
200
216
 
201
- static make<R, E, A, B, C>(fx: Fx<R, E, A>, b: B, f: (b: B, a: A) => readonly [C, B]): Fx<R, E, C> {
202
- if (fx instanceof Transformer) {
203
- return FilterMapLoop.make(fx.i0 as Fx<R, E, any>, b, compileSyncReducer(fx.i1, f))
204
- } else if (fx instanceof TransformerEffect) {
205
- return new FilterMapLoopEffect(
206
- fx.i0 as Fx<R, E, any>,
207
- b,
208
- compileEffectLoop(fx.i1, (b: B, a: A) => Effect.sync(() => f(b, a)))
209
- )
210
- } else {
211
- return new Loop(fx, f, b)
212
- }
217
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
218
+ return SyncProducer.runSink(this.i0, Op.compileOperatorSink(this.i1, sink))
213
219
  }
220
+ }
214
221
 
215
- toFx(): Fx<R, E, C> {
216
- return fromSink((sink) =>
217
- Effect.suspend(() => {
218
- let acc = this.i2
222
+ /**
223
+ * @internal
224
+ */
225
+ export function isProducerSyncTransformer<R, E, A>(fx: Fx<R, E, A>): fx is ProducerSyncTransformer<R, E, A> {
226
+ return fx.constructor === ProducerSyncTransformer
227
+ }
219
228
 
220
- return run(
221
- this.i0,
222
- Sink.WithContext(
223
- sink.onFailure,
224
- (a) =>
225
- Effect.suspend(() => {
226
- const [c, b] = this.i1(acc, a)
229
+ export const map = <R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => B): Fx<R, E, B> => Transformer.make(fx, SyncOp.Map(f))
227
230
 
228
- acc = b
231
+ export const filter = <R, E, A>(fx: Fx<R, E, A>, f: Predicate.Predicate<A>): Fx<R, E, A> =>
232
+ Transformer.make(fx, SyncOp.Filter(f))
229
233
 
230
- return sink.onSuccess(c)
231
- })
232
- )
233
- )
234
- })
235
- )
236
- }
237
- }
234
+ export const filterMap = <R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => Option.Option<B>): Fx<R, E, B> =>
235
+ Transformer.make(fx, SyncOp.FilterMap(f))
238
236
 
239
- class FilterMapLoop<R, E, A, B, C> extends ToFx<R, E, C> {
240
- constructor(
241
- readonly i0: Fx<R, E, A>,
242
- readonly i1: B,
243
- readonly i2: (b: B, a: A) => Option.Option<readonly [C, B]>
244
- ) {
245
- super(i0, i1, i2)
246
- }
237
+ export const mapEffect = <R, E, A, R2, E2, B>(
238
+ fx: Fx<R, E, A>,
239
+ f: (a: A) => Effect.Effect<R2, E2, B>
240
+ ): Fx<R | R2, E | E2, B> => Transformer.make(fx, EffectOp.MapEffect(f))
247
241
 
248
- static make<R, E, A, B, C>(
249
- fx: Fx<R, E, A>,
250
- b: B,
251
- f: (b: B, a: A) => Option.Option<readonly [C, B]>
252
- ): Fx<R, E, C> {
253
- return new FilterMapLoop(fx, b, f)
254
- }
242
+ export const filterMapEffect = <R, E, A, R2, E2, B>(
243
+ fx: Fx<R, E, A>,
244
+ f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>
245
+ ): Fx<R | R2, E | E2, B> => Transformer.make(fx, EffectOp.FilterMapEffect(f))
255
246
 
256
- toFx(): Fx<R, E, C> {
257
- return fromSink((sink) =>
258
- Effect.suspend(() => {
259
- let acc = this.i1
247
+ export const filterEffect = <R, E, A, R2, E2>(
248
+ fx: Fx<R, E, A>,
249
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
250
+ ): Fx<R | R2, E | E2, A> => Transformer.make(fx, EffectOp.FilterEffect(f))
260
251
 
261
- return run(
262
- this.i0,
263
- Sink.WithContext(
264
- sink.onFailure,
265
- (a) =>
266
- Effect.suspend(() => {
267
- const optionCB = this.i2(acc, a)
252
+ export const tapEffect = <R, E, A, R2, E2>(
253
+ fx: Fx<R, E, A>,
254
+ f: (a: A) => Effect.Effect<R2, E2, unknown>
255
+ ): Fx<R | R2, E | E2, A> => Transformer.make(fx, EffectOp.TapEffect(f))
268
256
 
269
- if (Option.isNone(optionCB)) return Effect.unit
257
+ export const loop = <R, E, A, B, C>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => readonly [C, B]): Fx<R, E, C> =>
258
+ Transformer.make(fx, SyncLoopOp.LoopOperator(seed, f))
270
259
 
271
- const [c, b] = optionCB.value
272
- acc = b
260
+ export const withPrevious = <R, E, A>(fx: Fx<R, E, A>): Fx<R, E, readonly [Option.Option<A>, A]> =>
261
+ loop(fx, Option.none<A>(), (acc, a) => [[acc, a], Option.some(a)] as const)
273
262
 
274
- return sink.onSuccess(c)
275
- })
276
- )
277
- )
278
- })
279
- )
280
- }
281
- }
263
+ export const filterMapLoop = <R, E, A, B, C>(
264
+ fx: Fx<R, E, A>,
265
+ seed: B,
266
+ f: (acc: B, a: A) => readonly [Option.Option<C>, B]
267
+ ): Fx<R, E, C> => Transformer.make(fx, SyncLoopOp.FilterMapLoopOperator(seed, f))
282
268
 
283
- class LoopEffect<R, E, A, R2, E2, B, C> extends ToFx<R | R2, E | E2, C> {
284
- constructor(
285
- readonly i0: Fx<R, E, A>,
286
- readonly i1: (b: B, a: A) => Effect.Effect<R2, E2, readonly [C, B]>,
287
- readonly i2: B
288
- ) {
289
- super(i0, i1, i2)
290
- }
269
+ export const loopEffect = <R, E, A, R2, E2, B, C>(
270
+ fx: Fx<R, E, A>,
271
+ seed: B,
272
+ f: (acc: B, a: A) => Effect.Effect<R2, E2, readonly [C, B]>
273
+ ): Fx<R | R2, E | E2, C> => Transformer.make(fx, EffectLoopOp.LoopEffectOperator(seed, f))
291
274
 
292
- static make<R, E, A, R2, E2, B, C>(
293
- fx: Fx<R, E, A>,
294
- f: (b: B, a: A) => Effect.Effect<R2, E2, readonly [C, B]>,
295
- b: B
296
- ): Fx<R | R2, E | E2, C> {
297
- if (fx instanceof TransformerEffect) {
298
- return new FilterMapLoopEffect(fx.i0 as Fx<R, E, any>, b, compileEffectLoop(fx.i1, f))
299
- } else if (fx instanceof Transformer) {
300
- return new FilterMapLoopEffect(fx.i0 as Fx<R, E, any>, b, compileEffectLoop(liftSyncOperator(fx.i1), f))
301
- } else {
302
- return new LoopEffect(fx, f, b)
303
- }
304
- }
275
+ export const filterMapLoopEffect = <R, E, A, R2, E2, B, C>(
276
+ fx: Fx<R, E, A>,
277
+ seed: B,
278
+ f: (acc: B, a: A) => Effect.Effect<R2, E2, readonly [Option.Option<C>, B]>
279
+ ): Fx<R | R2, E | E2, C> => Transformer.make(fx, EffectLoopOp.FilterMapLoopEffectOperator(seed, f))
305
280
 
306
- toFx(): Fx<R | R2, E | E2, C> {
307
- const { i0, i1, i2 } = this
308
-
309
- return fromSink((sink) =>
310
- Effect.flatMap(SynchronizedRef.make(i2), (ref) =>
311
- run(
312
- i0,
313
- Sink.WithContext(sink.onFailure, (a) =>
314
- SynchronizedRef.updateEffect(ref, (b) =>
315
- Effect.matchCauseEffect(i1(b, a), {
316
- onFailure: (cause) => Effect.as(sink.onFailure(cause), b),
317
- onSuccess: ([c, b2]: readonly [C, B]) => Effect.as(sink.onSuccess(c), b2)
318
- })))
319
- ))
320
- )
321
- }
322
- }
281
+ export const observe = <R, E, A, R2, E2, B>(
282
+ fx: Fx<R, E, A>,
283
+ f: (a: A) => Effect.Effect<R2, E2, B>
284
+ ): Effect.Effect<R | R2, E | E2, void> => Observe.make(fx, f)
285
+
286
+ const constUnit = () => Effect.unit
287
+
288
+ export const drain = <R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, void> => Observe.make(fx, constUnit)
323
289
 
324
- class FilterMapLoopEffect<R, E, A, R2, E2, B, C> extends ToFx<R | R2, E | E2, C> {
290
+ class Observe<R, E, A, R2, E2, B> extends EffectBase<R | R2, E | E2, void> {
325
291
  constructor(
326
292
  readonly i0: Fx<R, E, A>,
327
- readonly i1: B,
328
- readonly i2: (b: B, a: A) => Effect.Effect<R2, E2, Option.Option<readonly [C, B]>>
293
+ readonly i1: (a: A) => Effect.Effect<R2, E2, B>
329
294
  ) {
330
- super(i0, i1, i2)
295
+ super()
331
296
  }
332
297
 
333
- toFx(): Fx<R | R2, E | E2, C> {
334
- return fromSink((sink) =>
335
- Effect.suspend(() => {
336
- let acc = this.i1
337
-
338
- return run(
339
- this.i0,
340
- Sink.WithContext(
341
- sink.onFailure,
342
- (a) =>
343
- this.i2(acc, a).pipe(
344
- Effect.matchCauseEffect({
345
- onFailure: sink.onFailure,
346
- onSuccess: (optionCB) =>
347
- Effect.suspend(() => {
348
- if (Option.isNone(optionCB)) return Effect.unit
349
-
350
- const [c, b] = optionCB.value
351
- acc = b
352
-
353
- return sink.onSuccess(c)
354
- })
355
- })
356
- )
357
- )
358
- )
359
- })
360
- )
361
- }
362
- }
298
+ toEffect(): Effect.Effect<R | R2, E | E2, void> {
299
+ return Effect.asyncEffect((resume) => {
300
+ const { i0: fx, i1: f } = this
301
+ const onFailure = (cause: Cause.Cause<E | E2>) => Effect.sync(() => resume(Effect.failCause(cause)))
363
302
 
364
- class FxProvide<R, E, A, R2, E2, B> extends ToFx<Exclude<R, B> | R2, E | E2, A> {
365
- constructor(
366
- readonly i0: Fx<R, E, A>,
367
- readonly i1: Provide.Provide<R2, E2, B>
368
- ) {
369
- super(i0, i1)
303
+ return Effect.zipRight(
304
+ fx.run(Sink.make(onFailure, (a) => Effect.catchAllCause(f(a), onFailure))),
305
+ Effect.sync(() => resume(Effect.unit))
306
+ )
307
+ })
370
308
  }
371
309
 
372
310
  static make<R, E, A, R2, E2, B>(
373
311
  fx: Fx<R, E, A>,
374
- provide: Provide.Provide<R2, E2, B>
375
- ): Fx<Exclude<R, B> | R2, E | E2, A> {
376
- if (fx instanceof FxProvide) {
377
- return new FxProvide(fx.i0, Provide.merge(fx.i1, provide))
312
+ f: (a: A) => Effect.Effect<R2, E2, B>
313
+ ): Effect.Effect<R | R2, E | E2, void> {
314
+ if (isEmpty(fx)) {
315
+ return Effect.unit
316
+ } else if (isNever(fx)) {
317
+ return Effect.never
318
+ } else if (isProducer(fx)) {
319
+ return SyncProducer.runEffect(fx.i0, f)
320
+ } else if (isProducerSyncTransformer(fx)) {
321
+ return Op.matchOperator(fx.i1, {
322
+ SyncOperator: (op): Effect.Effect<R | R2, E | E2, void> =>
323
+ SyncOp.matchSyncOperator(op, {
324
+ Map: (op): Effect.Effect<R | R2, E | E2, void> =>
325
+ SyncProducer.effectOnce(() => SyncProducer.runEffect(fx.i0, (a) => f(op.f(a)))),
326
+ Filter: (op) =>
327
+ SyncProducer.effectOnce(() =>
328
+ SyncProducer.runEffect(fx.i0, Effect.unifiedFn((a) => op.f(a) ? f(a) : Effect.unit))
329
+ ),
330
+ FilterMap: (op) =>
331
+ SyncProducer.effectOnce(() =>
332
+ SyncProducer.runEffect(
333
+ fx.i0,
334
+ Effect.unifiedFn((a) => Option.match(op.f(a), { onNone: () => Effect.unit, onSome: f }))
335
+ )
336
+ )
337
+ }),
338
+ EffectOperator: (op) =>
339
+ EffectOp.matchEffectOperator(op, {
340
+ MapEffect: (op): Effect.Effect<R | R2, E | E2, void> =>
341
+ SyncProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), f)),
342
+ FilterMapEffect: (op) =>
343
+ SyncProducer.runEffect(fx.i0, (a) =>
344
+ Effect.flatMap(op.f(a), Effect.unifiedFn(Option.match({ onNone: () => Effect.unit, onSome: f })))),
345
+ FilterEffect: (op) =>
346
+ SyncProducer.runEffect(
347
+ fx.i0,
348
+ Effect.unifiedFn((a) =>
349
+ Effect.flatMap(op.f(a), Effect.unifiedFn((b) => b ? f(a) : Effect.unit))
350
+ )
351
+ ),
352
+ TapEffect: (op) => SyncProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), () => f(a)))
353
+ }),
354
+ SyncLoopOperator: (op) =>
355
+ SyncLoopOp.matchSyncLoopOperator(op, {
356
+ Loop: (op) =>
357
+ SyncProducer.effectOnce(() =>
358
+ SyncProducer.runReduceEffect(fx.i0, op.seed, (acc, a) => {
359
+ const [c, b] = op.f(acc, a)
360
+ return Effect.as(f(c), b)
361
+ })
362
+ ),
363
+ FilterMapLoop: (op) =>
364
+ SyncProducer.effectOnce(() =>
365
+ SyncProducer.runReduceEffect(fx.i0, op.seed, (acc, a) => {
366
+ const [c, b] = op.f(acc, a)
367
+ return Option.match(c, { onNone: () => Effect.succeed(acc), onSome: (c) => Effect.as(f(c), b) })
368
+ })
369
+ )
370
+ }),
371
+ EffectLoopOperator: (op) =>
372
+ EffectLoopOp.matchEffectLoopOperator(op, {
373
+ LoopEffect: (op) =>
374
+ SyncProducer.runReduceEffect(
375
+ fx.i0,
376
+ op.seed,
377
+ (acc, a) => Effect.flatMap(op.f(acc, a), ([c, b]) => Effect.as(f(c), b))
378
+ ),
379
+ FilterMapLoopEffect: (op) =>
380
+ SyncProducer.runReduceEffect(
381
+ fx.i0,
382
+ op.seed,
383
+ (acc, a) =>
384
+ Effect.flatMap(op.f(acc, a), ([c, b]) =>
385
+ Option.match(c, {
386
+ onNone: () => Effect.succeed(b),
387
+ onSome: (c) => Effect.as(f(c), b)
388
+ }))
389
+ )
390
+ })
391
+ })
392
+ } else if (isProducerEffect(fx)) {
393
+ return EffectProducer.runEffect(fx.i0, f)
394
+ } else if (isProducerEffectTransformer(fx)) {
395
+ return Op.matchOperator(fx.i1, {
396
+ SyncOperator: (op): Effect.Effect<R | R2, E | E2, void> =>
397
+ SyncOp.matchSyncOperator(op, {
398
+ Map: (op): Effect.Effect<R | R2, E | E2, void> =>
399
+ SyncProducer.effectOnce(() => EffectProducer.runEffect(fx.i0, (a) => f(op.f(a)))),
400
+ Filter: (op) =>
401
+ SyncProducer.effectOnce(() =>
402
+ EffectProducer.runEffect(fx.i0, Effect.unifiedFn((a) => op.f(a) ? f(a) : Effect.unit))
403
+ ),
404
+ FilterMap: (op) =>
405
+ SyncProducer.effectOnce(() =>
406
+ EffectProducer.runEffect(
407
+ fx.i0,
408
+ Effect.unifiedFn((a) => Option.match(op.f(a), { onNone: () => Effect.unit, onSome: f }))
409
+ )
410
+ )
411
+ }),
412
+ EffectOperator: (op) =>
413
+ EffectOp.matchEffectOperator(op, {
414
+ MapEffect: (op): Effect.Effect<R | R2, E | E2, void> =>
415
+ EffectProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), f)),
416
+ FilterMapEffect: (op) =>
417
+ EffectProducer.runEffect(fx.i0, (a) =>
418
+ Effect.flatMap(op.f(a), Effect.unifiedFn(Option.match({ onNone: () => Effect.unit, onSome: f })))),
419
+ FilterEffect: (op) =>
420
+ EffectProducer.runEffect(
421
+ fx.i0,
422
+ Effect.unifiedFn((a) =>
423
+ Effect.flatMap(op.f(a), Effect.unifiedFn((b) => b ? f(a) : Effect.unit))
424
+ )
425
+ ),
426
+ TapEffect: (op) => EffectProducer.runEffect(fx.i0, (a) => Effect.flatMap(op.f(a), () => f(a)))
427
+ }),
428
+ SyncLoopOperator: (op) =>
429
+ SyncLoopOp.matchSyncLoopOperator(op, {
430
+ Loop: (op) =>
431
+ SyncProducer.effectOnce(() =>
432
+ EffectProducer.runReduceEffect(fx.i0, op.seed, (acc, a) => {
433
+ const [c, b] = op.f(acc, a)
434
+ return Effect.as(f(c), b)
435
+ })
436
+ ),
437
+ FilterMapLoop: (op) =>
438
+ SyncProducer.effectOnce(() =>
439
+ EffectProducer.runReduceEffect(fx.i0, op.seed, (acc, a) => {
440
+ const [c, b] = op.f(acc, a)
441
+ return Option.match(c, { onNone: () => Effect.succeed(acc), onSome: (c) => Effect.as(f(c), b) })
442
+ })
443
+ )
444
+ }),
445
+ EffectLoopOperator: (op) =>
446
+ EffectLoopOp.matchEffectLoopOperator(op, {
447
+ LoopEffect: (op) =>
448
+ EffectProducer.runReduceEffect(
449
+ fx.i0,
450
+ op.seed,
451
+ (acc, a) => Effect.flatMap(op.f(acc, a), ([c, b]) => Effect.as(f(c), b))
452
+ ),
453
+ FilterMapLoopEffect: (op) =>
454
+ EffectProducer.runReduceEffect(
455
+ fx.i0,
456
+ op.seed,
457
+ (acc, a) =>
458
+ Effect.flatMap(op.f(acc, a), ([c, b]) =>
459
+ Option.match(c, {
460
+ onNone: () => Effect.succeed(b),
461
+ onSome: (c) => Effect.as(f(c), b)
462
+ }))
463
+ )
464
+ })
465
+ })
466
+ } else if (isFailCause(fx)) {
467
+ return Effect.failCause(fx.i0)
378
468
  } else {
379
- return new FxProvide(fx, provide)
469
+ return new Observe(fx, f)
380
470
  }
381
471
  }
472
+ }
382
473
 
383
- protected toFx(): Fx<R2 | Exclude<R, B>, E | E2, A> {
384
- return fromSink((sink) =>
385
- Effect.catchAllCause(Provide.provideToEffect(run(this.i0, sink), this.i1), sink.onFailure)
386
- )
474
+ export const reduce = <R, E, A, B>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => B): Effect.Effect<R, E, B> =>
475
+ Reduce.make(fx, seed, f)
476
+
477
+ class Reduce<R, E, A, B> extends EffectBase<R, E, B> {
478
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: B, readonly i2: (acc: B, a: A) => B) {
479
+ super()
387
480
  }
388
- }
389
481
 
390
- class Snapshot<R, E, A, R2, E2, B, R3, E3, C> extends ToFx<R | R2 | R3, E | E2 | E3, C> {
391
- constructor(
392
- readonly i0: Fx<R, E, A>,
393
- readonly i1: FxInput<R2, E2, B>,
394
- readonly i2: (a: A, b: B) => Effect.Effect<R3, E3, C>
395
- ) {
396
- super(i0, i1, i2)
397
- }
398
-
399
- toFx(): Fx<R | R2 | R3, E | E2 | E3, C> {
400
- return matchFxInput(this.i1, {
401
- RefSubject: (fx2) => this.runScoped(this.i0, fx2, this.i2),
402
- Fx: (fx2) => this.runScoped(this.i0, fx2, this.i2),
403
- Effect: (effect2) => mapEffect(this.i0, (a) => Effect.flatMap(effect2, (b) => this.i2(a, b))),
404
- Cause: (cause2) =>
405
- matchCause(this.i0, {
406
- onFailure: (cause1) => Effect.failCause(Cause.sequential(cause1, cause2)),
407
- onSuccess: () => Effect.failCause(cause2)
408
- }),
409
- Iterable: (iterable) =>
410
- withEarlyExit(({ sink }) => {
411
- const iterator = iterable[Symbol.iterator]()
412
-
413
- return run(
414
- this.i0,
415
- Sink.WithContext(sink.onFailure, (a) => {
416
- const result = iterator.next()
417
- if (result.done) {
418
- return sink.earlyExit
419
- } else {
420
- return Effect.matchCauseEffect(this.i2(a, result.value), sink)
421
- }
422
- })
423
- )
424
- }),
425
- Otherwise: (b) => mapEffect(this.i0, (a) => this.i2(a, b))
482
+ toEffect(): Effect.Effect<R, E, B> {
483
+ return Effect.suspend(() => {
484
+ let acc = this.i1
485
+
486
+ return Effect.map(
487
+ observe(this.i0, (a) => Effect.sync(() => acc = this.i2(acc, a))),
488
+ () => acc
489
+ )
426
490
  })
427
491
  }
428
492
 
429
- private runScoped<R, E, A, R2, E2, B, R3, E3, C>(
430
- fx: Fx<R, E, A>,
431
- fx2: Fx<R2, E2, B>,
432
- f: (a: A, b: B) => Effect.Effect<R3, E3, C>
433
- ): Fx<R | R2 | R3, E | E2 | E3, C> {
434
- return withScopedFork(({ fork, sink }) =>
435
- Effect.flatMap(Ref.make(Option.none<B>()), (ref) =>
436
- Effect.flatMap(
437
- fork(run(
438
- fx2,
439
- Sink.WithContext(
440
- sink.onFailure,
441
- (b) => Ref.set(ref, Option.some(b))
442
- )
443
- )),
444
- () =>
445
- adjustTime(1).pipe(Effect.zipRight(run(
446
- fx,
447
- Sink.WithContext(
448
- sink.onFailure,
449
- (a: A) =>
450
- Effect.flatten(Ref.get(ref)).pipe(
451
- Effect.flatMap((b: B) => Effect.matchCauseEffect(f(a, b), sink)),
452
- Effect.optionFromOptional,
453
- Effect.asUnit
454
- )
493
+ static make<R, E, A, B>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => B) {
494
+ // TODO: optimize Effect trasformers
495
+
496
+ if (isEmpty(fx)) return Effect.succeed(seed)
497
+ else if (isProducer(fx)) {
498
+ return SyncProducer.runReduce(fx.i0, seed, f)
499
+ } else if (isProducerSyncTransformer(fx)) {
500
+ return Op.matchOperator(fx.i1, {
501
+ SyncOperator: (op) => SyncProducer.syncOnce(() => SyncOp.runSyncReduce(fx.i0, op, seed, f)),
502
+ EffectOperator: (op) => EffectOp.runSyncReduce(fx.i0, op, seed, f),
503
+ SyncLoopOperator: (op) =>
504
+ SyncLoopOp.matchSyncLoopOperator(op, {
505
+ Loop: (op) =>
506
+ Effect.map(
507
+ SyncProducer.runReduce(fx.i0, [op.seed, seed] as const, ([opAcc, acc], a) => {
508
+ const [c, b] = op.f(opAcc, a)
509
+ const newAcc = f(acc, c)
510
+ return [b, newAcc] as const
511
+ }),
512
+ (x) => x[1]
513
+ ),
514
+ FilterMapLoop: (op) =>
515
+ Effect.map(
516
+ SyncProducer.runReduce(fx.i0, [op.seed, seed] as const, ([opAcc, acc], a) => {
517
+ const [c, b] = op.f(opAcc, a)
518
+ const newAcc = Option.match(c, { onNone: () => acc, onSome: (c) => f(acc, c) })
519
+
520
+ return [b, newAcc] as const
521
+ }),
522
+ (x) => x[1]
455
523
  )
456
- )))
457
- ))
458
- )
524
+ }),
525
+ EffectLoopOperator: (op) =>
526
+ EffectLoopOp.matchEffectLoopOperator(op, {
527
+ LoopEffect: (op) =>
528
+ Effect.map(
529
+ SyncProducer.runReduceEffect(fx.i0, [op.seed, seed] as const, ([opAcc, acc], a) => {
530
+ return Effect.flatMap(op.f(opAcc, a), ([c, b]) => {
531
+ const newAcc = f(acc, c)
532
+ return Effect.succeed([b, newAcc] as const)
533
+ })
534
+ }),
535
+ (x) => x[1]
536
+ ),
537
+ FilterMapLoopEffect: (op) =>
538
+ Effect.map(
539
+ SyncProducer.runReduceEffect(fx.i0, [op.seed, seed] as const, ([opAcc, acc], a) => {
540
+ return Effect.map(op.f(opAcc, a), ([c, b]) => {
541
+ const newAcc = Option.match(c, { onNone: () => acc, onSome: () => f(acc, b) })
542
+ return [b, newAcc] as const
543
+ })
544
+ }),
545
+ (x) => x[1]
546
+ )
547
+ })
548
+ })
549
+ } else if (isProducerEffect(fx)) {
550
+ return EffectProducer.runReduceEffect(fx.i0, seed, (b, a) => Effect.succeed(f(b, a)))
551
+ } else if (isFailCause(fx)) {
552
+ return Effect.failCause(fx.i0)
553
+ } else {
554
+ return new Reduce(fx, seed, f)
555
+ }
459
556
  }
460
557
  }
461
558
 
462
- class Middleware<R, E, A, R2, R3> extends ToFx<R2 | R3, E, A> {
463
- constructor(
464
- readonly i0: Fx<R, E, A>,
465
- readonly i1: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R2, never, unknown>,
466
- readonly i2: (sink: Sink.Sink<E, A>) => Sink.Sink<E, A>
467
- ) {
468
- super(i0, i1)
559
+ export const toReadonlyArray = <R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, ReadonlyArray<A>> =>
560
+ Effect.suspend(() => {
561
+ const init = [] as Array<A>
562
+ return Reduce.make(fx, init, (acc, a) => {
563
+ acc.push(a)
564
+ return acc
565
+ })
566
+ })
567
+
568
+ export const slice = <R, E, A>(fx: Fx<R, E, A>, drop: number, take: number): Fx<R, E, A> =>
569
+ Slice.make(fx, boundsFrom(drop, take))
570
+
571
+ export const take = <R, E, A>(fx: Fx<R, E, A>, n: number): Fx<R, E, A> => slice(fx, 0, n)
572
+
573
+ export const drop = <R, E, A>(fx: Fx<R, E, A>, n: number): Fx<R, E, A> => slice(fx, n, Infinity)
574
+
575
+ class Slice<R, E, A> extends FxBase<R, E, A> {
576
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Bounds) {
577
+ super()
469
578
  }
470
579
 
471
- static make<R, R2, E, A>(
472
- fx: Fx<R, E, A>,
473
- middleware: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R2, never, unknown>,
474
- mapSink: (sink: Sink.Sink<E, A>) => Sink.Sink<E, A>
475
- ): Fx<R2, E, A> {
476
- if (fx instanceof Middleware) {
477
- return new Middleware(fx.i0 as Fx<R, E, any>, (effect) => middleware(fx.i1(effect)), (s) => fx.i2(mapSink(s)))
478
- } else {
479
- return new Middleware(fx, middleware, mapSink)
480
- }
580
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
581
+ return Sink.slice(sink, this.i1, (s) => this.i0.run(s))
481
582
  }
482
583
 
483
- protected toFx(): Fx<R2, E, A> {
484
- return fromSink((sink) => this.i1(run(this.i0, this.i2(sink))))
584
+ static make<R, E, A>(fx: Fx<R, E, A>, bounds: Bounds): Fx<R, E, A> {
585
+ if (isNilBounds(bounds)) return empty
586
+ if (isInfiniteBounds(bounds)) return fx
587
+
588
+ if (isSlice(fx)) {
589
+ return Slice.make(fx.i0, mergeBounds(fx.i1, bounds))
590
+ } else if (isTransformer(fx) && fx.i1._tag === "Map") {
591
+ // Commute map and slice
592
+ return map(Slice.make(fx.i0, bounds), fx.i1.f)
593
+ } else {
594
+ return new Slice(fx, bounds)
595
+ }
485
596
  }
486
597
  }
487
598
 
488
- export function succeed<A>(value: A): Fx<never, never, A> {
489
- return new Succeed(value)
599
+ /**
600
+ * @internal
601
+ */
602
+ export function isSlice<R, E, A>(fx: Fx<R, E, A>): fx is Slice<R, E, A> {
603
+ return fx.constructor === Slice
490
604
  }
491
605
 
492
- export function fromIterable<A>(iterable: Iterable<A>): Fx<never, never, A> {
493
- return new FromIterable(iterable)
606
+ export function skipRepeatsWith<R, E, A>(
607
+ fx: Fx<R, E, A>,
608
+ eq: Equivalence.Equivalence<A>
609
+ ): Fx<R, E, A> {
610
+ return filterMapLoop(fx, Option.none<A>(), (previous, a) => {
611
+ if (Option.isSome(previous) && eq(a, previous.value)) {
612
+ return [Option.none<A>(), Option.some<A>(a)] as const
613
+ } else {
614
+ return [Option.some<A>(a), Option.some<A>(a)] as const
615
+ }
616
+ })
494
617
  }
495
618
 
496
- export const map: {
497
- <A, B>(f: (a: A) => B): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, B>
498
- <R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => B): Fx<R, E, B>
499
- } = dual(2, function map<R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => B) {
500
- return Transformer.make<R, E, B>(fx, Map(f))
501
- })
502
-
503
- export const mapBoth: {
504
- <E, E2, A, B>(
505
- options: {
506
- readonly onFailure: (e: E) => E2
507
- readonly onSuccess: (a: A) => B
508
- }
509
- ): <R>(fx: Fx<R, E, A>) => Fx<R, E2, B>
619
+ export function skipRepeats<R, E, A>(
620
+ fx: Fx<R, E, A>
621
+ ): Fx<R, E, A> {
622
+ return skipRepeatsWith(fx, Equal.equals)
623
+ }
510
624
 
511
- <R, E, A, E2, B>(
512
- fx: Fx<R, E, A>,
513
- options: {
514
- readonly onFailure: (e: E) => E2
515
- readonly onSuccess: (a: A) => B
516
- }
517
- ): Fx<R, E2, B>
518
- } = dual(2, function mapBoth<R, E, A, E2, B>(
519
- fx: Fx<R, E, A>,
520
- options: {
521
- readonly onFailure: (e: E) => E2
522
- readonly onSuccess: (a: A) => B
625
+ class ProducerEffectTransformer<R, E, A, R2, E2, B> extends FxBase<R | R2, E | E2, B> {
626
+ constructor(readonly i0: EffectProducer.EffectProducer<R, E, A>, readonly i1: Op.Operator) {
627
+ super()
523
628
  }
524
- ) {
525
- return map(mapError(fx, options.onFailure), options.onSuccess)
526
- })
527
-
528
- export const filter: {
529
- <A, B extends A>(f: (a: A) => a is B): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, B>
530
- <A>(f: (a: A) => boolean): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, A>
531
- <R, E, A, B extends A>(fx: Fx<R, E, A>, f: (a: A) => a is B): Fx<R, E, B>
532
- <R, E, A>(fx: Fx<R, E, A>, f: (a: A) => boolean): Fx<R, E, A>
533
- } = dual(2, function map<R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => boolean) {
534
- return Transformer.make<R, E, B>(fx, Filter(f))
535
- })
536
-
537
- export const filterMap: {
538
- <A, B>(f: (a: A) => Option.Option<B>): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, B>
539
- <R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => Option.Option<B>): Fx<R, E, B>
540
- } = dual(2, function map<R, E, A, B>(fx: Fx<R, E, A>, f: (a: A) => Option.Option<B>) {
541
- return Transformer.make<R, E, B>(fx, FilterMap(f))
542
- })
543
-
544
- export const compact = <R, E, A>(fx: Fx<R, E, Option.Option<A>>): Fx<R, E, A> => filterMap(fx, identity)
545
-
546
- export const mapErrorCause: {
547
- <E, E2>(f: (a: Cause.Cause<E>) => Cause.Cause<E2>): <R, A>(fx: Fx<R, E, A>) => Fx<R, E2, A>
548
- <R, E, A, E2>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => Cause.Cause<E2>): Fx<R, E2, A>
549
- } = dual(2, function map<R, E, A, E2>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => Cause.Cause<E2>) {
550
- return TransformerCause.make<R, E2, A>(fx, Map(f))
551
- })
552
-
553
- export const mapError: {
554
- <E, E2>(f: (a: E) => E2): <R, A>(fx: Fx<R, E, A>) => Fx<R, E2, A>
555
- <R, E, A, E2>(fx: Fx<R, E, A>, f: (a: E) => E2): Fx<R, E2, A>
556
- } = dual(2, function map<R, E, A, E2>(fx: Fx<R, E, A>, f: (a: E) => E2) {
557
- return TransformerCause.make<R, E2, A>(fx, Map(Cause.map(f)))
558
- })
559
-
560
- export const filterCause: {
561
- <E, E2 extends E>(f: (a: Cause.Cause<E>) => a is Cause.Cause<E2>): <R, A>(fx: Fx<R, E, A>) => Fx<R, E2, A>
562
- <E>(f: (a: Cause.Cause<E>) => boolean): <R, A>(fx: Fx<R, E, A>) => Fx<R, E, A>
563
- <R, E, E2 extends E, A>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => a is Cause.Cause<E2>): Fx<R, E2, A>
564
- <R, E, A>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => boolean): Fx<R, E, A>
565
- } = dual(2, function map<R, E, A, E2>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => boolean) {
566
- return TransformerCause.make<R, E2, A>(fx, Filter(f))
567
- })
568
-
569
- export const filterMapCause: {
570
- <E, E2>(f: (a: Cause.Cause<E>) => Option.Option<Cause.Cause<E2>>): <R, A>(fx: Fx<R, E, A>) => Fx<R, E2, A>
571
- <R, E, A, E2>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => Option.Option<Cause.Cause<E2>>): Fx<R, E2, A>
572
- } = dual(2, function map<R, E, A, E2>(fx: Fx<R, E, A>, f: (a: Cause.Cause<E>) => Option.Option<Cause.Cause<E2>>) {
573
- return TransformerCause.make<R, E2, A>(fx, FilterMap(f))
574
- })
575
-
576
- export const filterError: {
577
- <E, E2 extends E>(f: (a: E) => a is E2): <R, A>(fx: Fx<R, E, A>) => Fx<R, E2, A>
578
- <E>(f: (a: E) => boolean): <R, A>(fx: Fx<R, E, A>) => Fx<R, E, A>
579
- <R, E, E2 extends E, A>(fx: Fx<R, E, A>, f: (a: E) => a is E2): Fx<R, E2, A>
580
- <R, E, A>(fx: Fx<R, E, A>, f: (a: E) => boolean): Fx<R, E, A>
581
- } = dual(2, function map<R, E, A>(fx: Fx<R, E, A>, f: (a: E) => boolean) {
582
- return filterMapCause(fx, (cause) =>
583
- Cause.failureOrCause(cause).pipe(
584
- Either.match({
585
- onLeft: (e) => f(e) ? Option.some(Cause.fail(e)) : Option.none(),
586
- onRight: Option.some
587
- })
588
- ))
589
- })
590
629
 
591
- export const filterMapError: {
592
- <E, E2>(f: (a: E) => Option.Option<E2>): <R, A>(fx: Fx<R, E, A>) => Fx<R, E2, A>
593
- <R, E, A, E2>(fx: Fx<R, E, A>, f: (a: E) => Option.Option<E2>): Fx<R, E2, A>
594
- } = dual(2, function map<R, E, A, E2>(fx: Fx<R, E, A>, f: (a: E) => Option.Option<E2>) {
595
- return filterMapCause(fx, (cause) =>
596
- Cause.failureOrCause(cause).pipe(
597
- Either.match({
598
- onLeft: (e) => Option.map(f(e), Cause.fail),
599
- onRight: Option.some
600
- })
601
- ))
602
- })
603
-
604
- export const filterMapErrorEffect: {
605
- <E, R2, E2, B>(f: (e: E) => Effect.Effect<R2, E2, Option.Option<B>>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2 | B, A>
606
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (e: E) => Effect.Effect<R2, E2, Option.Option<B>>): Fx<R | R2, E2 | B, A>
607
- } = dual(2, <R, E, A, R2, E2, B>(
608
- fx: Fx<R, E, A>,
609
- f: (e: E) => Effect.Effect<R2, E2, Option.Option<B>>
610
- ): Fx<R | R2, B | E2, A> => {
611
- return fromSink((sink) =>
612
- run(
613
- fx,
614
- Sink.WithContext(
615
- (cause) =>
616
- Either.match(Cause.failureOrCause(cause), {
617
- onLeft: (e) =>
618
- Effect.matchCauseEffect(f(e), {
619
- onFailure: sink.onFailure,
620
- onSuccess: Option.match({
621
- onNone: () => Effect.unit,
622
- onSome: (b) => sink.onFailure(Cause.fail(b))
623
- })
624
- }),
625
- onRight: sink.onFailure
626
- }),
627
- sink.onSuccess
628
- )
629
- )
630
- )
631
- })
632
-
633
- export function observe<R, E, A, R2, E2>(
634
- fx: Fx<R, E, A>,
635
- onSuccees: (a: A) => Effect.Effect<R2, E2, unknown>
636
- ): Effect.Effect<R | R2, E | E2, void> {
637
- return helpers.withScopedFork((fork) =>
638
- Effect.flatMap(Deferred.make<E | E2, void>(), (deferred) =>
639
- run(
640
- fx,
641
- Sink.WithContext(
642
- (cause) => Deferred.failCause(deferred, cause),
643
- (a) => Effect.catchAllCause(onSuccees(a), (cause) => Deferred.failCause(deferred, cause))
644
- )
645
- ).pipe(
646
- Effect.intoDeferred(deferred),
647
- fork,
648
- Effect.flatMap(() => Deferred.await(deferred))
649
- ))
650
- )
630
+ run<R3>(sink: Sink.Sink<R3, E | E2, B>): Effect.Effect<R | R2 | R3, never, unknown> {
631
+ return EffectProducer.runSink(this.i0, Op.compileOperatorSink(this.i1, sink))
632
+ }
651
633
  }
652
634
 
653
- export function drain<R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, void> {
654
- return observe(fx, constUnit)
635
+ /**
636
+ * @internal
637
+ */
638
+ export function isProducerEffectTransformer<R, E, A>(
639
+ fx: Fx<R, E, A>
640
+ ): fx is ProducerEffectTransformer<R, E, any, R, E, A> {
641
+ return fx.constructor === ProducerEffectTransformer
655
642
  }
656
643
 
657
- export function toArray<R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, Array<A>> {
658
- return Effect.suspend(() => {
659
- const array: Array<A> = []
660
-
661
- return Effect.as(
662
- observe(fx, (a) => Effect.sync(() => array.push(a))),
663
- array
664
- )
665
- })
644
+ class Empty extends FxBase<never, never, never> {
645
+ run<R2>(): Effect.Effect<R2, never, unknown> {
646
+ return Effect.unit
647
+ }
666
648
  }
667
649
 
668
- export function toReadonlyArray<R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, ReadonlyArray<A>> {
669
- return toArray(fx)
650
+ /**
651
+ * @internal
652
+ */
653
+ export function isEmpty<R, E, A>(fx: Fx<R, E, A>): fx is Empty {
654
+ return fx.constructor === Empty
670
655
  }
671
656
 
672
- export const flatMapWithStrategy: {
673
- <A, R2, E2, B>(
674
- f: (a: A) => FxInput<R2, E2, B>,
675
- strategy: FlattenStrategy
676
- ): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
677
- <R, E, A, R2, E2, B>(
678
- fx: Fx<R, E, A>,
679
- f: (a: A) => FxInput<R2, E2, B>,
680
- strategy: FlattenStrategy
681
- ): Fx<R | R2, E | E2, B>
682
- } = dual(
683
- 3,
684
- function flatMapWithStrategy<R, E, A, R2, E2, B>(
685
- fx: Fx<R, E, A>,
686
- f: (a: A) => FxInput<R2, E2, B>,
687
- strategy: FlattenStrategy
688
- ): Fx<R | R2, E | E2, B> {
689
- return new WithFlattenStrategy(
690
- ({ fork, sink }) => run(fx, Sink.WithContext(sink.onFailure, (a) => fork(run(from(f(a)), sink)))),
691
- strategy
692
- )
693
- }
694
- )
657
+ export const empty: Fx<never, never, never> = new Empty()
695
658
 
696
- export const switchMap: {
697
- <A, R2, E2, B>(f: (a: A) => FxInput<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
698
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B>
699
- } = dual(
700
- 2,
701
- function switchMap<R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B> {
702
- return flatMapWithStrategy(fx, f, strategies.Switch)
659
+ class Never extends FxBase<never, never, never> {
660
+ run<R2>(): Effect.Effect<R2, never, unknown> {
661
+ return Effect.never
703
662
  }
704
- )
663
+ }
705
664
 
706
- export const exhaustMap: {
707
- <A, R2, E2, B>(f: (a: A) => FxInput<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
708
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B>
709
- } = dual(
710
- 2,
711
- function exhaustmap<R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B> {
712
- return flatMapWithStrategy(fx, f, strategies.Exhaust)
713
- }
714
- )
665
+ /**
666
+ * @internal
667
+ */
668
+ export function isNever<R, E, A>(fx: Fx<R, E, A>): fx is Never {
669
+ return fx.constructor === Never
670
+ }
715
671
 
716
- export const exhaust = <R, E, R2, E2, A>(fx: Fx<R, E, Fx<R2, E2, A>>) => exhaustMap(fx, identity)
672
+ export const never: Fx<never, never, never> = new Never()
717
673
 
718
- export const exhaustMapLatest: {
719
- <A, R2, E2, B>(f: (a: A) => FxInput<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
720
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B>
721
- } = dual(
722
- 2,
723
- function exhaustMapLatest<R, E, A, R2, E2, B>(
724
- fx: Fx<R, E, A>,
725
- f: (a: A) => FxInput<R2, E2, B>
726
- ): Fx<R | R2, E | E2, B> {
727
- return flatMapWithStrategy(fx, f, strategies.ExhaustLatest)
728
- }
729
- )
674
+ export function padWith<R, E, A, B, C>(
675
+ fx: Fx<R, E, A>,
676
+ start: Iterable<B>,
677
+ end: Iterable<C>
678
+ ): Fx<R, E, A | B | C> {
679
+ return new PadWith(fx, start, end)
680
+ }
730
681
 
731
- export const exhaustLatest = <R, E, R2, E2, A>(fx: Fx<R, E, Fx<R2, E2, A>>) => exhaustMapLatest(fx, identity)
682
+ export function prependAll<R, E, A, B>(
683
+ fx: Fx<R, E, A>,
684
+ start: Iterable<B>
685
+ ): Fx<R, E, A | B> {
686
+ return new PadWith(fx, start, [])
687
+ }
732
688
 
733
- export const flatMap: {
734
- <A, R2, E2, B>(f: (a: A) => FxInput<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
735
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B>
736
- } = dual(
737
- 2,
738
- function flatMap<R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B> {
739
- return flatMapWithStrategy(fx, f, strategies.Unbounded)
740
- }
741
- )
689
+ export function appendAll<R, E, A, C>(
690
+ fx: Fx<R, E, A>,
691
+ end: Iterable<C>
692
+ ): Fx<R, E, A | C> {
693
+ return new PadWith(fx, [], end)
694
+ }
742
695
 
743
- export const flatten = <R, E, R2, E2, A>(fx: Fx<R, E, Fx<R2, E2, A>>) => flatMap(fx, identity)
696
+ export function prepend<R, E, A, B>(fx: Fx<R, E, A>, start: B): Fx<R, E, A | B> {
697
+ return new PadWith(fx, [start], [])
698
+ }
744
699
 
745
- export const flatMapConcurrently: {
746
- <A, R2, E2, B>(f: (a: A) => FxInput<R2, E2, B>, concurrency: number): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
747
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>, concurrency: number): Fx<R | R2, E | E2, B>
748
- } = dual(
749
- 3,
750
- function flatMapConcurrently<R, E, A, R2, E2, B>(
751
- fx: Fx<R, E, A>,
752
- f: (a: A) => FxInput<R2, E2, B>,
753
- concurrency: number
754
- ): Fx<R | R2, E | E2, B> {
755
- return flatMapWithStrategy(fx, f, strategies.Bounded(concurrency))
756
- }
757
- )
758
-
759
- export const concatMap: {
760
- <A, R2, E2, B>(f: (a: A) => FxInput<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
761
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => FxInput<R2, E2, B>): Fx<R | R2, E | E2, B>
762
- } = dual(
763
- 2,
764
- function concatMap<R, E, A, R2, E2, B>(
765
- fx: Fx<R, E, A>,
766
- f: (a: A) => FxInput<R2, E2, B>
767
- ): Fx<R | R2, E | E2, B> {
768
- return flatMapConcurrently(fx, f, 1)
769
- }
770
- )
771
-
772
- export const acquireUseRelease: {
773
- <A, R2, E2, B, R3, E3>(
774
- use: (a: A) => FxInput<R2, E2, B>,
775
- release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<R3, E3, unknown>
776
- ): <R, E>(acquire: Effect.Effect<R, E, A>) => Fx<R | R2 | R3, E | E2 | E3, B>
777
-
778
- <R, E, A, R2, E2, B, R3, E3>(
779
- acquire: Effect.Effect<R, E, A>,
780
- use: (a: A) => FxInput<R2, E2, B>,
781
- release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<R3, E3, unknown>
782
- ): Fx<R | R2 | R3, E | E2 | E3, B>
783
- } = dual(3, function acquireUseRelease<R, E, A, R2, E2, B, R3, E3>(
784
- acquire: Effect.Effect<R, E, A>,
785
- use: (a: A) => FxInput<R2, E2, B>,
786
- release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<R3, E3, unknown>
787
- ): Fx<R | R2 | R3, E | E2 | E3, B> {
788
- return fromSink((sink) =>
789
- Effect.catchAllCause(
790
- Effect.acquireUseRelease(
791
- acquire,
792
- (a) => run(from(use(a)), sink),
793
- (a, exit) => Effect.catchAllCause(release(a, exit), sink.onFailure)
794
- ),
795
- sink.onFailure
796
- )
700
+ export function append<R, E, A, C>(fx: Fx<R, E, A>, end: C): Fx<R, E, A | C> {
701
+ return new PadWith<R, E, A, never, C>(fx, [], [end])
702
+ }
703
+
704
+ export function scan<R, E, A, B>(fx: Fx<R, E, A>, seed: B, f: (b: B, a: A) => B): Fx<R, E, B> {
705
+ return prepend(
706
+ loop(fx, seed, (b, a) => {
707
+ const b2 = f(b, a)
708
+ return [b2, b2] as const
709
+ }),
710
+ seed
797
711
  )
798
- })
712
+ }
799
713
 
800
- export function combine<const FX extends ReadonlyArray<Fx<any, any, any>>>(
801
- fxs: FX
802
- ): Fx<
803
- Fx.Context<FX[number]>,
804
- Fx.Error<FX[number]>,
805
- {
806
- readonly [K in keyof FX]: Fx.Success<FX[K]>
714
+ class PadWith<
715
+ R,
716
+ E,
717
+ A,
718
+ B,
719
+ C
720
+ > extends FxBase<R, E, A | B | C> {
721
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Iterable<B>, readonly i2: Iterable<C>) {
722
+ super()
807
723
  }
808
- > {
809
- return fromSink((sink) =>
810
- Effect.suspend(() => {
811
- const total = fxs.length
812
-
813
- if (total === 0) return Effect.unit
814
724
 
815
- const values = new globalThis.Map<number, any>()
816
- const sample = () =>
817
- Array.from({ length: total }, (_, i) => values.get(i)) as {
818
- readonly [K in keyof FX]: Fx.Success<FX[K]>
819
- }
725
+ run<R2>(sink: Sink.Sink<R2, E, A | B | C>): Effect.Effect<R | R2, never, unknown> {
726
+ const onSuccess = (a: A | B | C) => sink.onSuccess(a)
820
727
 
821
- const emitIfReady = (value: any, index: number) =>
822
- Effect.suspend(() => {
823
- values.set(index, value)
824
- if (values.size === total) {
825
- return sink.onSuccess(sample())
826
- } else {
827
- return Effect.unit
828
- }
829
- })
728
+ return Effect.forEach(this.i1, onSuccess, DISCARD).pipe(
729
+ Effect.zipRight(this.i0.run(sink)),
730
+ Effect.zipRight(Effect.forEach(this.i2, onSuccess, DISCARD))
731
+ )
732
+ }
830
733
 
831
- return Effect.all(
832
- fxs.map((fx, index) => run(fx, Sink.WithContext(sink.onFailure, (a) => emitIfReady(a, index)))),
833
- { concurrency: "unbounded" }
834
- )
835
- })
836
- )
734
+ static make<R, E, A, B, C>(
735
+ fx: Fx<R, E, A>,
736
+ start: Iterable<B>,
737
+ end: Iterable<C>
738
+ ): Fx<R, E, A | B | C> {
739
+ if (isEmpty(fx) || isNever(fx)) return fx
740
+ else if (isPadWith(fx)) {
741
+ return new PadWith(fx.i0, concat(start, fx.i1), concat(fx.i2, end))
742
+ } else {
743
+ return new PadWith(fx, start, end)
744
+ }
745
+ }
837
746
  }
838
747
 
839
- export function struct<const FX extends Readonly<Record<PropertyKey, Fx<any, any, any>>>>(
840
- fxs: FX
841
- ): Fx<
842
- Fx.Context<FX[string]>,
843
- Fx.Error<FX[string]>,
844
- {
845
- readonly [K in keyof FX]: Fx.Success<FX[K]>
748
+ function concat<A, B>(a: Iterable<A>, b: Iterable<B>): Iterable<A | B> {
749
+ return {
750
+ *[Symbol.iterator]() {
751
+ yield* a
752
+ yield* b
753
+ }
846
754
  }
847
- > {
848
- return map(combine(Reflect.ownKeys(fxs).map((k) => map(fxs[k], (a) => [k, a] as const))), Object.fromEntries)
849
755
  }
850
756
 
851
- export function merge<const FX extends ReadonlyArray<Fx<any, any, any>>>(
852
- fxs: FX
853
- ): Fx<
854
- Fx.Context<FX[number]>,
855
- Fx.Error<FX[number]>,
856
- Fx.Success<FX[number]>
857
- > {
858
- return Merge.make(fxs, strategies.Unordered(Infinity))
859
- }
860
-
861
- export const mergeConcurrently: {
862
- (concurrency: number): <const FX extends ReadonlyArray<Fx<any, any, any>>>(
863
- fxs: FX
864
- ) => Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>>
865
- <const FX extends ReadonlyArray<Fx<any, any, any>>>(
866
- fxs: FX,
867
- concurrency: number
868
- ): Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>>
869
- } = dual(2, function mergeConcurrently<FX extends ReadonlyArray<Fx<any, any, any>>>(
870
- fxs: FX,
871
- concurrency: number
872
- ): Fx<
873
- Fx.Context<FX[number]>,
874
- Fx.Error<FX[number]>,
875
- Fx.Success<FX[number]>
876
- > {
877
- return Merge.make(fxs, strategies.Unordered(concurrency))
878
- })
757
+ /**
758
+ * @internal
759
+ */
760
+ export function isPadWith<R, E, A>(
761
+ fx: Fx<R, E, A>
762
+ ): fx is PadWith<R, E, A, A, A> {
763
+ return fx.constructor === PadWith
764
+ }
879
765
 
880
- export function mergeBuffer<const FX extends ReadonlyArray<Fx<any, any, any>>>(
881
- fxs: FX
882
- ): Fx<
883
- Fx.Context<FX[number]>,
884
- Fx.Error<FX[number]>,
885
- Fx.Success<FX[number]>
886
- > {
887
- return Merge.make(fxs, strategies.Ordered(Infinity))
888
- }
889
-
890
- export const mergeBufferConcurrently: {
891
- (concurrency: number): <const FX extends ReadonlyArray<Fx<any, any, any>>>(
892
- fxs: FX
893
- ) => Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>>
894
- <const FX extends ReadonlyArray<Fx<any, any, any>>>(
895
- fxs: FX,
896
- concurrency: number
897
- ): Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>>
898
- } = dual(2, function mergeConcurrently<FX extends ReadonlyArray<Fx<any, any, any>>>(
899
- fxs: FX,
900
- concurrency: number
901
- ): Fx<
902
- Fx.Context<FX[number]>,
903
- Fx.Error<FX[number]>,
904
- Fx.Success<FX[number]>
905
- > {
906
- return Merge.make(fxs, strategies.Ordered(concurrency))
907
- })
766
+ export function flatMapWithStrategy<R, E, A, R2, E2, B>(
767
+ fx: Fx<R, E, A>,
768
+ f: (a: A) => Fx<R2, E2, B>,
769
+ strategy: FlattenStrategy,
770
+ executionStrategy: ExecutionStrategy.ExecutionStrategy = ExecutionStrategy.sequential
771
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
772
+ return FlatMapWithStrategy.make(fx, f, strategy, executionStrategy)
773
+ }
908
774
 
909
- export const mergeSwitch = <const FX extends ReadonlyArray<Fx<any, any, any>>>(
910
- fxs: FX
911
- ): Fx<
912
- Fx.Context<FX[number]>,
913
- Fx.Error<FX[number]>,
914
- Fx.Success<FX[number]>
915
- > => Merge.make(fxs, strategies.Switch)
775
+ export function switchMap<R, E, A, R2, E2, B>(
776
+ fx: Fx<R, E, A>,
777
+ f: (a: A) => Fx<R2, E2, B>,
778
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
779
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
780
+ return flatMapWithStrategy(fx, f, Switch, executionStrategy)
781
+ }
916
782
 
917
- export function race<const FX extends ReadonlyArray<Fx<any, any, any>>>(
918
- fxs: FX
919
- ): Fx<
920
- Fx.Context<FX[number]>,
921
- Fx.Error<FX[number]>,
922
- Fx.Success<FX[number]>
923
- > {
924
- if (fxs.length === 0) return empty
925
- if (fxs.length === 1) return fxs[0]
926
-
927
- return withScopedFork(({ fork, sink }) =>
928
- Effect.asyncEffect<
929
- never,
930
- never,
931
- readonly [
932
- number,
933
- Array<Fiber.Fiber<never, unknown>>
934
- ],
935
- Fx.Context<FX[number]>,
936
- never,
937
- unknown
938
- >((resume) =>
939
- Effect.gen(function*(_) {
940
- let winningIndex = -1
941
- const fibers: Array<Fiber.Fiber<never, unknown>> = yield* _(
942
- Effect.forEach(fxs, (fx, i) =>
943
- fork(
944
- run(
945
- fx,
946
- Sink.Sink(
947
- (cause) => Effect.suspend(() => pickWinner(i) ? sink.onFailure(cause) : Effect.unit),
948
- (a) => Effect.suspend(() => pickWinner(i) ? sink.onSuccess(a) : Effect.unit)
949
- )
950
- )
951
- ))
952
- )
783
+ export function switchMapEffect<R, E, A, R2, E2, B>(
784
+ fx: Fx<R, E, A>,
785
+ f: (a: A) => Effect.Effect<R2, E2, B>,
786
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
787
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
788
+ return switchMap(fx, (a) => fromEffect(f(a)), executionStrategy)
789
+ }
953
790
 
954
- function pickWinner(i: number) {
955
- if (winningIndex === -1) {
956
- winningIndex = i
957
- resume(Effect.succeed([i, fibers]))
958
- }
791
+ export function exhaustMap<R, E, A, R2, E2, B>(
792
+ fx: Fx<R, E, A>,
793
+ f: (a: A) => Fx<R2, E2, B>,
794
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
795
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
796
+ return flatMapWithStrategy(fx, f, Exhaust, executionStrategy)
797
+ }
959
798
 
960
- return winningIndex === i
961
- }
799
+ export function exhaustMapEffect<R, E, A, R2, E2, B>(
800
+ fx: Fx<R, E, A>,
801
+ f: (a: A) => Effect.Effect<R2, E2, B>,
802
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
803
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
804
+ return exhaustMap(fx, (a) => fromEffect(f(a)), executionStrategy)
805
+ }
806
+
807
+ export function exhaustMapLatest<R, E, A, R2, E2, B>(
808
+ fx: Fx<R, E, A>,
809
+ f: (a: A) => Fx<R2, E2, B>,
810
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
811
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
812
+ return flatMapWithStrategy(fx, f, ExhaustLatest, executionStrategy)
813
+ }
814
+
815
+ export function exhaustMapLatestEffect<R, E, A, R2, E2, B>(
816
+ fx: Fx<R, E, A>,
817
+ f: (a: A) => Effect.Effect<R2, E2, B>,
818
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
819
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
820
+ return exhaustMapLatest(fx, (a) => fromEffect(f(a)), executionStrategy)
821
+ }
822
+
823
+ export function exhaustFilterMapLatestEffect<R, E, A, R2, E2, B>(
824
+ fx: Fx<R, E, A>,
825
+ f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>,
826
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
827
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
828
+ return exhaustMapLatest(fx, (a) =>
829
+ fromFxEffect(Effect.map(
830
+ f(a),
831
+ Option.match({
832
+ onNone: () => empty,
833
+ onSome: succeed
962
834
  })
963
- ).pipe(
964
- Effect.flatMap(([winningIndex, fibers]) =>
965
- Effect.suspend(() => {
966
- const [winner] = fibers.splice(winningIndex, 1)
835
+ )), executionStrategy)
836
+ }
967
837
 
968
- return Effect.flatMap(Fiber.interruptAll(fibers), () => Fiber.join(winner))
969
- })
970
- )
971
- )
972
- )
838
+ export function flatMapConcurrently<R, E, A, R2, E2, B>(
839
+ fx: Fx<R, E, A>,
840
+ f: (a: A) => Fx<R2, E2, B>,
841
+ capacity: number,
842
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
843
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
844
+ return flatMapWithStrategy(fx, f, Bounded(capacity), executionStrategy)
973
845
  }
974
846
 
975
- export const empty: Fx<never, never, never> = new Empty()
847
+ export function concatMap<R, E, A, R2, E2, B>(
848
+ fx: Fx<R, E, A>,
849
+ f: (a: A) => Fx<R2, E2, B>,
850
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
851
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
852
+ return flatMapConcurrently(fx, f, 1, executionStrategy)
853
+ }
976
854
 
977
- export const never: Fx<never, never, never> = new Never()
855
+ export function flatMapConcurrentlyEffect<R, E, A, R2, E2, B>(
856
+ fx: Fx<R, E, A>,
857
+ f: (a: A) => Effect.Effect<R2, E2, B>,
858
+ capacity: number,
859
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
860
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
861
+ return flatMapConcurrently(fx, (a) => fromEffect(f(a)), capacity, executionStrategy)
862
+ }
978
863
 
979
- export const failCause = <E>(cause: Cause.Cause<E>): Fx<never, E, never> => new Fail(cause)
980
-
981
- export const fail = <E>(e: E): Fx<never, E, never> => failCause(Cause.fail(e))
982
-
983
- export const fromSink = <R, E, A>(
984
- f: (sink: Sink.Sink<E, A>) => Effect.Effect<R, E, unknown>
985
- ): Fx<R, E, A> => new FromSink((sink) => Effect.catchAllCause(f(sink), sink.onFailure))
986
-
987
- export const suspend = <R, E, A>(f: () => Fx<R, E, A>): Fx<R, E, A> => new Suspend(f)
988
-
989
- export const sync = <A>(f: () => A): Fx<never, never, A> => new Sync(f)
990
-
991
- export const slice: {
992
- (skip: number, take: number): <R, E, A>(fx: Fx<R, E, A>) => Fx<R, E, A>
993
- <R, E, A>(fx: Fx<R, E, A>, skip: number, take: number): Fx<R, E, A>
994
- } = dual(3, function slice<R, E, A>(fx: Fx<R, E, A>, skip: number, take: number): Fx<R, E, A> {
995
- return Slice.make(fx, boundsFrom(skip, take))
996
- })
997
-
998
- export const take: {
999
- (n: number): <R, E, A>(fx: Fx<R, E, A>) => Fx<R, E, A>
1000
- <R, E, A>(fx: Fx<R, E, A>, n: number): Fx<R, E, A>
1001
- } = dual(2, function take<R, E, A>(fx: Fx<R, E, A>, n: number): Fx<R, E, A> {
1002
- return slice(fx, 0, n)
1003
- })
1004
-
1005
- export const drop: {
1006
- (n: number): <R, E, A>(fx: Fx<R, E, A>) => Fx<R, E, A>
1007
- <R, E, A>(fx: Fx<R, E, A>, n: number): Fx<R, E, A>
1008
- } = dual(2, function drop<R, E, A>(fx: Fx<R, E, A>, n: number): Fx<R, E, A> {
1009
- return slice(fx, n, Infinity)
1010
- })
1011
-
1012
- export const takeWhile: {
1013
- <A, R2, E2>(predicate: (a: A) => Effect.Effect<R2, E2, boolean>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1014
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, predicate: (a: A) => Effect.Effect<R2, E2, boolean>): Fx<R | R2, E | E2, A>
1015
- } = dual(
1016
- 2,
1017
- function takeWhile<R, E, A, R2, E2>(
1018
- fx: Fx<R, E, A>,
1019
- predicate: (a: A) => Effect.Effect<R2, E2, boolean>
1020
- ): Fx<R | R2, E | E2, A> {
1021
- return withEarlyExit(({ sink }) =>
1022
- run(
1023
- fx,
1024
- Sink.WithContext(sink.onFailure, (a) =>
1025
- Effect.matchCauseEffect(predicate(a), {
1026
- onFailure: sink.onFailure,
1027
- onSuccess: (b) => b ? sink.onSuccess(a) : sink.earlyExit
1028
- }))
1029
- )
1030
- )
1031
- }
1032
- )
864
+ export function flatMap<R, E, A, R2, E2, B>(
865
+ fx: Fx<R, E, A>,
866
+ f: (a: A) => Fx<R2, E2, B>,
867
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
868
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
869
+ return flatMapWithStrategy(fx, f, Unbounded, executionStrategy)
870
+ }
1033
871
 
1034
- export const takeUntil: {
1035
- <A, R2, E2>(predicate: (a: A) => Effect.Effect<R2, E2, boolean>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1036
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, predicate: (a: A) => Effect.Effect<R2, E2, boolean>): Fx<R | R2, E | E2, A>
1037
- } = dual(
1038
- 2,
1039
- function takeUntil<R, E, A, R2, E2>(
1040
- fx: Fx<R, E, A>,
1041
- predicate: (a: A) => Effect.Effect<R2, E2, boolean>
1042
- ): Fx<R | R2, E | E2, A> {
1043
- return takeWhile(fx, (a) => Effect.map(predicate(a), (x) => !x))
872
+ export function flatMapEffect<R, E, A, R2, E2, B>(
873
+ fx: Fx<R, E, A>,
874
+ f: (a: A) => Effect.Effect<R2, E2, B>,
875
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
876
+ ): Fx<R | R2 | Scope.Scope, E | E2, B> {
877
+ return flatMap(fx, (a) => fromEffect(f(a)), executionStrategy)
878
+ }
879
+
880
+ class FlatMapWithStrategy<
881
+ R,
882
+ E,
883
+ A,
884
+ R2,
885
+ E2,
886
+ B
887
+ > extends FxBase<R | R2 | Scope.Scope, E | E2, B> {
888
+ private withFork: <R, E, A>(
889
+ f: (
890
+ fork: FxFork,
891
+ scope: Scope.Scope
892
+ ) => Effect.Effect<R, E, A>,
893
+ executionStrategy: ExecutionStrategy.ExecutionStrategy
894
+ ) => Effect.Effect<Scope.Scope | R, E, void>
895
+
896
+ constructor(
897
+ readonly i0: Fx<R, E, A>,
898
+ readonly i1: (a: A) => Fx<R2, E2, B>,
899
+ readonly i2: FlattenStrategy,
900
+ readonly i3: ExecutionStrategy.ExecutionStrategy
901
+ ) {
902
+ super()
903
+
904
+ this.withFork = withFlattenStrategy(i2)
1044
905
  }
1045
- )
1046
906
 
1047
- export const dropWhile: {
1048
- <A, R2, E2>(predicate: (a: A) => Effect.Effect<R2, E2, boolean>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1049
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, predicate: (a: A) => Effect.Effect<R2, E2, boolean>): Fx<R | R2, E | E2, A>
1050
- } = dual(
1051
- 2,
1052
- function dropWhile<R, E, A, R2, E2>(
1053
- fx: Fx<R, E, A>,
1054
- predicate: (a: A) => Effect.Effect<R2, E2, boolean>
1055
- ): Fx<R | R2, E | E2, A> {
1056
- return withEarlyExit(({ sink }) =>
1057
- Effect.suspend(() => {
1058
- let isDropping = true
1059
-
1060
- return run(
1061
- fx,
1062
- Sink.WithContext(sink.onFailure, (a) =>
1063
- isDropping ?
1064
- Effect.matchCauseEffect(predicate(a), {
1065
- onFailure: sink.onFailure,
1066
- onSuccess: (b) => {
1067
- if (b) {
1068
- return Effect.unit
1069
- } else {
1070
- isDropping = false
1071
- return sink.onSuccess(a)
1072
- }
1073
- }
1074
- }) :
1075
- sink.onSuccess(a))
1076
- )
1077
- })
907
+ run<R3>(sink: Sink.Sink<R3, E | E2, B>): Effect.Effect<R | R2 | R3 | Scope.Scope, never, unknown> {
908
+ return this.withFork(
909
+ (fork) =>
910
+ Sink.withEarlyExit(sink, (sink) =>
911
+ this.i0.run(
912
+ Sink.make(
913
+ (cause) => Cause.isInterruptedOnly(cause) ? sink.earlyExit : sink.onFailure(cause),
914
+ (a) => fork(this.i1(a).run(sink))
915
+ )
916
+ )),
917
+ this.i3
1078
918
  )
1079
919
  }
1080
- )
1081
920
 
1082
- export const dropUntil: {
1083
- <A, R2, E2>(predicate: (a: A) => Effect.Effect<R2, E2, boolean>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1084
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, predicate: (a: A) => Effect.Effect<R2, E2, boolean>): Fx<R | R2, E | E2, A>
1085
- } = dual(
1086
- 2,
1087
- function dropUntil<R, E, A, R2, E2>(
921
+ static make<R, E, A, R2, E2, B>(
1088
922
  fx: Fx<R, E, A>,
1089
- predicate: (a: A) => Effect.Effect<R2, E2, boolean>
1090
- ): Fx<R | R2, E | E2, A> {
1091
- return dropWhile(fx, (a) => Effect.map(predicate(a), (x) => !x))
1092
- }
1093
- )
923
+ f: (a: A) => Fx<R2, E2, B>,
924
+ strategy: FlattenStrategy,
925
+ executionStrategy: ExecutionStrategy.ExecutionStrategy
926
+ ) {
927
+ if (isEmpty(fx) || isNever(fx)) return fx
928
+ else if (isProducer(fx)) {
929
+ if (fx.i0._tag === "Success") return f(fx.i0.source)
930
+ if (fx.i0._tag === "FromSync") {
931
+ const producer = fx.i0
932
+ return suspend(() => f(producer.source()))
933
+ }
1094
934
 
1095
- export const dropAfter: {
1096
- <A, R2, E2>(predicate: (a: A) => Effect.Effect<R2, E2, boolean>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1097
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, predicate: (a: A) => Effect.Effect<R2, E2, boolean>): Fx<R | R2, E | E2, A>
1098
- } = dual(
1099
- 2,
1100
- function dropAfter<R, E, A, R2, E2>(
1101
- fx: Fx<R, E, A>,
1102
- predicate: (a: A) => Effect.Effect<R2, E2, boolean>
1103
- ): Fx<R | R2, E | E2, A> {
1104
- return fromSink((sink) =>
1105
- Effect.suspend(() => {
1106
- let isDropping = false
1107
-
1108
- return run(
1109
- fx,
1110
- Sink.WithContext(sink.onFailure, (a) =>
1111
- isDropping ?
1112
- Effect.unit :
1113
- Effect.matchCauseEffect(predicate(a), {
1114
- onFailure: sink.onFailure,
1115
- onSuccess: (b) => {
1116
- if (b) {
1117
- isDropping = true
1118
- return Effect.unit
1119
- } else {
1120
- return sink.onSuccess(a)
1121
- }
1122
- }
1123
- }))
1124
- )
1125
- })
1126
- )
935
+ const arr = Array.isArray(fx.i0.source) ? fx.i0.source : Array.from(fx.i0.source)
936
+ if (arr.length === 0) return empty
937
+ if (arr.length === 1) return f(arr[0])
938
+
939
+ switch (strategy._tag) {
940
+ case "Switch":
941
+ return f(arr[arr.length - 1])
942
+ case "Exhaust":
943
+ return f(arr[0])
944
+ case "ExhaustLatest":
945
+ return arr.length > 1 ? continueWith(f(arr[0]), () => f(arr[arr.length - 1])) : f(arr[0])
946
+ default:
947
+ return new FlatMapWithStrategy(fx, f, strategy, executionStrategy)
948
+ }
949
+ } else if (isProducerEffect(fx) && fx.i0._tag === "FromEffect") {
950
+ return fromFxEffect(Effect.map(fx.i0.source, f))
951
+ } else if (isTransformer(fx) && fx.i1._tag === "Map") {
952
+ const { f: op } = fx.i1
953
+ return new FlatMapWithStrategy(fx.i0, (a) => f(op(a)), strategy, executionStrategy)
954
+ } else {
955
+ return new FlatMapWithStrategy(fx, f, strategy, executionStrategy)
956
+ }
1127
957
  }
1128
- )
958
+ }
1129
959
 
1130
- export const continueWith: {
1131
- <R2, E2, B>(f: () => Fx<R2, E2, B>): <R, E, A>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A | B>
1132
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: () => Fx<R2, E2, B>): Fx<R | R2, E | E2, A | B>
1133
- } = dual(
1134
- 2,
1135
- function continueWith<R, E, R2, E2, A>(fx: Fx<R, E, A>, f: () => Fx<R2, E2, A>): Fx<R | R2, E | E2, A> {
1136
- return fromSink((sink) => Effect.flatMap(run(fx, sink), () => run(f(), sink)))
1137
- }
1138
- )
960
+ export function fromFxEffect<R, E, R2, E2, B>(
961
+ effect: Effect.Effect<R, E, Fx<R2, E2, B>>
962
+ ): Fx<R | R2, E | E2, B> {
963
+ return new FromFxEffect(effect)
964
+ }
1139
965
 
1140
- export const recoverWith: {
1141
- <E, R2, E2, B>(f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1142
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (cause: Cause.Cause<E>) => Fx<R2, E2, A>): Fx<R | R2, E2, A | B>
1143
- } = dual(
1144
- 2,
1145
- function recoverWith<R, E, A, R2, E2, B>(
1146
- fx: Fx<R, E, A>,
1147
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1148
- ): Fx<R | R2, E2, A | B> {
1149
- return fromSink((sink) => Effect.catchAllCause(observe(fx, sink.onSuccess), (cause) => run(from(f(cause)), sink)))
966
+ class FromFxEffect<
967
+ R,
968
+ E,
969
+ R2,
970
+ E2,
971
+ B
972
+ > extends FxBase<R | R2, E | E2, B> {
973
+ constructor(readonly i0: Effect.Effect<R, E, Fx<R2, E2, B>>) {
974
+ super()
1150
975
  }
1151
- )
1152
976
 
1153
- export const mapEffect: {
1154
- <A, R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
1155
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => Effect.Effect<R2, E2, B>): Fx<R | R2, E | E2, B>
1156
- } = dual(
1157
- 2,
1158
- function mapEffect<R, E, A, R2, E2, B>(
1159
- fx: Fx<R, E, A>,
1160
- f: (a: A) => Effect.Effect<R2, E2, B>
1161
- ): Fx<R | R2, E | E2, B> {
1162
- return TransformerEffect.make(fx, MapEffect(f))
977
+ run<R3>(sink: Sink.Sink<R3, E | E2, B>): Effect.Effect<R | R2 | R3, never, unknown> {
978
+ return Effect.matchCauseEffect(this.i0, {
979
+ onFailure: (cause) => sink.onFailure(cause),
980
+ onSuccess: (fx) => fx.run(sink)
981
+ })
1163
982
  }
1164
- )
983
+ }
1165
984
 
1166
- export const tap: {
1167
- <A, R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, B>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1168
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => Effect.Effect<R2, E2, B>): Fx<R | R2, E | E2, A>
1169
- } = dual(
1170
- 2,
1171
- function tap<R, E, A, R2, E2, B>(
1172
- fx: Fx<R, E, A>,
1173
- f: (a: A) => Effect.Effect<R2, E2, B>
1174
- ): Fx<R | R2, E | E2, A> {
1175
- return TransformerEffect.make(fx, TapEffect(f))
1176
- }
1177
- )
985
+ export function gen<Y extends Effect.EffectGen<any, any, any>, FX extends Fx<any, any, any>>(
986
+ f: (_: Effect.Adapter) => Generator<Y, FX, any>
987
+ ): Fx<
988
+ Effect.Effect.Context<Y["value"]> | Fx.Context<FX>,
989
+ Effect.Effect.Error<Y["value"]> | Fx.Error<FX>,
990
+ Fx.Success<FX>
991
+ > {
992
+ return fromFxEffect(Effect.gen(f))
993
+ }
1178
994
 
1179
- export const filterEffect: {
1180
- <A, R2, E2>(predicate: (a: A) => Effect.Effect<R2, E2, boolean>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1181
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, predicate: (a: A) => Effect.Effect<R2, E2, boolean>): Fx<R | R2, E | E2, A>
1182
- } = dual(2, function filterEffect<R, E, A, R2, E2>(
1183
- fx: Fx<R, E, A>,
1184
- predicate: (a: A) => Effect.Effect<R2, E2, boolean>
1185
- ): Fx<R | R2, E | E2, A> {
1186
- return TransformerEffect.make(fx, FilterEffect(predicate))
1187
- })
995
+ export function genScoped<Y extends Effect.EffectGen<any, any, any>, FX extends Fx<any, any, any>>(
996
+ f: (_: Effect.Adapter) => Generator<Y, FX, any>
997
+ ): Fx<
998
+ Exclude<Effect.Effect.Context<Y["value"]> | Fx.Context<FX>, Scope.Scope>,
999
+ Effect.Effect.Error<Y["value"]> | Fx.Error<FX>,
1000
+ Fx.Success<FX>
1001
+ > {
1002
+ return scoped(fromFxEffect(Effect.gen(f)))
1003
+ }
1188
1004
 
1189
- export const filterMapEffect: {
1190
- <A, R2, E2, B>(f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
1191
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>): Fx<R | R2, E | E2, B>
1192
- } = dual(2, function filterEffect<R, E, A, R2, E2, B>(
1005
+ export function continueWith<R, E, A, R2, E2, B>(
1193
1006
  fx: Fx<R, E, A>,
1194
- f: (a: A) => Effect.Effect<R2, E2, Option.Option<B>>
1195
- ): Fx<R | R2, E | E2, A> {
1196
- return TransformerEffect.make(fx, FilterMapEffect(f))
1197
- })
1198
-
1199
- export const middleware: {
1200
- <R, E, A, R2>(
1201
- f: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R2, never, unknown>,
1202
- g?: (sink: Sink.Sink<E, A>) => Sink.Sink<E, A>
1203
- ): (fx: Fx<R, E, A>) => Fx<R2, E, A>
1007
+ f: () => Fx<R2, E2, B>
1008
+ ): Fx<R | R2, E | E2, A | B> {
1009
+ return ContinueWith.make(fx, f)
1010
+ }
1204
1011
 
1205
- <R, E, A, R2>(
1206
- fx: Fx<R, E, A>,
1207
- f: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R2, never, unknown>,
1208
- g?: (sink: Sink.Sink<E, A>) => Sink.Sink<E, A>
1209
- ): Fx<R2, E, A>
1210
- } = dual((args) => args.length === 3 || typeof args[0] !== "function", function middleware<R, E, A, R2>(
1211
- fx: Fx<R, E, A>,
1212
- f: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R2, never, unknown>,
1213
- g?: (sink: Sink.Sink<E, A>) => Sink.Sink<E, A>
1214
- ): Fx<R2, E, A> {
1215
- return Middleware.make(fx, f, g ?? identity)
1216
- })
1217
-
1218
- export const loop: {
1219
- <A, B, C>(seed: B, f: (acc: B, a: A) => readonly [C, B]): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, C>
1220
- <R, E, A, B, C>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => readonly [C, B]): Fx<R, E, C>
1221
- } = dual(3, function loop<R, E, A, B, C>(
1222
- fx: Fx<R, E, A>,
1223
- seed: B,
1224
- f: (acc: B, a: A) => readonly [C, B]
1225
- ): Fx<R, E, C> {
1226
- return Loop.make(fx, seed, f)
1227
- })
1228
-
1229
- export const loopEffect: {
1230
- <B, A, R2, E2, C>(
1231
- seed: B,
1232
- f: (acc: B, a: A) => Effect.Effect<R2, E2, readonly [C, B]>
1233
- ): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, C>
1234
-
1235
- <R, E, A, B, R2, E2, C>(
1236
- fx: Fx<R, E, A>,
1237
- seed: B,
1238
- f: (acc: B, a: A) => Effect.Effect<R2, E2, readonly [C, B]>
1239
- ): Fx<R | R2, E | E2, C>
1240
- } = dual(3, function loopEffect<R, E, A, B, R2, E2, C>(
1241
- fx: Fx<R, E, A>,
1242
- seed: B,
1243
- f: (acc: B, a: A) => Effect.Effect<R2, E2, readonly [C, B]>
1244
- ): Fx<R | R2, E | E2, C> {
1245
- return LoopEffect.make(fx, f, seed)
1246
- })
1247
-
1248
- export const startWith: {
1249
- <B>(value: B): <R, E, A>(fx: Fx<R, E, A>) => Fx<R, E, A | B>
1250
- <R, E, A, B>(fx: Fx<R, E, A>, value: B): Fx<R, E, A | B>
1251
- } = dual(2, function startWith<R, E, A, B>(fx: Fx<R, E, A>, value: B): Fx<R, E, A | B> {
1252
- return fromSink((sink) => Effect.flatMap(sink.onSuccess(value), () => run(fx, sink)))
1253
- })
1254
-
1255
- export const endWith: {
1256
- <B>(value: B): <R, E, A>(fx: Fx<R, E, A>) => Fx<R, E, A | B>
1257
- <R, E, A, B>(fx: Fx<R, E, A>, value: B): Fx<R, E, A | B>
1258
- } = dual(2, function endWith<R, E, A, B>(fx: Fx<R, E, A>, value: B): Fx<R, E, A | B> {
1259
- return fromSink((sink) => Effect.flatMap(run(fx, sink), () => sink.onSuccess(value)))
1260
- })
1261
-
1262
- export const scan: {
1263
- <A, B>(seed: B, f: (acc: B, a: A) => B): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, B>
1264
- <R, E, A, B>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => B): Fx<R, E, B>
1265
- } = dual(3, function loop<R, E, A, B>(
1266
- fx: Fx<R, E, A>,
1267
- seed: B,
1268
- f: (acc: B, a: A) => B
1269
- ): Fx<R, E, B> {
1270
- return continueWith(
1271
- new Succeed(seed),
1272
- () =>
1273
- Loop.make(fx, seed, (b, a) => {
1274
- const b2 = f(b, a)
1012
+ class ContinueWith<
1013
+ R,
1014
+ E,
1015
+ A,
1016
+ R2,
1017
+ E2,
1018
+ B
1019
+ > extends FxBase<R | R2, E | E2, A | B> {
1020
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: () => Fx<R2, E2, B>) {
1021
+ super()
1022
+ }
1275
1023
 
1276
- return [b2, b2]
1277
- })
1278
- )
1279
- })
1024
+ run<R3>(sink: Sink.Sink<R3, E | E2, A | B>): Effect.Effect<R | R2 | R3, never, unknown> {
1025
+ return Effect.flatMap(this.i0.run(sink), () => this.i1().run(sink))
1026
+ }
1280
1027
 
1281
- export const scanEffect: {
1282
- <A, B, R2, E2>(
1283
- seed: B,
1284
- f: (acc: B, a: A) => Effect.Effect<R2, E2, B>
1285
- ): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, B>
1286
- <R, E, A, B, R2, E2>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => Effect.Effect<R2, E2, B>): Fx<R | R2, E | E2, B>
1287
- } = dual(3, function loopEffect<R, E, A, B, R2, E2>(
1288
- fx: Fx<R, E, A>,
1289
- seed: B,
1290
- f: (acc: B, a: A) => Effect.Effect<R2, E2, B>
1291
- ): Fx<R | R2, E | E2, B> {
1292
- return continueWith(
1293
- new Succeed(seed),
1294
- () => LoopEffect.make(fx, (b, a) => Effect.map(f(b, a), (b2) => [b2, b2]), seed)
1295
- )
1296
- })
1297
-
1298
- export const flatMapCauseWithStrategy: {
1299
- <E, R2, E2, B>(
1300
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>,
1301
- strategy: FlattenStrategy
1302
- ): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1303
- <R, E, A, R2, E2, B>(
1304
- fx: Fx<R, E, A>,
1305
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>,
1306
- strategy: FlattenStrategy
1307
- ): Fx<R | R2, E2, A | B>
1308
- } = dual(3, function flatMapCause<R, E, A, R2, E2, B>(
1309
- fx: Fx<R, E, A>,
1310
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>,
1311
- strategy: FlattenStrategy
1312
- ): Fx<R | R2, E2, A | B> {
1313
- return new WithFlattenStrategy(
1314
- ({ fork, sink }) => run(fx, Sink.WithContext((cause) => fork(run(from(f(cause)), sink)), sink.onSuccess)),
1315
- strategy
1316
- )
1317
- })
1318
-
1319
- export const flatMapErrorWithStrategy: {
1320
- <E, R2, E2, B>(
1321
- f: (error: E) => FxInput<R2, E2, B>,
1322
- strategy: FlattenStrategy
1323
- ): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1324
- <R, E, A, R2, E2, B>(
1028
+ static make<R, E, A, R2, E2, B>(
1325
1029
  fx: Fx<R, E, A>,
1326
- f: (error: E) => FxInput<R2, E2, B>,
1327
- strategy: FlattenStrategy
1328
- ): Fx<R | R2, E2, A | B>
1329
- } = dual(3, function flatMapCause<R, E, A, R2, E2, B>(
1330
- fx: Fx<R, E, A>,
1331
- f: (error: E) => FxInput<R2, E2, B>,
1332
- strategy: FlattenStrategy
1333
- ): Fx<R | R2, E2, A | B> {
1334
- return new WithFlattenStrategy(
1335
- ({ fork, sink }) =>
1336
- run(
1337
- fx,
1338
- Sink.WithContext((cause) =>
1339
- fork(run(
1340
- from(cause.pipe(
1341
- Cause.failureOrCause,
1342
- Either.match({
1343
- onLeft: f,
1344
- onRight: failCause
1345
- })
1346
- )),
1347
- sink
1348
- )), sink.onSuccess)
1349
- ),
1350
- strategy
1351
- )
1352
- })
1030
+ f: () => Fx<R2, E2, B>
1031
+ ): Fx<R | R2, E | E2, A | B> {
1032
+ if (isEmpty(fx)) return f()
1033
+ else if (isNever(fx)) return fx
1034
+ else if (isProducer(fx)) {
1035
+ return SyncProducer.matchSyncProducer(fx.i0, {
1036
+ Success: (source) => prependAll(f(), [source]),
1037
+ FromSync: (source) => suspend(() => prependAll(f(), [source()])),
1038
+ FromArray: (source) => prependAll(f(), source),
1039
+ FromIterable: (source) => prependAll(f(), source)
1040
+ })
1041
+ } else {
1042
+ return new ContinueWith(fx, f)
1043
+ }
1044
+ }
1045
+ }
1353
1046
 
1354
- export const flatMapCause: {
1355
- <E, R2, E2, B>(f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1356
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1357
- } = dual(2, function flatMapCause<R, E, A, R2, E2, B>(
1047
+ export function orElseCause<R, E, A, R2, E2, B>(
1358
1048
  fx: Fx<R, E, A>,
1359
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1049
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>
1360
1050
  ): Fx<R | R2, E2, A | B> {
1361
- return flatMapCauseWithStrategy(fx, f, strategies.Unbounded)
1362
- })
1051
+ return OrElseCause.make(fx, f)
1052
+ }
1363
1053
 
1364
- export const flatMapError: {
1365
- <E, R2, E2, B>(f: (error: E) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1366
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (error: E) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1367
- } = dual(2, function flatMapError<R, E, A, R2, E2, B>(
1368
- fx: Fx<R, E, A>,
1369
- f: (error: E) => FxInput<R2, E2, B>
1370
- ): Fx<R | R2, E2, A | B> {
1371
- return flatMapErrorWithStrategy(fx, f, strategies.Unbounded)
1372
- })
1373
-
1374
- export const flatMapCauseConcurrently: {
1375
- <E, R2, E2, B>(
1376
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>,
1377
- concurrency: number
1378
- ): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1379
- <R, E, A, R2, E2, B>(
1380
- fx: Fx<R, E, A>,
1381
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>,
1382
- concurrency: number
1383
- ): Fx<R | R2, E2, A | B>
1384
- } = dual(3, function flatMapCauseConcurrently<R, E, A, R2, E2, B>(
1385
- fx: Fx<R, E, A>,
1386
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>,
1387
- concurrency: number
1388
- ): Fx<R | R2, E2, A | B> {
1389
- return flatMapCauseWithStrategy(fx, f, strategies.Bounded(concurrency))
1390
- })
1391
-
1392
- export const flatMapErrorConcurrently: {
1393
- <E, R2, E2, B>(
1394
- f: (error: E) => FxInput<R2, E2, B>,
1395
- concurrency: number
1396
- ): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1397
- <R, E, A, R2, E2, B>(
1398
- fx: Fx<R, E, A>,
1399
- f: (error: E) => FxInput<R2, E2, B>,
1400
- concurrency: number
1401
- ): Fx<R | R2, E2, A | B>
1402
- } = dual(3, function flatMapCauseConcurrently<R, E, A, R2, E2, B>(
1403
- fx: Fx<R, E, A>,
1404
- f: (error: E) => FxInput<R2, E2, B>,
1405
- concurrency: number
1406
- ): Fx<R | R2, E2, A | B> {
1407
- return flatMapErrorWithStrategy(fx, f, strategies.Bounded(concurrency))
1408
- })
1054
+ class OrElseCause<
1055
+ R,
1056
+ E,
1057
+ A,
1058
+ R2,
1059
+ E2,
1060
+ B
1061
+ > extends FxBase<R | R2, E2, A | B> {
1062
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: (cause: Cause.Cause<E>) => Fx<R2, E2, B>) {
1063
+ super()
1064
+ }
1409
1065
 
1410
- export const switchMapCause: {
1411
- <E, R2, E2, B>(f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1412
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1413
- } = dual(2, function switchMapCause<R, E, A, R2, E2, B>(
1414
- fx: Fx<R, E, A>,
1415
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1416
- ): Fx<R | R2, E2, A | B> {
1417
- return flatMapCauseWithStrategy(fx, f, strategies.Switch)
1418
- })
1066
+ run<R3>(sink: Sink.Sink<R3, E | E2, A | B>): Effect.Effect<R | R2 | R3, never, unknown> {
1067
+ return Effect.catchAllCause(observe(this.i0, sink.onSuccess), (cause) => this.i1(cause).run(sink))
1068
+ }
1419
1069
 
1420
- export const switchMapError: {
1421
- <E, R2, E2, B>(f: (error: E) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1422
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (error: E) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1423
- } = dual(2, function switchMapError<R, E, A, R2, E2, B>(
1424
- fx: Fx<R, E, A>,
1425
- f: (error: E) => FxInput<R2, E2, B>
1426
- ): Fx<R | R2, E2, A | B> {
1427
- return flatMapErrorWithStrategy(fx, f, strategies.Switch)
1428
- })
1070
+ static make<R, E, A, R2, E2, B>(
1071
+ fx: Fx<R, E, A>,
1072
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>
1073
+ ): Fx<R | R2, E2, A | B> {
1074
+ if (isEmpty(fx)) return fx
1075
+ else if (isNever(fx)) return fx
1076
+ else {
1077
+ return new OrElseCause(fx, f)
1078
+ }
1079
+ }
1080
+ }
1429
1081
 
1430
- export const exhaustMapCause: {
1431
- <E, R2, E2, B>(f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1432
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1433
- } = dual(2, function exhaustMapCause<R, E, A, R2, E2, B>(
1082
+ export function orElse<R, E, A, R2, E2, B>(
1434
1083
  fx: Fx<R, E, A>,
1435
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1084
+ f: (error: E) => Fx<R2, E2, B>
1436
1085
  ): Fx<R | R2, E2, A | B> {
1437
- return flatMapCauseWithStrategy(fx, f, strategies.Exhaust)
1438
- })
1086
+ return OrElse.make(fx, f)
1087
+ }
1439
1088
 
1440
- export const exhaustMapError: {
1441
- <E, R2, E2, B>(f: (error: E) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1442
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (error: E) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1443
- } = dual(2, function switchMapError<R, E, A, R2, E2, B>(
1444
- fx: Fx<R, E, A>,
1445
- f: (error: E) => FxInput<R2, E2, B>
1446
- ): Fx<R | R2, E2, A | B> {
1447
- return flatMapErrorWithStrategy(fx, f, strategies.Exhaust)
1448
- })
1089
+ class OrElse<
1090
+ R,
1091
+ E,
1092
+ A,
1093
+ R2,
1094
+ E2,
1095
+ B
1096
+ > extends FxBase<R | R2, E2, A | B> {
1097
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: (error: E) => Fx<R2, E2, B>) {
1098
+ super()
1099
+ }
1449
1100
 
1450
- export const exhaustMapLatestCause: {
1451
- <E, R2, E2, B>(f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1452
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1453
- } = dual(2, function exhaustMapLatestCause<R, E, A, R2, E2, B>(
1454
- fx: Fx<R, E, A>,
1455
- f: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1456
- ): Fx<R | R2, E2, A | B> {
1457
- return flatMapCauseWithStrategy(fx, f, strategies.ExhaustLatest)
1458
- })
1101
+ run<R3>(sink: Sink.Sink<R3, E | E2, A | B>): Effect.Effect<R | R2 | R3, never, unknown> {
1102
+ return Effect.catchAll(
1103
+ Effect.asyncEffect<never, E, void, R | R2 | R3, never, unknown>((resume) =>
1104
+ Effect.zipRight(
1105
+ this.i0.run(
1106
+ Sink.make(
1107
+ (cause) =>
1108
+ Either.match(Cause.failureOrCause(cause), {
1109
+ onLeft: (e) => Effect.succeed(resume(Effect.fail(e))),
1110
+ onRight: (cause) => sink.onFailure(cause)
1111
+ }),
1112
+ sink.onSuccess
1113
+ )
1114
+ ),
1115
+ Effect.sync(() => resume(Effect.unit))
1116
+ )
1117
+ ),
1118
+ (error) => this.i1(error).run(sink)
1119
+ )
1120
+ }
1459
1121
 
1460
- export const exhaustMapLatestError: {
1461
- <E, R2, E2, B>(f: (error: E) => FxInput<R2, E2, B>): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1462
- <R, E, A, R2, E2, B>(fx: Fx<R, E, A>, f: (error: E) => FxInput<R2, E2, B>): Fx<R | R2, E2, A | B>
1463
- } = dual(2, function switchMapError<R, E, A, R2, E2, B>(
1464
- fx: Fx<R, E, A>,
1465
- f: (error: E) => FxInput<R2, E2, B>
1466
- ): Fx<R | R2, E2, A | B> {
1467
- return flatMapErrorWithStrategy(fx, f, strategies.ExhaustLatest)
1468
- })
1469
-
1470
- export const matchCauseWithStrategy: {
1471
- <E, R2, E2, B, A, R3, E3, C>(
1472
- options: {
1473
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1474
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1475
- readonly strategy: FlattenStrategy
1476
- }
1477
- ): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1478
- <R, E, A, R2, E2, B, R3, E3, C>(
1122
+ static make<R, E, A, R2, E2, B>(
1479
1123
  fx: Fx<R, E, A>,
1480
- options: {
1481
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1482
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1483
- readonly strategy: FlattenStrategy
1124
+ f: (error: E) => Fx<R2, E2, B>
1125
+ ): Fx<R | R2, E2, A | B> {
1126
+ if (isEmpty(fx)) return fx
1127
+ else if (isNever(fx)) return fx
1128
+ else {
1129
+ return new OrElse(fx, f)
1484
1130
  }
1485
- ): Fx<R | R2, E2 | E3, B | C>
1486
- } = dual(2, function flatMapCause<R, E, A, R2, E2, B, R3, E3, C>(
1131
+ }
1132
+ }
1133
+
1134
+ export function suspend<R, E, A>(f: () => Fx<R, E, A>): Fx<R, E, A> {
1135
+ return new Suspend(f)
1136
+ }
1137
+
1138
+ class Suspend<R, E, A> extends FxBase<R, E, A> {
1139
+ constructor(readonly i0: () => Fx<R, E, A>) {
1140
+ super()
1141
+ }
1142
+
1143
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
1144
+ return this.i0().run(sink)
1145
+ }
1146
+ }
1147
+
1148
+ function isSuspend<R, E, A>(fx: Fx<R, E, A>): fx is Suspend<R, E, A> {
1149
+ return fx.constructor === Suspend
1150
+ }
1151
+
1152
+ class SuspendedTransformer<R, E, A, R2, E2, B> extends FxBase<R | R2, E2, B> {
1153
+ constructor(readonly i0: () => Fx<R, E, A>, readonly i1: Op.Operator) {
1154
+ super()
1155
+ }
1156
+
1157
+ run<R3>(sink: Sink.Sink<R3, E2, B>): Effect.Effect<R | R2 | R3, never, unknown> {
1158
+ return this.i0().run(Op.compileOperatorSink(this.i1, sink))
1159
+ }
1160
+ }
1161
+
1162
+ function isSuspendedTransformer<R, E, A>(fx: Fx<R, E, A>): fx is SuspendedTransformer<R, E, A, any, any, any> {
1163
+ return fx.constructor === SuspendedTransformer
1164
+ }
1165
+
1166
+ export function mergeWithStrategy<const FX extends ReadonlyArray<Fx<any, any, any>>>(
1167
+ fx: FX,
1168
+ stategy: MergeStrategy
1169
+ ): Fx<
1170
+ Fx.Context<FX[number]>,
1171
+ Fx.Error<FX[number]>,
1172
+ Fx.Success<FX[number]>
1173
+ > {
1174
+ return MergeWithStrategy.make(fx, stategy)
1175
+ }
1176
+
1177
+ export function merge<R, E, A, R2, E2, B>(
1487
1178
  fx: Fx<R, E, A>,
1488
- options: {
1489
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1490
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1491
- readonly strategy: FlattenStrategy
1492
- }
1493
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1494
- return new WithFlattenStrategy(
1495
- ({ fork, sink }) =>
1496
- run(
1497
- fx,
1498
- Sink.WithContext((cause) => fork(run(from(options.onFailure(cause)), sink)), (a) =>
1499
- fork(run(from(options.onSuccess(a)), sink)))
1500
- ),
1501
- options.strategy
1179
+ other: Fx<R2, E2, B>
1180
+ ): Fx<R | R2, E | E2, A | B> {
1181
+ return mergeWithStrategy([fx, other], Unordered(2))
1182
+ }
1183
+
1184
+ export function mergeAll<FX extends ReadonlyArray<Fx<any, any, any>>>(
1185
+ fx: FX
1186
+ ): Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>> {
1187
+ return mergeWithStrategy(fx, Unordered(Infinity))
1188
+ }
1189
+
1190
+ export function mergeOrdered<FX extends ReadonlyArray<Fx<any, any, any>>>(
1191
+ fx: FX
1192
+ ): Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>> {
1193
+ return mergeOrderedConcurrently(fx, Infinity)
1194
+ }
1195
+
1196
+ export function mergeOrderedConcurrently<FX extends ReadonlyArray<Fx<any, any, any>>>(
1197
+ fx: FX,
1198
+ concurrency: number
1199
+ ): Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>> {
1200
+ return mergeWithStrategy(fx, Ordered(concurrency))
1201
+ }
1202
+
1203
+ export function mergeSwitch<FX extends ReadonlyArray<Fx<any, any, any>>>(
1204
+ fx: FX
1205
+ ): Fx<Fx.Context<FX[number]>, Fx.Error<FX[number]>, Fx.Success<FX[number]>> {
1206
+ return mergeWithStrategy(fx, Switch)
1207
+ }
1208
+
1209
+ class MergeWithStrategy<
1210
+ const FX extends ReadonlyArray<Fx<any, any, any>>
1211
+ > extends FxBase<
1212
+ Fx.Context<FX[number]>,
1213
+ Fx.Error<FX[number]>,
1214
+ Fx.Success<FX[number]>
1215
+ > {
1216
+ constructor(readonly i0: FX, readonly i1: MergeStrategy) {
1217
+ super()
1218
+ }
1219
+
1220
+ run<R2>(
1221
+ sink: Sink.Sink<R2, Fx.Error<FX[number]>, Fx.Success<FX[number]>>
1222
+ ): Effect.Effect<Fx.Context<FX[number]> | R2, never, unknown> {
1223
+ switch (this.i1._tag) {
1224
+ case "Unordered":
1225
+ return runUnordered(this.i0, sink, this.i1.concurrency === Infinity ? "unbounded" : this.i1.concurrency)
1226
+ case "Ordered":
1227
+ return runOrdered(this.i0, sink, this.i1.concurrency === Infinity ? "unbounded" : this.i1.concurrency)
1228
+ case "Switch":
1229
+ return runSwitch(this.i0, sink)
1230
+ }
1231
+ }
1232
+
1233
+ static make<const FX extends ReadonlyArray<Fx<any, any, any>>>(
1234
+ fx: FX,
1235
+ strategy: MergeStrategy
1236
+ ): Fx<
1237
+ Fx.Context<FX[number]>,
1238
+ Fx.Error<FX[number]>,
1239
+ Fx.Success<FX[number]>
1240
+ > {
1241
+ if (fx.length === 0) return empty
1242
+ else if (fx.length === 1) return fx[0]
1243
+ else return new MergeWithStrategy(fx.filter(Predicate.not(isEmpty)), strategy)
1244
+ }
1245
+ }
1246
+
1247
+ function runUnordered<
1248
+ const FX extends ReadonlyArray<Fx<any, any, any>>,
1249
+ R2
1250
+ >(
1251
+ fx: FX,
1252
+ sink: Sink.Sink<R2, any, any>,
1253
+ concurrency: number | "unbounded"
1254
+ ): Effect.Effect<R2 | Fx.Context<FX[number]>, never, unknown> {
1255
+ return Effect.forEach(fx, (fx) => fx.run(sink), { concurrency, discard: true })
1256
+ }
1257
+
1258
+ function runOrdered<
1259
+ const FX extends ReadonlyArray<Fx<any, any, any>>,
1260
+ R2
1261
+ >(
1262
+ fx: FX,
1263
+ sink: Sink.Sink<R2, any, any>,
1264
+ concurrency: number | "unbounded"
1265
+ ): Effect.Effect<R2 | Fx.Context<FX[number]>, never, unknown> {
1266
+ return Effect.suspend(
1267
+ () => {
1268
+ const buffers = withBuffers(fx.length, sink)
1269
+ return Effect.all(
1270
+ fx.map((fx, i) =>
1271
+ Effect.flatMap(
1272
+ fx.run(
1273
+ Sink.make(
1274
+ (cause) => Cause.isInterruptedOnly(cause) ? Effect.unit : sink.onFailure(cause),
1275
+ (a) => buffers.onSuccess(i, a)
1276
+ )
1277
+ ),
1278
+ () => buffers.onEnd(i)
1279
+ )
1280
+ ),
1281
+ {
1282
+ concurrency
1283
+ }
1284
+ )
1285
+ }
1502
1286
  )
1503
- })
1504
-
1505
- export const matchErrorWithStrategy: {
1506
- <E, R2, E2, B, A, R3, E3, C>(
1507
- options: {
1508
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1509
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1510
- readonly strategy: FlattenStrategy
1287
+ }
1288
+
1289
+ function runSwitch<
1290
+ const FX extends ReadonlyArray<Fx<any, any, any>>,
1291
+ R2
1292
+ >(
1293
+ fx: FX,
1294
+ sink: Sink.Sink<R2, any, any>
1295
+ ): Effect.Effect<R2 | Fx.Context<FX[number]>, never, unknown> {
1296
+ return Effect.forEach(fx, (fx) => fx.run(sink), { concurrency: 1, discard: true })
1297
+ }
1298
+
1299
+ export function takeWhile<R, E, A>(
1300
+ fx: Fx<R, E, A>,
1301
+ f: Predicate.Predicate<A>
1302
+ ): Fx<R, E, A> {
1303
+ return TakeWhile.make(fx, f)
1304
+ }
1305
+
1306
+ export function takeUntil<R, E, A>(
1307
+ fx: Fx<R, E, A>,
1308
+ f: Predicate.Predicate<A>
1309
+ ): Fx<R, E, A> {
1310
+ return TakeWhile.make(fx, Predicate.not(f))
1311
+ }
1312
+
1313
+ class TakeWhile<R, E, A> extends FxBase<R, E, A> {
1314
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Predicate.Predicate<A>) {
1315
+ super()
1316
+ }
1317
+
1318
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
1319
+ return Sink.takeWhile(sink, this.i1, (s) => this.i0.run(s))
1320
+ }
1321
+
1322
+ static make<R, E, A>(fx: Fx<R, E, A>, predicate: Predicate.Predicate<A>): Fx<R, E, A> {
1323
+ if (isEmpty(fx) || isNever(fx)) return fx
1324
+ else {
1325
+ return new TakeWhile(fx, predicate)
1326
+ }
1327
+ }
1328
+ }
1329
+
1330
+ export function dropWhile<R, E, A>(
1331
+ fx: Fx<R, E, A>,
1332
+ f: Predicate.Predicate<A>
1333
+ ): Fx<R, E, A> {
1334
+ return DropUntil.make(fx, f)
1335
+ }
1336
+
1337
+ export function dropUntil<R, E, A>(
1338
+ fx: Fx<R, E, A>,
1339
+ f: Predicate.Predicate<A>
1340
+ ): Fx<R, E, A> {
1341
+ return DropUntil.make(fx, Predicate.not(f))
1342
+ }
1343
+
1344
+ class DropUntil<R, E, A> extends FxBase<R, E, A> {
1345
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Predicate.Predicate<A>) {
1346
+ super()
1347
+ }
1348
+
1349
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
1350
+ return this.i0.run(Sink.dropWhile(sink, this.i1))
1351
+ }
1352
+
1353
+ static make<R, E, A>(fx: Fx<R, E, A>, predicate: Predicate.Predicate<A>): Fx<R, E, A> {
1354
+ if (isEmpty(fx) || isNever(fx)) return fx
1355
+ else {
1356
+ return new DropUntil(fx, predicate)
1357
+ }
1358
+ }
1359
+ }
1360
+
1361
+ export function dropAfter<R, E, A>(
1362
+ fx: Fx<R, E, A>,
1363
+ f: Predicate.Predicate<A>
1364
+ ): Fx<R, E, A> {
1365
+ return DropAfter.make(fx, f)
1366
+ }
1367
+
1368
+ class DropAfter<R, E, A> extends FxBase<R, E, A> {
1369
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Predicate.Predicate<A>) {
1370
+ super()
1371
+ }
1372
+
1373
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
1374
+ return this.i0.run(Sink.dropAfter(sink, this.i1))
1375
+ }
1376
+
1377
+ static make<R, E, A>(fx: Fx<R, E, A>, predicate: Predicate.Predicate<A>): Fx<R, E, A> {
1378
+ if (isEmpty(fx) || isNever(fx)) return fx
1379
+ else {
1380
+ return new DropAfter(fx, predicate)
1381
+ }
1382
+ }
1383
+ }
1384
+
1385
+ export function takeWhileEffect<R, E, A, R2, E2>(
1386
+ fx: Fx<R, E, A>,
1387
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
1388
+ ): Fx<R | R2, E | E2, A> {
1389
+ return TakeWhileEffect.make(fx, f)
1390
+ }
1391
+
1392
+ export function takeUntilEffect<R, E, A, R2, E2>(
1393
+ fx: Fx<R, E, A>,
1394
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
1395
+ ): Fx<R | R2, E | E2, A> {
1396
+ return TakeWhileEffect.make(fx, (a) => Effect.map(f(a), Boolean.not))
1397
+ }
1398
+
1399
+ class TakeWhileEffect<R, E, A, R2, E2> extends FxBase<R | R2, E | E2, A> {
1400
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: (a: A) => Effect.Effect<R2, E2, boolean>) {
1401
+ super()
1402
+ }
1403
+
1404
+ run<R3>(sink: Sink.Sink<R3, E | E2, A>): Effect.Effect<R | R2 | R3, never, unknown> {
1405
+ return Sink.takeWhileEffect(sink, this.i1, (s) => this.i0.run(s))
1406
+ }
1407
+
1408
+ static make<R, E, A, R2, E2>(
1409
+ fx: Fx<R, E, A>,
1410
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
1411
+ ): Fx<R | R2, E | E2, A> {
1412
+ if (isEmpty(fx) || isNever(fx)) return fx
1413
+ else {
1414
+ return new TakeWhileEffect(fx, f)
1511
1415
  }
1512
- ): <R, A>(fx: Fx<R, E, A>) => Fx<R | R2, E2, A | B>
1513
- <R, E, A, R2, E2, B, R3, E3, C>(
1416
+ }
1417
+ }
1418
+
1419
+ export function dropWhileEffect<R, E, A>(
1420
+ fx: Fx<R, E, A>,
1421
+ f: (a: A) => Effect.Effect<R, E, boolean>
1422
+ ): Fx<R, E, A> {
1423
+ return DropWhileEffect.make(fx, f)
1424
+ }
1425
+
1426
+ export function dropUntilEffect<R, E, A>(
1427
+ fx: Fx<R, E, A>,
1428
+ f: (a: A) => Effect.Effect<R, E, boolean>
1429
+ ): Fx<R, E, A> {
1430
+ return DropWhileEffect.make(fx, (a) => Effect.map(f(a), Boolean.not))
1431
+ }
1432
+
1433
+ class DropWhileEffect<R, E, A> extends FxBase<R, E, A> {
1434
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: (a: A) => Effect.Effect<R, E, boolean>) {
1435
+ super()
1436
+ }
1437
+
1438
+ run<R2>(sink: Sink.Sink<R2, E, A>): Effect.Effect<R | R2, never, unknown> {
1439
+ return this.i0.run(Sink.dropWhileEffect(sink, this.i1))
1440
+ }
1441
+
1442
+ static make<R, E, A>(
1514
1443
  fx: Fx<R, E, A>,
1515
- options: {
1516
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1517
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1518
- readonly strategy: FlattenStrategy
1444
+ f: (a: A) => Effect.Effect<R, E, boolean>
1445
+ ): Fx<R, E, A> {
1446
+ if (isEmpty(fx) || isNever(fx)) return fx
1447
+ else {
1448
+ return new DropWhileEffect(fx, f)
1519
1449
  }
1520
- ): Fx<R | R2, E2 | E3, B | C>
1521
- } = dual(2, function flatMapCause<R, E, A, R2, E2, B, R3, E3, C>(
1450
+ }
1451
+ }
1452
+
1453
+ export function dropAfterEffect<R, E, A, R2, E2>(
1522
1454
  fx: Fx<R, E, A>,
1523
- options: {
1524
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1525
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1526
- readonly strategy: FlattenStrategy
1527
- }
1528
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1529
- return new WithFlattenStrategy(
1530
- ({ fork, sink }) =>
1531
- run(
1532
- fx,
1533
- Sink.WithContext((cause) =>
1534
- fork(run(
1535
- from(cause.pipe(
1536
- Cause.failureOrCause,
1537
- Either.match({
1538
- onLeft: options.onFailure,
1539
- onRight: failCause
1540
- })
1541
- )),
1542
- sink
1543
- )), (a) => fork(run(from(options.onSuccess(a)), sink)))
1544
- ),
1545
- options.strategy
1546
- )
1547
- })
1455
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
1456
+ ): Fx<R | R2, E | E2, A> {
1457
+ return DropAfterEffect.make(fx, f)
1458
+ }
1459
+
1460
+ class DropAfterEffect<R, E, A, R2, E2> extends FxBase<R | R2, E | E2, A> {
1461
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: (a: A) => Effect.Effect<R2, E2, boolean>) {
1462
+ super()
1463
+ }
1464
+
1465
+ run<R3>(sink: Sink.Sink<R3, E | E2, A>): Effect.Effect<R | R2 | R3, never, unknown> {
1466
+ return this.i0.run(Sink.dropAfterEffect(sink, this.i1))
1467
+ }
1468
+
1469
+ static make<R, E, A, R2, E2>(
1470
+ fx: Fx<R, E, A>,
1471
+ f: (a: A) => Effect.Effect<R2, E2, boolean>
1472
+ ): Fx<R | R2, E | E2, A> {
1473
+ if (isEmpty(fx) || isNever(fx)) return fx
1474
+ else {
1475
+ return new DropAfterEffect(fx, f)
1476
+ }
1477
+ }
1478
+ }
1479
+
1480
+ export function during<R, E, A, R2, E2, R3, E3, B>(
1481
+ fx: Fx<R, E, A>,
1482
+ window: Fx<R2, E2, Fx<R3, E3, B>>
1483
+ ): Fx<R | R2 | R3 | Scope.Scope, E | E2 | E3, A> {
1484
+ return During.make(fx, window)
1485
+ }
1486
+
1487
+ export function since<R, E, A, R2, E2, B>(
1488
+ fx: Fx<R, E, A>,
1489
+ window: Fx<R2, E2, B>
1490
+ ): Fx<R | R2 | Scope.Scope, E | E2, A> {
1491
+ return During.make(fx, map(window, () => never))
1492
+ }
1493
+
1494
+ export function until<R, E, A, R2, E2, B>(
1495
+ fx: Fx<R, E, A>,
1496
+ window: Fx<R2, E2, B>
1497
+ ): Fx<R | R2 | Scope.Scope, E | E2, A> {
1498
+ return During.make(fx, succeed(window))
1499
+ }
1500
+
1501
+ class During<R, E, A, R2, E2, R3, E3, B> extends FxBase<R | R2 | R3 | Scope.Scope, E | E2 | E3, A> {
1502
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Fx<R2, E2, Fx<R3, E3, B>>) {
1503
+ super()
1504
+ }
1505
+
1506
+ run<R4>(sink: Sink.Sink<R4, E | E2 | E3, A>): Effect.Effect<R | R2 | R3 | R4 | Scope.Scope, never, unknown> {
1507
+ return withScopedFork(
1508
+ (fork) =>
1509
+ Sink.withEarlyExit(sink, (s) => {
1510
+ let taking = false
1511
+
1512
+ const onFailure = (cause: Cause.Cause<E | E2 | E3>) => s.onFailure(cause)
1513
+
1514
+ return Effect.flatMap(
1515
+ fork(
1516
+ take(this.i1, 1).run(
1517
+ Sink.make(onFailure, (nested) => {
1518
+ taking = true
1519
+ return take(nested, 1).run(Sink.make(onFailure, () => s.earlyExit))
1520
+ })
1521
+ )
1522
+ ),
1523
+ () =>
1524
+ Effect.zipRight(
1525
+ // Allow fibers to start
1526
+ adjustTime(1),
1527
+ this.i0.run(
1528
+ Sink.make(
1529
+ onFailure,
1530
+ (a) => taking ? s.onSuccess(a) : Effect.unit
1531
+ )
1532
+ )
1533
+ )
1534
+ )
1535
+ }),
1536
+ ExecutionStrategy.sequential
1537
+ )
1538
+ }
1548
1539
 
1549
- export const matchCause: {
1550
- <E, R2, E2, B, A, R3, E3, C>(
1551
- options: {
1552
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1553
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1540
+ static make<R, E, A, R2, E2, R3, E3, B>(
1541
+ fx: Fx<R, E, A>,
1542
+ window: Fx<R2, E2, Fx<R3, E3, B>>
1543
+ ): Fx<R | R2 | R3 | Scope.Scope, E | E2 | E3, A> {
1544
+ if (isEmpty(fx) || isNever(fx)) return fx
1545
+ else {
1546
+ return new During(fx, window)
1554
1547
  }
1555
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
1548
+ }
1549
+ }
1550
+
1551
+ export function middleware<R, E, A, R3>(
1552
+ fx: Fx<R, E, A>,
1553
+ effect: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R3, never, unknown>,
1554
+ sink?: (sink: Sink.Sink<never, E, A>) => Sink.Sink<R, E, A>
1555
+ ): Fx<R3, E, A> {
1556
+ return new Middleware(fx, effect, sink)
1557
+ }
1558
+
1559
+ export function onExit<R, E, A, R2>(
1560
+ fx: Fx<R, E, A>,
1561
+ f: (exit: Exit.Exit<never, unknown>) => Effect.Effect<R2, never, unknown>
1562
+ ): Fx<R | R2, E, A> {
1563
+ return middleware(fx, Effect.onExit(f))
1564
+ }
1565
+
1566
+ export function onInterrupt<R, E, A, R2>(
1567
+ fx: Fx<R, E, A>,
1568
+ f: (interruptors: HashSet.HashSet<FiberId.FiberId>) => Effect.Effect<R2, never, unknown>
1569
+ ): Fx<R | R2, E, A> {
1570
+ return middleware(fx, Effect.onInterrupt(f))
1571
+ }
1572
+
1573
+ export function onError<R, E, A, R2>(
1574
+ fx: Fx<R, E, A>,
1575
+ f: (cause: Cause.Cause<never>) => Effect.Effect<R2, never, unknown>
1576
+ ): Fx<R | R2, E, A> {
1577
+ return middleware(fx, Effect.onError(f))
1578
+ }
1579
+
1580
+ export const scoped = <R, E, A>(fx: Fx<R, E, A>): Fx<Exclude<R, Scope.Scope>, E, A> => middleware(fx, Effect.scoped)
1581
+
1582
+ export function annotateLogs<R, E, A>(
1583
+ fx: Fx<R, E, A>,
1584
+ key: string | Record<string, unknown>,
1585
+ value?: unknown
1586
+ ): Fx<R, E, A> {
1587
+ return middleware(fx, (effect) => Effect.annotateLogs(effect, key as string, value as unknown))
1588
+ }
1589
+
1590
+ export function annotateSpans<R, E, A>(
1591
+ fx: Fx<R, E, A>,
1592
+ key: string | Record<string, unknown>,
1593
+ value?: unknown
1594
+ ): Fx<R, E, A> {
1595
+ return middleware(fx, (effect) => Effect.annotateSpans(effect, key as string, value as unknown))
1596
+ }
1597
+
1598
+ export const interruptible = <R, E, A>(fx: Fx<R, E, A>): Fx<R, E, A> => middleware(fx, Effect.interruptible)
1599
+
1600
+ export const uninterruptible = <R, E, A>(fx: Fx<R, E, A>): Fx<R, E, A> => middleware(fx, Effect.uninterruptible)
1601
+
1602
+ export function locally<R, E, B, A>(
1603
+ use: Fx<R, E, B>,
1604
+ self: FiberRef.FiberRef<A>,
1605
+ value: A
1606
+ ): Fx<R, E, B> {
1607
+ return middleware(use, (effect) => Effect.locally(effect, self, value))
1608
+ }
1609
+
1610
+ export function locallyWith<R, E, B, A>(
1611
+ use: Fx<R, E, B>,
1612
+ self: FiberRef.FiberRef<A>,
1613
+ f: (a: A) => A
1614
+ ): Fx<R, E, B> {
1615
+ return middleware(use, (effect) => Effect.locallyWith(effect, self, f))
1616
+ }
1617
+
1618
+ export function withTracerTiming<R, E, A>(
1619
+ fx: Fx<R, E, A>,
1620
+ enabled: boolean
1621
+ ): Fx<R, E, A> {
1622
+ return middleware(fx, (effect) => Effect.withTracerTiming(effect, enabled))
1623
+ }
1624
+
1625
+ export function withConcurrency<R, E, A>(
1626
+ fx: Fx<R, E, A>,
1627
+ concurrency: number | "unbounded"
1628
+ ): Fx<R, E, A> {
1629
+ return middleware(fx, (effect) => Effect.withConcurrency(effect, concurrency))
1630
+ }
1631
+
1632
+ export function withConfigProvider<R, E, A>(
1633
+ fx: Fx<R, E, A>,
1634
+ configProvider: ConfigProvider.ConfigProvider
1635
+ ): Fx<R, E, A> {
1636
+ return middleware(fx, (effect) => Effect.withConfigProvider(effect, configProvider))
1637
+ }
1638
+
1639
+ export function withLogSpan<R, E, A>(
1640
+ fx: Fx<R, E, A>,
1641
+ span: string
1642
+ ): Fx<R, E, A> {
1643
+ return middleware(fx, (effect) => Effect.withLogSpan(effect, span))
1644
+ }
1645
+
1646
+ export function withMaxOpsBeforeYield<R, E, A>(
1647
+ fx: Fx<R, E, A>,
1648
+ maxOps: number
1649
+ ): Fx<R, E, A> {
1650
+ return middleware(fx, (effect) => Effect.withMaxOpsBeforeYield(effect, maxOps))
1651
+ }
1652
+
1653
+ export function withParentSpan<R, E, A>(
1654
+ fx: Fx<R, E, A>,
1655
+ parentSpan: Tracer.ParentSpan
1656
+ ): Fx<R, E, A> {
1657
+ return middleware(fx, (effect) => Effect.withParentSpan(effect, parentSpan))
1658
+ }
1659
+
1660
+ export function withRequestBatching<R, E, A>(
1661
+ fx: Fx<R, E, A>,
1662
+ requestBatching: boolean
1663
+ ): Fx<R, E, A> {
1664
+ return middleware(fx, (effect) => Effect.withRequestBatching(effect, requestBatching))
1665
+ }
1666
+
1667
+ export function withRequestCache<R, E, A>(
1668
+ fx: Fx<R, E, A>,
1669
+ cache: Request.Cache
1670
+ ): Fx<R, E, A> {
1671
+ return middleware(fx, (effect) => Effect.withRequestCache(effect, cache))
1672
+ }
1673
+
1674
+ export function withRequestCaching<R, E, A>(
1675
+ fx: Fx<R, E, A>,
1676
+ requestCaching: boolean
1677
+ ): Fx<R, E, A> {
1678
+ return middleware(fx, (effect) => Effect.withRequestCaching(effect, requestCaching))
1679
+ }
1680
+
1681
+ export function withScheduler<R, E, A>(
1682
+ fx: Fx<R, E, A>,
1683
+ scheduler: Scheduler.Scheduler
1684
+ ): Fx<R, E, A> {
1685
+ return middleware(fx, (effect) => Effect.withScheduler(effect, scheduler))
1686
+ }
1687
+
1688
+ export function withTracer<R, E, A>(
1689
+ fx: Fx<R, E, A>,
1690
+ tracer: Tracer.Tracer
1691
+ ): Fx<R, E, A> {
1692
+ return middleware(fx, (effect) => Effect.withTracer(effect, tracer))
1693
+ }
1694
+
1695
+ class Middleware<R, E, A, R2> extends FxBase<R2, E, A> {
1696
+ constructor(
1697
+ readonly i0: Fx<R, E, A>,
1698
+ readonly i1: (effect: Effect.Effect<R, never, unknown>) => Effect.Effect<R2, never, unknown>,
1699
+ readonly i2?: (sink: Sink.Sink<never, E, A>) => Sink.Sink<R, E, A>
1700
+ ) {
1701
+ super()
1702
+ }
1703
+
1704
+ run<R3>(sink: Sink.Sink<R3, E, A>): Effect.Effect<R2 | R3, never, unknown> {
1705
+ return Effect.contextWithEffect((ctx) => {
1706
+ const s = Sink.provide(sink, ctx)
1707
+
1708
+ return this.i1(this.i0.run(this.i2 ? this.i2(s) : s))
1709
+ })
1710
+ }
1711
+ }
1712
+
1713
+ export function acquireUseRelease<R, E, A, R2, E2, B, R3, E3, C>(
1714
+ acquire: Effect.Effect<R, E, A>,
1715
+ use: (a: A) => Fx<R2, E2, B>,
1716
+ release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<R3, E3, C>
1717
+ ): Fx<R | R2 | R3, E | E2 | E3, B> {
1718
+ return new AcquireUseRelease(acquire, use, release)
1719
+ }
1720
+
1721
+ class AcquireUseRelease<R, E, A, R2, E2, B, R3, E3, C> extends FxBase<R | R2 | R3, E | E2 | E3, B> {
1722
+ constructor(
1723
+ readonly acquire: Effect.Effect<R, E, A>,
1724
+ readonly use: (a: A) => Fx<R2, E2, B>,
1725
+ readonly release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<R3, E3, C>
1726
+ ) {
1727
+ super()
1728
+ }
1729
+
1730
+ run<R4>(sink: Sink.Sink<R4, E | E2 | E3, B>): Effect.Effect<R | R2 | R3 | R4, never, unknown> {
1731
+ return Effect.catchAllCause(
1732
+ Effect.acquireUseRelease(
1733
+ this.acquire,
1734
+ (a) => this.use(a).run(sink),
1735
+ (a, exit) => Effect.catchAllCause(this.release(a, exit), (cause) => sink.onFailure(cause))
1736
+ ),
1737
+ (cause) => sink.onFailure(cause)
1738
+ )
1739
+ }
1740
+ }
1741
+
1742
+ export function withSpan<R, E, A>(
1743
+ self: Fx<R, E, A>,
1744
+ name: string,
1745
+ options: {
1746
+ readonly attributes?: Record<string, unknown>
1747
+ readonly links?: ReadonlyArray<Tracer.SpanLink>
1748
+ readonly parent?: Tracer.ParentSpan
1749
+ readonly root?: boolean
1750
+ readonly context?: Context.Context<never>
1751
+ } = {}
1752
+ ): Fx<R, E, A> {
1753
+ return acquireUseRelease(
1754
+ Effect.flatMap(
1755
+ Effect.optionFromOptional(Effect.currentSpan),
1756
+ (parent) => Effect.makeSpan(name, { ...options, parent: options?.parent || Option.getOrUndefined(parent) } as any)
1757
+ ),
1758
+ (span) =>
1759
+ middleware(
1760
+ self,
1761
+ (effect) => Effect.provideService(effect, Tracer.ParentSpan, span),
1762
+ (s) => Sink.setSpan(s, span)
1763
+ ),
1764
+ (span, exit) => Effect.flatMap(Clock.currentTimeNanos, (time) => Effect.sync(() => span.end(time, exit)))
1765
+ )
1766
+ }
1767
+
1768
+ export function provideContext<R, E, A, R2>(
1769
+ fx: Fx<R, E, A>,
1770
+ context: Context.Context<R2>
1771
+ ): Fx<Exclude<R, R2>, E, A> {
1772
+ return ProvideFx.make(fx, Provide.ProvideContext(context))
1773
+ }
1774
+
1775
+ export function provideLayer<R, E, A, R2, E2, S>(
1776
+ fx: Fx<R, E, A>,
1777
+ layer: Layer.Layer<R2, E2, S>
1778
+ ): Fx<R2 | Exclude<R, S>, E | E2, A> {
1779
+ return ProvideFx.make(fx, Provide.ProvideLayer(layer))
1780
+ }
1781
+
1782
+ export function provideRuntime<R, E, A, R2>(
1783
+ fx: Fx<R, E, A>,
1784
+ runtime: Runtime.Runtime<R2>
1785
+ ): Fx<Exclude<R, R2>, E, A> {
1786
+ return ProvideFx.make(fx, Provide.ProvideRuntime(runtime))
1787
+ }
1788
+
1789
+ export function provideService<R, E, A, I, S>(
1790
+ fx: Fx<R, E, A>,
1791
+ service: Context.Tag<I, S>,
1792
+ instance: S
1793
+ ): Fx<Exclude<R, I>, E, A> {
1794
+ return ProvideFx.make(fx, Provide.ProvideService(service, instance))
1795
+ }
1796
+
1797
+ export function provideServiceEffect<R, E, A, I, S, R2, E2>(
1798
+ fx: Fx<R, E, A>,
1799
+ service: Context.Tag<I, S>,
1800
+ instance: Effect.Effect<R2, E2, S>
1801
+ ): Fx<Exclude<R, I> | R2, E | E2, A> {
1802
+ return ProvideFx.make(fx, Provide.ProvideServiceEffect(service, instance))
1803
+ }
1804
+
1805
+ export function provide<R, E, A, R2 = never, E2 = never, S = never>(
1806
+ fx: Fx<R, E, A>,
1807
+ provide: Layer.Layer<R2, E2, S> | Context.Context<S> | Runtime.Runtime<S>
1808
+ ): Fx<Exclude<R, S> | R2, E | E2, A> {
1809
+ if (Layer.isLayer(provide)) return provideLayer(fx, provide as Layer.Layer<R2, E2, S>)
1810
+ else if (Context.isContext(provide)) return provideContext(fx, provide as Context.Context<S>)
1811
+ else return provideRuntime(fx, provide as Runtime.Runtime<S>)
1812
+ }
1813
+
1814
+ class ProvideFx<R, E, A, R2, E2, S> extends FxBase<R2 | Exclude<R, S>, E | E2, A> {
1815
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Provide.Provide<R2, E2, S>) {
1816
+ super()
1817
+ }
1818
+
1819
+ run<R3>(sink: Sink.Sink<R3, E | E2, A>): Effect.Effect<R2 | R3 | Exclude<R, S>, never, unknown> {
1820
+ return Effect.acquireUseRelease(
1821
+ Scope.make(),
1822
+ (scope) =>
1823
+ Effect.matchEffect(Provide.buildWithScope(this.i1, scope), {
1824
+ onFailure: (error) => sink.onFailure(Cause.fail(error)),
1825
+ onSuccess: (ctx) => Effect.provide(this.i0.run(sink), ctx)
1826
+ }),
1827
+ (scope, exit) => Scope.close(scope, exit)
1828
+ )
1829
+ }
1830
+
1831
+ static make<R, E, A, R2, E2, S>(
1832
+ fx: Fx<R, E, A>,
1833
+ provide: Provide.Provide<R2, E2, S>
1834
+ ): Fx<Exclude<R, S> | R2, E | E2, A> {
1835
+ if (isEmpty(fx) || isNever(fx)) return fx
1836
+ else if (isProvideFx(fx)) {
1837
+ return new ProvideFx(fx.i0, Provide.merge(fx.i1, provide))
1838
+ } else {
1839
+ return new ProvideFx(fx, provide)
1840
+ }
1841
+ }
1842
+ }
1843
+
1844
+ function isProvideFx<R, E, A>(u: Fx<R, E, A>): u is ProvideFx<R, E, A, R, E, never> {
1845
+ return u.constructor === ProvideFx
1846
+ }
1847
+
1848
+ export function mapCause<R, E, A, E2>(
1849
+ fx: Fx<R, E, A>,
1850
+ f: (cause: Cause.Cause<E>) => Cause.Cause<E2>
1851
+ ): Fx<R, E2, A> {
1852
+ return new TransformerCause(fx, SyncOp.Map(f))
1853
+ }
1854
+
1855
+ export function mapError<R, E, A, E2>(
1856
+ fx: Fx<R, E, A>,
1857
+ f: (e: E) => E2
1858
+ ): Fx<R, E2, A> {
1859
+ return mapCause(fx, Cause.map(f))
1860
+ }
1861
+
1862
+ export function filterCause<R, E, A>(
1863
+ fx: Fx<R, E, A>,
1864
+ f: (cause: Cause.Cause<E>) => boolean
1865
+ ): Fx<R, E, A> {
1866
+ return new TransformerCause(fx, SyncOp.Filter(f))
1867
+ }
1868
+
1869
+ export function filterError<R, E, A>(
1870
+ fx: Fx<R, E, A>,
1871
+ f: (e: E) => boolean
1872
+ ): Fx<R, E, A> {
1873
+ return filterCause(fx, (cause) =>
1874
+ Option.match(Cause.failureOption(cause), {
1875
+ onNone: constTrue,
1876
+ onSome: f
1877
+ }))
1878
+ }
1879
+
1880
+ export function filterMapCause<R, E, A, E2>(
1881
+ fx: Fx<R, E, A>,
1882
+ f: (cause: Cause.Cause<E>) => Option.Option<Cause.Cause<E2>>
1883
+ ): Fx<R, E2, A> {
1884
+ return new TransformerCause(fx, SyncOp.FilterMap(f))
1885
+ }
1886
+
1887
+ export function filterMapError<R, E, A, E2>(
1888
+ fx: Fx<R, E, A>,
1889
+ f: (e: E) => Option.Option<E2>
1890
+ ): Fx<R, E2, A> {
1891
+ return filterMapCause(fx, (cause) =>
1892
+ Either.match(Cause.failureOrCause(cause), {
1893
+ onLeft: (e) => Option.map(f(e), Cause.fail),
1894
+ onRight: Option.some
1895
+ }))
1896
+ }
1897
+
1898
+ export function mapCauseEffect<R, E, A, R2, E2, E3>(
1899
+ fx: Fx<R, E, A>,
1900
+ f: (cause: Cause.Cause<E>) => Effect.Effect<R2, E2, Cause.Cause<E3>>
1901
+ ): Fx<R | R2, E2 | E3, A> {
1902
+ return new TransformerCause(fx, EffectOp.MapEffect(f))
1903
+ }
1904
+
1905
+ export function mapErrorEffect<R, E, A, R2, E2, E3>(
1906
+ fx: Fx<R, E, A>,
1907
+ f: (e: E) => Effect.Effect<R2, E2, E3>
1908
+ ): Fx<R | R2, E2 | E3, A> {
1909
+ return mapCauseEffect(fx, (cause) =>
1910
+ Either.match(Cause.failureOrCause(cause), {
1911
+ onLeft: (e) => Effect.map(f(e), Cause.fail),
1912
+ onRight: (cause) => Effect.succeed(cause)
1913
+ }))
1914
+ }
1915
+
1916
+ export function filterCauseEffect<R, E, A, R2, E2>(
1917
+ fx: Fx<R, E, A>,
1918
+ f: (cause: Cause.Cause<E>) => Effect.Effect<R2, E2, boolean>
1919
+ ): Fx<R | R2, E2, A> {
1920
+ return new TransformerCause(fx, EffectOp.FilterEffect(f))
1921
+ }
1922
+
1923
+ export function filterErrorEffect<R, E, A, R2, E2>(
1924
+ fx: Fx<R, E, A>,
1925
+ f: (e: E) => Effect.Effect<R2, E2, boolean>
1926
+ ): Fx<R | R2, E2, A> {
1927
+ return filterCauseEffect(fx, (cause) =>
1928
+ Either.match(Cause.failureOrCause(cause), {
1929
+ onLeft: f,
1930
+ onRight: () => Effect.succeed(true)
1931
+ }))
1932
+ }
1933
+
1934
+ export function filterMapCauseEffect<R, E, A, R2, E2, E3>(
1935
+ fx: Fx<R, E, A>,
1936
+ f: (cause: Cause.Cause<E>) => Effect.Effect<R2, E2, Option.Option<Cause.Cause<E3>>>
1937
+ ): Fx<R | R2, E2 | E3, A> {
1938
+ return new TransformerCause(fx, EffectOp.FilterMapEffect(f))
1939
+ }
1940
+
1941
+ export function filterMapErrorEffect<R, E, A, R2, E2, E3>(
1942
+ fx: Fx<R, E, A>,
1943
+ f: (e: E) => Effect.Effect<R2, E2, Option.Option<E3>>
1944
+ ): Fx<R | R2, E2 | E3, A> {
1945
+ return filterMapCauseEffect(fx, (cause) =>
1946
+ Either.match(Cause.failureOrCause(cause), {
1947
+ onLeft: (e) => Effect.map(f(e), Option.map(Cause.fail)),
1948
+ onRight: (cause) => Effect.succeed(Option.some(cause))
1949
+ }))
1950
+ }
1951
+
1952
+ export function loopCause<R, E, A, B, C>(
1953
+ fx: Fx<R, E, A>,
1954
+ seed: B,
1955
+ f: (b: B, cause: Cause.Cause<E>) => readonly [Cause.Cause<C>, B]
1956
+ ): Fx<R, C, A> {
1957
+ return new TransformerCause(fx, SyncLoopOp.LoopOperator(seed, f))
1958
+ }
1959
+
1960
+ export function loopError<R, E, A, B, C>(
1961
+ fx: Fx<R, E, A>,
1962
+ seed: B,
1963
+ f: (b: B, e: E) => readonly [C, B]
1964
+ ): Fx<R, C, A> {
1965
+ return loopCause(fx, seed, (b, cause) =>
1966
+ Either.match(Cause.failureOrCause(cause), {
1967
+ onLeft: (e) => {
1968
+ const [c, b2] = f(b, e)
1969
+ return [Cause.fail(c), b2]
1970
+ },
1971
+ onRight: (cause) => [cause, b]
1972
+ }))
1973
+ }
1974
+
1975
+ export function loopCauseEffect<R, E, A, R2, E2, B, C>(
1976
+ fx: Fx<R, E, A>,
1977
+ seed: B,
1978
+ f: (b: B, cause: Cause.Cause<E>) => Effect.Effect<R2, E2, readonly [Cause.Cause<C>, B]>
1979
+ ): Fx<R | R2, E2 | C, A> {
1980
+ return new TransformerCause(fx, EffectLoopOp.LoopEffectOperator(seed, f))
1981
+ }
1982
+
1983
+ export function loopErrorEffect<R, E, A, R2, E2, B, C>(
1984
+ fx: Fx<R, E, A>,
1985
+ seed: B,
1986
+ f: (b: B, e: E) => Effect.Effect<R2, E2, readonly [C, B]>
1987
+ ) {
1988
+ return loopCauseEffect(fx, seed, (b, cause) =>
1989
+ Either.match(Cause.failureOrCause(cause), {
1990
+ onLeft: (e) => Effect.map(f(b, e), ([c, b2]) => [Cause.fail(c), b2]),
1991
+ onRight: (cause) => Effect.succeed([cause, b])
1992
+ }))
1993
+ }
1994
+
1995
+ export function filterMapLoopCause<R, E, A, B, C>(
1996
+ fx: Fx<R, E, A>,
1997
+ seed: B,
1998
+ f: (b: B, cause: Cause.Cause<E>) => readonly [Option.Option<Cause.Cause<C>>, B]
1999
+ ): Fx<R, C, A> {
2000
+ return new TransformerCause(fx, SyncLoopOp.FilterMapLoopOperator(seed, f))
2001
+ }
2002
+
2003
+ export function filterMapLoopError<R, E, A, B, C>(
2004
+ fx: Fx<R, E, A>,
2005
+ seed: B,
2006
+ f: (b: B, e: E) => readonly [Option.Option<C>, B]
2007
+ ) {
2008
+ return filterMapLoopCause(fx, seed, (b, cause) =>
2009
+ Either.match(Cause.failureOrCause(cause), {
2010
+ onLeft: (e) => {
2011
+ const [c, b2] = f(b, e)
2012
+ return [Option.map(Cause.fail)(c), b2]
2013
+ },
2014
+ onRight: (cause) => [Option.some(cause), b]
2015
+ }))
2016
+ }
2017
+
2018
+ export function filterMapLoopCauseEffect<R, E, A, R2, E2, B, C>(
2019
+ fx: Fx<R, E, A>,
2020
+ seed: B,
2021
+ f: (b: B, cause: Cause.Cause<E>) => Effect.Effect<R2, E2, readonly [Option.Option<Cause.Cause<C>>, B]>
2022
+ ): Fx<R | R2, E2 | C, A> {
2023
+ return new TransformerCause(fx, EffectLoopOp.FilterMapLoopEffectOperator(seed, f))
2024
+ }
2025
+
2026
+ export function filterMapLoopErrorEffect<R, E, A, R2, E2, B, C>(
2027
+ fx: Fx<R, E, A>,
2028
+ seed: B,
2029
+ f: (b: B, e: E) => Effect.Effect<R2, E2, readonly [Option.Option<C>, B]>
2030
+ ) {
2031
+ return filterMapLoopCauseEffect(fx, seed, (b, cause) =>
2032
+ Either.match(Cause.failureOrCause(cause), {
2033
+ onLeft: (e) => Effect.map(f(b, e), ([c, b2]) => [Option.map(c, Cause.fail), b2]),
2034
+ onRight: (cause) => Effect.succeed([Option.some(cause), b])
2035
+ }))
2036
+ }
2037
+
2038
+ class TransformerCause<R, E, A, R2, E2> extends FxBase<R | R2, E2, A> {
2039
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Op.Operator) {
2040
+ super()
2041
+ }
2042
+
2043
+ run<R2>(sink: Sink.Sink<R2, E2, A>): Effect.Effect<R | R2, never, unknown> {
2044
+ return this.i0.run(Op.compileOperatorSinkCause(this.i1, sink))
2045
+ }
2046
+ }
2047
+
2048
+ export function flatMapCauseWithStrategy<R, E, A, R2, E2, B>(
2049
+ fx: Fx<R, E, A>,
2050
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2051
+ flattenStrategy: FlattenStrategy,
2052
+ executionStrategy: ExecutionStrategy.ExecutionStrategy = ExecutionStrategy.sequential
2053
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2054
+ return new FlatMapCauseWithStrategy(fx, f, flattenStrategy, executionStrategy)
2055
+ }
2056
+
2057
+ export function flatMapErrorWithStrategy<R, E, A, R2, E2, B>(
2058
+ fx: Fx<R, E, A>,
2059
+ f: (e: E) => Fx<R2, E2, B>,
2060
+ flattenStrategy: FlattenStrategy,
2061
+ executionStrategy: ExecutionStrategy.ExecutionStrategy = ExecutionStrategy.sequential
2062
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2063
+ return flatMapCauseWithStrategy(
2064
+ fx,
2065
+ (cause) =>
2066
+ Either.match(Cause.failureOrCause(cause), {
2067
+ onLeft: f,
2068
+ onRight: (cause) => failCause(cause)
2069
+ }),
2070
+ flattenStrategy,
2071
+ executionStrategy
2072
+ )
2073
+ }
2074
+
2075
+ export function switchMapCause<R, E, A, R2, E2, B>(
2076
+ fx: Fx<R, E, A>,
2077
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2078
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2079
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2080
+ return flatMapCauseWithStrategy(fx, f, Switch, executionStrategy)
2081
+ }
2082
+
2083
+ export function switchMapError<R, E, A, R2, E2, B>(
2084
+ fx: Fx<R, E, A>,
2085
+ f: (e: E) => Fx<R2, E2, B>,
2086
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2087
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2088
+ return flatMapErrorWithStrategy(fx, f, Switch, executionStrategy)
2089
+ }
2090
+
2091
+ export function flatMapCause<R, E, A, R2, E2, B>(
2092
+ fx: Fx<R, E, A>,
2093
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2094
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2095
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2096
+ return flatMapCauseWithStrategy(fx, f, Unbounded, executionStrategy)
2097
+ }
2098
+
2099
+ export function flatMapError<R, E, A, R2, E2, B>(
2100
+ fx: Fx<R, E, A>,
2101
+ f: (e: E) => Fx<R2, E2, B>,
2102
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2103
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2104
+ return flatMapErrorWithStrategy(fx, f, Unbounded, executionStrategy)
2105
+ }
2106
+
2107
+ export function flatMapCauseConcurrently<R, E, A, R2, E2, B>(
2108
+ fx: Fx<R, E, A>,
2109
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2110
+ concurrency: number,
2111
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2112
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2113
+ return flatMapCauseWithStrategy(fx, f, Bounded(concurrency), executionStrategy)
2114
+ }
2115
+
2116
+ export function flatMapErrorConcurrently<R, E, A, R2, E2, B>(
2117
+ fx: Fx<R, E, A>,
2118
+ f: (e: E) => Fx<R2, E2, B>,
2119
+ concurrency: number,
2120
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2121
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2122
+ return flatMapErrorWithStrategy(fx, f, Bounded(concurrency), executionStrategy)
2123
+ }
2124
+
2125
+ export function exhaustMapCause<R, E, A, R2, E2, B>(
2126
+ fx: Fx<R, E, A>,
2127
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2128
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2129
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2130
+ return flatMapCauseWithStrategy(fx, f, Exhaust, executionStrategy)
2131
+ }
2132
+
2133
+ export function exhaustMapError<R, E, A, R2, E2, B>(
2134
+ fx: Fx<R, E, A>,
2135
+ f: (e: E) => Fx<R2, E2, B>,
2136
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2137
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2138
+ return flatMapErrorWithStrategy(fx, f, Exhaust, executionStrategy)
2139
+ }
2140
+
2141
+ export function exhaustMapLatestCause<R, E, A, R2, E2, B>(
2142
+ fx: Fx<R, E, A>,
2143
+ f: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2144
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2145
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2146
+ return flatMapCauseWithStrategy(fx, f, ExhaustLatest, executionStrategy)
2147
+ }
2148
+
2149
+ export function exhaustMapLatestError<R, E, A, R2, E2, B>(
2150
+ fx: Fx<R, E, A>,
2151
+ f: (e: E) => Fx<R2, E2, B>,
2152
+ executionStrategy?: ExecutionStrategy.ExecutionStrategy
2153
+ ): Fx<R | R2 | Scope.Scope, E2, A | B> {
2154
+ return flatMapErrorWithStrategy(fx, f, ExhaustLatest, executionStrategy)
2155
+ }
2156
+
2157
+ class FlatMapCauseWithStrategy<
2158
+ R,
2159
+ E,
2160
+ A,
2161
+ R2,
2162
+ E2,
2163
+ B
2164
+ > extends FxBase<R | R2 | Scope.Scope, E2, A | B> {
2165
+ private withFork: <R, E, A>(
2166
+ f: (
2167
+ fork: FxFork,
2168
+ scope: Scope.Scope
2169
+ ) => Effect.Effect<R, E, A>,
2170
+ executionStrategy: ExecutionStrategy.ExecutionStrategy
2171
+ ) => Effect.Effect<Scope.Scope | R, E, void>
2172
+
2173
+ constructor(
2174
+ readonly i0: Fx<R, E, A>,
2175
+ readonly i1: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2176
+ readonly i2: FlattenStrategy,
2177
+ readonly i3: ExecutionStrategy.ExecutionStrategy
2178
+ ) {
2179
+ super()
2180
+
2181
+ this.withFork = withFlattenStrategy(this.i2)
2182
+ }
2183
+
2184
+ run<R3>(sink: Sink.Sink<R3, E | E2, A | B>): Effect.Effect<R | R2 | R3 | Scope.Scope, never, unknown> {
2185
+ return this.withFork(
2186
+ (fork) => this.i0.run(Sink.make((cause) => fork(this.i1(cause).run(sink)), (a) => sink.onSuccess(a))),
2187
+ this.i3
2188
+ )
2189
+ }
2190
+ }
2191
+
2192
+ class MatchWithStrategy<
2193
+ R,
2194
+ E,
2195
+ A,
2196
+ R2,
2197
+ E2,
2198
+ B,
2199
+ R3,
2200
+ E3,
2201
+ C
2202
+ > extends FxBase<R | R2 | R3 | Scope.Scope, E2 | E3, B | C> {
2203
+ private withFork: <R, E, A>(
2204
+ f: (
2205
+ fork: FxFork,
2206
+ scope: Scope.Scope
2207
+ ) => Effect.Effect<R, E, A>,
2208
+ executionStrategy: ExecutionStrategy.ExecutionStrategy
2209
+ ) => Effect.Effect<Scope.Scope | R, E, void>
2210
+
2211
+ constructor(
2212
+ readonly i0: Fx<R, E, A>,
2213
+ readonly i1: (cause: Cause.Cause<E>) => Fx<R2, E2, B>,
2214
+ readonly i2: (a: A) => Fx<R3, E3, C>,
2215
+ readonly i3: FlattenStrategy,
2216
+ readonly i4: ExecutionStrategy.ExecutionStrategy
2217
+ ) {
2218
+ super()
2219
+
2220
+ this.withFork = withFlattenStrategy(this.i3)
2221
+ }
2222
+
2223
+ run<R4>(sink: Sink.Sink<R4, E2 | E3, B | C>): Effect.Effect<R | R2 | R3 | R4 | Scope.Scope, never, unknown> {
2224
+ return this.withFork(
2225
+ (fork) =>
2226
+ this.i0.run(Sink.make(
2227
+ (cause) => fork(this.i1(cause).run(sink)),
2228
+ (a) => fork(this.i2(a).run(sink))
2229
+ )),
2230
+ this.i4
2231
+ )
2232
+ }
2233
+ }
2234
+
2235
+ export type MatchCauseOptions<E, A, R2, E2, B, R3, E3, C> = {
2236
+ readonly onFailure: (cause: Cause.Cause<E>) => Fx<R2, E2, B>
2237
+ readonly onSuccess: (a: A) => Fx<R3, E3, C>
2238
+ readonly executionStrategy?: ExecutionStrategy.ExecutionStrategy | undefined
2239
+ }
2240
+
2241
+ export function matchCauseWithStrategy<R, E, A, R2, E2, B, R3, E3, C>(
2242
+ fx: Fx<R, E, A>,
2243
+ flattenStrategy: FlattenStrategy,
2244
+ opts: MatchCauseOptions<E, A, R2, E2, B, R3, E3, C>
2245
+ ): Fx<R | R2 | R3 | Scope.Scope, E2 | E3, B | C> {
2246
+ return new MatchWithStrategy(
2247
+ fx,
2248
+ opts.onFailure,
2249
+ opts.onSuccess,
2250
+ flattenStrategy,
2251
+ opts.executionStrategy || ExecutionStrategy.sequential
2252
+ )
2253
+ }
2254
+
2255
+ export type MatchErrorOptions<E, A, R2, E2, B, R3, E3, C> = {
2256
+ readonly onFailure: (e: E) => Fx<R2, E2, B>
2257
+ readonly onSuccess: (a: A) => Fx<R3, E3, C>
2258
+ readonly executionStrategy?: ExecutionStrategy.ExecutionStrategy | undefined
2259
+ }
2260
+
2261
+ export function matchErrorWithStrategy<R, E, A, R2, E2, B, R3, E3, C>(
2262
+ fx: Fx<R, E, A>,
2263
+ flattenStrategy: FlattenStrategy,
2264
+ { executionStrategy, onFailure, onSuccess }: MatchErrorOptions<E, A, R2, E2, B, R3, E3, C>
2265
+ ): Fx<R | R2 | R3 | Scope.Scope, E2 | E3, B | C> {
2266
+ return new MatchWithStrategy(
2267
+ fx,
2268
+ (cause) =>
2269
+ Either.match(Cause.failureOrCause(cause), {
2270
+ onLeft: onFailure,
2271
+ onRight: (cause) => failCause(cause)
2272
+ }),
2273
+ onSuccess,
2274
+ flattenStrategy,
2275
+ executionStrategy || ExecutionStrategy.sequential
2276
+ )
2277
+ }
2278
+
2279
+ export function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
2280
+ fx: Fx<R, E, A>,
2281
+ opts: MatchCauseOptions<E, A, R2, E2, B, R3, E3, C>
2282
+ ) {
2283
+ return matchCauseWithStrategy(fx, Unbounded, opts)
2284
+ }
2285
+
2286
+ export function matchError<R, E, A, R2, E2, B, R3, E3, C>(
2287
+ fx: Fx<R, E, A>,
2288
+ opts: MatchErrorOptions<E, A, R2, E2, B, R3, E3, C>
2289
+ ) {
2290
+ return matchErrorWithStrategy(fx, Unbounded, opts)
2291
+ }
2292
+
2293
+ export function matchCauseConcurrently<R, E, A, R2, E2, B, R3, E3, C>(
2294
+ fx: Fx<R, E, A>,
2295
+ concurrency: number,
2296
+ opts: MatchCauseOptions<E, A, R2, E2, B, R3, E3, C>
2297
+ ) {
2298
+ return matchCauseWithStrategy(fx, Bounded(concurrency), opts)
2299
+ }
2300
+
2301
+ export function matchErrorConcurrently<R, E, A, R2, E2, B, R3, E3, C>(
2302
+ fx: Fx<R, E, A>,
2303
+ concurrency: number,
2304
+ opts: MatchErrorOptions<E, A, R2, E2, B, R3, E3, C>
2305
+ ) {
2306
+ return matchErrorWithStrategy(fx, Bounded(concurrency), opts)
2307
+ }
2308
+
2309
+ export function switchMatchCause<R, E, A, R2, E2, B, R3, E3, C>(
2310
+ fx: Fx<R, E, A>,
2311
+ opts: MatchCauseOptions<E, A, R2, E2, B, R3, E3, C>
2312
+ ) {
2313
+ return matchCauseWithStrategy(fx, Switch, opts)
2314
+ }
1556
2315
 
1557
- <R, E, A, R2, E2, B, R3, E3, C>(
1558
- fx: Fx<R, E, A>,
1559
- options: {
1560
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1561
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1562
- }
1563
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1564
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
2316
+ export function switchMatchError<R, E, A, R2, E2, B, R3, E3, C>(
1565
2317
  fx: Fx<R, E, A>,
1566
- options: {
1567
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1568
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1569
- }
1570
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1571
- return matchCauseWithStrategy(fx, {
1572
- ...options,
1573
- strategy: strategies.Unbounded
1574
- })
1575
- })
2318
+ opts: MatchErrorOptions<E, A, R2, E2, B, R3, E3, C>
2319
+ ) {
2320
+ return matchErrorWithStrategy(fx, Switch, opts)
2321
+ }
1576
2322
 
1577
- export const match: {
1578
- <E, R2, E2, B, A, R3, E3, C>(
1579
- options: {
1580
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1581
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1582
- }
1583
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2323
+ export function exhaustMatchCause<R, E, A, R2, E2, B, R3, E3, C>(
2324
+ fx: Fx<R, E, A>,
2325
+ opts: MatchCauseOptions<E, A, R2, E2, B, R3, E3, C>
2326
+ ) {
2327
+ return matchCauseWithStrategy(fx, Exhaust, opts)
2328
+ }
1584
2329
 
1585
- <R, E, A, R2, E2, B, R3, E3, C>(
1586
- fx: Fx<R, E, A>,
1587
- options: {
1588
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1589
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1590
- }
1591
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1592
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
2330
+ export function exhaustMatchError<R, E, A, R2, E2, B, R3, E3, C>(
1593
2331
  fx: Fx<R, E, A>,
1594
- options: {
1595
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1596
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1597
- }
1598
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1599
- return matchErrorWithStrategy(
1600
- fx,
1601
- { ...options, strategy: strategies.Unbounded }
1602
- )
1603
- })
1604
-
1605
- export const matchCauseConcurrently: {
1606
- <E, R2, E2, B, A, R3, E3, C>(
1607
- options: {
1608
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1609
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1610
- readonly concurrency: number
1611
- }
1612
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2332
+ opts: MatchErrorOptions<E, A, R2, E2, B, R3, E3, C>
2333
+ ) {
2334
+ return matchErrorWithStrategy(fx, Exhaust, opts)
2335
+ }
1613
2336
 
1614
- <R, E, A, R2, E2, B, R3, E3, C>(
1615
- fx: Fx<R, E, A>,
1616
- options: {
1617
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1618
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1619
- readonly concurrency: number
1620
- }
1621
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1622
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
2337
+ export function exhaustMatchLatestCause<R, E, A, R2, E2, B, R3, E3, C>(
1623
2338
  fx: Fx<R, E, A>,
1624
- options: {
1625
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1626
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1627
- readonly concurrency: number
1628
- }
1629
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1630
- return matchCauseWithStrategy(fx, {
1631
- onFailure: options.onFailure,
1632
- onSuccess: options.onSuccess,
1633
- strategy: strategies.Bounded(options.concurrency)
1634
- })
1635
- })
1636
-
1637
- export const matchErrorConcurrently: {
1638
- <E, R2, E2, B, A, R3, E3, C>(
1639
- options: {
1640
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1641
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1642
- readonly concurrency: number
1643
- }
1644
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2339
+ opts: MatchCauseOptions<E, A, R2, E2, B, R3, E3, C>
2340
+ ) {
2341
+ return matchCauseWithStrategy(fx, ExhaustLatest, opts)
2342
+ }
1645
2343
 
1646
- <R, E, A, R2, E2, B, R3, E3, C>(
1647
- fx: Fx<R, E, A>,
1648
- options: {
1649
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1650
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1651
- readonly concurrency: number
1652
- }
1653
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1654
- } = dual(2, function matchErrorConcurrently<R, E, A, R2, E2, B, R3, E3, C>(
2344
+ export function exhaustMatchLatestError<R, E, A, R2, E2, B, R3, E3, C>(
1655
2345
  fx: Fx<R, E, A>,
1656
- options: {
1657
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1658
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1659
- readonly concurrency: number
1660
- }
1661
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1662
- return matchErrorWithStrategy(
1663
- fx,
1664
- { ...options, strategy: strategies.Bounded(options.concurrency) }
1665
- )
1666
- })
2346
+ opts: MatchErrorOptions<E, A, R2, E2, B, R3, E3, C>
2347
+ ) {
2348
+ return matchErrorWithStrategy(fx, ExhaustLatest, opts)
2349
+ }
1667
2350
 
1668
- export const switchMatchCause: {
1669
- <E, R2, E2, B, A, R3, E3, C>(
1670
- options: {
1671
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1672
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1673
- }
1674
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2351
+ export function tuple<const FX extends ReadonlyArray<Fx<any, any, any>>>(
2352
+ fx: FX
2353
+ ): Fx<
2354
+ Fx.Context<FX[number]>,
2355
+ Fx.Error<FX[number]>,
2356
+ {
2357
+ readonly [K in keyof FX]: Fx.Success<FX[K]>
2358
+ }
2359
+ > {
2360
+ return new Tuple(fx)
2361
+ }
1675
2362
 
1676
- <R, E, A, R2, E2, B, R3, E3, C>(
1677
- fx: Fx<R, E, A>,
1678
- options: {
1679
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1680
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1681
- }
1682
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1683
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
1684
- fx: Fx<R, E, A>,
1685
- options: {
1686
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1687
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
2363
+ class Tuple<const FX extends ReadonlyArray<Fx<any, any, any>>> extends FxBase<
2364
+ Fx.Context<FX[number]>,
2365
+ Fx.Error<FX[number]>,
2366
+ {
2367
+ readonly [K in keyof FX]: Fx.Success<FX[K]>
2368
+ }
2369
+ > {
2370
+ constructor(readonly i0: FX) {
2371
+ super()
1688
2372
  }
1689
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1690
- return matchCauseWithStrategy(fx, {
1691
- ...options,
1692
- strategy: strategies.Switch
1693
- })
1694
- })
1695
2373
 
1696
- export const switchMatch: {
1697
- <E, R2, E2, B, A, R3, E3, C>(
1698
- options: {
1699
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1700
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1701
- }
1702
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2374
+ run<R2>(
2375
+ sink: Sink.Sink<R2, Fx.Error<FX[number]>, { readonly [K in keyof FX]: Fx.Success<FX[K]> }>
2376
+ ): Effect.Effect<Fx.Context<FX[number]> | R2, never, unknown> {
2377
+ return tupleSink(
2378
+ sink,
2379
+ (onSuccess) =>
2380
+ Effect.forEach(
2381
+ this.i0,
2382
+ (fx, i) =>
2383
+ fx.run(
2384
+ Sink.make(
2385
+ sink.onFailure,
2386
+ (a) => onSuccess(i, a)
2387
+ )
2388
+ ),
2389
+ UNBOUNDED
2390
+ ),
2391
+ this.i0.length
2392
+ )
2393
+ }
2394
+ }
1703
2395
 
1704
- <R, E, A, R2, E2, B, R3, E3, C>(
1705
- fx: Fx<R, E, A>,
1706
- options: {
1707
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1708
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1709
- }
1710
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1711
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
1712
- fx: Fx<R, E, A>,
1713
- options: {
1714
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1715
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
2396
+ export function struct<const FX extends Readonly<Record<string, Fx<any, any, any>>>>(
2397
+ fx: FX
2398
+ ): Fx<
2399
+ Fx.Context<FX[string]>,
2400
+ Fx.Error<FX[string]>,
2401
+ {
2402
+ readonly [K in keyof FX]: Fx.Success<FX[K]>
1716
2403
  }
1717
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1718
- return matchErrorWithStrategy(
1719
- fx,
1720
- { ...options, strategy: strategies.Switch }
1721
- )
1722
- })
2404
+ > {
2405
+ const entries: ReadonlyArray<readonly [keyof FX, FX[keyof FX]]> = Object.entries(fx) as any
1723
2406
 
1724
- export const exhaustMatchCause: {
1725
- <E, R2, E2, B, A, R3, E3, C>(
1726
- options: {
1727
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1728
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1729
- }
1730
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2407
+ return map(tuple(entries.map(([key, fx]) => map(fx, (a) => [key, a] as const))), Object.fromEntries)
2408
+ }
1731
2409
 
1732
- <R, E, A, R2, E2, B, R3, E3, C>(
1733
- fx: Fx<R, E, A>,
1734
- options: {
1735
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1736
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1737
- }
1738
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1739
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
1740
- fx: Fx<R, E, A>,
1741
- options: {
1742
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1743
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1744
- }
1745
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1746
- return matchCauseWithStrategy(fx, {
1747
- ...options,
1748
- strategy: strategies.Exhaust
1749
- })
1750
- })
2410
+ export function all<const FX extends ReadonlyArray<Fx<any, any, any>>>(
2411
+ fx: FX
2412
+ ): Fx<
2413
+ Fx.Context<FX[number]>,
2414
+ Fx.Error<FX[number]>,
2415
+ { readonly [K in keyof FX]: Fx.Success<FX[K]> }
2416
+ >
1751
2417
 
1752
- export const exhaustMatch: {
1753
- <E, R2, E2, B, A, R3, E3, C>(
1754
- options: {
1755
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1756
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1757
- }
1758
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2418
+ export function all<const FX extends Readonly<Record<string, Fx<any, any, any>>>>(
2419
+ fx: FX
2420
+ ): Fx<
2421
+ Fx.Context<FX[string]>,
2422
+ Fx.Error<FX[string]>,
2423
+ { readonly [K in keyof FX]: Fx.Success<FX[K]> }
2424
+ >
1759
2425
 
1760
- <R, E, A, R2, E2, B, R3, E3, C>(
1761
- fx: Fx<R, E, A>,
1762
- options: {
1763
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1764
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1765
- }
1766
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1767
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
1768
- fx: Fx<R, E, A>,
1769
- options: {
1770
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1771
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1772
- }
1773
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1774
- return matchErrorWithStrategy(
1775
- fx,
1776
- { ...options, strategy: strategies.Exhaust }
1777
- )
1778
- })
2426
+ export function all<const FX extends ReadonlyArray<Fx<any, any, any> | Readonly<Record<string, Fx<any, any, any>>>>>(
2427
+ fx: FX
2428
+ ): Fx<
2429
+ Fx.Context<FX[keyof FX]>,
2430
+ Fx.Error<FX[keyof FX]>,
2431
+ any
2432
+ > {
2433
+ if (Array.isArray(fx)) return tuple(fx)
2434
+ else return struct(fx as any) as any
2435
+ }
1779
2436
 
1780
- export const exhaustLatestMatchCause: {
1781
- <E, R2, E2, B, A, R3, E3, C>(
1782
- options: {
1783
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1784
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1785
- }
1786
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2437
+ export function exit<R, E, A>(
2438
+ fx: Fx<R, E, A>
2439
+ ): Fx<R, never, Exit.Exit<E, A>> {
2440
+ return new ExitFx(fx)
2441
+ }
1787
2442
 
1788
- <R, E, A, R2, E2, B, R3, E3, C>(
1789
- fx: Fx<R, E, A>,
1790
- options: {
1791
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1792
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1793
- }
1794
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1795
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
1796
- fx: Fx<R, E, A>,
1797
- options: {
1798
- readonly onFailure: (cause: Cause.Cause<E>) => FxInput<R2, E2, B>
1799
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
2443
+ class ExitFx<R, E, A> extends FxBase<R, never, Exit.Exit<E, A>> {
2444
+ constructor(readonly i0: Fx<R, E, A>) {
2445
+ super()
1800
2446
  }
1801
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1802
- return matchCauseWithStrategy(fx, {
1803
- ...options,
1804
- strategy: strategies.ExhaustLatest
1805
- })
1806
- })
1807
2447
 
1808
- export const exhaustLatestMatch: {
1809
- <E, R2, E2, B, A, R3, E3, C>(
1810
- options: {
1811
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1812
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1813
- }
1814
- ): <R>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E2 | E3, B | C>
2448
+ run<R2>(sink: Sink.Sink<R2, never, Exit.Exit<E, A>>): Effect.Effect<R | R2, never, unknown> {
2449
+ return this.i0.run(
2450
+ Sink.make((cause) => sink.onSuccess(Exit.failCause(cause)), (a) => sink.onSuccess(Exit.succeed(a)))
2451
+ )
2452
+ }
2453
+ }
1815
2454
 
1816
- <R, E, A, R2, E2, B, R3, E3, C>(
1817
- fx: Fx<R, E, A>,
1818
- options: {
1819
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1820
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1821
- }
1822
- ): Fx<R | R2 | R3, E2 | E3, B | C>
1823
- } = dual(2, function matchCause<R, E, A, R2, E2, B, R3, E3, C>(
2455
+ export function toEnqueue<R, E, A, R2 = never>(
1824
2456
  fx: Fx<R, E, A>,
1825
- options: {
1826
- readonly onFailure: (error: E) => FxInput<R2, E2, B>
1827
- readonly onSuccess: (a: A) => FxInput<R3, E3, C>
1828
- }
1829
- ): Fx<R | R2 | R3, E2 | E3, B | C> {
1830
- return matchErrorWithStrategy(
1831
- fx,
1832
- { ...options, strategy: strategies.ExhaustLatest }
1833
- )
1834
- })
2457
+ queue: Context.Enqueue<R2, A> | Queue.Enqueue<A>
2458
+ ) {
2459
+ return observe(fx, (a) => queue.offer(a))
2460
+ }
1835
2461
 
1836
- export const withEarlyExit = <R, E, A>(
1837
- f: (params: WithEarlyExitParams<E, A>) => Effect.Effect<R, never, unknown>
1838
- ): Fx<R, E, A> => new WithEarlyExit(f)
2462
+ export function debounce<R, E, A>(fx: Fx<R, E, A>, delay: Duration.DurationInput): Fx<R | Scope.Scope, E, A> {
2463
+ return switchMapEffect(fx, (a) => Effect.as(Effect.sleep(delay), a))
2464
+ }
1839
2465
 
1840
- export const withScopedFork = <R, E, A>(
1841
- f: (params: WithScopedForkParams<E, A>) => Effect.Effect<R, never, unknown>
1842
- ): Fx<R, E, A> => new WithScopedFork(f)
2466
+ export function throttle<R, E, A>(fx: Fx<R, E, A>, delay: Duration.DurationInput): Fx<R | Scope.Scope, E, A> {
2467
+ return exhaustMapEffect(fx, (a) => Effect.as(Effect.sleep(delay), a))
2468
+ }
1843
2469
 
1844
- export const withFlattenStrategy = <R, E, A>(
1845
- f: (params: WithFlattenStrategyParams<E, A>) => Effect.Effect<R, never, unknown>,
1846
- strategy: FlattenStrategy
1847
- ): Fx<R, E, A> => new WithFlattenStrategy(f, strategy)
2470
+ export function throttleLatest<R, E, A>(fx: Fx<R, E, A>, delay: Duration.DurationInput): Fx<R | Scope.Scope, E, A> {
2471
+ return exhaustMapLatestEffect(fx, (a) => Effect.as(Effect.sleep(delay), a))
2472
+ }
1848
2473
 
1849
- export const during: {
1850
- <R2, E2, R3, E3>(
1851
- window: Fx<R2, E2, Fx<R3, E3, unknown>>
1852
- ): <R, E, A>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E | E2 | E3, A>
2474
+ export function fromAsyncIterable<A>(iterable: AsyncIterable<A>): Fx<never, never, A> {
2475
+ return new FromAsyncIterable(iterable)
2476
+ }
1853
2477
 
1854
- <R, E, A, R2, E2, R3, E3>(
1855
- fx: Fx<R, E, A>,
1856
- window: Fx<R2, E2, Fx<R3, E3, unknown>>
1857
- ): Fx<R | R2 | R3, E | E2 | E3, A>
1858
- } = dual(2, function during<R, E, A, R2, E2, R3, E3>(
1859
- fx: Fx<R, E, A>,
1860
- window: Fx<R2, E2, Fx<R3, E3, unknown>>
1861
- ): Fx<R | R2 | R3, E | E2 | E3, A> {
1862
- return withEarlyExit(({ fork, sink }) =>
1863
- Effect.suspend(() => {
1864
- let taking = false
2478
+ class FromAsyncIterable<A> extends FxBase<never, never, A> {
2479
+ constructor(readonly i0: AsyncIterable<A>) {
2480
+ super()
2481
+ }
2482
+
2483
+ run<R>(sink: Sink.Sink<R, never, A>): Effect.Effect<R, never, unknown> {
2484
+ return Effect.asyncEffect((cb) => {
2485
+ const iterator = this.i0[Symbol.asyncIterator]()
2486
+ const loop = (result: IteratorResult<A>): Effect.Effect<R, never, unknown> =>
2487
+ result.done
2488
+ ? Effect.sync(() => cb(Effect.unit))
2489
+ : Effect.zipRight(sink.onSuccess(result.value), Effect.flatMap(Effect.promise(() => iterator.next()), loop))
1865
2490
 
1866
2491
  return Effect.flatMap(
1867
- fork(run(
1868
- take(window, 1),
1869
- Sink.WithContext(sink.onFailure, (nested) => {
1870
- taking = true
1871
- return fork(run(take(nested, 1), Sink.WithContext(sink.onFailure, () => sink.earlyExit)))
1872
- })
1873
- )),
1874
- () =>
1875
- adjustTime(1).pipe(Effect.zipRight(run(
1876
- fx,
1877
- Sink.Sink(
1878
- sink.onFailure,
1879
- (a) => taking ? sink.onSuccess(a) : Effect.unit
1880
- )
1881
- )))
2492
+ Effect.promise(() => iterator.next()),
2493
+ loop
1882
2494
  )
1883
2495
  })
2496
+ }
2497
+ }
2498
+
2499
+ export function findFirst<R, E, A>(fx: Fx<R, E, A>, predicate: Predicate.Predicate<A>): Effect.Effect<R, E, A> {
2500
+ return Effect.asyncEffect((cb) =>
2501
+ observe(fx, (a) => predicate(a) ? Effect.sync(() => cb(Effect.succeed(a))) : Effect.unit)
1884
2502
  )
1885
- })
2503
+ }
1886
2504
 
1887
- export const since: {
1888
- <R2, E2>(window: Fx<R2, E2, unknown>): <R, E, A>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1889
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, window: Fx<R2, E2, unknown>): Fx<R | R2, E | E2, A>
1890
- } = dual(2, function since<R, E, A, R2, E2>(
1891
- fx: Fx<R, E, A>,
1892
- window: Fx<R2, E2, unknown>
1893
- ): Fx<R | R2, E | E2, A> {
1894
- return during(fx, map(window, () => never))
1895
- })
2505
+ export function first<R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, A> {
2506
+ return findFirst(fx, constTrue)
2507
+ }
2508
+
2509
+ export function either<R, E, A>(fx: Fx<R, E, A>): Fx<R, never, Either.Either<E, A>> {
2510
+ return new EitherFx(fx)
2511
+ }
1896
2512
 
1897
- export const until: {
1898
- <R2, E2>(window: Fx<R2, E2, unknown>): <R, E, A>(fx: Fx<R, E, A>) => Fx<R | R2, E | E2, A>
1899
- <R, E, A, R2, E2>(fx: Fx<R, E, A>, window: Fx<R2, E2, unknown>): Fx<R | R2, E | E2, A>
1900
- } = dual(2, function until<R, E, A, R2, E2>(
2513
+ class EitherFx<R, E, A> extends FxBase<R, never, Either.Either<E, A>> {
2514
+ constructor(readonly i0: Fx<R, E, A>) {
2515
+ super()
2516
+ }
2517
+
2518
+ run<R2>(sink: Sink.Sink<R2, never, Either.Either<E, A>>): Effect.Effect<R | R2, never, unknown> {
2519
+ return this.i0.run(
2520
+ Sink.make(
2521
+ (cause) =>
2522
+ Either.match(Cause.failureOrCause(cause), {
2523
+ onLeft: (e) => sink.onSuccess(Either.left(e)),
2524
+ onRight: (cause) => sink.onFailure(cause)
2525
+ }),
2526
+ (a) => sink.onSuccess(Either.right(a))
2527
+ )
2528
+ )
2529
+ }
2530
+ }
2531
+
2532
+ export function mergeFirst<R, E, A, R2, E2, B>(
1901
2533
  fx: Fx<R, E, A>,
1902
- window: Fx<R2, E2, unknown>
2534
+ that: Fx<R2, E2, B>
1903
2535
  ): Fx<R | R2, E | E2, A> {
1904
- return during(fx, succeed(window))
1905
- })
1906
-
1907
- export const fromScheduled: {
1908
- <R2>(scheduled: Schedule.Schedule<R2, unknown, unknown>): <R, E, A>(fx: Effect.Effect<R, E, A>) => Fx<R | R2, E, A>
1909
- <R, E, A, R2>(fx: Effect.Effect<R, E, A>, scheduled: Schedule.Schedule<R2, unknown, unknown>): Fx<R | R2, E, A>
1910
- } = dual(2, function fromScheduled<R, E, A, R2>(
1911
- fx: Effect.Effect<R, E, A>,
1912
- scheduled: Schedule.Schedule<R2, unknown, unknown>
1913
- ): Fx<R | R2, E, A> {
1914
- return fromSink((sink) =>
1915
- Effect.catchAllCause(Effect.repeat(Effect.matchCauseEffect(fx, sink), scheduled), sink.onFailure)
1916
- )
1917
- })
1918
-
1919
- export const periodic: {
1920
- (duration: DurationInput): <R, E, A>(fx: Effect.Effect<R, E, A>) => Fx<R, E, A>
1921
- <R, E, A>(fx: Effect.Effect<R, E, A>, duration: DurationInput): Fx<R, E, A>
1922
- } = dual(2, function periodic<R, E, A>(
1923
- fx: Effect.Effect<R, E, A>,
1924
- duration: DurationInput
1925
- ): Fx<R, E, A> {
1926
- return fromScheduled(fx, Schedule.spaced(duration))
1927
- })
1928
-
1929
- export const provide: {
1930
- <R2, E2, S>(layer: Layer.Layer<R2, E2, S>): <R, E, A>(fx: Fx<R, E, A>) => Fx<R2 | Exclude<R, S>, E | E2, A>
1931
- <R2>(runtime: Runtime<R2>): <R, E, A>(fx: Fx<R, E, A>) => Fx<Exclude<R, R2>, E, A>
1932
- <R2>(context: Context<R2>): <R, E, A>(fx: Fx<R, E, A>) => Fx<Exclude<R, R2>, E, A>
1933
- <R, E, A, R2, E2, S>(fx: Fx<R, E, A>, layer: Layer.Layer<R2, E2, S>): Fx<Exclude<R, S> | R2, E | E2, A>
1934
- <R, E, A, R2>(fx: Fx<R, E, A>, runtime: Runtime<R2>): Fx<Exclude<R, R2>, E, A>
1935
- <R, E, A, R2>(fx: Fx<R, E, A>, context: Context<R2>): Fx<Exclude<R, R2>, E, A>
1936
- } = dual(2, function provideContext<R, E, A, R2, E2, S>(
1937
- fx: Fx<R, E, A>,
1938
- context: Context<S> | Layer.Layer<R2, E2, S> | Runtime<S>
1939
- ): Fx<R2 | Exclude<R, S>, E, A> {
1940
- if (Layer.isLayer(context)) {
1941
- return FxProvide.make(fx, Provide.ProvideLayer(context)) as any
1942
- } else if (isContext(context)) {
1943
- return FxProvide.make(fx, Provide.ProvideContext(context as Context<S>))
1944
- } else {
1945
- return FxProvide.make(fx, Provide.ProvideRuntime(context as Runtime<S>))
1946
- }
1947
- })
1948
-
1949
- export const provideService: {
1950
- <I, S>(tag: Tag<I, S>, service: S): <R, E, A>(fx: Fx<R, E, A>) => Fx<Exclude<R, I>, E, A>
1951
- <R, E, A, I, S>(fx: Fx<R, E, A>, tag: Tag<I, S>, service: S): Fx<Exclude<R, I>, E, A>
1952
- } = dual(3, function provideService<R, E, A, I, S>(
1953
- fx: Fx<R, E, A>,
1954
- tag: Tag<I, S>,
1955
- service: S
1956
- ): Fx<Exclude<R, I>, E, A> {
1957
- return FxProvide.make(fx, Provide.ProvideService(tag, service))
1958
- })
1959
-
1960
- export const provideServiceEffect: {
1961
- <I, S, R2, E2>(
1962
- tag: Tag<I, S>,
1963
- service: Effect.Effect<R2, E2, S>
1964
- ): <R, E, A>(fx: Fx<R, E, A>) => Fx<R2 | Exclude<R, I>, E, A>
1965
- <R, E, A, I, S, R2, E2>(
1966
- fx: Fx<R, E, A>,
1967
- tag: Tag<I, S>,
1968
- service: Effect.Effect<R2, E2, S>
1969
- ): Fx<R2 | Exclude<R, I>, E, A>
1970
- } = dual(3, function provideService<R, E, A, I, S, R2, E2>(
1971
- fx: Fx<R, E, A>,
1972
- tag: Tag<I, S>,
1973
- service: Effect.Effect<R2, E2, S>
1974
- ): Fx<Exclude<R, I> | R2, E | E2, A> {
1975
- return FxProvide.make(fx, Provide.ProvideServiceEffect(tag, service))
1976
- })
2536
+ return merge(fx, filter(that, constFalse) as Fx<R2, E2, never>)
2537
+ }
1977
2538
 
1978
- export const skipRepeatsWith: {
1979
- <A>(eq: Equivalence<A>): <R, E>(fx: Fx<R, E, A>) => Fx<R, E, A>
1980
- <R, E, A>(fx: Fx<R, E, A>, eq: Equivalence<A>): Fx<R, E, A>
1981
- } = dual(2, function skipRepeatsWith<R, E, A>(
2539
+ export function mergeRace<R, E, A, R2, E2, B>(
1982
2540
  fx: Fx<R, E, A>,
1983
- eq: Equivalence<A>
1984
- ): Fx<R, E, A> {
1985
- return FilterMapLoop.make(fx, Option.none<A>(), (previous, a) =>
1986
- Option.match(previous, {
1987
- onNone: () => Option.some([a, Option.some(a)]),
1988
- onSome: (prev) => eq(a, prev) ? Option.none() : Option.some([a, Option.some(a)])
1989
- }))
1990
- })
1991
-
1992
- export const skipRepeats: <R, E, A>(fx: Fx<R, E, A>) => Fx<R, E, A> = (fx) => skipRepeatsWith(fx, Equal.equals)
2541
+ that: Fx<R2, E2, B>
2542
+ ): Fx<R | R2, E | E2, A | B> {
2543
+ return new MergeRace(fx, that)
2544
+ }
1993
2545
 
1994
- class Reduce<R, E, A, B> extends Effectable.Class<R, E, B> {
1995
- constructor(readonly fx: Fx<R, E, A>, readonly seed: B, readonly f: (acc: B, a: A) => B) {
2546
+ class MergeRace<R, E, A, R2, E2, B> extends FxBase<R | R2, E | E2, A | B> {
2547
+ constructor(readonly i0: Fx<R, E, A>, readonly i1: Fx<R2, E2, B>) {
1996
2548
  super()
1997
2549
  }
1998
2550
 
1999
- static make<R, E, A, B>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => B): Effect.Effect<R, E, B> {
2000
- if (fx instanceof Transformer) {
2001
- return FilterMapReduce.make<R, E, A, B>(fx.i0 as Fx<R, E, any>, seed, compileSyncReducer(fx.i1, f))
2002
- }
2551
+ run<R3>(sink: Sink.Sink<R3, E | E2, A | B>): Effect.Effect<R | R2 | R3, never, unknown> {
2552
+ return Effect.gen(this, function*(_) {
2553
+ const fiber1 = yield* _(Effect.fork(this.i0.run(Sink.make(
2554
+ sink.onFailure,
2555
+ (a) => Effect.flatMap(sink.onSuccess(a), () => Fiber.interrupt(fiber2))
2556
+ ))))
2557
+ const fiber2 = yield* _(Effect.fork(this.i1.run(sink)))
2003
2558
 
2004
- return new Reduce(fx, seed, f)
2559
+ return yield* _(Fiber.joinAll([fiber1, fiber2]))
2560
+ })
2005
2561
  }
2562
+ }
2006
2563
 
2007
- private cached: Effect.Effect<R, E, B> | null = null
2008
-
2009
- commit() {
2010
- return (this.cached ||= Effect.suspend(() => {
2011
- let acc = this.seed
2564
+ export function raceAll<const FX extends ReadonlyArray<Fx<any, any, any>>>(
2565
+ fx: FX
2566
+ ): Fx<
2567
+ Fx.Context<FX[number]>,
2568
+ Fx.Error<FX[number]>,
2569
+ Fx.Success<FX[number]>
2570
+ > {
2571
+ return new RaceAll(fx)
2572
+ }
2012
2573
 
2013
- return Effect.map(observe(this.fx, (a) => Effect.sync(() => acc = this.f(acc, a))), () => acc)
2014
- }))
2015
- }
2574
+ export function race<R, E, A, R2, E2, B>(
2575
+ fx: Fx<R, E, A>,
2576
+ that: Fx<R2, E2, B>
2577
+ ): Fx<R | R2, E | E2, A | B> {
2578
+ return raceAll([fx, that])
2016
2579
  }
2017
2580
 
2018
- class FilterMapReduce<R, E, A, B> extends Effectable.Class<R, E, B> {
2019
- constructor(
2020
- readonly i0: Fx<R, E, A>,
2021
- readonly i1: B,
2022
- readonly i2: (b: B, a: A) => Option.Option<B>
2023
- ) {
2581
+ class RaceAll<const FX extends ReadonlyArray<Fx<any, any, any>>> extends FxBase<
2582
+ Fx.Context<FX[number]>,
2583
+ Fx.Error<FX[number]>,
2584
+ Fx.Success<FX[number]>
2585
+ > {
2586
+ constructor(readonly i0: FX) {
2024
2587
  super()
2025
2588
  }
2026
2589
 
2027
- static make<R, E, A, B>(
2028
- fx: Fx<R, E, A>,
2029
- seed: B,
2030
- f: (b: B, a: A) => Option.Option<B>
2031
- ): Effect.Effect<R, E, B> {
2032
- if (fx instanceof FromIterable) {
2033
- if (Array.isArray(fx.i0)) {
2034
- return new OnceEffect(Effect.sync(() => reduceFilterArray(fx.i0 as Array<A>, seed, f)))
2035
- } else {
2036
- return Effect.sync(() => reduceFilterIterable(fx.i0, seed, f))
2037
- }
2038
- }
2590
+ run<R2>(
2591
+ sink: Sink.Sink<R2, Fx.Error<FX[number]>, Fx.Success<FX[number]>>
2592
+ ): Effect.Effect<Fx.Context<FX[number]> | R2, never, unknown> {
2593
+ return Effect.gen(this, function*(_) {
2594
+ const winner = yield* _(Deferred.make<never, Fiber.RuntimeFiber<never, unknown>>())
2595
+ const fibers: Array<Fiber.RuntimeFiber<never, unknown>> = []
2039
2596
 
2040
- return new FilterMapReduce(fx, seed, f)
2041
- }
2597
+ for (const fx of this.i0) {
2598
+ const fiber: Fiber.RuntimeFiber<never, unknown> = yield* _(Effect.fork(fx.run(Sink.make(
2599
+ sink.onFailure,
2600
+ (a) => Effect.flatMap(Deferred.succeed(winner, fiber), () => sink.onSuccess(a))
2601
+ ))))
2602
+ fibers.push(fiber)
2603
+ }
2042
2604
 
2043
- private cached: Effect.Effect<R, E, B> | null = null
2605
+ const winningFiber = yield* _(Deferred.await(winner))
2044
2606
 
2045
- commit(): Effect.Effect<R, E, B> {
2046
- return this.cached ||= Effect.suspend(() => {
2047
- let acc = this.i1
2607
+ yield* _(Fiber.interruptAll(fibers.filter((x) => x !== winningFiber)))
2048
2608
 
2049
- return Effect.map(
2050
- observe(this.i0, (a) =>
2051
- Option.match(this.i2(acc, a), {
2052
- onNone: () => Effect.unit,
2053
- onSome: (b) => Effect.succeed(acc = b)
2054
- })),
2055
- () => acc
2056
- )
2609
+ return yield* _(Fiber.join(winningFiber))
2057
2610
  })
2058
2611
  }
2059
2612
  }
2060
2613
 
2061
- function reduceFilterIterable<A, B>(
2062
- iterable: Iterable<A>,
2063
- seed: B,
2064
- f: (acc: B, a: A) => Option.Option<B>
2065
- ): B {
2066
- const iterator = iterable[Symbol.iterator]()
2067
- let acc = seed
2068
- let result = iterator.next()
2069
- let option: Option.Option<B> = Option.none()
2070
-
2071
- while (!result.done) {
2072
- option = f(acc, result.value)
2073
- if (Option.isSome(option)) {
2074
- acc = option.value
2075
- }
2076
- result = iterator.next()
2077
- }
2078
-
2079
- return acc
2614
+ export function snapshot<R, E, A, R2, E2, B, C>(
2615
+ fx: Fx<R, E, A>,
2616
+ sampled: Fx<R2, E2, B>,
2617
+ f: (a: A, b: B) => C
2618
+ ): Fx<R | R2, E | E2, C> {
2619
+ return new Snapshot(fx, sampled, f)
2080
2620
  }
2081
2621
 
2082
- function reduceFilterArray<A, B>(
2083
- iterable: Array<A>,
2084
- seed: B,
2085
- f: (acc: B, a: A) => Option.Option<B>
2086
- ): B {
2087
- const length = iterable.length
2088
- let acc = seed
2089
- let option: Option.Option<B> = Option.none()
2090
-
2091
- for (let i = 0; i < length; i++) {
2092
- option = f(acc, iterable[i])
2093
- if (Option.isSome(option)) {
2094
- acc = option.value
2095
- }
2096
- }
2097
-
2098
- return acc
2622
+ export function sample<R, E, A, R2, E2, B>(
2623
+ fx: Fx<R, E, A>,
2624
+ sampled: Fx<R2, E2, B>
2625
+ ): Fx<R | R2, E | E2, B> {
2626
+ return snapshot(fx, sampled, (_, b) => b)
2099
2627
  }
2100
2628
 
2101
- export const reduce: {
2102
- <A, B>(seed: B, f: (acc: B, a: A) => B): <R, E>(fx: Fx<R, E, A>) => Effect.Effect<R, E, B>
2103
- <R, E, A, B>(fx: Fx<R, E, A>, seed: B, f: (acc: B, a: A) => B): Effect.Effect<R, E, B>
2104
- } = dual(3, function reduce<R, E, A, B>(
2105
- fx: Fx<R, E, A>,
2106
- seed: B,
2107
- f: (acc: B, a: A) => B
2108
- ): Effect.Effect<R, E, B> {
2109
- return Reduce.make(fx, seed, f)
2110
- })
2629
+ class Snapshot<R, E, A, R2, E2, B, C> extends FxBase<R | R2, E | E2, C> {
2630
+ constructor(
2631
+ readonly i0: Fx<R, E, A>,
2632
+ readonly i1: Fx<R2, E2, B>,
2633
+ readonly i2: (a: A, b: B) => C
2634
+ ) {
2635
+ super()
2636
+ }
2111
2637
 
2112
- export function toChunk<R, E, A>(fx: Fx<R, E, A>): Effect.Effect<R, E, Chunk.Chunk<A>> {
2113
- return reduce(fx, Chunk.empty<A>(), Chunk.append<A, A>)
2638
+ run<R3>(sink: Sink.Sink<R3, E | E2, C>): Effect.Effect<R | R2 | R3, never, unknown> {
2639
+ return Effect.flatMap(
2640
+ Ref.make(Option.none<B>()),
2641
+ (ref) =>
2642
+ Effect.all([
2643
+ this.i1.run(Sink.make(
2644
+ sink.onFailure,
2645
+ (b) => Ref.set(ref, Option.some(b))
2646
+ )),
2647
+ this.i0.run(Sink.make(
2648
+ sink.onFailure,
2649
+ (a) =>
2650
+ Effect.flatMap(
2651
+ Ref.get(ref),
2652
+ Option.match({
2653
+ onNone: () => Effect.unit,
2654
+ onSome: (b) => sink.onSuccess(this.i2(a, b))
2655
+ })
2656
+ )
2657
+ ))
2658
+ ], UNBOUNDED)
2659
+ )
2660
+ }
2114
2661
  }
2115
2662
 
2116
- export const snapshot: {
2117
- <R2, E2, B, A, R3, E3, C>(
2118
- sampled: FxInput<R2, E2, B>,
2119
- f: (a: A, b: B) => Effect.Effect<R3, E3, C>
2120
- ): <R, E>(fx: Fx<R, E, A>) => Fx<R | R2 | R3, E | E2 | E3, C>
2121
- <R, E, A, R2, E2, B, R3, E3, C>(
2122
- fx: Fx<R, E, A>,
2123
- sampled: FxInput<R2, E2, B>,
2124
- f: (a: A, b: B) => Effect.Effect<R3, E3, C>
2125
- ): Fx<R | R2 | R3, E | E2 | E3, C>
2126
- } = dual(3, function snapshot<R, E, A, R2, E2, B, R3, E3, C>(
2663
+ export function snapshotEffect<R, E, A, R2, E2, B, R3, E3, C>(
2127
2664
  fx: Fx<R, E, A>,
2128
2665
  sampled: Fx<R2, E2, B>,
2129
2666
  f: (a: A, b: B) => Effect.Effect<R3, E3, C>
2130
2667
  ): Fx<R | R2 | R3, E | E2 | E3, C> {
2131
- return new Snapshot(fx, sampled, f)
2132
- })
2133
-
2134
- export function fromEmitter<R, E, A>(
2135
- f: (emitter: Emitter.Emitter<E, A>) => Effect.Effect<R | Scope.Scope, never, unknown>
2136
- ): Fx<Exclude<R, Scope.Scope>, E, A> {
2137
- return withEarlyExit(({ scope, sink }) =>
2138
- Effect.zipRight(Effect.provideService(Effect.flatMap(Emitter.make(sink), f), Scope.Scope, scope), Effect.never)
2139
- )
2668
+ return new SnapshotEffect(fx, sampled, f)
2140
2669
  }
2141
2670
 
2142
- export function fromEffect<R, E, A>(effect: Effect.Effect<R, E, A>): Fx<R, E, A> {
2143
- return matchEffectPrimitive<Fx<R, E, A>>(effect as InternalEffect, {
2144
- Success: (e) => succeed(e.i0 as A),
2145
- Failure: (e) => failCause(e.i0 as Cause.Cause<E>),
2146
- Left: (e) => fail(e.left as E),
2147
- Right: (e) => succeed(e.right as A),
2148
- None: () => fail(new Cause.NoSuchElementException() as E),
2149
- Some: (e) => succeed(e.value),
2150
- Sync: (e) => sync(e.i0 as () => A),
2151
- Otherwise: () => fromSink((sink) => Effect.matchCauseEffect(effect, sink))
2152
- })
2153
- }
2671
+ class SnapshotEffect<R, E, A, R2, E2, B, R3, E3, C> extends FxBase<R | R2 | R3, E | E2 | E3, C> {
2672
+ constructor(
2673
+ readonly i0: Fx<R, E, A>,
2674
+ readonly i1: Fx<R2, E2, B>,
2675
+ readonly i2: (a: A, b: B) => Effect.Effect<R3, E3, C>
2676
+ ) {
2677
+ super()
2678
+ }
2154
2679
 
2155
- export function fromStream<R, E, A>(stream: Stream.Stream<R, E, A>, options?: { priority?: number }): Fx<R, E, A> {
2156
- return fromSink<R, E, A>((sink) =>
2157
- Effect.acquireUseRelease<never, never, Scope.CloseableScope, R, never, unknown, never, unknown>(
2158
- Scope.make(),
2159
- (scope) =>
2160
- Effect.gen(function*(_) {
2161
- const pull = Effect.either(yield* _(Stream.toPull(stream), Effect.provideService(Scope.Scope, scope)))
2162
-
2163
- while (true) {
2164
- const either = yield* _(pull)
2165
-
2166
- if (Either.isRight(either)) {
2167
- yield* _(Effect.forEach(either.right, sink.onSuccess))
2168
- } else if (Option.isNone(either.left)) {
2169
- return
2170
- } else {
2171
- yield* _(sink.onFailure(Cause.fail(either.left.value)))
2172
- }
2173
-
2174
- // Schedule subsequent pulls using the current scheduler.
2175
- yield* _(Effect.yieldNow(options))
2176
- }
2177
- }),
2178
- Scope.close
2680
+ run<R4>(sink: Sink.Sink<R4, E | E2 | E3, C>): Effect.Effect<R | R2 | R3 | R4, never, unknown> {
2681
+ return Effect.flatMap(
2682
+ Ref.make(Option.none<B>()),
2683
+ (ref) =>
2684
+ Effect.flatMap(
2685
+ Effect.tap(
2686
+ Effect.fork(
2687
+ this.i1.run(Sink.make(
2688
+ sink.onFailure,
2689
+ (b) => Ref.set(ref, Option.some(b))
2690
+ ))
2691
+ ),
2692
+ () =>
2693
+ this.i0.run(Sink.make(sink.onFailure, (a) =>
2694
+ Effect.flatMap(
2695
+ Ref.get(ref),
2696
+ Option.match({
2697
+ onNone: () => Effect.unit,
2698
+ onSome: (b) => Effect.matchCauseEffect(this.i2(a, b), sink)
2699
+ })
2700
+ )))
2701
+ ),
2702
+ Fiber.interrupt
2703
+ )
2179
2704
  )
2180
- )
2705
+ }
2706
+ }
2707
+
2708
+ function if_<R, E, R2, E2, B, R3, E3, C>(
2709
+ bool: Fx<R, E, boolean>,
2710
+ options: {
2711
+ readonly onTrue: Fx<R2, E2, B>
2712
+ readonly onFalse: Fx<R3, E3, C>
2713
+ }
2714
+ ): Fx<R | R2 | R3 | Scope.Scope, E | E2 | E3, B | C> {
2715
+ return switchMap(bool, (b): Fx<R2 | R3, E2 | E3, B | C> => b ? options.onTrue : options.onFalse)
2181
2716
  }
2182
2717
 
2183
- const matchers = {
2184
- RefSubject: identity,
2185
- Fx: identity,
2186
- Effect: fromEffect,
2187
- Cause: failCause,
2188
- Iterable: fromIterable,
2189
- Otherwise: succeed
2718
+ export { if_ as if }
2719
+
2720
+ export function when<R, E, B, C>(
2721
+ bool: Fx<R, E, boolean>,
2722
+ options: {
2723
+ readonly onTrue: B
2724
+ readonly onFalse: C
2725
+ }
2726
+ ): Fx<R | Scope.Scope, E, B | C> {
2727
+ return if_(bool, {
2728
+ onTrue: succeed(options.onTrue),
2729
+ onFalse: succeed(options.onFalse)
2730
+ })
2190
2731
  }
2191
2732
 
2192
- export function from<A>(input: Iterable<A>): Fx<never, never, A>
2193
- export function from<E>(input: Cause.Cause<E>): Fx<never, E, never>
2194
- export function from<R, E, A>(input: FxInput<R, E, A>): Fx<R, E, A>
2195
- export function from<A>(input: A): Fx<never, never, A>
2196
- export function from<R, E, A>(input: FxInput<R, E, A>): Fx<R, E, A> {
2197
- return matchFxInput(input, matchers as any)
2733
+ export function mapBoth<R, E, A, B, C>(
2734
+ fx: Fx<R, E, A>,
2735
+ f: (e: E) => B,
2736
+ g: (a: A) => C
2737
+ ): Fx<R, B, C> {
2738
+ return map(mapError(fx, f), g)
2198
2739
  }