effect 3.10.18 → 3.11.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 (448) hide show
  1. package/dist/cjs/Array.js +206 -0
  2. package/dist/cjs/Array.js.map +1 -1
  3. package/dist/cjs/BigDecimal.js +181 -24
  4. package/dist/cjs/BigDecimal.js.map +1 -1
  5. package/dist/cjs/BigInt.js +54 -0
  6. package/dist/cjs/BigInt.js.map +1 -1
  7. package/dist/cjs/Boolean.js +24 -0
  8. package/dist/cjs/Boolean.js.map +1 -1
  9. package/dist/cjs/Brand.js +4 -0
  10. package/dist/cjs/Brand.js.map +1 -1
  11. package/dist/cjs/Channel.js +44 -4
  12. package/dist/cjs/Channel.js.map +1 -1
  13. package/dist/cjs/Chunk.js +8 -0
  14. package/dist/cjs/Chunk.js.map +1 -1
  15. package/dist/cjs/Config.js +10 -1
  16. package/dist/cjs/Config.js.map +1 -1
  17. package/dist/cjs/Context.js +50 -1
  18. package/dist/cjs/Context.js.map +1 -1
  19. package/dist/cjs/Cron.js +81 -67
  20. package/dist/cjs/Cron.js.map +1 -1
  21. package/dist/cjs/Data.js +14 -0
  22. package/dist/cjs/Data.js.map +1 -1
  23. package/dist/cjs/DateTime.js +178 -664
  24. package/dist/cjs/DateTime.js.map +1 -1
  25. package/dist/cjs/Duration.js +2 -0
  26. package/dist/cjs/Duration.js.map +1 -1
  27. package/dist/cjs/Effect.js +296 -4
  28. package/dist/cjs/Effect.js.map +1 -1
  29. package/dist/cjs/Either.js +38 -2
  30. package/dist/cjs/Either.js.map +1 -1
  31. package/dist/cjs/FiberHandle.js +6 -0
  32. package/dist/cjs/FiberHandle.js.map +1 -1
  33. package/dist/cjs/FiberMap.js +6 -0
  34. package/dist/cjs/FiberMap.js.map +1 -1
  35. package/dist/cjs/FiberSet.js +6 -0
  36. package/dist/cjs/FiberSet.js.map +1 -1
  37. package/dist/cjs/Function.js +34 -0
  38. package/dist/cjs/Function.js.map +1 -1
  39. package/dist/cjs/GlobalValue.js +2 -0
  40. package/dist/cjs/GlobalValue.js.map +1 -1
  41. package/dist/cjs/HashMap.js.map +1 -1
  42. package/dist/cjs/Inspectable.js +8 -4
  43. package/dist/cjs/Inspectable.js.map +1 -1
  44. package/dist/cjs/Iterable.js +18 -0
  45. package/dist/cjs/Iterable.js.map +1 -1
  46. package/dist/cjs/JSONSchema.js.map +1 -1
  47. package/dist/cjs/List.js +4 -0
  48. package/dist/cjs/List.js.map +1 -1
  49. package/dist/cjs/Logger.js +26 -0
  50. package/dist/cjs/Logger.js.map +1 -1
  51. package/dist/cjs/Mailbox.js +2 -0
  52. package/dist/cjs/Mailbox.js.map +1 -1
  53. package/dist/cjs/ManagedRuntime.js +2 -0
  54. package/dist/cjs/ManagedRuntime.js.map +1 -1
  55. package/dist/cjs/Metric.js +10 -0
  56. package/dist/cjs/Metric.js.map +1 -1
  57. package/dist/cjs/Micro.js +1104 -1069
  58. package/dist/cjs/Micro.js.map +1 -1
  59. package/dist/cjs/Number.js +44 -0
  60. package/dist/cjs/Number.js.map +1 -1
  61. package/dist/cjs/Option.js +70 -0
  62. package/dist/cjs/Option.js.map +1 -1
  63. package/dist/cjs/Order.js +2 -0
  64. package/dist/cjs/Order.js.map +1 -1
  65. package/dist/cjs/Ordering.js +4 -0
  66. package/dist/cjs/Ordering.js.map +1 -1
  67. package/dist/cjs/Predicate.js +68 -0
  68. package/dist/cjs/Predicate.js.map +1 -1
  69. package/dist/cjs/Random.js +4 -0
  70. package/dist/cjs/Random.js.map +1 -1
  71. package/dist/cjs/RateLimiter.js +4 -0
  72. package/dist/cjs/RateLimiter.js.map +1 -1
  73. package/dist/cjs/RcMap.js +2 -0
  74. package/dist/cjs/RcMap.js.map +1 -1
  75. package/dist/cjs/RcRef.js +2 -0
  76. package/dist/cjs/RcRef.js.map +1 -1
  77. package/dist/cjs/Record.js +56 -0
  78. package/dist/cjs/Record.js.map +1 -1
  79. package/dist/cjs/Redacted.js +8 -0
  80. package/dist/cjs/Redacted.js.map +1 -1
  81. package/dist/cjs/RegExp.js +4 -0
  82. package/dist/cjs/RegExp.js.map +1 -1
  83. package/dist/cjs/Request.js +4 -0
  84. package/dist/cjs/Request.js.map +1 -1
  85. package/dist/cjs/RequestResolver.js +2 -0
  86. package/dist/cjs/RequestResolver.js.map +1 -1
  87. package/dist/cjs/Runtime.js +6 -0
  88. package/dist/cjs/Runtime.js.map +1 -1
  89. package/dist/cjs/STM.js.map +1 -1
  90. package/dist/cjs/Schema.js +91 -8
  91. package/dist/cjs/Schema.js.map +1 -1
  92. package/dist/cjs/Sink.js +9 -1
  93. package/dist/cjs/Sink.js.map +1 -1
  94. package/dist/cjs/Stream.js +179 -7
  95. package/dist/cjs/Stream.js.map +1 -1
  96. package/dist/cjs/String.js +62 -0
  97. package/dist/cjs/String.js.map +1 -1
  98. package/dist/cjs/Struct.js +12 -0
  99. package/dist/cjs/Struct.js.map +1 -1
  100. package/dist/cjs/Symbol.js +2 -0
  101. package/dist/cjs/Symbol.js.map +1 -1
  102. package/dist/cjs/Trie.js +56 -0
  103. package/dist/cjs/Trie.js.map +1 -1
  104. package/dist/cjs/Tuple.js +18 -0
  105. package/dist/cjs/Tuple.js.map +1 -1
  106. package/dist/cjs/Utils.js +7 -1
  107. package/dist/cjs/Utils.js.map +1 -1
  108. package/dist/cjs/internal/channel/channelExecutor.js +5 -9
  109. package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
  110. package/dist/cjs/internal/channel.js +156 -130
  111. package/dist/cjs/internal/channel.js.map +1 -1
  112. package/dist/cjs/internal/config.js +13 -4
  113. package/dist/cjs/internal/config.js.map +1 -1
  114. package/dist/cjs/internal/context.js +46 -3
  115. package/dist/cjs/internal/context.js.map +1 -1
  116. package/dist/cjs/internal/dateTime.js +747 -0
  117. package/dist/cjs/internal/dateTime.js.map +1 -0
  118. package/dist/cjs/internal/fiberRuntime.js +34 -11
  119. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  120. package/dist/cjs/internal/groupBy.js +9 -3
  121. package/dist/cjs/internal/groupBy.js.map +1 -1
  122. package/dist/cjs/internal/layer.js +1 -1
  123. package/dist/cjs/internal/layer.js.map +1 -1
  124. package/dist/cjs/internal/mailbox.js +1 -1
  125. package/dist/cjs/internal/mailbox.js.map +1 -1
  126. package/dist/cjs/internal/sink.js +25 -21
  127. package/dist/cjs/internal/sink.js.map +1 -1
  128. package/dist/cjs/internal/stream.js +70 -71
  129. package/dist/cjs/internal/stream.js.map +1 -1
  130. package/dist/cjs/internal/version.js +1 -1
  131. package/dist/cjs/internal/version.js.map +1 -1
  132. package/dist/dts/Array.d.ts +534 -0
  133. package/dist/dts/Array.d.ts.map +1 -1
  134. package/dist/dts/BigDecimal.d.ts +172 -1
  135. package/dist/dts/BigDecimal.d.ts.map +1 -1
  136. package/dist/dts/BigInt.d.ts +114 -0
  137. package/dist/dts/BigInt.d.ts.map +1 -1
  138. package/dist/dts/Boolean.d.ts +56 -0
  139. package/dist/dts/Boolean.d.ts.map +1 -1
  140. package/dist/dts/Brand.d.ts +6 -0
  141. package/dist/dts/Brand.d.ts.map +1 -1
  142. package/dist/dts/Channel.d.ts +66 -5
  143. package/dist/dts/Channel.d.ts.map +1 -1
  144. package/dist/dts/Chunk.d.ts +30 -0
  145. package/dist/dts/Chunk.d.ts.map +1 -1
  146. package/dist/dts/Config.d.ts +25 -1
  147. package/dist/dts/Config.d.ts.map +1 -1
  148. package/dist/dts/Context.d.ts +155 -0
  149. package/dist/dts/Context.d.ts.map +1 -1
  150. package/dist/dts/Cron.d.ts +21 -6
  151. package/dist/dts/Cron.d.ts.map +1 -1
  152. package/dist/dts/Data.d.ts +26 -0
  153. package/dist/dts/Data.d.ts.map +1 -1
  154. package/dist/dts/DateTime.d.ts +192 -49
  155. package/dist/dts/DateTime.d.ts.map +1 -1
  156. package/dist/dts/Duration.d.ts +2 -0
  157. package/dist/dts/Duration.d.ts.map +1 -1
  158. package/dist/dts/Effect.d.ts +658 -1
  159. package/dist/dts/Effect.d.ts.map +1 -1
  160. package/dist/dts/Either.d.ts +84 -2
  161. package/dist/dts/Either.d.ts.map +1 -1
  162. package/dist/dts/FiberHandle.d.ts +6 -0
  163. package/dist/dts/FiberHandle.d.ts.map +1 -1
  164. package/dist/dts/FiberMap.d.ts +6 -0
  165. package/dist/dts/FiberMap.d.ts.map +1 -1
  166. package/dist/dts/FiberSet.d.ts +6 -0
  167. package/dist/dts/FiberSet.d.ts.map +1 -1
  168. package/dist/dts/Function.d.ts +50 -0
  169. package/dist/dts/Function.d.ts.map +1 -1
  170. package/dist/dts/GlobalValue.d.ts +2 -0
  171. package/dist/dts/GlobalValue.d.ts.map +1 -1
  172. package/dist/dts/HashMap.d.ts +6 -0
  173. package/dist/dts/HashMap.d.ts.map +1 -1
  174. package/dist/dts/Inspectable.d.ts.map +1 -1
  175. package/dist/dts/Iterable.d.ts +26 -0
  176. package/dist/dts/Iterable.d.ts.map +1 -1
  177. package/dist/dts/JSONSchema.d.ts +1 -0
  178. package/dist/dts/JSONSchema.d.ts.map +1 -1
  179. package/dist/dts/List.d.ts +20 -0
  180. package/dist/dts/List.d.ts.map +1 -1
  181. package/dist/dts/Logger.d.ts +34 -0
  182. package/dist/dts/Logger.d.ts.map +1 -1
  183. package/dist/dts/Mailbox.d.ts +2 -0
  184. package/dist/dts/Mailbox.d.ts.map +1 -1
  185. package/dist/dts/ManagedRuntime.d.ts +2 -0
  186. package/dist/dts/ManagedRuntime.d.ts.map +1 -1
  187. package/dist/dts/Metric.d.ts +18 -0
  188. package/dist/dts/Metric.d.ts.map +1 -1
  189. package/dist/dts/Micro.d.ts +880 -863
  190. package/dist/dts/Micro.d.ts.map +1 -1
  191. package/dist/dts/Number.d.ts +104 -0
  192. package/dist/dts/Number.d.ts.map +1 -1
  193. package/dist/dts/Option.d.ts +142 -0
  194. package/dist/dts/Option.d.ts.map +1 -1
  195. package/dist/dts/Order.d.ts +2 -0
  196. package/dist/dts/Order.d.ts.map +1 -1
  197. package/dist/dts/Ordering.d.ts +8 -0
  198. package/dist/dts/Ordering.d.ts.map +1 -1
  199. package/dist/dts/Predicate.d.ts +104 -0
  200. package/dist/dts/Predicate.d.ts.map +1 -1
  201. package/dist/dts/Random.d.ts +4 -0
  202. package/dist/dts/Random.d.ts.map +1 -1
  203. package/dist/dts/RateLimiter.d.ts +4 -0
  204. package/dist/dts/RateLimiter.d.ts.map +1 -1
  205. package/dist/dts/RcMap.d.ts +6 -0
  206. package/dist/dts/RcMap.d.ts.map +1 -1
  207. package/dist/dts/RcRef.d.ts +2 -0
  208. package/dist/dts/RcRef.d.ts.map +1 -1
  209. package/dist/dts/Record.d.ts +136 -0
  210. package/dist/dts/Record.d.ts.map +1 -1
  211. package/dist/dts/Redacted.d.ts +8 -0
  212. package/dist/dts/Redacted.d.ts.map +1 -1
  213. package/dist/dts/RegExp.d.ts +4 -0
  214. package/dist/dts/RegExp.d.ts.map +1 -1
  215. package/dist/dts/Request.d.ts +4 -0
  216. package/dist/dts/Request.d.ts.map +1 -1
  217. package/dist/dts/RequestResolver.d.ts +6 -0
  218. package/dist/dts/RequestResolver.d.ts.map +1 -1
  219. package/dist/dts/Runtime.d.ts +18 -0
  220. package/dist/dts/Runtime.d.ts.map +1 -1
  221. package/dist/dts/STM.d.ts +2 -0
  222. package/dist/dts/STM.d.ts.map +1 -1
  223. package/dist/dts/Schema.d.ts +90 -0
  224. package/dist/dts/Schema.d.ts.map +1 -1
  225. package/dist/dts/Sink.d.ts +8 -0
  226. package/dist/dts/Sink.d.ts.map +1 -1
  227. package/dist/dts/Stream.d.ts +394 -32
  228. package/dist/dts/Stream.d.ts.map +1 -1
  229. package/dist/dts/String.d.ts +94 -0
  230. package/dist/dts/String.d.ts.map +1 -1
  231. package/dist/dts/Struct.d.ts +24 -0
  232. package/dist/dts/Struct.d.ts.map +1 -1
  233. package/dist/dts/Symbol.d.ts +2 -0
  234. package/dist/dts/Symbol.d.ts.map +1 -1
  235. package/dist/dts/Trie.d.ts +132 -0
  236. package/dist/dts/Trie.d.ts.map +1 -1
  237. package/dist/dts/Tuple.d.ts +42 -0
  238. package/dist/dts/Tuple.d.ts.map +1 -1
  239. package/dist/dts/Types.d.ts +24 -0
  240. package/dist/dts/Types.d.ts.map +1 -1
  241. package/dist/dts/Utils.d.ts +4 -0
  242. package/dist/dts/Utils.d.ts.map +1 -1
  243. package/dist/dts/internal/context.d.ts +1 -1
  244. package/dist/dts/internal/context.d.ts.map +1 -1
  245. package/dist/dts/internal/dateTime.d.ts +2 -0
  246. package/dist/dts/internal/dateTime.d.ts.map +1 -0
  247. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  248. package/dist/dts/internal/stream.d.ts.map +1 -1
  249. package/dist/esm/Array.js +208 -0
  250. package/dist/esm/Array.js.map +1 -1
  251. package/dist/esm/BigDecimal.js +175 -20
  252. package/dist/esm/BigDecimal.js.map +1 -1
  253. package/dist/esm/BigInt.js +54 -0
  254. package/dist/esm/BigInt.js.map +1 -1
  255. package/dist/esm/Boolean.js +24 -0
  256. package/dist/esm/Boolean.js.map +1 -1
  257. package/dist/esm/Brand.js +4 -0
  258. package/dist/esm/Brand.js.map +1 -1
  259. package/dist/esm/Channel.js +42 -2
  260. package/dist/esm/Channel.js.map +1 -1
  261. package/dist/esm/Chunk.js +8 -0
  262. package/dist/esm/Chunk.js.map +1 -1
  263. package/dist/esm/Config.js +9 -0
  264. package/dist/esm/Config.js.map +1 -1
  265. package/dist/esm/Context.js +49 -0
  266. package/dist/esm/Context.js.map +1 -1
  267. package/dist/esm/Cron.js +81 -67
  268. package/dist/esm/Cron.js.map +1 -1
  269. package/dist/esm/Data.js +16 -0
  270. package/dist/esm/Data.js.map +1 -1
  271. package/dist/esm/DateTime.js +176 -627
  272. package/dist/esm/DateTime.js.map +1 -1
  273. package/dist/esm/Duration.js +2 -0
  274. package/dist/esm/Duration.js.map +1 -1
  275. package/dist/esm/Effect.js +297 -0
  276. package/dist/esm/Effect.js.map +1 -1
  277. package/dist/esm/Either.js +40 -2
  278. package/dist/esm/Either.js.map +1 -1
  279. package/dist/esm/FiberHandle.js +6 -0
  280. package/dist/esm/FiberHandle.js.map +1 -1
  281. package/dist/esm/FiberMap.js +6 -0
  282. package/dist/esm/FiberMap.js.map +1 -1
  283. package/dist/esm/FiberSet.js +6 -0
  284. package/dist/esm/FiberSet.js.map +1 -1
  285. package/dist/esm/Function.js +34 -0
  286. package/dist/esm/Function.js.map +1 -1
  287. package/dist/esm/GlobalValue.js +2 -0
  288. package/dist/esm/GlobalValue.js.map +1 -1
  289. package/dist/esm/HashMap.js.map +1 -1
  290. package/dist/esm/Inspectable.js +8 -4
  291. package/dist/esm/Inspectable.js.map +1 -1
  292. package/dist/esm/Iterable.js +18 -0
  293. package/dist/esm/Iterable.js.map +1 -1
  294. package/dist/esm/JSONSchema.js.map +1 -1
  295. package/dist/esm/List.js +4 -0
  296. package/dist/esm/List.js.map +1 -1
  297. package/dist/esm/Logger.js +26 -0
  298. package/dist/esm/Logger.js.map +1 -1
  299. package/dist/esm/Mailbox.js +2 -0
  300. package/dist/esm/Mailbox.js.map +1 -1
  301. package/dist/esm/ManagedRuntime.js +2 -0
  302. package/dist/esm/ManagedRuntime.js.map +1 -1
  303. package/dist/esm/Metric.js +10 -0
  304. package/dist/esm/Metric.js.map +1 -1
  305. package/dist/esm/Micro.js +1077 -1037
  306. package/dist/esm/Micro.js.map +1 -1
  307. package/dist/esm/Number.js +44 -0
  308. package/dist/esm/Number.js.map +1 -1
  309. package/dist/esm/Option.js +72 -0
  310. package/dist/esm/Option.js.map +1 -1
  311. package/dist/esm/Order.js +2 -0
  312. package/dist/esm/Order.js.map +1 -1
  313. package/dist/esm/Ordering.js +4 -0
  314. package/dist/esm/Ordering.js.map +1 -1
  315. package/dist/esm/Predicate.js +68 -0
  316. package/dist/esm/Predicate.js.map +1 -1
  317. package/dist/esm/Random.js +4 -0
  318. package/dist/esm/Random.js.map +1 -1
  319. package/dist/esm/RateLimiter.js +4 -0
  320. package/dist/esm/RateLimiter.js.map +1 -1
  321. package/dist/esm/RcMap.js +2 -0
  322. package/dist/esm/RcMap.js.map +1 -1
  323. package/dist/esm/RcRef.js +2 -0
  324. package/dist/esm/RcRef.js.map +1 -1
  325. package/dist/esm/Record.js +56 -0
  326. package/dist/esm/Record.js.map +1 -1
  327. package/dist/esm/Redacted.js +8 -0
  328. package/dist/esm/Redacted.js.map +1 -1
  329. package/dist/esm/RegExp.js +4 -0
  330. package/dist/esm/RegExp.js.map +1 -1
  331. package/dist/esm/Request.js +4 -0
  332. package/dist/esm/Request.js.map +1 -1
  333. package/dist/esm/RequestResolver.js +2 -0
  334. package/dist/esm/RequestResolver.js.map +1 -1
  335. package/dist/esm/Runtime.js +6 -0
  336. package/dist/esm/Runtime.js.map +1 -1
  337. package/dist/esm/STM.js.map +1 -1
  338. package/dist/esm/Schema.js +88 -0
  339. package/dist/esm/Schema.js.map +1 -1
  340. package/dist/esm/Sink.js +8 -0
  341. package/dist/esm/Sink.js.map +1 -1
  342. package/dist/esm/Stream.js +183 -5
  343. package/dist/esm/Stream.js.map +1 -1
  344. package/dist/esm/String.js +62 -0
  345. package/dist/esm/String.js.map +1 -1
  346. package/dist/esm/Struct.js +12 -0
  347. package/dist/esm/Struct.js.map +1 -1
  348. package/dist/esm/Symbol.js +2 -0
  349. package/dist/esm/Symbol.js.map +1 -1
  350. package/dist/esm/Trie.js +56 -0
  351. package/dist/esm/Trie.js.map +1 -1
  352. package/dist/esm/Tuple.js +22 -0
  353. package/dist/esm/Tuple.js.map +1 -1
  354. package/dist/esm/Utils.js +5 -0
  355. package/dist/esm/Utils.js.map +1 -1
  356. package/dist/esm/internal/channel/channelExecutor.js +5 -7
  357. package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
  358. package/dist/esm/internal/channel.js +152 -129
  359. package/dist/esm/internal/channel.js.map +1 -1
  360. package/dist/esm/internal/config.js +11 -3
  361. package/dist/esm/internal/config.js.map +1 -1
  362. package/dist/esm/internal/context.js +42 -2
  363. package/dist/esm/internal/context.js.map +1 -1
  364. package/dist/esm/internal/dateTime.js +704 -0
  365. package/dist/esm/internal/dateTime.js.map +1 -0
  366. package/dist/esm/internal/fiberRuntime.js +31 -9
  367. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  368. package/dist/esm/internal/groupBy.js +9 -3
  369. package/dist/esm/internal/groupBy.js.map +1 -1
  370. package/dist/esm/internal/layer.js +1 -1
  371. package/dist/esm/internal/layer.js.map +1 -1
  372. package/dist/esm/internal/mailbox.js +1 -1
  373. package/dist/esm/internal/mailbox.js.map +1 -1
  374. package/dist/esm/internal/sink.js +23 -20
  375. package/dist/esm/internal/sink.js.map +1 -1
  376. package/dist/esm/internal/stream.js +66 -69
  377. package/dist/esm/internal/stream.js.map +1 -1
  378. package/dist/esm/internal/version.js +1 -1
  379. package/dist/esm/internal/version.js.map +1 -1
  380. package/package.json +1 -1
  381. package/src/Array.ts +534 -0
  382. package/src/BigDecimal.ts +247 -21
  383. package/src/BigInt.ts +114 -0
  384. package/src/Boolean.ts +56 -0
  385. package/src/Brand.ts +6 -0
  386. package/src/Channel.ts +81 -5
  387. package/src/Chunk.ts +32 -0
  388. package/src/Config.ts +26 -1
  389. package/src/Context.ts +163 -0
  390. package/src/Cron.ts +91 -68
  391. package/src/Data.ts +26 -0
  392. package/src/DateTime.ts +307 -757
  393. package/src/Duration.ts +2 -0
  394. package/src/Effect.ts +910 -1
  395. package/src/Either.ts +84 -2
  396. package/src/FiberHandle.ts +6 -0
  397. package/src/FiberMap.ts +6 -0
  398. package/src/FiberSet.ts +6 -0
  399. package/src/Function.ts +50 -0
  400. package/src/GlobalValue.ts +2 -0
  401. package/src/HashMap.ts +6 -0
  402. package/src/Inspectable.ts +11 -7
  403. package/src/Iterable.ts +26 -0
  404. package/src/JSONSchema.ts +1 -0
  405. package/src/List.ts +24 -0
  406. package/src/Logger.ts +34 -0
  407. package/src/Mailbox.ts +2 -0
  408. package/src/ManagedRuntime.ts +2 -0
  409. package/src/Metric.ts +18 -0
  410. package/src/Micro.ts +2007 -1745
  411. package/src/Number.ts +104 -0
  412. package/src/Option.ts +142 -0
  413. package/src/Order.ts +2 -0
  414. package/src/Ordering.ts +8 -0
  415. package/src/Predicate.ts +104 -0
  416. package/src/Random.ts +4 -0
  417. package/src/RateLimiter.ts +4 -0
  418. package/src/RcMap.ts +6 -0
  419. package/src/RcRef.ts +2 -0
  420. package/src/Record.ts +136 -0
  421. package/src/Redacted.ts +8 -0
  422. package/src/RegExp.ts +4 -0
  423. package/src/Request.ts +4 -0
  424. package/src/RequestResolver.ts +6 -0
  425. package/src/Runtime.ts +18 -0
  426. package/src/STM.ts +2 -0
  427. package/src/Schema.ts +124 -0
  428. package/src/Sink.ts +11 -0
  429. package/src/Stream.ts +399 -44
  430. package/src/String.ts +94 -0
  431. package/src/Struct.ts +24 -0
  432. package/src/Symbol.ts +2 -0
  433. package/src/Trie.ts +132 -0
  434. package/src/Tuple.ts +42 -0
  435. package/src/Types.ts +24 -0
  436. package/src/Utils.ts +8 -0
  437. package/src/internal/channel/channelExecutor.ts +37 -33
  438. package/src/internal/channel.ts +504 -467
  439. package/src/internal/config.ts +18 -6
  440. package/src/internal/context.ts +56 -4
  441. package/src/internal/dateTime.ts +1126 -0
  442. package/src/internal/fiberRuntime.ts +35 -16
  443. package/src/internal/groupBy.ts +13 -22
  444. package/src/internal/layer.ts +5 -8
  445. package/src/internal/mailbox.ts +6 -4
  446. package/src/internal/sink.ts +55 -35
  447. package/src/internal/stream.ts +299 -299
  448. package/src/internal/version.ts +1 -1
package/dist/esm/Micro.js CHANGED
@@ -1,16 +1,25 @@
1
+ /**
2
+ * A lightweight alternative to the `Effect` data type, with a subset of the functionality.
3
+ *
4
+ * @since 3.4.0
5
+ * @experimental
6
+ */
7
+ import * as Arr from "effect/Array";
1
8
  import * as Context from "./Context.js";
2
9
  import * as Effectable from "./Effectable.js";
3
10
  import * as Either from "./Either.js";
11
+ import * as Equal from "./Equal.js";
4
12
  import { constTrue, constVoid, dual, identity } from "./Function.js";
5
13
  import { globalValue } from "./GlobalValue.js";
6
- import { NodeInspectSymbol, toStringUnknown } from "./Inspectable.js";
14
+ import * as Hash from "./Hash.js";
15
+ import { format, NodeInspectSymbol, toStringUnknown } from "./Inspectable.js";
16
+ import * as InternalContext from "./internal/context.js";
7
17
  import * as doNotation from "./internal/doNotation.js";
8
18
  import { StructuralPrototype } from "./internal/effectable.js";
9
- import { SingleShotGen } from "./internal/singleShotGen.js";
10
19
  import * as Option from "./Option.js";
11
20
  import { pipeArguments } from "./Pipeable.js";
12
21
  import { hasProperty, isIterable, isTagged } from "./Predicate.js";
13
- import { YieldWrap, yieldWrapGet } from "./Utils.js";
22
+ import { SingleShotGen, YieldWrap, yieldWrapGet } from "./Utils.js";
14
23
  /**
15
24
  * @since 3.4.0
16
25
  * @experimental
@@ -20,9 +29,9 @@ export const TypeId = /*#__PURE__*/Symbol.for("effect/Micro");
20
29
  /**
21
30
  * @since 3.4.0
22
31
  * @experimental
23
- * @category symbols
32
+ * @category MicroExit
24
33
  */
25
- export const runSymbol = /*#__PURE__*/Symbol.for("effect/Micro/runSymbol");
34
+ export const MicroExitTypeId = /*#__PURE__*/Symbol.for("effect/Micro/MicroExit");
26
35
  /**
27
36
  * @since 3.4.0
28
37
  * @experimental
@@ -30,40 +39,6 @@ export const runSymbol = /*#__PURE__*/Symbol.for("effect/Micro/runSymbol");
30
39
  */
31
40
  export const isMicro = u => typeof u === "object" && u !== null && TypeId in u;
32
41
  // ----------------------------------------------------------------------------
33
- // Microable
34
- // ----------------------------------------------------------------------------
35
- const MicroProto = {
36
- ...Effectable.EffectPrototype,
37
- _op: "Micro",
38
- [TypeId]: {
39
- _A: identity,
40
- _E: identity,
41
- _R: identity
42
- },
43
- [Symbol.iterator]() {
44
- return new SingleShotGen(new YieldWrap(this));
45
- }
46
- };
47
- const MicroBase = /*#__PURE__*/function () {
48
- function Base() {}
49
- Base.prototype = MicroProto;
50
- return Base;
51
- }();
52
- /**
53
- * @since 3.8.4
54
- * @experimental
55
- * @category constructors
56
- */
57
- export class Class extends MicroBase {
58
- /**
59
- * @since 3.8.4
60
- * @experimental
61
- */
62
- [runSymbol](env, onExit) {
63
- this.asMicro()[runSymbol](env, onExit);
64
- }
65
- }
66
- // ----------------------------------------------------------------------------
67
42
  // MicroCause
68
43
  // ----------------------------------------------------------------------------
69
44
  /**
@@ -197,970 +172,1102 @@ export const causeWithTrace = /*#__PURE__*/dual(2, (self, trace) => {
197
172
  return causeFail(self.error, traces);
198
173
  }
199
174
  });
175
+ // ----------------------------------------------------------------------------
176
+ // Fiber
177
+ // ----------------------------------------------------------------------------
200
178
  /**
201
- * @since 3.4.6
202
- * @experimental
203
- * @category MicroExit
204
- */
205
- export const exitInterrupt = /*#__PURE__*/Either.left( /*#__PURE__*/causeInterrupt());
206
- /**
207
- * @since 3.4.6
208
- * @experimental
209
- * @category MicroExit
210
- */
211
- export const exitSucceed = Either.right;
212
- /**
213
- * @since 3.4.6
214
- * @experimental
215
- * @category MicroExit
216
- */
217
- export const exitFail = e => Either.left(causeFail(e));
218
- /**
219
- * @since 3.4.6
220
- * @experimental
221
- * @category MicroExit
222
- */
223
- export const exitDie = defect => Either.left(causeDie(defect));
224
- /**
225
- * @since 3.4.6
179
+ * @since 3.11.0
226
180
  * @experimental
227
- * @category MicroExit
181
+ * @category Fiber
228
182
  */
229
- export const exitFailCause = Either.left;
183
+ export const FiberTypeId = /*#__PURE__*/Symbol.for("effect/Micro/Fiber");
184
+ const fiberVariance = {
185
+ _A: identity,
186
+ _E: identity
187
+ };
188
+ class FiberImpl {
189
+ context;
190
+ interruptible;
191
+ [FiberTypeId];
192
+ _stack = [];
193
+ _observers = [];
194
+ _exit;
195
+ _children;
196
+ currentOpCount = 0;
197
+ constructor(context, interruptible = true) {
198
+ this.context = context;
199
+ this.interruptible = interruptible;
200
+ this[FiberTypeId] = fiberVariance;
201
+ }
202
+ getRef(ref) {
203
+ return InternalContext.unsafeGetReference(this.context, ref);
204
+ }
205
+ addObserver(cb) {
206
+ if (this._exit) {
207
+ cb(this._exit);
208
+ return constVoid;
209
+ }
210
+ this._observers.push(cb);
211
+ return () => {
212
+ const index = this._observers.indexOf(cb);
213
+ if (index >= 0) {
214
+ this._observers.splice(index, 1);
215
+ }
216
+ };
217
+ }
218
+ _interrupted = false;
219
+ unsafeInterrupt() {
220
+ if (this._exit) {
221
+ return;
222
+ }
223
+ this._interrupted = true;
224
+ if (this.interruptible) {
225
+ this.evaluate(exitInterrupt);
226
+ }
227
+ }
228
+ unsafePoll() {
229
+ return this._exit;
230
+ }
231
+ evaluate(effect) {
232
+ if (this._exit) {
233
+ return;
234
+ } else if (this._yielded !== undefined) {
235
+ const yielded = this._yielded;
236
+ this._yielded = undefined;
237
+ yielded();
238
+ }
239
+ const exit = this.runLoop(effect);
240
+ if (exit === Yield) {
241
+ return;
242
+ }
243
+ // the interruptChildren middlware is added in Micro.fork, so it can be
244
+ // tree-shaken if not used
245
+ const interruptChildren = fiberMiddleware.interruptChildren && fiberMiddleware.interruptChildren(this);
246
+ if (interruptChildren !== undefined) {
247
+ return this.evaluate(flatMap(interruptChildren, () => exit));
248
+ }
249
+ this._exit = exit;
250
+ for (let i = 0; i < this._observers.length; i++) {
251
+ this._observers[i](exit);
252
+ }
253
+ this._observers.length = 0;
254
+ }
255
+ runLoop(effect) {
256
+ let yielding = false;
257
+ let current = effect;
258
+ this.currentOpCount = 0;
259
+ try {
260
+ while (true) {
261
+ this.currentOpCount++;
262
+ if (!yielding && this.getRef(CurrentScheduler).shouldYield(this)) {
263
+ yielding = true;
264
+ const prev = current;
265
+ current = flatMap(yieldNow, () => prev);
266
+ }
267
+ current = current[evaluate](this);
268
+ if (current === Yield) {
269
+ const yielded = this._yielded;
270
+ if (MicroExitTypeId in yielded) {
271
+ this._yielded = undefined;
272
+ return yielded;
273
+ }
274
+ return Yield;
275
+ }
276
+ }
277
+ } catch (error) {
278
+ if (!hasProperty(current, evaluate)) {
279
+ return exitDie(`Micro/Fiber.runLoop: Not a valid effect: ${String(current)}`);
280
+ }
281
+ return exitDie(error);
282
+ }
283
+ }
284
+ getCont(symbol) {
285
+ while (true) {
286
+ const op = this._stack.pop();
287
+ if (!op) return undefined;
288
+ const cont = op[ensureCont] && op[ensureCont](this);
289
+ if (cont) return {
290
+ [symbol]: cont
291
+ };
292
+ if (op[symbol]) return op;
293
+ }
294
+ }
295
+ // cancel the yielded operation, or for the yielded exit value
296
+ _yielded = undefined;
297
+ yieldWith(value) {
298
+ this._yielded = value;
299
+ return Yield;
300
+ }
301
+ children() {
302
+ return this._children ??= new Set();
303
+ }
304
+ }
305
+ const fiberMiddleware = /*#__PURE__*/globalValue("effect/Micro/fiberMiddleware", () => ({
306
+ interruptChildren: undefined
307
+ }));
308
+ const fiberInterruptChildren = fiber => {
309
+ if (fiber._children === undefined || fiber._children.size === 0) {
310
+ return undefined;
311
+ }
312
+ return fiberInterruptAll(fiber._children);
313
+ };
230
314
  /**
231
- * @since 3.4.6
315
+ * @since 3.11.0
232
316
  * @experimental
233
- * @category MicroExit
317
+ * @category Fiber
234
318
  */
235
- export const exitIsSuccess = Either.isRight;
319
+ export const fiberAwait = self => async(resume => sync(self.addObserver(exit => resume(succeed(exit)))));
236
320
  /**
237
- * @since 3.4.6
321
+ * @since 3.11.0
238
322
  * @experimental
239
- * @category MicroExit
323
+ * @category Fiber
240
324
  */
241
- export const exitIsFailure = Either.isLeft;
325
+ export const fiberInterrupt = self => suspend(() => {
326
+ self.unsafeInterrupt();
327
+ return asVoid(fiberAwait(self));
328
+ });
242
329
  /**
243
- * @since 3.4.6
330
+ * @since 3.11.0
244
331
  * @experimental
245
- * @category MicroExit
332
+ * @category Fiber
246
333
  */
247
- export const exitIsInterrupt = self => exitIsFailure(self) && self.left._tag === "Interrupt";
334
+ export const fiberInterruptAll = fibers => suspend(() => {
335
+ for (const fiber of fibers) fiber.unsafeInterrupt();
336
+ const iter = fibers[Symbol.iterator]();
337
+ const wait = suspend(() => {
338
+ let result = iter.next();
339
+ while (!result.done) {
340
+ if (result.value.unsafePoll()) {
341
+ result = iter.next();
342
+ continue;
343
+ }
344
+ const fiber = result.value;
345
+ return async(resume => {
346
+ fiber.addObserver(_ => {
347
+ resume(wait);
348
+ });
349
+ });
350
+ }
351
+ return exitVoid;
352
+ });
353
+ return wait;
354
+ });
355
+ const identifier = /*#__PURE__*/Symbol.for("effect/Micro/identifier");
356
+ const args = /*#__PURE__*/Symbol.for("effect/Micro/args");
357
+ const evaluate = /*#__PURE__*/Symbol.for("effect/Micro/evaluate");
358
+ const successCont = /*#__PURE__*/Symbol.for("effect/Micro/successCont");
359
+ const failureCont = /*#__PURE__*/Symbol.for("effect/Micro/failureCont");
360
+ const ensureCont = /*#__PURE__*/Symbol.for("effect/Micro/ensureCont");
361
+ const Yield = /*#__PURE__*/Symbol.for("effect/Micro/Yield");
362
+ const microVariance = {
363
+ _A: identity,
364
+ _E: identity,
365
+ _R: identity
366
+ };
367
+ const MicroProto = {
368
+ ...Effectable.EffectPrototype,
369
+ _op: "Micro",
370
+ [TypeId]: microVariance,
371
+ pipe() {
372
+ return pipeArguments(this, arguments);
373
+ },
374
+ [Symbol.iterator]() {
375
+ return new SingleShotGen(new YieldWrap(this));
376
+ },
377
+ toJSON() {
378
+ return {
379
+ _id: "effect/Micro",
380
+ op: this[identifier],
381
+ ...(args in this ? {
382
+ args: this[args]
383
+ } : undefined)
384
+ };
385
+ },
386
+ toString() {
387
+ return format(this);
388
+ },
389
+ [NodeInspectSymbol]() {
390
+ return format(this);
391
+ }
392
+ };
393
+ function defaultEvaluate(_fiber) {
394
+ return exitDie(`Micro.evaluate: Not implemented`);
395
+ }
396
+ const makePrimitiveProto = options => ({
397
+ ...MicroProto,
398
+ [identifier]: options.op,
399
+ [evaluate]: options.eval ?? defaultEvaluate,
400
+ [successCont]: options.contA,
401
+ [failureCont]: options.contE,
402
+ [ensureCont]: options.ensure
403
+ });
404
+ const makePrimitive = options => {
405
+ const Proto = makePrimitiveProto(options);
406
+ return function () {
407
+ const self = Object.create(Proto);
408
+ self[args] = options.single === false ? arguments : arguments[0];
409
+ return self;
410
+ };
411
+ };
412
+ const makeExit = options => {
413
+ const Proto = {
414
+ ...makePrimitiveProto(options),
415
+ [MicroExitTypeId]: MicroExitTypeId,
416
+ _tag: options.op,
417
+ get [options.prop]() {
418
+ return this[args];
419
+ },
420
+ toJSON() {
421
+ return {
422
+ _id: "effect/Micro/Exit",
423
+ _tag: options.op,
424
+ [options.prop]: this[args]
425
+ };
426
+ },
427
+ [Equal.symbol](that) {
428
+ return isMicroExit(that) && that._tag === options.op && Equal.equals(this[args], that[args]);
429
+ },
430
+ [Hash.symbol]() {
431
+ return Hash.cached(this, Hash.combine(Hash.string(options.op))(Hash.hash(this[args])));
432
+ }
433
+ };
434
+ return function (value) {
435
+ const self = Object.create(Proto);
436
+ self[args] = value;
437
+ self[successCont] = undefined;
438
+ self[failureCont] = undefined;
439
+ self[ensureCont] = undefined;
440
+ return self;
441
+ };
442
+ };
248
443
  /**
249
- * @since 3.4.6
444
+ * Creates a `Micro` effect that will succeed with the specified constant value.
445
+ *
446
+ * @since 3.4.0
250
447
  * @experimental
251
- * @category MicroExit
448
+ * @category constructors
252
449
  */
253
- export const exitIsFail = self => exitIsFailure(self) && self.left._tag === "Fail";
450
+ export const succeed = /*#__PURE__*/makeExit({
451
+ op: "Success",
452
+ prop: "value",
453
+ eval(fiber) {
454
+ const cont = fiber.getCont(successCont);
455
+ return cont ? cont[successCont](this[args], fiber) : fiber.yieldWith(this);
456
+ }
457
+ });
254
458
  /**
459
+ * Creates a `Micro` effect that will fail with the specified `MicroCause`.
460
+ *
255
461
  * @since 3.4.6
256
462
  * @experimental
257
- * @category MicroExit
463
+ * @category constructors
258
464
  */
259
- export const exitIsDie = self => exitIsFailure(self) && self.left._tag === "Die";
465
+ export const failCause = /*#__PURE__*/makeExit({
466
+ op: "Failure",
467
+ prop: "cause",
468
+ eval(fiber) {
469
+ let cont = fiber.getCont(failureCont);
470
+ while (causeIsInterrupt(this[args]) && cont && fiber.interruptible) {
471
+ cont = fiber.getCont(failureCont);
472
+ }
473
+ return cont ? cont[failureCont](this[args], fiber) : fiber.yieldWith(this);
474
+ }
475
+ });
260
476
  /**
261
- * @since 3.4.6
477
+ * Creates a `Micro` effect that will fail with the specified error.
478
+ *
479
+ * This will result in a `CauseFail`, where the error is tracked at the
480
+ * type level.
481
+ *
482
+ * @since 3.4.0
262
483
  * @experimental
263
- * @category MicroExit
484
+ * @category constructors
264
485
  */
265
- export const exitVoid = /*#__PURE__*/exitSucceed(void 0);
266
- // ----------------------------------------------------------------------------
267
- // env
268
- // ----------------------------------------------------------------------------
486
+ export const fail = error => failCause(causeFail(error));
269
487
  /**
488
+ * Creates a `Micro` effect that will succeed with the lazily evaluated value.
489
+ *
490
+ * If the evaluation of the value throws an error, the effect will fail with
491
+ * `CauseDie`.
492
+ *
270
493
  * @since 3.4.0
271
494
  * @experimental
272
- * @category environment
495
+ * @category constructors
273
496
  */
274
- export const EnvTypeId = /*#__PURE__*/Symbol.for("effect/Micro/Env");
275
- const EnvProto = {
276
- [EnvTypeId]: {
277
- _R: identity
278
- },
279
- pipe() {
280
- return pipeArguments(this, arguments);
497
+ export const sync = /*#__PURE__*/makePrimitive({
498
+ op: "Sync",
499
+ eval(fiber) {
500
+ const value = this[args]();
501
+ const cont = fiber.getCont(successCont);
502
+ return cont ? cont[successCont](value, fiber) : fiber.yieldWith(exitSucceed(value));
281
503
  }
282
- };
504
+ });
283
505
  /**
506
+ * Lazily creates a `Micro` effect from the given side-effect.
507
+ *
284
508
  * @since 3.4.0
285
509
  * @experimental
286
- * @category environment
510
+ * @category constructors
287
511
  */
288
- export const envMake = refs => {
289
- const self = Object.create(EnvProto);
290
- self.refs = refs;
291
- return self;
292
- };
512
+ export const suspend = /*#__PURE__*/makePrimitive({
513
+ op: "Suspend",
514
+ eval(_fiber) {
515
+ return this[args]();
516
+ }
517
+ });
293
518
  /**
519
+ * Pause the execution of the current `Micro` effect, and resume it on the next
520
+ * scheduler tick.
521
+ *
294
522
  * @since 3.4.0
295
523
  * @experimental
296
- * @category environment
524
+ * @category constructors
297
525
  */
298
- export const envUnsafeMakeEmpty = () => {
299
- const controller = new AbortController();
300
- const refs = Object.create(null);
301
- refs[currentAbortController.key] = controller;
302
- refs[currentAbortSignal.key] = controller.signal;
303
- refs[currentScheduler.key] = new MicroSchedulerDefault();
304
- return envMake(refs);
305
- };
526
+ export const yieldNowWith = /*#__PURE__*/makePrimitive({
527
+ op: "Yield",
528
+ eval(fiber) {
529
+ let resumed = false;
530
+ fiber.getRef(CurrentScheduler).scheduleTask(() => {
531
+ if (resumed) return;
532
+ fiber.evaluate(exitVoid);
533
+ }, this[args] ?? 0);
534
+ return fiber.yieldWith(() => {
535
+ resumed = true;
536
+ });
537
+ }
538
+ });
306
539
  /**
540
+ * Pause the execution of the current `Micro` effect, and resume it on the next
541
+ * scheduler tick.
542
+ *
307
543
  * @since 3.4.0
308
544
  * @experimental
309
- * @category environment
545
+ * @category constructors
310
546
  */
311
- export const envGet = /*#__PURE__*/dual(2, (self, ref) => ref.key in self.refs ? self.refs[ref.key] : ref.initial);
547
+ export const yieldNow = /*#__PURE__*/yieldNowWith(0);
312
548
  /**
549
+ * Creates a `Micro` effect that will succeed with `Option.Some` of the value.
550
+ *
313
551
  * @since 3.4.0
314
552
  * @experimental
315
- * @category environment
553
+ * @category constructors
316
554
  */
317
- export const envSet = /*#__PURE__*/dual(3, (self, ref, value) => {
318
- const refs = Object.assign(Object.create(null), self.refs);
319
- refs[ref.key] = value;
320
- return envMake(refs);
321
- });
555
+ export const succeedSome = a => succeed(Option.some(a));
322
556
  /**
557
+ * Creates a `Micro` effect that will succeed with `Option.None`.
558
+ *
323
559
  * @since 3.4.0
324
560
  * @experimental
325
- * @category environment
561
+ * @category constructors
326
562
  */
327
- export const envMutate = /*#__PURE__*/dual(2, (self, f) => envMake(f(Object.assign(Object.create(null), self.refs))));
563
+ export const succeedNone = /*#__PURE__*/succeed( /*#__PURE__*/Option.none());
328
564
  /**
329
- * Access the given `Context.Tag` from the environment.
565
+ * Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
330
566
  *
331
567
  * @since 3.4.0
332
568
  * @experimental
333
- * @category environment
569
+ * @category constructors
334
570
  */
335
- export const service = tag => make(function (env, onExit) {
336
- onExit(exitSucceed(Context.get(envGet(env, currentContext), tag)));
337
- });
571
+ export const failCauseSync = evaluate => suspend(() => failCause(evaluate()));
338
572
  /**
339
- * Access the given `Context.Tag` from the environment, without tracking the
340
- * dependency at the type level.
573
+ * Creates a `Micro` effect that will die with the specified error.
341
574
  *
342
- * It will return an `Option` of the service, depending on whether it is
343
- * available in the environment or not.
575
+ * This will result in a `CauseDie`, where the error is not tracked at
576
+ * the type level.
344
577
  *
345
578
  * @since 3.4.0
346
579
  * @experimental
347
- * @category environment
580
+ * @category constructors
348
581
  */
349
- export const serviceOption = tag => make(function (env, onExit) {
350
- onExit(exitSucceed(Context.getOption(envGet(env, currentContext), tag)));
351
- });
582
+ export const die = defect => exitDie(defect);
352
583
  /**
353
- * Retrieve the current value of the given `EnvRef`.
584
+ * Creates a `Micro` effect that will fail with the lazily evaluated error.
354
585
  *
355
- * @since 3.4.0
586
+ * This will result in a `CauseFail`, where the error is tracked at the
587
+ * type level.
588
+ *
589
+ * @since 3.4.6
356
590
  * @experimental
357
- * @category environment
591
+ * @category constructors
358
592
  */
359
- export const getEnvRef = envRef => make((env, onExit) => onExit(Either.right(envGet(env, envRef))));
593
+ export const failSync = error => suspend(() => fail(error()));
360
594
  /**
361
- * Set the value of the given `EnvRef` for the duration of the effect.
595
+ * Converts an `Option` into a `Micro` effect, that will fail with
596
+ * `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
597
+ * value of the option.
362
598
  *
363
599
  * @since 3.4.0
364
600
  * @experimental
365
- * @category environment
601
+ * @category constructors
366
602
  */
367
- export const locally = /*#__PURE__*/dual(3, (self, fiberRef, value) => make((env, onExit) => self[runSymbol](envSet(env, fiberRef, value), onExit)));
603
+ export const fromOption = option => option._tag === "Some" ? succeed(option.value) : fail(new NoSuchElementException({}));
368
604
  /**
369
- * Access the current `Context` from the environment.
605
+ * Converts an `Either` into a `Micro` effect, that will fail with the left side
606
+ * of the either if it is a `Left`. Otherwise, it will succeed with the right
607
+ * side of the either.
370
608
  *
371
609
  * @since 3.4.0
372
610
  * @experimental
373
- * @category environment
611
+ * @category constructors
374
612
  */
375
- export const context = () => getEnvRef(currentContext);
613
+ export const fromEither = either => either._tag === "Right" ? succeed(either.right) : fail(either.left);
614
+ const void_ = /*#__PURE__*/succeed(void 0);
615
+ export {
376
616
  /**
377
- * Merge the given `Context` with the current context.
617
+ * A `Micro` effect that will succeed with `void` (`undefined`).
378
618
  *
379
619
  * @since 3.4.0
380
620
  * @experimental
381
- * @category environment
621
+ * @category constructors
382
622
  */
383
- export const provideContext = /*#__PURE__*/dual(2, (self, provided) => make(function (env, onExit) {
384
- const context = envGet(env, currentContext);
385
- const nextEnv = envSet(env, currentContext, Context.merge(context, provided));
386
- self[runSymbol](nextEnv, onExit);
387
- }));
623
+ void_ as void };
624
+ const try_ = options => suspend(() => {
625
+ try {
626
+ return succeed(options.try());
627
+ } catch (err) {
628
+ return fail(options.catch(err));
629
+ }
630
+ });
631
+ export {
388
632
  /**
389
- * Add the provided service to the current context.
633
+ * The `Micro` equivalent of a try / catch block, which allows you to map
634
+ * thrown errors to a specific error type.
390
635
  *
391
636
  * @since 3.4.0
392
637
  * @experimental
393
- * @category environment
394
- */
395
- export const provideService = /*#__PURE__*/dual(3, (self, tag, service) => make(function (env, onExit) {
396
- const context = envGet(env, currentContext);
397
- const nextEnv = envSet(env, currentContext, Context.add(context, tag, service));
398
- self[runSymbol](nextEnv, onExit);
399
- }));
400
- /**
401
- * Create a service using the provided `Micro` effect, and add it to the
402
- * current context.
638
+ * @category constructors
639
+ * @example
640
+ * ```ts
641
+ * import { Micro } from "effect"
403
642
  *
404
- * @since 3.4.6
405
- * @experimental
406
- * @category environment
643
+ * Micro.try({
644
+ * try: () => throw new Error("boom"),
645
+ * catch: (cause) => new Error("caught", { cause })
646
+ * })
647
+ * ```
407
648
  */
408
- export const provideServiceEffect = /*#__PURE__*/dual(3, (self, tag, acquire) => flatMap(acquire, service => provideService(self, tag, service)));
409
- const setImmediate = "setImmediate" in globalThis ? globalThis.setImmediate : f => setTimeout(f, 0);
649
+ try_ as try };
410
650
  /**
411
- * @since 3.5.9
651
+ * Wrap a `Promise` into a `Micro` effect. Any errors will result in a
652
+ * `CauseDie`.
653
+ *
654
+ * @since 3.4.0
412
655
  * @experimental
413
- * @category scheduler
656
+ * @category constructors
414
657
  */
415
- export class MicroSchedulerDefault {
416
- tasks = [];
417
- running = false;
418
- /**
419
- * @since 3.5.9
420
- */
421
- scheduleTask(task, _priority) {
422
- this.tasks.push(task);
423
- if (!this.running) {
424
- this.running = true;
425
- setImmediate(this.afterScheduled);
426
- }
427
- }
428
- /**
429
- * @since 3.5.9
430
- */
431
- afterScheduled = () => {
432
- this.running = false;
433
- this.runTasks();
434
- };
435
- /**
436
- * @since 3.5.9
437
- */
438
- runTasks() {
439
- const tasks = this.tasks;
440
- this.tasks = [];
441
- for (let i = 0, len = tasks.length; i < len; i++) {
442
- tasks[i]();
443
- }
444
- }
445
- /**
446
- * @since 3.5.9
447
- */
448
- shouldYield(_env) {
449
- return false;
450
- }
451
- /**
452
- * @since 3.5.9
453
- */
454
- flush() {
455
- while (this.tasks.length > 0) {
456
- this.runTasks();
457
- }
458
- }
459
- }
460
- // ========================================================================
461
- // Env refs
462
- // ========================================================================
658
+ export const promise = evaluate => asyncOptions(function (resume, signal) {
659
+ evaluate(signal).then(a => resume(succeed(a)), e => resume(die(e)));
660
+ }, evaluate.length !== 0);
463
661
  /**
662
+ * Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
663
+ * converted into a specific error type.
664
+ *
464
665
  * @since 3.4.0
465
666
  * @experimental
466
- * @category environment
667
+ * @category constructors
668
+ * @example
669
+ * ```ts
670
+ * import { Micro } from "effect"
671
+ *
672
+ * Micro.tryPromise({
673
+ * try: () => Promise.resolve("success"),
674
+ * catch: (cause) => new Error("caught", { cause })
675
+ * })
676
+ * ```
467
677
  */
468
- export const EnvRefTypeId = /*#__PURE__*/Symbol.for("effect/Micro/EnvRef");
469
- const EnvRefProto = {
470
- ...MicroProto,
471
- [EnvRefTypeId]: EnvRefTypeId,
472
- [runSymbol](env, onExit) {
473
- getEnvRef(this)[runSymbol](env, onExit);
678
+ export const tryPromise = options => asyncOptions(function (resume, signal) {
679
+ try {
680
+ options.try(signal).then(a => resume(succeed(a)), e => resume(fail(options.catch(e))));
681
+ } catch (err) {
682
+ resume(fail(options.catch(err)));
474
683
  }
475
- };
684
+ }, options.try.length !== 0);
476
685
  /**
686
+ * Create a `Micro` effect using the current `Fiber`.
687
+ *
477
688
  * @since 3.4.0
478
689
  * @experimental
479
- * @category environment refs
690
+ * @category constructors
480
691
  */
481
- export const envRefMake = (key, initial) => globalValue(key, () => {
482
- const self = Object.create(EnvRefProto);
483
- self.key = key;
484
- self.initial = initial();
485
- return self;
692
+ export const withFiber = /*#__PURE__*/makePrimitive({
693
+ op: "WithFiber",
694
+ eval(fiber) {
695
+ return this[args](fiber);
696
+ }
486
697
  });
487
698
  /**
488
- * @since 3.4.0
489
- * @experimental
490
- * @category environment refs
491
- */
492
- export const currentAbortController = /*#__PURE__*/envRefMake("effect/Micro/currentAbortController", () => undefined);
493
- /**
494
- * @since 3.4.0
495
- * @experimental
496
- * @category environment refs
497
- */
498
- export const currentAbortSignal = /*#__PURE__*/envRefMake("effect/Micro/currentAbortSignal", () => undefined);
499
- /**
500
- * @since 3.4.0
501
- * @experimental
502
- * @category environment refs
503
- */
504
- export const currentContext = /*#__PURE__*/envRefMake("effect/Micro/currentContext", () => Context.empty());
505
- /**
506
- * @since 3.4.0
507
- * @experimental
508
- * @category environment refs
509
- */
510
- export const currentConcurrency = /*#__PURE__*/envRefMake("effect/Micro/currentConcurrency", () => "unbounded");
511
- /**
512
- * @since 3.4.0
513
- * @experimental
514
- * @category environment refs
515
- */
516
- export const currentMaxDepthBeforeYield = /*#__PURE__*/envRefMake("effect/Micro/currentMaxDepthBeforeYield", () => 2048);
517
- const currentInterruptible = /*#__PURE__*/envRefMake("effect/Micro/currentInterruptible", () => true);
518
- /**
519
- * @since 3.4.0
520
- * @experimental
521
- * @category environment refs
522
- */
523
- export const currentScheduler = /*#__PURE__*/envRefMake("effect/Micro/currentScheduler", () => new MicroSchedulerDefault());
524
- /**
525
- * If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
526
- * api to control the concurrency of that `Micro` when it is run.
699
+ * Flush any yielded effects that are waiting to be executed.
527
700
  *
528
701
  * @since 3.4.0
529
702
  * @experimental
530
- * @category environment refs
531
- * @example
532
- * import * as Micro from "effect/Micro"
533
- *
534
- * Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
535
- * concurrency: "inherit"
536
- * }).pipe(
537
- * Micro.withConcurrency(2) // use a concurrency of 2
538
- * )
703
+ * @category constructors
539
704
  */
540
- export const withConcurrency = /*#__PURE__*/dual(2, (self, concurrency) => locally(self, currentConcurrency, concurrency));
541
- // ----------------------------------------------------------------------------
542
- // constructors
543
- // ----------------------------------------------------------------------------
544
- const microDepthState = /*#__PURE__*/globalValue("effect/Micro/microDepthState", () => ({
545
- depth: 0,
546
- maxDepthBeforeYield: currentMaxDepthBeforeYield.initial
547
- }));
548
- const unsafeMake = run => {
549
- const self = Object.create(MicroProto);
550
- self[runSymbol] = run;
551
- return self;
552
- };
553
- const unsafeMakeOptions = (run, checkAbort) => unsafeMake(function execute(env, onExit) {
554
- if (checkAbort && env.refs[currentInterruptible.key] !== false && env.refs[currentAbortSignal.key].aborted) {
555
- return onExit(exitInterrupt);
556
- }
557
- microDepthState.depth++;
558
- if (microDepthState.depth === 1) {
559
- microDepthState.maxDepthBeforeYield = envGet(env, currentMaxDepthBeforeYield);
705
+ export const yieldFlush = /*#__PURE__*/withFiber(fiber => {
706
+ fiber.getRef(CurrentScheduler).flush();
707
+ return exitVoid;
708
+ });
709
+ const asyncOptions = /*#__PURE__*/makePrimitive({
710
+ op: "Async",
711
+ single: false,
712
+ eval(fiber) {
713
+ const register = this[args][0];
714
+ let resumed = false;
715
+ let yielded = false;
716
+ const controller = this[args][1] ? new AbortController() : undefined;
717
+ const onCancel = register(effect => {
718
+ if (resumed) return;
719
+ resumed = true;
720
+ if (yielded) {
721
+ fiber.evaluate(effect);
722
+ } else {
723
+ yielded = effect;
724
+ }
725
+ }, controller?.signal);
726
+ if (yielded !== false) return yielded;
727
+ yielded = true;
728
+ fiber._yielded = () => {
729
+ resumed = true;
730
+ };
731
+ if (controller === undefined && onCancel === undefined) {
732
+ return Yield;
733
+ }
734
+ fiber._stack.push(asyncFinalizer(() => {
735
+ resumed = true;
736
+ controller?.abort();
737
+ return onCancel ?? exitVoid;
738
+ }));
739
+ return Yield;
560
740
  }
561
- const scheduler = env.refs[currentScheduler.key];
562
- if (microDepthState.depth >= microDepthState.maxDepthBeforeYield || scheduler.shouldYield(env)) {
563
- scheduler.scheduleTask(() => execute(env, onExit), 0);
564
- } else {
565
- try {
566
- run(env, onExit);
567
- } catch (err) {
568
- onExit(exitDie(err));
741
+ });
742
+ const asyncFinalizer = /*#__PURE__*/makePrimitive({
743
+ op: "AsyncFinalizer",
744
+ ensure(fiber) {
745
+ if (fiber.interruptible) {
746
+ fiber.interruptible = false;
747
+ fiber._stack.push(setInterruptible(true));
569
748
  }
749
+ },
750
+ contE(cause, _fiber) {
751
+ return causeIsInterrupt(cause) ? flatMap(this[args](), () => failCause(cause)) : failCause(cause);
570
752
  }
571
- microDepthState.depth--;
572
753
  });
573
754
  /**
574
- * A low-level constructor for creating a `Micro` effect. It takes a function
575
- * that receives an environment and a callback which should be called with the
576
- * result of the effect.
755
+ * Create a `Micro` effect from an asynchronous computation.
756
+ *
757
+ * You can return a cleanup effect that will be run when the effect is aborted.
758
+ * It is also passed an `AbortSignal` that is triggered when the effect is
759
+ * aborted.
577
760
  *
578
761
  * @since 3.4.0
579
762
  * @experimental
580
763
  * @category constructors
581
764
  */
582
- export const make = run => unsafeMakeOptions(run, true);
765
+ export const async = register => asyncOptions(register, register.length >= 2);
583
766
  /**
584
- * Converts a `MicroExit` into a `Micro` effect.
767
+ * A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
768
+ * the Javascript runtime from exiting.
585
769
  *
586
- * @since 3.4.6
770
+ * @since 3.4.0
587
771
  * @experimental
588
772
  * @category constructors
589
773
  */
590
- export const fromExit = self => make(function (_env, onExit) {
591
- onExit(self);
774
+ export const never = /*#__PURE__*/async(function () {
775
+ const interval = setInterval(constVoid, 2147483646);
776
+ return sync(() => clearInterval(interval));
592
777
  });
593
778
  /**
594
- * Converts a lazy `MicroExit` into a `Micro` effect.
595
- *
596
- * @since 3.4.6
779
+ * @since 3.4.0
597
780
  * @experimental
598
781
  * @category constructors
599
782
  */
600
- export const fromExitSync = self => make(function (_env, onExit) {
601
- onExit(self());
783
+ export const gen = (...args) => suspend(() => fromIterator(args.length === 1 ? args[0]() : args[1].call(args[0])));
784
+ const fromIterator = /*#__PURE__*/makePrimitive({
785
+ op: "Iterator",
786
+ contA(value, fiber) {
787
+ const state = this[args].next(value);
788
+ if (state.done) return succeed(state.value);
789
+ fiber._stack.push(this);
790
+ return yieldWrapGet(state.value);
791
+ },
792
+ eval(fiber) {
793
+ return this[successCont](undefined, fiber);
794
+ }
602
795
  });
796
+ // ----------------------------------------------------------------------------
797
+ // mapping & sequencing
798
+ // ----------------------------------------------------------------------------
603
799
  /**
604
- * Creates a `Micro` effect that will succeed with the specified constant value.
800
+ * Create a `Micro` effect that will replace the success value of the given
801
+ * effect.
605
802
  *
606
803
  * @since 3.4.0
607
804
  * @experimental
608
- * @category constructors
805
+ * @category mapping & sequencing
609
806
  */
610
- export const succeed = a => fromExit(exitSucceed(a));
807
+ export const as = /*#__PURE__*/dual(2, (self, value) => map(self, _ => value));
611
808
  /**
612
- * Creates a `Micro` effect that will succeed with `Option.Some` of the value.
809
+ * Wrap the success value of this `Micro` effect in an `Option.Some`.
613
810
  *
614
811
  * @since 3.4.0
615
812
  * @experimental
616
- * @category constructors
813
+ * @category mapping & sequencing
617
814
  */
618
- export const succeedSome = a => succeed(Option.some(a));
815
+ export const asSome = self => map(self, Option.some);
619
816
  /**
620
- * Creates a `Micro` effect that will succeed with `Option.None`.
817
+ * Swap the error and success types of the `Micro` effect.
621
818
  *
622
819
  * @since 3.4.0
623
820
  * @experimental
624
- * @category constructors
821
+ * @category mapping & sequencing
625
822
  */
626
- export const succeedNone = /*#__PURE__*/succeed( /*#__PURE__*/Option.none());
823
+ export const flip = self => matchEffect(self, {
824
+ onFailure: succeed,
825
+ onSuccess: fail
826
+ });
627
827
  /**
628
- * Creates a `Micro` effect that will fail with the specified error.
828
+ * A more flexible version of `flatMap`, that combines `map` and `flatMap` into
829
+ * a single api.
629
830
  *
630
- * This will result in a `CauseFail`, where the error is tracked at the
631
- * type level.
831
+ * It also allows you to pass in a `Micro` effect directly, which will be
832
+ * executed after the current effect.
632
833
  *
633
834
  * @since 3.4.0
634
835
  * @experimental
635
- * @category constructors
836
+ * @category mapping & sequencing
636
837
  */
637
- export const fail = e => fromExit(exitFail(e));
838
+ export const andThen = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => {
839
+ const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f;
840
+ return isMicro(value) ? value : succeed(value);
841
+ }));
638
842
  /**
639
- * Creates a `Micro` effect that will fail with the lazily evaluated error.
843
+ * Execute a side effect from the success value of the `Micro` effect.
640
844
  *
641
- * This will result in a `CauseFail`, where the error is tracked at the
642
- * type level.
845
+ * It is similar to the `andThen` api, but the success value is ignored.
643
846
  *
644
847
  * @since 3.4.0
645
848
  * @experimental
646
- * @category constructors
849
+ * @category mapping & sequencing
647
850
  */
648
- export const failSync = e => make(function (_env, onExit) {
649
- onExit(exitFail(e()));
650
- });
851
+ export const tap = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => {
852
+ const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f;
853
+ return isMicro(value) ? as(value, a) : succeed(a);
854
+ }));
651
855
  /**
652
- * Creates a `Micro` effect that will die with the specified error.
653
- *
654
- * This will result in a `CauseDie`, where the error is not tracked at
655
- * the type level.
856
+ * Replace the success value of the `Micro` effect with `void`.
656
857
  *
657
858
  * @since 3.4.0
658
859
  * @experimental
659
- * @category constructors
660
- */
661
- export const die = defect => fromExit(exitDie(defect));
662
- /**
663
- * Creates a `Micro` effect that will fail with the specified `MicroCause`.
664
- *
665
- * @since 3.4.6
666
- * @experimental
667
- * @category constructors
860
+ * @category mapping & sequencing
668
861
  */
669
- export const failCause = cause => fromExit(exitFailCause(cause));
862
+ export const asVoid = self => flatMap(self, _ => exitVoid);
670
863
  /**
671
- * Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
864
+ * Access the `MicroExit` of the given `Micro` effect.
672
865
  *
673
866
  * @since 3.4.6
674
867
  * @experimental
675
- * @category constructors
868
+ * @category mapping & sequencing
676
869
  */
677
- export const failCauseSync = cause => fromExitSync(() => exitFailCause(cause()));
870
+ export const exit = self => matchCause(self, {
871
+ onFailure: exitFailCause,
872
+ onSuccess: exitSucceed
873
+ });
678
874
  /**
679
- * Creates a `Micro` effect that will succeed with the lazily evaluated value.
680
- *
681
- * If the evaluation of the value throws an error, the effect will fail with
682
- * `CauseDie`.
875
+ * Replace the error type of the given `Micro` with the full `MicroCause` object.
683
876
  *
684
877
  * @since 3.4.0
685
878
  * @experimental
686
- * @category constructors
879
+ * @category mapping & sequencing
687
880
  */
688
- export const sync = evaluate => make(function (_env, onExit) {
689
- onExit(exitSucceed(evaluate()));
690
- });
881
+ export const sandbox = self => catchAllCause(self, fail);
691
882
  /**
692
- * Converts an `Option` into a `Micro` effect, that will fail with
693
- * `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
694
- * value of the option.
883
+ * Returns an effect that races all the specified effects,
884
+ * yielding the value of the first effect to succeed with a value. Losers of
885
+ * the race will be interrupted immediately
695
886
  *
696
887
  * @since 3.4.0
697
888
  * @experimental
698
- * @category constructors
889
+ * @category sequencing
699
890
  */
700
- export const fromOption = option => make(function (_env, onExit) {
701
- onExit(option._tag === "Some" ? exitSucceed(option.value) : exitFail(new NoSuchElementException({})));
702
- });
891
+ export const raceAll = all => withFiber(parent => async(resume => {
892
+ const effects = Arr.fromIterable(all);
893
+ const len = effects.length;
894
+ let doneCount = 0;
895
+ let done = false;
896
+ const fibers = new Set();
897
+ const causes = [];
898
+ const onExit = exit => {
899
+ doneCount++;
900
+ if (exit._tag === "Failure") {
901
+ causes.push(exit.cause);
902
+ if (doneCount >= len) {
903
+ resume(failCause(causes[0]));
904
+ }
905
+ return;
906
+ }
907
+ done = true;
908
+ resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit));
909
+ };
910
+ for (let i = 0; i < len; i++) {
911
+ if (done) break;
912
+ const fiber = unsafeFork(parent, interruptible(effects[i]), true, true);
913
+ fibers.add(fiber);
914
+ fiber.addObserver(exit => {
915
+ fibers.delete(fiber);
916
+ onExit(exit);
917
+ });
918
+ }
919
+ return fiberInterruptAll(fibers);
920
+ }));
703
921
  /**
704
- * Converts an `Either` into a `Micro` effect, that will fail with the left side
705
- * of the either if it is a `Left`. Otherwise, it will succeed with the right
706
- * side of the either.
922
+ * Returns an effect that races all the specified effects,
923
+ * yielding the value of the first effect to succeed or fail. Losers of
924
+ * the race will be interrupted immediately
707
925
  *
708
926
  * @since 3.4.0
709
927
  * @experimental
710
- * @category constructors
928
+ * @category sequencing
711
929
  */
712
- export const fromEither = either => make(function (_env, onExit) {
713
- onExit(either._tag === "Right" ? either : exitFail(either.left));
714
- });
930
+ export const raceAllFirst = all => withFiber(parent => async(resume => {
931
+ let done = false;
932
+ const fibers = new Set();
933
+ const onExit = exit => {
934
+ done = true;
935
+ resume(fibers.size === 0 ? exit : flatMap(fiberInterruptAll(fibers), () => exit));
936
+ };
937
+ for (const effect of all) {
938
+ if (done) break;
939
+ const fiber = unsafeFork(parent, interruptible(effect), true, true);
940
+ fibers.add(fiber);
941
+ fiber.addObserver(exit => {
942
+ fibers.delete(fiber);
943
+ onExit(exit);
944
+ });
945
+ }
946
+ return fiberInterruptAll(fibers);
947
+ }));
715
948
  /**
716
- * Lazily creates a `Micro` effect from the given side-effect.
949
+ * Returns an effect that races two effects, yielding the value of the first
950
+ * effect to succeed. Losers of the race will be interrupted immediately
717
951
  *
718
952
  * @since 3.4.0
719
953
  * @experimental
720
- * @category constructors
954
+ * @category sequencing
721
955
  */
722
- export const suspend = evaluate => make(function (env, onExit) {
723
- evaluate()[runSymbol](env, onExit);
724
- });
725
- const void_ = /*#__PURE__*/succeed(void 0);
726
- export {
956
+ export const race = /*#__PURE__*/dual(2, (self, that) => raceAll([self, that]));
727
957
  /**
728
- * A `Micro` effect that will succeed with `void` (`undefined`).
958
+ * Returns an effect that races two effects, yielding the value of the first
959
+ * effect to succeed *or* fail. Losers of the race will be interrupted immediately
729
960
  *
730
961
  * @since 3.4.0
731
962
  * @experimental
732
- * @category constructors
963
+ * @category sequencing
733
964
  */
734
- void_ as void };
965
+ export const raceFirst = /*#__PURE__*/dual(2, (self, that) => raceAllFirst([self, that]));
735
966
  /**
736
- * Create a `Micro` effect from an asynchronous computation.
737
- *
738
- * You can return a cleanup effect that will be run when the effect is aborted.
739
- * It is also passed an `AbortSignal` that is triggered when the effect is
740
- * aborted.
967
+ * Map the success value of this `Micro` effect to another `Micro` effect, then
968
+ * flatten the result.
741
969
  *
742
970
  * @since 3.4.0
743
971
  * @experimental
744
- * @category constructors
972
+ * @category mapping & sequencing
745
973
  */
746
- export const async = register => make(function (env, onExit) {
747
- let resumed = false;
748
- const controller = register.length > 1 ? new AbortController() : undefined;
749
- const signal = envGet(env, currentAbortSignal);
750
- let cleanup = undefined;
751
- function onAbort() {
752
- if (cleanup) {
753
- resume(uninterruptible(andThen(cleanup, fromExit(exitInterrupt))));
754
- } else {
755
- resume(fromExit(exitInterrupt));
756
- }
757
- if (controller !== undefined) {
758
- controller.abort();
759
- }
760
- }
761
- function resume(effect) {
762
- if (resumed) {
763
- return;
764
- }
765
- resumed = true;
766
- signal.removeEventListener("abort", onAbort);
767
- effect[runSymbol](env, onExit);
768
- }
769
- cleanup = controller === undefined ? register(resume) : register(resume, controller.signal);
770
- if (resumed) return;
771
- signal.addEventListener("abort", onAbort);
974
+ export const flatMap = /*#__PURE__*/dual(2, (self, f) => {
975
+ const onSuccess = Object.create(OnSuccessProto);
976
+ onSuccess[args] = self;
977
+ onSuccess[successCont] = f;
978
+ return onSuccess;
772
979
  });
773
- const try_ = options => make(function (_env, onExit) {
774
- try {
775
- onExit(exitSucceed(options.try()));
776
- } catch (err) {
777
- onExit(exitFail(options.catch(err)));
980
+ const OnSuccessProto = /*#__PURE__*/makePrimitiveProto({
981
+ op: "OnSuccess",
982
+ eval(fiber) {
983
+ fiber._stack.push(this);
984
+ return this[args];
778
985
  }
779
986
  });
780
- export {
987
+ // ----------------------------------------------------------------------------
988
+ // mapping & sequencing
989
+ // ----------------------------------------------------------------------------
781
990
  /**
782
- * The `Micro` equivalent of a try / catch block, which allows you to map
783
- * thrown errors to a specific error type.
991
+ * Flattens any nested `Micro` effects, merging the error and requirement types.
784
992
  *
785
993
  * @since 3.4.0
786
994
  * @experimental
787
- * @category constructors
788
- * @example
789
- * import { Micro } from "effect"
790
- *
791
- * Micro.try({
792
- * try: () => throw new Error("boom"),
793
- * catch: (cause) => new Error("caught", { cause })
794
- * })
995
+ * @category mapping & sequencing
795
996
  */
796
- try_ as try };
997
+ export const flatten = self => flatMap(self, identity);
797
998
  /**
798
- * Wrap a `Promise` into a `Micro` effect. Any errors will result in a
799
- * `CauseDie`.
999
+ * Transforms the success value of the `Micro` effect with the specified
1000
+ * function.
800
1001
  *
801
1002
  * @since 3.4.0
802
1003
  * @experimental
803
- * @category constructors
1004
+ * @category mapping & sequencing
804
1005
  */
805
- export const promise = evaluate => async(function (resume, signal) {
806
- evaluate(signal).then(a => resume(succeed(a)), e => resume(die(e)));
807
- });
1006
+ export const map = /*#__PURE__*/dual(2, (self, f) => flatMap(self, a => succeed(f(a))));
808
1007
  /**
809
- * Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
810
- * converted into a specific error type.
811
- *
812
- * @since 3.4.0
1008
+ * @since 3.4.6
813
1009
  * @experimental
814
- * @category constructors
815
- * @example
816
- * import { Micro } from "effect"
817
- *
818
- * Micro.tryPromise({
819
- * try: () => Promise.resolve("success"),
820
- * catch: (cause) => new Error("caught", { cause })
821
- * })
1010
+ * @category MicroExit
822
1011
  */
823
- export const tryPromise = options => async(function (resume, signal) {
824
- try {
825
- options.try(signal).then(a => resume(succeed(a)), e => resume(fail(options.catch(e))));
826
- } catch (err) {
827
- resume(fail(options.catch(err)));
828
- }
829
- });
1012
+ export const isMicroExit = u => hasProperty(u, MicroExitTypeId);
830
1013
  /**
831
- * Pause the execution of the current `Micro` effect, and resume it on the next
832
- * iteration of the event loop.
833
- *
834
- * You can specify a priority for the task, which will determine when it is
835
- * executed relative to other tasks.
836
- *
837
- * @since 3.4.0
1014
+ * @since 3.4.6
838
1015
  * @experimental
839
- * @category constructors
1016
+ * @category MicroExit
840
1017
  */
841
- export const yieldWithPriority = priority => make(function (env, onExit) {
842
- envGet(env, currentScheduler).scheduleTask(() => onExit(exitVoid), priority);
843
- });
1018
+ export const exitSucceed = succeed;
844
1019
  /**
845
- * Pause the execution of the current `Micro` effect, and resume it on the next
846
- * iteration of the event loop.
847
- *
848
- * @since 3.4.0
1020
+ * @since 3.4.6
849
1021
  * @experimental
850
- * @category constructors
1022
+ * @category MicroExit
851
1023
  */
852
- export const yieldNow = /*#__PURE__*/yieldWithPriority(0);
1024
+ export const exitFailCause = failCause;
853
1025
  /**
854
- * Flush any yielded effects that are waiting to be executed.
855
- *
856
- * @since 3.4.0
1026
+ * @since 3.4.6
857
1027
  * @experimental
858
- * @category constructors
1028
+ * @category MicroExit
859
1029
  */
860
- export const yieldFlush = /*#__PURE__*/make(function (env, onExit) {
861
- envGet(env, currentScheduler).flush();
862
- onExit(exitVoid);
863
- });
1030
+ export const exitInterrupt = /*#__PURE__*/exitFailCause( /*#__PURE__*/causeInterrupt());
864
1031
  /**
865
- * A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
866
- * the Javascript runtime from exiting.
867
- *
868
- * @since 3.4.0
1032
+ * @since 3.4.6
869
1033
  * @experimental
870
- * @category constructors
1034
+ * @category MicroExit
871
1035
  */
872
- export const never = /*#__PURE__*/async(function () {
873
- const interval = setInterval(constVoid, 2147483646);
874
- return sync(() => clearInterval(interval));
875
- });
1036
+ export const exitFail = e => exitFailCause(causeFail(e));
876
1037
  /**
877
- * @since 3.4.0
1038
+ * @since 3.4.6
878
1039
  * @experimental
879
- * @category constructors
1040
+ * @category MicroExit
880
1041
  */
881
- export const gen = (...args) => make(function (env, onExit) {
882
- const iterator = args.length === 1 ? args[0]() : args[1].call(args[0]);
883
- let running = false;
884
- let value = undefined;
885
- function run() {
886
- running = true;
887
- try {
888
- let shouldContinue = true;
889
- while (shouldContinue) {
890
- const result = iterator.next(value);
891
- if (result.done) {
892
- return onExit(exitSucceed(result.value));
893
- }
894
- shouldContinue = false;
895
- yieldWrapGet(result.value)[runSymbol](env, function (exit) {
896
- if (exit._tag === "Left") {
897
- onExit(exit);
898
- } else {
899
- shouldContinue = true;
900
- value = exit.right;
901
- if (!running) run();
902
- }
903
- });
904
- }
905
- } catch (err) {
906
- onExit(exitDie(err));
907
- }
908
- running = false;
909
- }
910
- run();
911
- });
912
- // ----------------------------------------------------------------------------
913
- // mapping & sequencing
914
- // ----------------------------------------------------------------------------
1042
+ export const exitDie = defect => exitFailCause(causeDie(defect));
915
1043
  /**
916
- * Flattens any nested `Micro` effects, merging the error and requirement types.
917
- *
918
- * @since 3.4.0
1044
+ * @since 3.4.6
919
1045
  * @experimental
920
- * @category mapping & sequencing
1046
+ * @category MicroExit
921
1047
  */
922
- export const flatten = self => make(function (env, onExit) {
923
- self[runSymbol](env, exit => exit._tag === "Left" ? onExit(exit) : exit.right[runSymbol](env, onExit));
924
- });
1048
+ export const exitIsSuccess = self => self._tag === "Success";
925
1049
  /**
926
- * Transforms the success value of the `Micro` effect with the specified
927
- * function.
928
- *
929
- * @since 3.4.0
1050
+ * @since 3.4.6
930
1051
  * @experimental
931
- * @category mapping & sequencing
1052
+ * @category MicroExit
932
1053
  */
933
- export const map = /*#__PURE__*/dual(2, (self, f) => make(function (env, onExit) {
934
- self[runSymbol](env, function (exit) {
935
- onExit(exit._tag === "Left" ? exit : exitSucceed(f(exit.right)));
936
- });
937
- }));
1054
+ export const exitIsFailure = self => self._tag === "Failure";
938
1055
  /**
939
- * Create a `Micro` effect that will replace the success value of the given
940
- * effect.
941
- *
942
- * @since 3.4.0
1056
+ * @since 3.4.6
943
1057
  * @experimental
944
- * @category mapping & sequencing
1058
+ * @category MicroExit
945
1059
  */
946
- export const as = /*#__PURE__*/dual(2, (self, value) => map(self, _ => value));
1060
+ export const exitIsInterrupt = self => exitIsFailure(self) && self.cause._tag === "Interrupt";
947
1061
  /**
948
- * Wrap the success value of this `Micro` effect in an `Option.Some`.
949
- *
950
- * @since 3.4.0
1062
+ * @since 3.4.6
951
1063
  * @experimental
952
- * @category mapping & sequencing
1064
+ * @category MicroExit
953
1065
  */
954
- export const asSome = self => map(self, Option.some);
1066
+ export const exitIsFail = self => exitIsFailure(self) && self.cause._tag === "Fail";
955
1067
  /**
956
- * Map the success value of this `Micro` effect to another `Micro` effect, then
957
- * flatten the result.
1068
+ * @since 3.4.6
1069
+ * @experimental
1070
+ * @category MicroExit
1071
+ */
1072
+ export const exitIsDie = self => exitIsFailure(self) && self.cause._tag === "Die";
1073
+ /**
1074
+ * @since 3.4.6
1075
+ * @experimental
1076
+ * @category MicroExit
1077
+ */
1078
+ export const exitVoid = /*#__PURE__*/exitSucceed(void 0);
1079
+ /**
1080
+ * @since 3.11.0
1081
+ * @experimental
1082
+ * @category MicroExit
1083
+ */
1084
+ export const exitVoidAll = exits => {
1085
+ for (const exit of exits) {
1086
+ if (exit._tag === "Failure") {
1087
+ return exit;
1088
+ }
1089
+ }
1090
+ return exitVoid;
1091
+ };
1092
+ const setImmediate = "setImmediate" in globalThis ? globalThis.setImmediate : f => setTimeout(f, 0);
1093
+ /**
1094
+ * @since 3.5.9
1095
+ * @experimental
1096
+ * @category scheduler
1097
+ */
1098
+ export class MicroSchedulerDefault {
1099
+ tasks = [];
1100
+ running = false;
1101
+ /**
1102
+ * @since 3.5.9
1103
+ */
1104
+ scheduleTask(task, _priority) {
1105
+ this.tasks.push(task);
1106
+ if (!this.running) {
1107
+ this.running = true;
1108
+ setImmediate(this.afterScheduled);
1109
+ }
1110
+ }
1111
+ /**
1112
+ * @since 3.5.9
1113
+ */
1114
+ afterScheduled = () => {
1115
+ this.running = false;
1116
+ this.runTasks();
1117
+ };
1118
+ /**
1119
+ * @since 3.5.9
1120
+ */
1121
+ runTasks() {
1122
+ const tasks = this.tasks;
1123
+ this.tasks = [];
1124
+ for (let i = 0, len = tasks.length; i < len; i++) {
1125
+ tasks[i]();
1126
+ }
1127
+ }
1128
+ /**
1129
+ * @since 3.5.9
1130
+ */
1131
+ shouldYield(fiber) {
1132
+ return fiber.currentOpCount >= fiber.getRef(MaxOpsBeforeYield);
1133
+ }
1134
+ /**
1135
+ * @since 3.5.9
1136
+ */
1137
+ flush() {
1138
+ while (this.tasks.length > 0) {
1139
+ this.runTasks();
1140
+ }
1141
+ }
1142
+ }
1143
+ /**
1144
+ * Access the given `Context.Tag` from the environment.
958
1145
  *
959
1146
  * @since 3.4.0
960
1147
  * @experimental
961
- * @category mapping & sequencing
1148
+ * @category environment
962
1149
  */
963
- export const flatMap = /*#__PURE__*/dual(2, (self, f) => make(function (env, onExit) {
964
- self[runSymbol](env, function (exit) {
965
- if (exit._tag === "Left") {
966
- return onExit(exit);
967
- }
968
- f(exit.right)[runSymbol](env, onExit);
969
- });
970
- }));
1150
+ export const service = tag => withFiber(fiber => succeed(Context.unsafeGet(fiber.context, tag)));
971
1151
  /**
972
- * Swap the error and success types of the `Micro` effect.
1152
+ * Access the given `Context.Tag` from the environment, without tracking the
1153
+ * dependency at the type level.
1154
+ *
1155
+ * It will return an `Option` of the service, depending on whether it is
1156
+ * available in the environment or not.
973
1157
  *
974
1158
  * @since 3.4.0
975
1159
  * @experimental
976
- * @category mapping & sequencing
1160
+ * @category environment
977
1161
  */
978
- export const flip = self => matchEffect(self, {
979
- onFailure: succeed,
980
- onSuccess: fail
981
- });
1162
+ export const serviceOption = tag => withFiber(fiber => succeed(Context.getOption(fiber.context, tag)));
982
1163
  /**
983
- * A more flexible version of `flatMap`, that combines `map` and `flatMap` into
984
- * a single api.
985
- *
986
- * It also allows you to pass in a `Micro` effect directly, which will be
987
- * executed after the current effect.
1164
+ * Update the Context with the given mapping function.
988
1165
  *
989
- * @since 3.4.0
1166
+ * @since 3.11.0
990
1167
  * @experimental
991
- * @category mapping & sequencing
1168
+ * @category environment
992
1169
  */
993
- export const andThen = /*#__PURE__*/dual(2, (self, f) => make(function (env, onExit) {
994
- self[runSymbol](env, function (exit) {
995
- if (exit._tag === "Left") {
996
- return onExit(exit);
997
- } else if (envGet(env, currentAbortSignal).aborted) {
998
- return onExit(exitInterrupt);
999
- }
1000
- const value = isMicro(f) ? f : typeof f === "function" ? f(exit.right) : f;
1001
- if (isMicro(value)) {
1002
- value[runSymbol](env, onExit);
1003
- } else {
1004
- onExit(exitSucceed(value));
1005
- }
1170
+ export const updateContext = /*#__PURE__*/dual(2, (self, f) => withFiber(fiber => {
1171
+ const prev = fiber.context;
1172
+ fiber.context = f(prev);
1173
+ return onExit(self, () => {
1174
+ fiber.context = prev;
1175
+ return void_;
1006
1176
  });
1007
1177
  }));
1008
1178
  /**
1009
- * Execute a side effect from the success value of the `Micro` effect.
1179
+ * Update the service for the given `Context.Tag` in the environment.
1010
1180
  *
1011
- * It is similar to the `andThen` api, but the success value is ignored.
1012
- *
1013
- * @since 3.4.0
1181
+ * @since 3.11.0
1014
1182
  * @experimental
1015
- * @category mapping & sequencing
1183
+ * @category environment
1016
1184
  */
1017
- export const tap = /*#__PURE__*/dual(2, (self, f) => make(function (env, onExit) {
1018
- self[runSymbol](env, function (selfExit) {
1019
- if (selfExit._tag === "Left") {
1020
- return onExit(selfExit);
1021
- } else if (envGet(env, currentAbortSignal).aborted) {
1022
- return onExit(exitInterrupt);
1023
- }
1024
- const value = isMicro(f) ? f : typeof f === "function" ? f(selfExit.right) : f;
1025
- if (isMicro(value)) {
1026
- value[runSymbol](env, function (tapExit) {
1027
- if (tapExit._tag === "Left") {
1028
- return onExit(tapExit);
1029
- }
1030
- onExit(selfExit);
1031
- });
1032
- } else {
1033
- onExit(selfExit);
1034
- }
1185
+ export const updateService = /*#__PURE__*/dual(3, (self, tag, f) => withFiber(fiber => {
1186
+ const prev = Context.unsafeGet(fiber.context, tag);
1187
+ fiber.context = Context.add(fiber.context, tag, f(prev));
1188
+ return onExit(self, () => {
1189
+ fiber.context = Context.add(fiber.context, tag, prev);
1190
+ return void_;
1035
1191
  });
1036
1192
  }));
1037
1193
  /**
1038
- * Replace the success value of the `Micro` effect with `void`.
1194
+ * Access the current `Context` from the environment.
1039
1195
  *
1040
1196
  * @since 3.4.0
1041
1197
  * @experimental
1042
- * @category mapping & sequencing
1198
+ * @category environment
1043
1199
  */
1044
- export const asVoid = self => map(self, _ => void 0);
1200
+ export const context = () => getContext;
1201
+ const getContext = /*#__PURE__*/withFiber(fiber => succeed(fiber.context));
1045
1202
  /**
1046
- * Access the `MicroExit` of the given `Micro` effect.
1203
+ * Merge the given `Context` with the current context.
1047
1204
  *
1048
- * @since 3.4.6
1205
+ * @since 3.4.0
1049
1206
  * @experimental
1050
- * @category mapping & sequencing
1207
+ * @category environment
1051
1208
  */
1052
- export const exit = self => make(function (env, onExit) {
1053
- self[runSymbol](env, function (exit) {
1054
- onExit(exitSucceed(exit));
1055
- });
1056
- });
1209
+ export const provideContext = /*#__PURE__*/dual(2, (self, provided) => updateContext(self, Context.merge(provided)));
1057
1210
  /**
1058
- * Replace the error type of the given `Micro` with the full `MicroCause` object.
1211
+ * Add the provided service to the current context.
1059
1212
  *
1060
1213
  * @since 3.4.0
1061
1214
  * @experimental
1062
- * @category mapping & sequencing
1215
+ * @category environment
1063
1216
  */
1064
- export const sandbox = self => catchAllCause(self, cause => fail(cause));
1065
- function forkSignal(env) {
1066
- const controller = new AbortController();
1067
- const parentSignal = envGet(env, currentAbortSignal);
1068
- function onAbort() {
1069
- controller.abort();
1070
- parentSignal.removeEventListener("abort", onAbort);
1071
- }
1072
- parentSignal.addEventListener("abort", onAbort);
1073
- const envWithSignal = envMutate(env, function (refs) {
1074
- refs[currentAbortController.key] = controller;
1075
- refs[currentAbortSignal.key] = controller.signal;
1076
- return refs;
1077
- });
1078
- return [envWithSignal, onAbort];
1079
- }
1217
+ export const provideService = /*#__PURE__*/dual(3, (self, tag, service) => updateContext(self, Context.add(tag, service)));
1080
1218
  /**
1081
- * Returns an effect that races all the specified effects,
1082
- * yielding the value of the first effect to succeed with a value. Losers of
1083
- * the race will be interrupted immediately
1219
+ * Create a service using the provided `Micro` effect, and add it to the
1220
+ * current context.
1084
1221
  *
1085
- * @since 3.4.0
1222
+ * @since 3.4.6
1086
1223
  * @experimental
1087
- * @category sequencing
1224
+ * @category environment
1088
1225
  */
1089
- export const raceAll = all => make(function (env, onExit) {
1090
- const [envWithSignal, onAbort] = forkSignal(env);
1091
- const effects = Array.from(all);
1092
- let len = effects.length;
1093
- let index = 0;
1094
- let done = 0;
1095
- let exit = undefined;
1096
- const causes = [];
1097
- function onDone(exit_) {
1098
- done++;
1099
- if (exit_._tag === "Right" && exit === undefined) {
1100
- len = index;
1101
- exit = exit_;
1102
- onAbort();
1103
- } else if (exit_._tag === "Left") {
1104
- causes.push(exit_.left);
1105
- }
1106
- if (done >= len) {
1107
- onExit(exit ?? Either.left(causes[0]));
1108
- }
1109
- }
1110
- for (; index < len; index++) {
1111
- effects[index][runSymbol](envWithSignal, onDone);
1112
- }
1113
- });
1226
+ export const provideServiceEffect = /*#__PURE__*/dual(3, (self, tag, acquire) => flatMap(acquire, service => provideService(self, tag, service)));
1227
+ // ========================================================================
1228
+ // References
1229
+ // ========================================================================
1114
1230
  /**
1115
- * Returns an effect that races all the specified effects,
1116
- * yielding the value of the first effect to succeed or fail. Losers of
1117
- * the race will be interrupted immediately
1118
- *
1119
- * @since 3.4.0
1231
+ * @since 3.11.0
1120
1232
  * @experimental
1121
- * @category sequencing
1233
+ * @category references
1122
1234
  */
1123
- export const raceAllFirst = all => make(function (env, onExit) {
1124
- const [envWithSignal, onAbort] = forkSignal(env);
1125
- const effects = Array.from(all);
1126
- let len = effects.length;
1127
- let index = 0;
1128
- let done = 0;
1129
- let exit = undefined;
1130
- const causes = [];
1131
- function onDone(exit_) {
1132
- done++;
1133
- if (exit === undefined) {
1134
- len = index;
1135
- exit = exit_;
1136
- onAbort();
1137
- }
1138
- if (done >= len) {
1139
- onExit(exit ?? Either.left(causes[0]));
1140
- }
1141
- }
1142
- for (; index < len; index++) {
1143
- effects[index][runSymbol](envWithSignal, onDone);
1144
- }
1145
- });
1235
+ export class MaxOpsBeforeYield extends /*#__PURE__*/Context.Reference()("effect/Micro/currentMaxOpsBeforeYield", {
1236
+ defaultValue: () => 2048
1237
+ }) {}
1146
1238
  /**
1147
- * Returns an effect that races two effects, yielding the value of the first
1148
- * effect to succeed. Losers of the race will be interrupted immediately
1149
- *
1150
- * @since 3.4.0
1239
+ * @since 3.11.0
1151
1240
  * @experimental
1152
- * @category sequencing
1241
+ * @category environment refs
1153
1242
  */
1154
- export const race = /*#__PURE__*/dual(2, (self, that) => raceAll([self, that]));
1243
+ export class CurrentConcurrency extends /*#__PURE__*/Context.Reference()("effect/Micro/currentConcurrency", {
1244
+ defaultValue: () => "unbounded"
1245
+ }) {}
1155
1246
  /**
1156
- * Returns an effect that races two effects, yielding the value of the first
1157
- * effect to succeed *or* fail. Losers of the race will be interrupted immediately
1247
+ * @since 3.11.0
1248
+ * @experimental
1249
+ * @category environment refs
1250
+ */
1251
+ export class CurrentScheduler extends /*#__PURE__*/Context.Reference()("effect/Micro/currentScheduler", {
1252
+ defaultValue: () => new MicroSchedulerDefault()
1253
+ }) {}
1254
+ /**
1255
+ * If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
1256
+ * api to control the concurrency of that `Micro` when it is run.
1158
1257
  *
1159
1258
  * @since 3.4.0
1160
1259
  * @experimental
1161
- * @category sequencing
1260
+ * @category environment refs
1261
+ * @example
1262
+ * import * as Micro from "effect/Micro"
1263
+ *
1264
+ * Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
1265
+ * concurrency: "inherit"
1266
+ * }).pipe(
1267
+ * Micro.withConcurrency(2) // use a concurrency of 2
1268
+ * )
1162
1269
  */
1163
- export const raceFirst = /*#__PURE__*/dual(2, (self, that) => raceAllFirst([self, that]));
1270
+ export const withConcurrency = /*#__PURE__*/dual(2, (self, concurrency) => provideService(self, CurrentConcurrency, concurrency));
1164
1271
  // ----------------------------------------------------------------------------
1165
1272
  // zipping
1166
1273
  // ----------------------------------------------------------------------------
@@ -1182,15 +1289,11 @@ export const zip = /*#__PURE__*/dual(args => isMicro(args[1]), (self, that, opti
1182
1289
  * @experimental
1183
1290
  * @category zipping
1184
1291
  */
1185
- export const zipWith = /*#__PURE__*/dual(args => isMicro(args[1]), (self, that, f, options) => {
1186
- if (options?.concurrent) {
1187
- // Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
1188
- return map(all([self, that], {
1189
- concurrency: "unbounded"
1190
- }), ([a, a2]) => f(a, a2));
1191
- }
1192
- return flatMap(self, a => map(that, a2 => f(a, a2)));
1193
- });
1292
+ export const zipWith = /*#__PURE__*/dual(args => isMicro(args[1]), (self, that, f, options) => options?.concurrent
1293
+ // Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
1294
+ ? map(all([self, that], {
1295
+ concurrency: 2
1296
+ }), ([a, a2]) => f(a, a2)) : flatMap(self, a => map(that, a2 => f(a, a2))));
1194
1297
  // ----------------------------------------------------------------------------
1195
1298
  // filtering & conditionals
1196
1299
  // ----------------------------------------------------------------------------
@@ -1225,7 +1328,7 @@ export const filterOrFail = /*#__PURE__*/dual(args => isMicro(args[0]), (self, r
1225
1328
  * @experimental
1226
1329
  * @category filtering & conditionals
1227
1330
  */
1228
- export const when = /*#__PURE__*/dual(2, (self, condition) => flatMap(isMicro(condition) ? condition : sync(condition), pass => pass ? asSome(self) : succeed(Option.none())));
1331
+ export const when = /*#__PURE__*/dual(2, (self, condition) => flatMap(isMicro(condition) ? condition : sync(condition), pass => pass ? asSome(self) : succeedNone));
1229
1332
  // ----------------------------------------------------------------------------
1230
1333
  // repetition
1231
1334
  // ----------------------------------------------------------------------------
@@ -1239,14 +1342,14 @@ export const when = /*#__PURE__*/dual(2, (self, condition) => flatMap(isMicro(co
1239
1342
  * @experimental
1240
1343
  * @category repetition
1241
1344
  */
1242
- export const repeatExit = /*#__PURE__*/dual(2, (self, options) => make(function (env, onExit) {
1345
+ export const repeatExit = /*#__PURE__*/dual(2, (self, options) => suspend(() => {
1243
1346
  const startedAt = options.schedule ? Date.now() : 0;
1244
1347
  let attempt = 0;
1245
- self[runSymbol](env, function loop(exit) {
1348
+ const loop = flatMap(exit(self), exit => {
1246
1349
  if (options.while !== undefined && !options.while(exit)) {
1247
- return onExit(exit);
1350
+ return exit;
1248
1351
  } else if (options.times !== undefined && attempt >= options.times) {
1249
- return onExit(exit);
1352
+ return exit;
1250
1353
  }
1251
1354
  attempt++;
1252
1355
  let delayEffect = yieldNow;
@@ -1254,17 +1357,13 @@ export const repeatExit = /*#__PURE__*/dual(2, (self, options) => make(function
1254
1357
  const elapsed = Date.now() - startedAt;
1255
1358
  const duration = options.schedule(attempt, elapsed);
1256
1359
  if (Option.isNone(duration)) {
1257
- return onExit(exit);
1360
+ return exit;
1258
1361
  }
1259
1362
  delayEffect = sleep(duration.value);
1260
1363
  }
1261
- delayEffect[runSymbol](env, function (exit) {
1262
- if (exit._tag === "Left") {
1263
- return onExit(exit);
1264
- }
1265
- self[runSymbol](env, loop);
1266
- });
1364
+ return flatMap(delayEffect, () => loop);
1267
1365
  });
1366
+ return loop;
1268
1367
  }));
1269
1368
  /**
1270
1369
  * Repeat the given `Micro` effect using the provided options. Only successful
@@ -1276,8 +1375,26 @@ export const repeatExit = /*#__PURE__*/dual(2, (self, options) => make(function
1276
1375
  */
1277
1376
  export const repeat = /*#__PURE__*/dual(args => isMicro(args[0]), (self, options) => repeatExit(self, {
1278
1377
  ...options,
1279
- while: exit => exit._tag === "Right" && (options?.while === undefined || options.while(exit.right))
1378
+ while: exit => exit._tag === "Success" && (options?.while === undefined || options.while(exit.value))
1280
1379
  }));
1380
+ /**
1381
+ * Replicates the given effect `n` times.
1382
+ *
1383
+ * @since 3.11.0
1384
+ * @experimental
1385
+ * @category repetition
1386
+ */
1387
+ export const replicate = /*#__PURE__*/dual(2, (self, n) => Array.from({
1388
+ length: n
1389
+ }, () => self));
1390
+ /**
1391
+ * Performs this effect the specified number of times and collects the
1392
+ * results.
1393
+ *
1394
+ * @since 3.11.0
1395
+ * @category repetition
1396
+ */
1397
+ export const replicateEffect = /*#__PURE__*/dual(args => isMicro(args[0]), (self, n, options) => all(replicate(self, n), options));
1281
1398
  /**
1282
1399
  * Repeat the given `Micro` effect forever, only stopping if the effect fails.
1283
1400
  *
@@ -1367,7 +1484,19 @@ export const scheduleIntersect = /*#__PURE__*/dual(2, (self, that) => (attempt,
1367
1484
  * @experimental
1368
1485
  * @category error handling
1369
1486
  */
1370
- export const catchAllCause = /*#__PURE__*/dual(2, (self, f) => catchCauseIf(self, constTrue, f));
1487
+ export const catchAllCause = /*#__PURE__*/dual(2, (self, f) => {
1488
+ const onFailure = Object.create(OnFailureProto);
1489
+ onFailure[args] = self;
1490
+ onFailure[failureCont] = f;
1491
+ return onFailure;
1492
+ });
1493
+ const OnFailureProto = /*#__PURE__*/makePrimitiveProto({
1494
+ op: "OnFailure",
1495
+ eval(fiber) {
1496
+ fiber._stack.push(this);
1497
+ return this[args];
1498
+ }
1499
+ });
1371
1500
  /**
1372
1501
  * Selectively catch a `MicroCause` object of the given `Micro` effect,
1373
1502
  * using the provided predicate to determine if the failure should be caught.
@@ -1376,15 +1505,7 @@ export const catchAllCause = /*#__PURE__*/dual(2, (self, f) => catchCauseIf(self
1376
1505
  * @experimental
1377
1506
  * @category error handling
1378
1507
  */
1379
- export const catchCauseIf = /*#__PURE__*/dual(3, (self, predicate, f) => make(function (env, onExit) {
1380
- self[runSymbol](env, function (exit) {
1381
- if (exit._tag === "Right" || !predicate(exit.left)) {
1382
- onExit(exit);
1383
- } else {
1384
- f(exit.left)[runSymbol](env, onExit);
1385
- }
1386
- });
1387
- }));
1508
+ export const catchCauseIf = /*#__PURE__*/dual(3, (self, predicate, f) => catchAllCause(self, cause => predicate(cause) ? f(cause) : failCause(cause)));
1388
1509
  /**
1389
1510
  * Catch the error of the given `Micro` effect, allowing you to recover from it.
1390
1511
  *
@@ -1394,7 +1515,7 @@ export const catchCauseIf = /*#__PURE__*/dual(3, (self, predicate, f) => make(fu
1394
1515
  * @experimental
1395
1516
  * @category error handling
1396
1517
  */
1397
- export const catchAll = /*#__PURE__*/dual(2, (self, f) => catchAllCause(self, cause => causeIsFail(cause) ? f(cause.error) : failCause(cause)));
1518
+ export const catchAll = /*#__PURE__*/dual(2, (self, f) => catchCauseIf(self, causeIsFail, cause => f(cause.error)));
1398
1519
  /**
1399
1520
  * Catch any unexpected errors of the given `Micro` effect, allowing you to recover from them.
1400
1521
  *
@@ -1518,7 +1639,7 @@ export const ignoreLogged = self => matchEffect(self, {
1518
1639
  * @category error handling
1519
1640
  */
1520
1641
  export const option = self => match(self, {
1521
- onFailure: _ => Option.none(),
1642
+ onFailure: Option.none,
1522
1643
  onSuccess: Option.some
1523
1644
  });
1524
1645
  /**
@@ -1543,7 +1664,7 @@ export const either = self => match(self, {
1543
1664
  */
1544
1665
  export const retry = /*#__PURE__*/dual(args => isMicro(args[0]), (self, options) => repeatExit(self, {
1545
1666
  ...options,
1546
- while: exit => exit._tag === "Left" && exit.left._tag === "Fail" && (options?.while === undefined || options.while(exit.left.error))
1667
+ while: exit => exit._tag === "Failure" && exit.cause._tag === "Fail" && (options?.while === undefined || options.while(exit.cause.error))
1547
1668
  }));
1548
1669
  /**
1549
1670
  * Add a stack trace to any failures that occur in the effect. The trace will be
@@ -1570,11 +1691,7 @@ export const withTrace = function () {
1570
1691
  const lineMatch = line.match(/\((.*)\)$/);
1571
1692
  return causeWithTrace(cause, `at ${name} (${lineMatch ? lineMatch[1] : line})`);
1572
1693
  }
1573
- const f = name => self => unsafeMakeOptions(function (env, onExit) {
1574
- self[runSymbol](env, function (exit) {
1575
- onExit(exit._tag === "Left" ? Either.left(generate(name, exit.left)) : exit);
1576
- });
1577
- }, false);
1694
+ const f = name => self => onError(self, cause => failCause(generate(name, cause)));
1578
1695
  if (arguments.length === 2) {
1579
1696
  return f(arguments[1])(arguments[0]);
1580
1697
  }
@@ -1588,16 +1705,20 @@ export const withTrace = function () {
1588
1705
  * @experimental
1589
1706
  * @category pattern matching
1590
1707
  */
1591
- export const matchCauseEffect = /*#__PURE__*/dual(2, (self, options) => make(function (env, onExit) {
1592
- self[runSymbol](env, function (exit) {
1593
- try {
1594
- const next = exit._tag === "Left" ? options.onFailure(exit.left) : options.onSuccess(exit.right);
1595
- next[runSymbol](env, onExit);
1596
- } catch (err) {
1597
- onExit(exitDie(err));
1598
- }
1599
- });
1600
- }));
1708
+ export const matchCauseEffect = /*#__PURE__*/dual(2, (self, options) => {
1709
+ const primitive = Object.create(OnSuccessAndFailureProto);
1710
+ primitive[args] = self;
1711
+ primitive[successCont] = options.onSuccess;
1712
+ primitive[failureCont] = options.onFailure;
1713
+ return primitive;
1714
+ });
1715
+ const OnSuccessAndFailureProto = /*#__PURE__*/makePrimitiveProto({
1716
+ op: "OnSuccessAndFailure",
1717
+ eval(fiber) {
1718
+ fiber._stack.push(this);
1719
+ return this[args];
1720
+ }
1721
+ });
1601
1722
  /**
1602
1723
  * @since 3.4.6
1603
1724
  * @experimental
@@ -1635,12 +1756,12 @@ export const match = /*#__PURE__*/dual(2, (self, options) => matchEffect(self, {
1635
1756
  * @experimental
1636
1757
  * @category delays & timeouts
1637
1758
  */
1638
- export const sleep = millis => async(function (resume) {
1639
- const timeout = setTimeout(function () {
1759
+ export const sleep = millis => async(resume => {
1760
+ const timeout = setTimeout(() => {
1640
1761
  resume(void_);
1641
1762
  }, millis);
1642
1763
  return sync(() => {
1643
- return clearTimeout(timeout);
1764
+ clearTimeout(timeout);
1644
1765
  });
1645
1766
  });
1646
1767
  /**
@@ -1741,7 +1862,7 @@ class MicroScopeImpl {
1741
1862
  _tag: "Closed",
1742
1863
  exit: microExit
1743
1864
  };
1744
- return flatMap(forEach(finalizers, finalizer => exit(finalizer(microExit))), exits => asVoid(fromExit(Either.all(exits))));
1865
+ return flatMap(forEach(finalizers, finalizer => exit(finalizer(microExit))), exitVoidAll);
1745
1866
  }
1746
1867
  return void_;
1747
1868
  });
@@ -1798,7 +1919,7 @@ export const provideScope = /*#__PURE__*/dual(2, (self, scope) => provideService
1798
1919
  * @experimental
1799
1920
  * @category resources & finalization
1800
1921
  */
1801
- export const scoped = self => suspend(function () {
1922
+ export const scoped = self => suspend(() => {
1802
1923
  const scope = new MicroScopeImpl();
1803
1924
  return onExit(provideService(self, MicroScope, scope), exit => scope.close(exit));
1804
1925
  });
@@ -1827,36 +1948,27 @@ export const addFinalizer = finalizer => flatMap(scope, scope => scope.addFinali
1827
1948
  * @experimental
1828
1949
  * @category resources & finalization
1829
1950
  */
1830
- export const onExit = /*#__PURE__*/dual(2, (self, f) => onExitIf(self, constTrue, f));
1951
+ export const onExit = /*#__PURE__*/dual(2, (self, f) => uninterruptibleMask(restore => matchCauseEffect(restore(self), {
1952
+ onFailure: cause => flatMap(f(exitFailCause(cause)), () => failCause(cause)),
1953
+ onSuccess: a => flatMap(f(exitSucceed(a)), () => succeed(a))
1954
+ })));
1831
1955
  /**
1832
- * When the `Micro` effect is completed, run the given finalizer effect if it
1833
- * matches the specified predicate.
1956
+ * Regardless of the result of the this `Micro` effect, run the finalizer effect.
1834
1957
  *
1835
- * @since 3.4.6
1958
+ * @since 3.4.0
1836
1959
  * @experimental
1837
1960
  * @category resources & finalization
1838
1961
  */
1839
- export const onExitIf = /*#__PURE__*/dual(3, (self, refinement, f) => uninterruptibleMask(restore => make(function (env, onExit) {
1840
- restore(self)[runSymbol](env, function (exit) {
1841
- if (!refinement(exit)) {
1842
- return onExit(exit);
1843
- }
1844
- f(exit)[runSymbol](env, function (finalizerExit) {
1845
- if (finalizerExit._tag === "Left") {
1846
- return onExit(finalizerExit);
1847
- }
1848
- onExit(exit);
1849
- });
1850
- });
1851
- })));
1962
+ export const ensuring = /*#__PURE__*/dual(2, (self, finalizer) => onExit(self, _ => finalizer));
1852
1963
  /**
1853
- * Regardless of the result of the this `Micro` effect, run the finalizer effect.
1964
+ * When the `Micro` effect is completed, run the given finalizer effect if it
1965
+ * matches the specified predicate.
1854
1966
  *
1855
- * @since 3.4.0
1967
+ * @since 3.4.6
1856
1968
  * @experimental
1857
1969
  * @category resources & finalization
1858
1970
  */
1859
- export const ensuring = /*#__PURE__*/dual(2, (self, finalizer) => onExit(self, _ => finalizer));
1971
+ export const onExitIf = /*#__PURE__*/dual(3, (self, refinement, f) => onExit(self, exit => refinement(exit) ? f(exit) : exitVoid));
1860
1972
  /**
1861
1973
  * When the `Micro` effect fails, run the given finalizer effect with the
1862
1974
  * `MicroCause` of the executed effect.
@@ -1865,7 +1977,7 @@ export const ensuring = /*#__PURE__*/dual(2, (self, finalizer) => onExit(self, _
1865
1977
  * @experimental
1866
1978
  * @category resources & finalization
1867
1979
  */
1868
- export const onError = /*#__PURE__*/dual(2, (self, f) => onExitIf(self, exitIsFailure, exit => f(exit.left)));
1980
+ export const onError = /*#__PURE__*/dual(2, (self, f) => onExitIf(self, exitIsFailure, exit => f(exit.cause)));
1869
1981
  /**
1870
1982
  * If this `Micro` effect is aborted, run the finalizer effect.
1871
1983
  *
@@ -1882,7 +1994,7 @@ export const onInterrupt = /*#__PURE__*/dual(2, (self, finalizer) => onExitIf(se
1882
1994
  * @experimental
1883
1995
  * @category resources & finalization
1884
1996
  */
1885
- export const acquireUseRelease = (acquire, use, release) => uninterruptibleMask(restore => flatMap(acquire, a => flatMap(exit(restore(use(a))), exit => andThen(release(a, exit), fromExit(exit)))));
1997
+ export const acquireUseRelease = (acquire, use, release) => uninterruptibleMask(restore => flatMap(acquire, a => flatMap(exit(restore(use(a))), exit => andThen(release(a, exit), exit))));
1886
1998
  // ----------------------------------------------------------------------------
1887
1999
  // interruption
1888
2000
  // ----------------------------------------------------------------------------
@@ -1893,27 +2005,45 @@ export const acquireUseRelease = (acquire, use, release) => uninterruptibleMask(
1893
2005
  * @experimental
1894
2006
  * @category interruption
1895
2007
  */
1896
- export const interrupt = /*#__PURE__*/make(function (env, onExit) {
1897
- const controller = envGet(env, currentAbortController);
1898
- controller.abort();
1899
- onExit(exitInterrupt);
2008
+ export const interrupt = /*#__PURE__*/failCause( /*#__PURE__*/causeInterrupt());
2009
+ /**
2010
+ * Flag the effect as uninterruptible, which means that when the effect is
2011
+ * interrupted, it will be allowed to continue running until completion.
2012
+ *
2013
+ * @since 3.4.0
2014
+ * @experimental
2015
+ * @category flags
2016
+ */
2017
+ export const uninterruptible = self => withFiber(fiber => {
2018
+ if (!fiber.interruptible) return self;
2019
+ fiber.interruptible = false;
2020
+ fiber._stack.push(setInterruptible(true));
2021
+ return self;
2022
+ });
2023
+ const setInterruptible = /*#__PURE__*/makePrimitive({
2024
+ op: "SetInterruptible",
2025
+ ensure(fiber) {
2026
+ fiber.interruptible = this[args];
2027
+ if (fiber._interrupted && fiber.interruptible) {
2028
+ return () => exitInterrupt;
2029
+ }
2030
+ }
1900
2031
  });
1901
2032
  /**
1902
- * Wrap the given `Micro` effect in an uninterruptible region, preventing the
1903
- * effect from being aborted.
2033
+ * Flag the effect as interruptible, which means that when the effect is
2034
+ * interrupted, it will be interrupted immediately.
1904
2035
  *
1905
2036
  * @since 3.4.0
1906
2037
  * @experimental
1907
- * @category interruption
2038
+ * @category flags
1908
2039
  */
1909
- export const uninterruptible = self => unsafeMakeOptions(function (env, onExit) {
1910
- const nextEnv = envMutate(env, function (env) {
1911
- env[currentInterruptible.key] = false;
1912
- env[currentAbortSignal.key] = new AbortController().signal;
1913
- return env;
1914
- });
1915
- self[runSymbol](nextEnv, onExit);
1916
- }, false);
2040
+ export const interruptible = self => withFiber(fiber => {
2041
+ if (fiber.interruptible) return self;
2042
+ fiber.interruptible = true;
2043
+ fiber._stack.push(setInterruptible(false));
2044
+ if (fiber._interrupted) return exitInterrupt;
2045
+ return self;
2046
+ });
1917
2047
  /**
1918
2048
  * Wrap the given `Micro` effect in an uninterruptible region, preventing the
1919
2049
  * effect from being aborted.
@@ -1925,6 +2055,7 @@ export const uninterruptible = self => unsafeMakeOptions(function (env, onExit)
1925
2055
  * @experimental
1926
2056
  * @category interruption
1927
2057
  * @example
2058
+ * ```ts
1928
2059
  * import * as Micro from "effect/Micro"
1929
2060
  *
1930
2061
  * Micro.uninterruptibleMask((restore) =>
@@ -1932,37 +2063,13 @@ export const uninterruptible = self => unsafeMakeOptions(function (env, onExit)
1932
2063
  * Micro.andThen(restore(Micro.sleep(1000))) // interruptible
1933
2064
  * )
1934
2065
  * )
2066
+ * ```
1935
2067
  */
1936
- export const uninterruptibleMask = f => unsafeMakeOptions((env, onExit) => {
1937
- const isInterruptible = envGet(env, currentInterruptible);
1938
- const effect = isInterruptible ? f(interruptible) : f(identity);
1939
- const nextEnv = isInterruptible ? envMutate(env, function (env) {
1940
- env[currentInterruptible.key] = false;
1941
- env[currentAbortSignal.key] = new AbortController().signal;
1942
- return env;
1943
- }) : env;
1944
- effect[runSymbol](nextEnv, onExit);
1945
- }, false);
1946
- /**
1947
- * Wrap the given `Micro` effect in an interruptible region, allowing the effect
1948
- * to be aborted.
1949
- *
1950
- * @since 3.4.0
1951
- * @experimental
1952
- * @category interruption
1953
- */
1954
- export const interruptible = self => make((env, onExit) => {
1955
- const isInterruptible = envGet(env, currentInterruptible);
1956
- let newEnv = env;
1957
- if (!isInterruptible) {
1958
- const controller = envGet(env, currentAbortController);
1959
- newEnv = envMutate(env, function (env) {
1960
- env[currentInterruptible.key] = true;
1961
- env[currentAbortSignal.key] = controller.signal;
1962
- return env;
1963
- });
1964
- }
1965
- self[runSymbol](newEnv, onExit);
2068
+ export const uninterruptibleMask = f => withFiber(fiber => {
2069
+ if (!fiber.interruptible) return f(identity);
2070
+ fiber.interruptible = false;
2071
+ fiber._stack.push(setInterruptible(true));
2072
+ return f(interruptible);
1966
2073
  });
1967
2074
  /**
1968
2075
  * Runs all the provided effects in sequence respecting the structure provided in input.
@@ -1989,6 +2096,29 @@ export const all = (arg, options) => {
1989
2096
  }), out);
1990
2097
  });
1991
2098
  };
2099
+ /**
2100
+ * @since 3.11.0
2101
+ * @experimental
2102
+ * @category collecting & elements
2103
+ */
2104
+ export const whileLoop = /*#__PURE__*/makePrimitive({
2105
+ op: "While",
2106
+ contA(value, fiber) {
2107
+ this[args].step(value);
2108
+ if (this[args].while()) {
2109
+ fiber._stack.push(this);
2110
+ return this[args].body();
2111
+ }
2112
+ return exitVoid;
2113
+ },
2114
+ eval(fiber) {
2115
+ if (this[args].while()) {
2116
+ fiber._stack.push(this);
2117
+ return this[args].body();
2118
+ }
2119
+ return exitVoid;
2120
+ }
2121
+ });
1992
2122
  /**
1993
2123
  * For each element of the provided iterable, run the effect and collect the results.
1994
2124
  *
@@ -2002,58 +2132,76 @@ export const all = (arg, options) => {
2002
2132
  * @experimental
2003
2133
  * @category collecting & elements
2004
2134
  */
2005
- export const forEach = (iterable, f, options) => make(function (env, onExit) {
2006
- const concurrencyOption = options?.concurrency === "inherit" ? envGet(env, currentConcurrency) : options?.concurrency ?? 1;
2135
+ export const forEach = (iterable, f, options) => withFiber(parent => {
2136
+ const concurrencyOption = options?.concurrency === "inherit" ? parent.getRef(CurrentConcurrency) : options?.concurrency ?? 1;
2007
2137
  const concurrency = concurrencyOption === "unbounded" ? Number.POSITIVE_INFINITY : Math.max(1, concurrencyOption);
2008
- // abort
2009
- const [envWithSignal, onAbort] = forkSignal(env);
2010
- // iterate
2011
- let result = undefined;
2012
- const items = Array.from(iterable);
2138
+ const items = Arr.fromIterable(iterable);
2013
2139
  let length = items.length;
2014
2140
  if (length === 0) {
2015
- return onExit(Either.right(options?.discard ? undefined : []));
2141
+ return options?.discard ? void_ : succeed([]);
2016
2142
  }
2017
2143
  const out = options?.discard ? undefined : new Array(length);
2018
2144
  let index = 0;
2019
- let inProgress = 0;
2020
- let doneCount = 0;
2021
- let pumping = false;
2022
- function pump() {
2023
- pumping = true;
2024
- while (inProgress < concurrency && index < length) {
2025
- const currentIndex = index;
2026
- const item = items[currentIndex];
2027
- index++;
2028
- inProgress++;
2029
- try {
2030
- f(item, currentIndex)[runSymbol](envWithSignal, function (exit) {
2031
- if (exit._tag === "Left") {
2032
- if (result === undefined) {
2033
- result = exit;
2034
- length = index;
2035
- onAbort();
2145
+ if (concurrency === 1) {
2146
+ return as(whileLoop({
2147
+ while: () => index < items.length,
2148
+ body: () => f(items[index], index),
2149
+ step: out ? b => out[index++] = b : _ => index++
2150
+ }), out);
2151
+ }
2152
+ return async(resume => {
2153
+ const fibers = new Set();
2154
+ let result = undefined;
2155
+ let inProgress = 0;
2156
+ let doneCount = 0;
2157
+ let pumping = false;
2158
+ let interrupted = false;
2159
+ function pump() {
2160
+ pumping = true;
2161
+ while (inProgress < concurrency && index < length) {
2162
+ const currentIndex = index;
2163
+ const item = items[currentIndex];
2164
+ index++;
2165
+ inProgress++;
2166
+ try {
2167
+ const child = unsafeFork(parent, f(item, currentIndex), true, true);
2168
+ fibers.add(child);
2169
+ child.addObserver(exit => {
2170
+ fibers.delete(child);
2171
+ if (interrupted) {
2172
+ return;
2173
+ } else if (exit._tag === "Failure") {
2174
+ if (result === undefined) {
2175
+ result = exit;
2176
+ length = index;
2177
+ fibers.forEach(fiber => fiber.unsafeInterrupt());
2178
+ }
2179
+ } else if (out !== undefined) {
2180
+ out[currentIndex] = exit.value;
2036
2181
  }
2037
- } else if (out !== undefined) {
2038
- out[currentIndex] = exit.right;
2039
- }
2040
- doneCount++;
2041
- inProgress--;
2042
- if (doneCount === length) {
2043
- onExit(result ?? Either.right(out));
2044
- } else if (!pumping && inProgress < concurrency) {
2045
- pump();
2046
- }
2047
- });
2048
- } catch (err) {
2049
- result = exitDie(err);
2050
- length = index;
2051
- onAbort();
2182
+ doneCount++;
2183
+ inProgress--;
2184
+ if (doneCount === length) {
2185
+ resume(result ?? succeed(out));
2186
+ } else if (!pumping && inProgress < concurrency) {
2187
+ pump();
2188
+ }
2189
+ });
2190
+ } catch (err) {
2191
+ result = exitDie(err);
2192
+ length = index;
2193
+ fibers.forEach(fiber => fiber.unsafeInterrupt());
2194
+ }
2052
2195
  }
2196
+ pumping = false;
2053
2197
  }
2054
- pumping = false;
2055
- }
2056
- pump();
2198
+ pump();
2199
+ return suspend(() => {
2200
+ interrupted = true;
2201
+ index = length;
2202
+ return fiberInterruptAll(fibers);
2203
+ });
2204
+ });
2057
2205
  });
2058
2206
  /**
2059
2207
  * Effectfully filter the elements of the provided iterable.
@@ -2126,92 +2274,8 @@ export {
2126
2274
  */
2127
2275
  let_ as let };
2128
2276
  // ----------------------------------------------------------------------------
2129
- // handle & forking
2277
+ // fibers & forking
2130
2278
  // ----------------------------------------------------------------------------
2131
- /**
2132
- * @since 3.4.0
2133
- * @experimental
2134
- * @category handle & forking
2135
- */
2136
- export const HandleTypeId = /*#__PURE__*/Symbol.for("effect/Micro/Handle");
2137
- /**
2138
- * @since 3.4.0
2139
- * @experimental
2140
- * @category handle & forking
2141
- */
2142
- export const isHandle = u => typeof u === "object" && u !== null && HandleTypeId in u;
2143
- class HandleImpl extends Class {
2144
- parentSignal;
2145
- [HandleTypeId];
2146
- observers = /*#__PURE__*/new Set();
2147
- _exit = undefined;
2148
- _controller;
2149
- isRoot;
2150
- constructor(parentSignal, controller) {
2151
- super();
2152
- this.parentSignal = parentSignal;
2153
- this[HandleTypeId] = HandleTypeId;
2154
- this.isRoot = controller !== undefined;
2155
- this._controller = controller ?? new AbortController();
2156
- if (!this.isRoot) {
2157
- parentSignal.addEventListener("abort", this.unsafeInterrupt);
2158
- }
2159
- }
2160
- unsafePoll() {
2161
- return this._exit ?? null;
2162
- }
2163
- unsafeInterrupt = () => {
2164
- this._controller.abort();
2165
- };
2166
- emit(exit) {
2167
- if (this._exit) {
2168
- return;
2169
- }
2170
- this._exit = exit;
2171
- if (!this.isRoot) {
2172
- this.parentSignal.removeEventListener("abort", this.unsafeInterrupt);
2173
- }
2174
- this.observers.forEach(observer => observer(exit));
2175
- this.observers.clear();
2176
- }
2177
- addObserver(observer) {
2178
- if (this._exit) {
2179
- return observer(this._exit);
2180
- }
2181
- this.observers.add(observer);
2182
- }
2183
- removeObserver(observer) {
2184
- this.observers.delete(observer);
2185
- }
2186
- get await() {
2187
- return suspend(() => {
2188
- if (this._exit) {
2189
- return succeed(this._exit);
2190
- }
2191
- return async(resume => {
2192
- function observer(exit) {
2193
- resume(succeed(exit));
2194
- }
2195
- this.addObserver(observer);
2196
- return sync(() => {
2197
- this.removeObserver(observer);
2198
- });
2199
- });
2200
- });
2201
- }
2202
- get join() {
2203
- return flatMap(this.await, fromExit);
2204
- }
2205
- get interrupt() {
2206
- return suspend(() => {
2207
- this.unsafeInterrupt();
2208
- return this.await;
2209
- });
2210
- }
2211
- asMicro() {
2212
- return this.join;
2213
- }
2214
- }
2215
2279
  /**
2216
2280
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2217
2281
  * aborted.
@@ -2222,21 +2286,23 @@ class HandleImpl extends Class {
2222
2286
  * @experimental
2223
2287
  * @category handle & forking
2224
2288
  */
2225
- export const fork = self => make(function (env, onExit) {
2226
- const signal = envGet(env, currentAbortSignal);
2227
- const handle = new HandleImpl(signal);
2228
- const nextEnv = envMutate(env, map => {
2229
- map[currentAbortController.key] = handle._controller;
2230
- map[currentAbortSignal.key] = handle._controller.signal;
2231
- return map;
2232
- });
2233
- envGet(env, currentScheduler).scheduleTask(() => {
2234
- self[runSymbol](nextEnv, exit => {
2235
- handle.emit(exit);
2236
- });
2237
- }, 0);
2238
- onExit(Either.right(handle));
2289
+ export const fork = self => withFiber(fiber => {
2290
+ fiberMiddleware.interruptChildren ??= fiberInterruptChildren;
2291
+ return succeed(unsafeFork(fiber, self));
2239
2292
  });
2293
+ const unsafeFork = (parent, effect, immediate = false, daemon = false) => {
2294
+ const child = new FiberImpl(parent.context, parent.interruptible);
2295
+ if (!daemon) {
2296
+ parent.children().add(child);
2297
+ child.addObserver(() => parent.children().delete(child));
2298
+ }
2299
+ if (immediate) {
2300
+ child.evaluate(effect);
2301
+ } else {
2302
+ parent.getRef(CurrentScheduler).scheduleTask(() => child.evaluate(effect), 0);
2303
+ }
2304
+ return child;
2305
+ };
2240
2306
  /**
2241
2307
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2242
2308
  * aborted.
@@ -2247,21 +2313,7 @@ export const fork = self => make(function (env, onExit) {
2247
2313
  * @experimental
2248
2314
  * @category handle & forking
2249
2315
  */
2250
- export const forkDaemon = self => make(function (env, onExit) {
2251
- const controller = new AbortController();
2252
- const handle = new HandleImpl(controller.signal, controller);
2253
- const nextEnv = envMutate(env, map => {
2254
- map[currentAbortController.key] = controller;
2255
- map[currentAbortSignal.key] = controller.signal;
2256
- return map;
2257
- });
2258
- envGet(env, currentScheduler).scheduleTask(() => {
2259
- self[runSymbol](nextEnv, exit => {
2260
- handle.emit(exit);
2261
- });
2262
- }, 0);
2263
- onExit(Either.right(handle));
2264
- });
2316
+ export const forkDaemon = self => withFiber(fiber => succeed(unsafeFork(fiber, self, false, true)));
2265
2317
  /**
2266
2318
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2267
2319
  * aborted.
@@ -2272,7 +2324,7 @@ export const forkDaemon = self => make(function (env, onExit) {
2272
2324
  * @experimental
2273
2325
  * @category handle & forking
2274
2326
  */
2275
- export const forkIn = /*#__PURE__*/dual(2, (self, scope) => uninterruptibleMask(restore => flatMap(scope.fork, scope => tap(restore(forkDaemon(onExit(self, exit => scope.close(exit)))), fiber => scope.addFinalizer(_ => asVoid(fiber.interrupt))))));
2327
+ export const forkIn = /*#__PURE__*/dual(2, (self, scope) => uninterruptibleMask(restore => flatMap(scope.fork, scope => tap(restore(forkDaemon(onExit(self, exit => scope.close(exit)))), fiber => scope.addFinalizer(_ => fiberInterrupt(fiber))))));
2276
2328
  /**
2277
2329
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2278
2330
  * aborted.
@@ -2298,6 +2350,7 @@ export const forkScoped = self => flatMap(scope, scope => forkIn(self, scope));
2298
2350
  * @experimental
2299
2351
  * @category execution
2300
2352
  * @example
2353
+ * ```ts
2301
2354
  * import * as Micro from "effect/Micro"
2302
2355
  *
2303
2356
  * const handle = Micro.succeed(42).pipe(
@@ -2308,31 +2361,23 @@ export const forkScoped = self => flatMap(scope, scope => forkIn(self, scope));
2308
2361
  * handle.addObserver((exit) => {
2309
2362
  * console.log(exit)
2310
2363
  * })
2364
+ * ```
2311
2365
  */
2312
2366
  export const runFork = (effect, options) => {
2313
- const controller = new AbortController();
2314
- const refs = Object.create(null);
2315
- refs[currentAbortController.key] = controller;
2316
- refs[currentAbortSignal.key] = controller.signal;
2317
- refs[currentScheduler.key] = options?.scheduler ?? new MicroSchedulerDefault();
2318
- const env = envMake(refs);
2319
- const handle = new HandleImpl(controller.signal, controller);
2320
- effect[runSymbol](envSet(env, currentAbortSignal, handle._controller.signal), exit => {
2321
- handle.emit(exit);
2322
- if (options?.signal) {
2323
- options.signal.removeEventListener("abort", handle.unsafeInterrupt);
2324
- }
2325
- });
2367
+ const fiber = new FiberImpl(CurrentScheduler.context(options?.scheduler ?? new MicroSchedulerDefault()));
2368
+ fiber.evaluate(effect);
2326
2369
  if (options?.signal) {
2327
2370
  if (options.signal.aborted) {
2328
- handle.unsafeInterrupt();
2371
+ fiber.unsafeInterrupt();
2329
2372
  } else {
2330
- options.signal.addEventListener("abort", handle.unsafeInterrupt, {
2373
+ const abort = () => fiber.unsafeInterrupt();
2374
+ options.signal.addEventListener("abort", abort, {
2331
2375
  once: true
2332
2376
  });
2377
+ fiber.addObserver(() => options.signal.removeEventListener("abort", abort));
2333
2378
  }
2334
2379
  }
2335
- return handle;
2380
+ return fiber;
2336
2381
  };
2337
2382
  /**
2338
2383
  * Execute the `Micro` effect and return a `Promise` that resolves with the
@@ -2355,10 +2400,10 @@ export const runPromiseExit = (effect, options) => new Promise((resolve, _reject
2355
2400
  * @category execution
2356
2401
  */
2357
2402
  export const runPromise = (effect, options) => runPromiseExit(effect, options).then(exit => {
2358
- if (exit._tag === "Left") {
2359
- throw exit.left;
2403
+ if (exit._tag === "Failure") {
2404
+ throw exit.cause;
2360
2405
  }
2361
- return exit.right;
2406
+ return exit.value;
2362
2407
  });
2363
2408
  /**
2364
2409
  * Attempt to execute the `Micro` effect synchronously and return the `MicroExit`.
@@ -2372,15 +2417,11 @@ export const runPromise = (effect, options) => runPromiseExit(effect, options).t
2372
2417
  */
2373
2418
  export const runSyncExit = effect => {
2374
2419
  const scheduler = new MicroSchedulerDefault();
2375
- const handle = runFork(effect, {
2420
+ const fiber = runFork(effect, {
2376
2421
  scheduler
2377
2422
  });
2378
2423
  scheduler.flush();
2379
- const exit = handle.unsafePoll();
2380
- if (exit === null) {
2381
- return exitDie(handle);
2382
- }
2383
- return exit;
2424
+ return fiber._exit ?? exitDie(fiber);
2384
2425
  };
2385
2426
  /**
2386
2427
  * Attempt to execute the `Micro` effect synchronously and return the success
@@ -2392,24 +2433,24 @@ export const runSyncExit = effect => {
2392
2433
  */
2393
2434
  export const runSync = effect => {
2394
2435
  const exit = runSyncExit(effect);
2395
- if (exit._tag === "Left") {
2396
- throw exit.left;
2397
- }
2398
- return exit.right;
2436
+ if (exit._tag === "Failure") throw exit.cause;
2437
+ return exit.value;
2399
2438
  };
2400
2439
  const YieldableError = /*#__PURE__*/function () {
2401
- class YieldableError extends globalThis.Error {
2402
- [runSymbol](_env, onExit) {
2403
- onExit(exitFail(this));
2404
- }
2440
+ class YieldableError extends globalThis.Error {}
2441
+ Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype, {
2442
+ [identifier]: "Failure",
2443
+ [evaluate]() {
2444
+ return fail(this);
2445
+ },
2405
2446
  toString() {
2406
2447
  return this.message ? `${this.name}: ${this.message}` : this.name;
2407
- }
2448
+ },
2408
2449
  toJSON() {
2409
2450
  return {
2410
2451
  ...this
2411
2452
  };
2412
- }
2453
+ },
2413
2454
  [NodeInspectSymbol]() {
2414
2455
  const stack = this.stack;
2415
2456
  if (stack) {
@@ -2417,8 +2458,7 @@ const YieldableError = /*#__PURE__*/function () {
2417
2458
  }
2418
2459
  return this.toString();
2419
2460
  }
2420
- }
2421
- Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype);
2461
+ });
2422
2462
  return YieldableError;
2423
2463
  }();
2424
2464
  /**