@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.2

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 (452) hide show
  1. package/SourceLocation/package.json +6 -0
  2. package/dist/cjs/Effect.js +2 -28
  3. package/dist/cjs/Effect.js.map +1 -1
  4. package/dist/cjs/FiberRef.js +12 -1
  5. package/dist/cjs/FiberRef.js.map +1 -1
  6. package/dist/cjs/Layer.js +2 -24
  7. package/dist/cjs/Layer.js.map +1 -1
  8. package/dist/cjs/RuntimeFlags.js +1 -29
  9. package/dist/cjs/RuntimeFlags.js.map +1 -1
  10. package/dist/cjs/SourceLocation.js +60 -0
  11. package/dist/cjs/SourceLocation.js.map +1 -0
  12. package/dist/cjs/Tracer.js +1 -15
  13. package/dist/cjs/Tracer.js.map +1 -1
  14. package/dist/cjs/Utils.js +1 -1
  15. package/dist/cjs/Utils.js.map +1 -1
  16. package/dist/cjs/index.js +3 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/internal/clock.js +1 -1
  19. package/dist/cjs/internal/clock.js.map +1 -1
  20. package/dist/cjs/internal/core.js +17 -50
  21. package/dist/cjs/internal/core.js.map +1 -1
  22. package/dist/cjs/internal/effect/circular.js +18 -30
  23. package/dist/cjs/internal/effect/circular.js.map +1 -1
  24. package/dist/cjs/internal/fiberRuntime.js +16 -65
  25. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  26. package/dist/cjs/internal/layer/circular.js +1 -5
  27. package/dist/cjs/internal/layer/circular.js.map +1 -1
  28. package/dist/cjs/internal/layer.js +1 -3
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/logger.js +25 -2
  31. package/dist/cjs/internal/logger.js.map +1 -1
  32. package/dist/cjs/internal/runtimeFlags.js +2 -11
  33. package/dist/cjs/internal/runtimeFlags.js.map +1 -1
  34. package/dist/cjs/internal/tracer.js +1 -114
  35. package/dist/cjs/internal/tracer.js.map +1 -1
  36. package/dist/dts/Config.d.ts +2 -2
  37. package/dist/dts/Config.d.ts.map +1 -1
  38. package/dist/dts/Effect.d.ts +8 -29
  39. package/dist/dts/Effect.d.ts.map +1 -1
  40. package/dist/dts/FiberRef.d.ts +12 -0
  41. package/dist/dts/FiberRef.d.ts.map +1 -1
  42. package/dist/dts/Layer.d.ts +0 -22
  43. package/dist/dts/Layer.d.ts.map +1 -1
  44. package/dist/dts/RuntimeFlags.d.ts +0 -28
  45. package/dist/dts/RuntimeFlags.d.ts.map +1 -1
  46. package/dist/dts/SourceLocation.d.ts +88 -0
  47. package/dist/dts/SourceLocation.d.ts.map +1 -0
  48. package/dist/dts/Tracer.d.ts +0 -15
  49. package/dist/dts/Tracer.d.ts.map +1 -1
  50. package/dist/dts/index.d.ts +6 -0
  51. package/dist/dts/index.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/layer.d.ts.map +1 -1
  54. package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
  55. package/dist/esm/Effect.js +0 -26
  56. package/dist/esm/Effect.js.map +1 -1
  57. package/dist/esm/FiberRef.js +11 -0
  58. package/dist/esm/FiberRef.js.map +1 -1
  59. package/dist/esm/Layer.js +0 -22
  60. package/dist/esm/Layer.js.map +1 -1
  61. package/dist/esm/RuntimeFlags.js +0 -28
  62. package/dist/esm/RuntimeFlags.js.map +1 -1
  63. package/dist/esm/SourceLocation.js +51 -0
  64. package/dist/esm/SourceLocation.js.map +1 -0
  65. package/dist/esm/Tracer.js +0 -14
  66. package/dist/esm/Tracer.js.map +1 -1
  67. package/dist/esm/Utils.js +1 -1
  68. package/dist/esm/Utils.js.map +1 -1
  69. package/dist/esm/index.js +6 -0
  70. package/dist/esm/index.js.map +1 -1
  71. package/dist/esm/internal/clock.js +1 -1
  72. package/dist/esm/internal/clock.js.map +1 -1
  73. package/dist/esm/internal/core.js +12 -45
  74. package/dist/esm/internal/core.js.map +1 -1
  75. package/dist/esm/internal/effect/circular.js +18 -30
  76. package/dist/esm/internal/effect/circular.js.map +1 -1
  77. package/dist/esm/internal/fiberRuntime.js +13 -60
  78. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  79. package/dist/esm/internal/layer/circular.js +0 -4
  80. package/dist/esm/internal/layer/circular.js.map +1 -1
  81. package/dist/esm/internal/layer.js +0 -2
  82. package/dist/esm/internal/layer.js.map +1 -1
  83. package/dist/esm/internal/logger.js +25 -2
  84. package/dist/esm/internal/logger.js.map +1 -1
  85. package/dist/esm/internal/runtimeFlags.js +1 -9
  86. package/dist/esm/internal/runtimeFlags.js.map +1 -1
  87. package/dist/esm/internal/tracer.js +0 -111
  88. package/dist/esm/internal/tracer.js.map +1 -1
  89. package/package.json +12 -1
  90. package/src/Arbitrary.ts +1101 -0
  91. package/src/Array.ts +3589 -0
  92. package/src/BigDecimal.ts +1349 -0
  93. package/src/BigInt.ts +643 -0
  94. package/src/Boolean.ts +287 -0
  95. package/src/Brand.ts +360 -0
  96. package/src/Cache.ts +281 -0
  97. package/src/Cause.ts +1555 -0
  98. package/src/Channel.ts +2355 -0
  99. package/src/ChildExecutorDecision.ts +146 -0
  100. package/src/Chunk.ts +1495 -0
  101. package/src/Clock.ts +111 -0
  102. package/src/Config.ts +542 -0
  103. package/src/ConfigError.ts +270 -0
  104. package/src/ConfigProvider.ts +333 -0
  105. package/src/ConfigProviderPathPatch.ts +100 -0
  106. package/src/Console.ts +226 -0
  107. package/src/Context.ts +585 -0
  108. package/src/Cron.ts +706 -0
  109. package/src/Data.ts +596 -0
  110. package/src/DateTime.ts +1686 -0
  111. package/src/DefaultServices.ts +34 -0
  112. package/src/Deferred.ts +301 -0
  113. package/src/Differ.ts +450 -0
  114. package/src/Duration.ts +1000 -0
  115. package/src/Effect.ts +14817 -0
  116. package/src/Effectable.ts +107 -0
  117. package/src/Either.ts +1040 -0
  118. package/src/Encoding.ts +195 -0
  119. package/src/Equal.ts +98 -0
  120. package/src/Equivalence.ts +235 -0
  121. package/src/ExecutionPlan.ts +308 -0
  122. package/src/ExecutionStrategy.ts +119 -0
  123. package/src/Exit.ts +467 -0
  124. package/src/FastCheck.ts +9 -0
  125. package/src/Fiber.ts +744 -0
  126. package/src/FiberHandle.ts +540 -0
  127. package/src/FiberId.ts +195 -0
  128. package/src/FiberMap.ts +656 -0
  129. package/src/FiberRef.ts +444 -0
  130. package/src/FiberRefs.ts +204 -0
  131. package/src/FiberRefsPatch.ts +105 -0
  132. package/src/FiberSet.ts +491 -0
  133. package/src/FiberStatus.ts +108 -0
  134. package/src/Function.ts +1222 -0
  135. package/src/GlobalValue.ts +53 -0
  136. package/src/Graph.ts +3732 -0
  137. package/src/GroupBy.ts +103 -0
  138. package/src/HKT.ts +45 -0
  139. package/src/Hash.ts +195 -0
  140. package/src/HashMap.ts +519 -0
  141. package/src/HashRing.ts +317 -0
  142. package/src/HashSet.ts +2346 -0
  143. package/src/Inspectable.ts +287 -0
  144. package/src/Iterable.ts +1119 -0
  145. package/src/JSONSchema.ts +1044 -0
  146. package/src/KeyedPool.ts +167 -0
  147. package/src/Layer.ts +1228 -0
  148. package/src/LayerMap.ts +436 -0
  149. package/src/List.ts +977 -0
  150. package/src/LogLevel.ts +285 -0
  151. package/src/LogSpan.ts +25 -0
  152. package/src/Logger.ts +702 -0
  153. package/src/Mailbox.ts +268 -0
  154. package/src/ManagedRuntime.ts +180 -0
  155. package/src/Match.ts +1477 -0
  156. package/src/MergeDecision.ts +95 -0
  157. package/src/MergeState.ts +172 -0
  158. package/src/MergeStrategy.ts +107 -0
  159. package/src/Metric.ts +780 -0
  160. package/src/MetricBoundaries.ts +69 -0
  161. package/src/MetricHook.ts +151 -0
  162. package/src/MetricKey.ts +224 -0
  163. package/src/MetricKeyType.ts +262 -0
  164. package/src/MetricLabel.ts +47 -0
  165. package/src/MetricPair.ts +71 -0
  166. package/src/MetricPolling.ts +148 -0
  167. package/src/MetricRegistry.ts +48 -0
  168. package/src/MetricState.ts +257 -0
  169. package/src/Micro.ts +4405 -0
  170. package/src/ModuleVersion.ts +18 -0
  171. package/src/MutableHashMap.ts +411 -0
  172. package/src/MutableHashSet.ts +706 -0
  173. package/src/MutableList.ts +297 -0
  174. package/src/MutableQueue.ts +227 -0
  175. package/src/MutableRef.ts +202 -0
  176. package/src/NonEmptyIterable.ts +32 -0
  177. package/src/Number.ts +1071 -0
  178. package/src/Option.ts +2170 -0
  179. package/src/Order.ts +373 -0
  180. package/src/Ordering.ts +111 -0
  181. package/src/ParseResult.ts +2031 -0
  182. package/src/PartitionedSemaphore.ts +200 -0
  183. package/src/Pipeable.ts +566 -0
  184. package/src/Pool.ts +204 -0
  185. package/src/Predicate.ts +1405 -0
  186. package/src/Pretty.ts +205 -0
  187. package/src/PrimaryKey.ts +23 -0
  188. package/src/PubSub.ts +182 -0
  189. package/src/Queue.ts +644 -0
  190. package/src/Random.ts +204 -0
  191. package/src/RateLimiter.ts +138 -0
  192. package/src/RcMap.ts +141 -0
  193. package/src/RcRef.ts +122 -0
  194. package/src/Readable.ts +93 -0
  195. package/src/Record.ts +1274 -0
  196. package/src/RedBlackTree.ts +421 -0
  197. package/src/Redacted.ts +144 -0
  198. package/src/Ref.ts +180 -0
  199. package/src/RegExp.ts +38 -0
  200. package/src/Reloadable.ts +127 -0
  201. package/src/Request.ts +347 -0
  202. package/src/RequestBlock.ts +118 -0
  203. package/src/RequestResolver.ts +366 -0
  204. package/src/Resource.ts +119 -0
  205. package/src/Runtime.ts +383 -0
  206. package/src/RuntimeFlags.ts +336 -0
  207. package/src/RuntimeFlagsPatch.ts +183 -0
  208. package/src/STM.ts +2045 -0
  209. package/src/Schedule.ts +2219 -0
  210. package/src/ScheduleDecision.ts +62 -0
  211. package/src/ScheduleInterval.ts +151 -0
  212. package/src/ScheduleIntervals.ts +122 -0
  213. package/src/Scheduler.ts +353 -0
  214. package/src/Schema.ts +10914 -0
  215. package/src/SchemaAST.ts +3043 -0
  216. package/src/Scope.ts +204 -0
  217. package/src/ScopedCache.ts +151 -0
  218. package/src/ScopedRef.ts +117 -0
  219. package/src/Secret.ts +88 -0
  220. package/src/SingleProducerAsyncInput.ts +67 -0
  221. package/src/Sink.ts +1461 -0
  222. package/src/SortedMap.ts +287 -0
  223. package/src/SortedSet.ts +390 -0
  224. package/src/SourceLocation.ts +108 -0
  225. package/src/Stream.ts +6468 -0
  226. package/src/StreamEmit.ts +136 -0
  227. package/src/StreamHaltStrategy.ts +123 -0
  228. package/src/Streamable.ts +45 -0
  229. package/src/String.ts +778 -0
  230. package/src/Struct.ts +243 -0
  231. package/src/Subscribable.ts +100 -0
  232. package/src/SubscriptionRef.ts +298 -0
  233. package/src/Supervisor.ts +240 -0
  234. package/src/Symbol.ts +29 -0
  235. package/src/SynchronizedRef.ts +270 -0
  236. package/src/TArray.ts +495 -0
  237. package/src/TDeferred.ts +100 -0
  238. package/src/TMap.ts +515 -0
  239. package/src/TPriorityQueue.ts +223 -0
  240. package/src/TPubSub.ts +200 -0
  241. package/src/TQueue.ts +432 -0
  242. package/src/TRandom.ts +129 -0
  243. package/src/TReentrantLock.ts +224 -0
  244. package/src/TRef.ts +178 -0
  245. package/src/TSemaphore.ts +129 -0
  246. package/src/TSet.ts +365 -0
  247. package/src/TSubscriptionRef.ts +192 -0
  248. package/src/Take.ts +258 -0
  249. package/src/TestAnnotation.ts +158 -0
  250. package/src/TestAnnotationMap.ts +119 -0
  251. package/src/TestAnnotations.ts +117 -0
  252. package/src/TestClock.ts +556 -0
  253. package/src/TestConfig.ts +47 -0
  254. package/src/TestContext.ts +36 -0
  255. package/src/TestLive.ts +53 -0
  256. package/src/TestServices.ts +390 -0
  257. package/src/TestSized.ts +55 -0
  258. package/src/Tracer.ts +182 -0
  259. package/src/Trie.ts +840 -0
  260. package/src/Tuple.ts +305 -0
  261. package/src/Types.ts +353 -0
  262. package/src/Unify.ts +113 -0
  263. package/src/UpstreamPullRequest.ts +117 -0
  264. package/src/UpstreamPullStrategy.ts +121 -0
  265. package/src/Utils.ts +809 -0
  266. package/src/index.ts +1568 -0
  267. package/src/internal/array.ts +8 -0
  268. package/src/internal/blockedRequests.ts +520 -0
  269. package/src/internal/cache.ts +733 -0
  270. package/src/internal/cause.ts +1050 -0
  271. package/src/internal/channel/channelExecutor.ts +1200 -0
  272. package/src/internal/channel/channelState.ts +134 -0
  273. package/src/internal/channel/childExecutorDecision.ts +96 -0
  274. package/src/internal/channel/continuation.ts +200 -0
  275. package/src/internal/channel/mergeDecision.ts +113 -0
  276. package/src/internal/channel/mergeState.ts +120 -0
  277. package/src/internal/channel/mergeStrategy.ts +72 -0
  278. package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
  279. package/src/internal/channel/subexecutor.ts +229 -0
  280. package/src/internal/channel/upstreamPullRequest.ts +84 -0
  281. package/src/internal/channel/upstreamPullStrategy.ts +87 -0
  282. package/src/internal/channel.ts +2603 -0
  283. package/src/internal/clock.ts +95 -0
  284. package/src/internal/completedRequestMap.ts +9 -0
  285. package/src/internal/concurrency.ts +54 -0
  286. package/src/internal/config.ts +716 -0
  287. package/src/internal/configError.ts +304 -0
  288. package/src/internal/configProvider/pathPatch.ts +97 -0
  289. package/src/internal/configProvider.ts +799 -0
  290. package/src/internal/console.ts +153 -0
  291. package/src/internal/context.ts +337 -0
  292. package/src/internal/core-effect.ts +2293 -0
  293. package/src/internal/core-stream.ts +998 -0
  294. package/src/internal/core.ts +3189 -0
  295. package/src/internal/data.ts +36 -0
  296. package/src/internal/dataSource.ts +327 -0
  297. package/src/internal/dateTime.ts +1277 -0
  298. package/src/internal/defaultServices/console.ts +100 -0
  299. package/src/internal/defaultServices.ts +163 -0
  300. package/src/internal/deferred.ts +46 -0
  301. package/src/internal/differ/chunkPatch.ts +211 -0
  302. package/src/internal/differ/contextPatch.ts +232 -0
  303. package/src/internal/differ/hashMapPatch.ts +220 -0
  304. package/src/internal/differ/hashSetPatch.ts +176 -0
  305. package/src/internal/differ/orPatch.ts +311 -0
  306. package/src/internal/differ/readonlyArrayPatch.ts +210 -0
  307. package/src/internal/differ.ts +200 -0
  308. package/src/internal/doNotation.ts +80 -0
  309. package/src/internal/effect/circular.ts +895 -0
  310. package/src/internal/effectable.ts +131 -0
  311. package/src/internal/either.ts +110 -0
  312. package/src/internal/encoding/base64.ts +286 -0
  313. package/src/internal/encoding/base64Url.ts +29 -0
  314. package/src/internal/encoding/common.ts +51 -0
  315. package/src/internal/encoding/hex.ts +315 -0
  316. package/src/internal/errors.ts +7 -0
  317. package/src/internal/executionPlan.ts +114 -0
  318. package/src/internal/executionStrategy.ts +74 -0
  319. package/src/internal/fiber.ts +388 -0
  320. package/src/internal/fiberId.ts +267 -0
  321. package/src/internal/fiberMessage.ts +82 -0
  322. package/src/internal/fiberRefs/patch.ts +144 -0
  323. package/src/internal/fiberRefs.ts +297 -0
  324. package/src/internal/fiberRuntime.ts +3842 -0
  325. package/src/internal/fiberScope.ts +71 -0
  326. package/src/internal/fiberStatus.ts +119 -0
  327. package/src/internal/groupBy.ts +530 -0
  328. package/src/internal/hashMap/array.ts +49 -0
  329. package/src/internal/hashMap/bitwise.ts +32 -0
  330. package/src/internal/hashMap/config.ts +14 -0
  331. package/src/internal/hashMap/keySet.ts +8 -0
  332. package/src/internal/hashMap/node.ts +391 -0
  333. package/src/internal/hashMap.ts +586 -0
  334. package/src/internal/hashSet.ts +323 -0
  335. package/src/internal/keyedPool.ts +244 -0
  336. package/src/internal/layer/circular.ts +214 -0
  337. package/src/internal/layer.ts +1483 -0
  338. package/src/internal/logSpan.ts +20 -0
  339. package/src/internal/logger-circular.ts +24 -0
  340. package/src/internal/logger.ts +522 -0
  341. package/src/internal/mailbox.ts +561 -0
  342. package/src/internal/managedRuntime/circular.ts +6 -0
  343. package/src/internal/managedRuntime.ts +134 -0
  344. package/src/internal/matcher.ts +652 -0
  345. package/src/internal/metric/boundaries.ts +75 -0
  346. package/src/internal/metric/hook.ts +483 -0
  347. package/src/internal/metric/key.ts +167 -0
  348. package/src/internal/metric/keyType.ts +238 -0
  349. package/src/internal/metric/label.ts +41 -0
  350. package/src/internal/metric/pair.ts +48 -0
  351. package/src/internal/metric/polling.ts +149 -0
  352. package/src/internal/metric/registry.ts +187 -0
  353. package/src/internal/metric/state.ts +290 -0
  354. package/src/internal/metric.ts +577 -0
  355. package/src/internal/opCodes/cause.ts +35 -0
  356. package/src/internal/opCodes/channel.ts +83 -0
  357. package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
  358. package/src/internal/opCodes/channelMergeDecision.ts +11 -0
  359. package/src/internal/opCodes/channelMergeState.ts +17 -0
  360. package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
  361. package/src/internal/opCodes/channelState.ts +23 -0
  362. package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
  363. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
  364. package/src/internal/opCodes/config.ts +65 -0
  365. package/src/internal/opCodes/configError.ts +35 -0
  366. package/src/internal/opCodes/continuation.ts +11 -0
  367. package/src/internal/opCodes/deferred.ts +11 -0
  368. package/src/internal/opCodes/effect.ts +89 -0
  369. package/src/internal/opCodes/layer.ts +59 -0
  370. package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
  371. package/src/internal/option.ts +80 -0
  372. package/src/internal/pool.ts +432 -0
  373. package/src/internal/pubsub.ts +1762 -0
  374. package/src/internal/query.ts +204 -0
  375. package/src/internal/queue.ts +766 -0
  376. package/src/internal/random.ts +161 -0
  377. package/src/internal/rateLimiter.ts +93 -0
  378. package/src/internal/rcMap.ts +285 -0
  379. package/src/internal/rcRef.ts +192 -0
  380. package/src/internal/redBlackTree/iterator.ts +200 -0
  381. package/src/internal/redBlackTree/node.ts +68 -0
  382. package/src/internal/redBlackTree.ts +1245 -0
  383. package/src/internal/redacted.ts +73 -0
  384. package/src/internal/ref.ts +171 -0
  385. package/src/internal/reloadable.ts +140 -0
  386. package/src/internal/request.ts +177 -0
  387. package/src/internal/resource.ts +76 -0
  388. package/src/internal/ringBuffer.ts +68 -0
  389. package/src/internal/runtime.ts +558 -0
  390. package/src/internal/runtimeFlags.ts +178 -0
  391. package/src/internal/runtimeFlagsPatch.ts +103 -0
  392. package/src/internal/schedule/decision.ts +47 -0
  393. package/src/internal/schedule/interval.ts +101 -0
  394. package/src/internal/schedule/intervals.ts +180 -0
  395. package/src/internal/schedule.ts +2199 -0
  396. package/src/internal/schema/errors.ts +191 -0
  397. package/src/internal/schema/schemaId.ts +106 -0
  398. package/src/internal/schema/util.ts +50 -0
  399. package/src/internal/scopedCache.ts +644 -0
  400. package/src/internal/scopedRef.ts +118 -0
  401. package/src/internal/secret.ts +89 -0
  402. package/src/internal/singleShotGen.ts +35 -0
  403. package/src/internal/sink.ts +2120 -0
  404. package/src/internal/stack.ts +10 -0
  405. package/src/internal/stm/core.ts +817 -0
  406. package/src/internal/stm/entry.ts +59 -0
  407. package/src/internal/stm/journal.ts +123 -0
  408. package/src/internal/stm/opCodes/stm.ts +71 -0
  409. package/src/internal/stm/opCodes/stmState.ts +17 -0
  410. package/src/internal/stm/opCodes/strategy.ts +17 -0
  411. package/src/internal/stm/opCodes/tExit.ts +29 -0
  412. package/src/internal/stm/opCodes/tryCommit.ts +11 -0
  413. package/src/internal/stm/stm.ts +1453 -0
  414. package/src/internal/stm/stmState.ts +136 -0
  415. package/src/internal/stm/tArray.ts +550 -0
  416. package/src/internal/stm/tDeferred.ts +81 -0
  417. package/src/internal/stm/tExit.ts +190 -0
  418. package/src/internal/stm/tMap.ts +824 -0
  419. package/src/internal/stm/tPriorityQueue.ts +267 -0
  420. package/src/internal/stm/tPubSub.ts +551 -0
  421. package/src/internal/stm/tQueue.ts +393 -0
  422. package/src/internal/stm/tRandom.ts +140 -0
  423. package/src/internal/stm/tReentrantLock.ts +352 -0
  424. package/src/internal/stm/tRef.ts +195 -0
  425. package/src/internal/stm/tSemaphore.ts +113 -0
  426. package/src/internal/stm/tSet.ts +259 -0
  427. package/src/internal/stm/tSubscriptionRef.ts +286 -0
  428. package/src/internal/stm/tryCommit.ts +34 -0
  429. package/src/internal/stm/txnId.ts +14 -0
  430. package/src/internal/stm/versioned.ts +4 -0
  431. package/src/internal/stream/debounceState.ts +57 -0
  432. package/src/internal/stream/emit.ts +123 -0
  433. package/src/internal/stream/haltStrategy.ts +94 -0
  434. package/src/internal/stream/handoff.ts +187 -0
  435. package/src/internal/stream/handoffSignal.ts +59 -0
  436. package/src/internal/stream/pull.ts +34 -0
  437. package/src/internal/stream/sinkEndReason.ts +30 -0
  438. package/src/internal/stream/zipAllState.ts +88 -0
  439. package/src/internal/stream/zipChunksState.ts +56 -0
  440. package/src/internal/stream.ts +8801 -0
  441. package/src/internal/string-utils.ts +107 -0
  442. package/src/internal/subscriptionRef.ts +138 -0
  443. package/src/internal/supervisor/patch.ts +190 -0
  444. package/src/internal/supervisor.ts +303 -0
  445. package/src/internal/synchronizedRef.ts +114 -0
  446. package/src/internal/take.ts +199 -0
  447. package/src/internal/testing/sleep.ts +27 -0
  448. package/src/internal/testing/suspendedWarningData.ts +85 -0
  449. package/src/internal/testing/warningData.ts +94 -0
  450. package/src/internal/tracer.ts +150 -0
  451. package/src/internal/trie.ts +722 -0
  452. package/src/internal/version.ts +7 -0
package/src/Micro.ts ADDED
@@ -0,0 +1,4405 @@
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 "./Array.js"
8
+ import type { Channel } from "./Channel.js"
9
+ import * as Context from "./Context.js"
10
+ import type { Effect, EffectUnify, EffectUnifyIgnore } from "./Effect.js"
11
+ import * as Effectable from "./Effectable.js"
12
+ import * as Either from "./Either.js"
13
+ import * as Equal from "./Equal.js"
14
+ import type { LazyArg } from "./Function.js"
15
+ import { constTrue, constVoid, dual, identity } from "./Function.js"
16
+ import { globalValue } from "./GlobalValue.js"
17
+ import * as Hash from "./Hash.js"
18
+ import type { TypeLambda } from "./HKT.js"
19
+ import type { Inspectable } from "./Inspectable.js"
20
+ import { format, NodeInspectSymbol, toStringUnknown } from "./Inspectable.js"
21
+ import * as InternalContext from "./internal/context.js"
22
+ import * as doNotation from "./internal/doNotation.js"
23
+ import { StructuralPrototype } from "./internal/effectable.js"
24
+ import * as Option from "./Option.js"
25
+ import type { Pipeable } from "./Pipeable.js"
26
+ import { pipeArguments } from "./Pipeable.js"
27
+ import type { Predicate, Refinement } from "./Predicate.js"
28
+ import { hasProperty, isIterable, isTagged } from "./Predicate.js"
29
+ import type { Sink } from "./Sink.js"
30
+ import type { Stream } from "./Stream.js"
31
+ import type { Concurrency, Covariant, Equals, NoExcessProperties, NotFunction, Simplify } from "./Types.js"
32
+ import type * as Unify from "./Unify.js"
33
+ import { SingleShotGen, YieldWrap, yieldWrapGet } from "./Utils.js"
34
+
35
+ /**
36
+ * @since 3.4.0
37
+ * @experimental
38
+ * @category type ids
39
+ */
40
+ export const TypeId: unique symbol = Symbol.for("effect/Micro")
41
+
42
+ /**
43
+ * @since 3.4.0
44
+ * @experimental
45
+ * @category type ids
46
+ */
47
+ export type TypeId = typeof TypeId
48
+
49
+ /**
50
+ * @since 3.4.0
51
+ * @experimental
52
+ * @category MicroExit
53
+ */
54
+ export const MicroExitTypeId: unique symbol = Symbol.for(
55
+ "effect/Micro/MicroExit"
56
+ )
57
+
58
+ /**
59
+ * @since 3.4.0
60
+ * @experimental
61
+ * @category MicroExit
62
+ */
63
+ export type MicroExitTypeId = typeof TypeId
64
+
65
+ /**
66
+ * A lightweight alternative to the `Effect` data type, with a subset of the functionality.
67
+ *
68
+ * @since 3.4.0
69
+ * @experimental
70
+ * @category models
71
+ */
72
+ export interface Micro<out A, out E = never, out R = never> extends Effect<A, E, R> {
73
+ readonly [TypeId]: Micro.Variance<A, E, R>
74
+ [Symbol.iterator](): MicroIterator<Micro<A, E, R>>
75
+ [Unify.typeSymbol]?: unknown
76
+ [Unify.unifySymbol]?: MicroUnify<this>
77
+ [Unify.ignoreSymbol]?: MicroUnifyIgnore
78
+ }
79
+
80
+ /**
81
+ * @category models
82
+ * @since 3.4.3
83
+ */
84
+ export interface MicroUnify<A extends { [Unify.typeSymbol]?: any }> extends EffectUnify<A> {
85
+ Micro?: () => A[Unify.typeSymbol] extends Micro<infer A0, infer E0, infer R0> | infer _ ? Micro<A0, E0, R0> : never
86
+ }
87
+
88
+ /**
89
+ * @category models
90
+ * @since 3.4.3
91
+ */
92
+ export interface MicroUnifyIgnore extends EffectUnifyIgnore {
93
+ Effect?: true
94
+ }
95
+ /**
96
+ * @category type lambdas
97
+ * @since 3.4.1
98
+ */
99
+ export interface MicroTypeLambda extends TypeLambda {
100
+ readonly type: Micro<this["Target"], this["Out1"], this["Out2"]>
101
+ }
102
+
103
+ /**
104
+ * @since 3.4.0
105
+ * @experimental
106
+ */
107
+ export declare namespace Micro {
108
+ /**
109
+ * @since 3.4.0
110
+ * @experimental
111
+ */
112
+ export interface Variance<A, E, R> {
113
+ _A: Covariant<A>
114
+ _E: Covariant<E>
115
+ _R: Covariant<R>
116
+ }
117
+
118
+ /**
119
+ * @since 3.4.0
120
+ * @experimental
121
+ */
122
+ export type Success<T> = T extends Micro<infer _A, infer _E, infer _R> ? _A : never
123
+
124
+ /**
125
+ * @since 3.4.0
126
+ * @experimental
127
+ */
128
+ export type Error<T> = T extends Micro<infer _A, infer _E, infer _R> ? _E : never
129
+
130
+ /**
131
+ * @since 3.4.0
132
+ * @experimental
133
+ */
134
+ export type Context<T> = T extends Micro<infer _A, infer _E, infer _R> ? _R : never
135
+ }
136
+
137
+ /**
138
+ * @since 3.4.0
139
+ * @experimental
140
+ * @category guards
141
+ */
142
+ export const isMicro = (u: unknown): u is Micro<any, any, any> => typeof u === "object" && u !== null && TypeId in u
143
+
144
+ /**
145
+ * @since 3.4.0
146
+ * @experimental
147
+ * @category models
148
+ */
149
+ export interface MicroIterator<T extends Micro<any, any, any>> {
150
+ next(...args: ReadonlyArray<any>): IteratorResult<YieldWrap<T>, Micro.Success<T>>
151
+ }
152
+
153
+ // ----------------------------------------------------------------------------
154
+ // MicroCause
155
+ // ----------------------------------------------------------------------------
156
+
157
+ /**
158
+ * @since 3.4.6
159
+ * @experimental
160
+ * @category MicroCause
161
+ */
162
+ export const MicroCauseTypeId = Symbol.for("effect/Micro/MicroCause")
163
+
164
+ /**
165
+ * @since 3.4.6
166
+ * @experimental
167
+ * @category MicroCause
168
+ */
169
+ export type MicroCauseTypeId = typeof MicroCauseTypeId
170
+
171
+ /**
172
+ * A `MicroCause` is a data type that represents the different ways a `Micro` can fail.
173
+ *
174
+ * **Details**
175
+ *
176
+ * `MicroCause` comes in three forms:
177
+ *
178
+ * - `Die`: Indicates an unforeseen defect that wasn't planned for in the system's logic.
179
+ * - `Fail`: Covers anticipated errors that are recognized and typically handled within the application.
180
+ * - `Interrupt`: Signifies an operation that has been purposefully stopped.
181
+ *
182
+ * @since 3.4.6
183
+ * @experimental
184
+ * @category MicroCause
185
+ */
186
+ export type MicroCause<E> =
187
+ | MicroCause.Die
188
+ | MicroCause.Fail<E>
189
+ | MicroCause.Interrupt
190
+
191
+ /**
192
+ * @since 3.6.6
193
+ * @experimental
194
+ * @category guards
195
+ */
196
+ export const isMicroCause = (self: unknown): self is MicroCause<unknown> => hasProperty(self, MicroCauseTypeId)
197
+
198
+ /**
199
+ * @since 3.4.6
200
+ * @experimental
201
+ * @category MicroCause
202
+ */
203
+ export declare namespace MicroCause {
204
+ /**
205
+ * @since 3.4.6
206
+ * @experimental
207
+ */
208
+ export type Error<T> = T extends MicroCause.Fail<infer E> ? E : never
209
+
210
+ /**
211
+ * @since 3.4.0
212
+ * @experimental
213
+ */
214
+ export interface Proto<Tag extends string, E> extends Pipeable, globalThis.Error {
215
+ readonly [MicroCauseTypeId]: {
216
+ _E: Covariant<E>
217
+ }
218
+ readonly _tag: Tag
219
+ readonly traces: ReadonlyArray<string>
220
+ }
221
+
222
+ /**
223
+ * @since 3.4.6
224
+ * @experimental
225
+ * @category MicroCause
226
+ */
227
+ export interface Die extends Proto<"Die", never> {
228
+ readonly defect: unknown
229
+ }
230
+
231
+ /**
232
+ * @since 3.4.6
233
+ * @experimental
234
+ * @category MicroCause
235
+ */
236
+ export interface Fail<E> extends Proto<"Fail", E> {
237
+ readonly error: E
238
+ }
239
+
240
+ /**
241
+ * @since 3.4.6
242
+ * @experimental
243
+ * @category MicroCause
244
+ */
245
+ export interface Interrupt extends Proto<"Interrupt", never> {}
246
+ }
247
+
248
+ const microCauseVariance = {
249
+ _E: identity
250
+ }
251
+
252
+ abstract class MicroCauseImpl<Tag extends string, E> extends globalThis.Error implements MicroCause.Proto<Tag, E> {
253
+ readonly [MicroCauseTypeId]: {
254
+ _E: Covariant<E>
255
+ }
256
+ constructor(
257
+ readonly _tag: Tag,
258
+ originalError: unknown,
259
+ readonly traces: ReadonlyArray<string>
260
+ ) {
261
+ const causeName = `MicroCause.${_tag}`
262
+ let name: string
263
+ let message: string
264
+ let stack: string
265
+ if (originalError instanceof globalThis.Error) {
266
+ name = `(${causeName}) ${originalError.name}`
267
+ message = originalError.message as string
268
+ const messageLines = message.split("\n").length
269
+ stack = originalError.stack
270
+ ? `(${causeName}) ${
271
+ originalError.stack
272
+ .split("\n")
273
+ .slice(0, messageLines + 3)
274
+ .join("\n")
275
+ }`
276
+ : `${name}: ${message}`
277
+ } else {
278
+ name = causeName
279
+ message = toStringUnknown(originalError, 0)
280
+ stack = `${name}: ${message}`
281
+ }
282
+ if (traces.length > 0) {
283
+ stack += `\n ${traces.join("\n ")}`
284
+ }
285
+ super(message)
286
+ this[MicroCauseTypeId] = microCauseVariance
287
+ this.name = name
288
+ this.stack = stack
289
+ }
290
+ pipe() {
291
+ return pipeArguments(this, arguments)
292
+ }
293
+ toString() {
294
+ return this.stack
295
+ }
296
+ [NodeInspectSymbol]() {
297
+ return this.stack
298
+ }
299
+ }
300
+
301
+ class Fail<E> extends MicroCauseImpl<"Fail", E> implements MicroCause.Fail<E> {
302
+ constructor(
303
+ readonly error: E,
304
+ traces: ReadonlyArray<string> = []
305
+ ) {
306
+ super("Fail", error, traces)
307
+ }
308
+ }
309
+
310
+ /**
311
+ * @since 3.4.6
312
+ * @experimental
313
+ * @category MicroCause
314
+ */
315
+ export const causeFail = <E>(
316
+ error: E,
317
+ traces: ReadonlyArray<string> = []
318
+ ): MicroCause<E> => new Fail(error, traces)
319
+
320
+ class Die extends MicroCauseImpl<"Die", never> implements MicroCause.Die {
321
+ constructor(
322
+ readonly defect: unknown,
323
+ traces: ReadonlyArray<string> = []
324
+ ) {
325
+ super("Die", defect, traces)
326
+ }
327
+ }
328
+
329
+ /**
330
+ * @since 3.4.6
331
+ * @experimental
332
+ * @category MicroCause
333
+ */
334
+ export const causeDie = (
335
+ defect: unknown,
336
+ traces: ReadonlyArray<string> = []
337
+ ): MicroCause<never> => new Die(defect, traces)
338
+
339
+ class Interrupt extends MicroCauseImpl<"Interrupt", never> implements MicroCause.Interrupt {
340
+ constructor(traces: ReadonlyArray<string> = []) {
341
+ super("Interrupt", "interrupted", traces)
342
+ }
343
+ }
344
+
345
+ /**
346
+ * @since 3.4.6
347
+ * @experimental
348
+ * @category MicroCause
349
+ */
350
+ export const causeInterrupt = (
351
+ traces: ReadonlyArray<string> = []
352
+ ): MicroCause<never> => new Interrupt(traces)
353
+
354
+ /**
355
+ * @since 3.4.6
356
+ * @experimental
357
+ * @category MicroCause
358
+ */
359
+ export const causeIsFail = <E>(
360
+ self: MicroCause<E>
361
+ ): self is MicroCause.Fail<E> => self._tag === "Fail"
362
+
363
+ /**
364
+ * @since 3.4.6
365
+ * @experimental
366
+ * @category MicroCause
367
+ */
368
+ export const causeIsDie = <E>(self: MicroCause<E>): self is MicroCause.Die => self._tag === "Die"
369
+
370
+ /**
371
+ * @since 3.4.6
372
+ * @experimental
373
+ * @category MicroCause
374
+ */
375
+ export const causeIsInterrupt = <E>(
376
+ self: MicroCause<E>
377
+ ): self is MicroCause.Interrupt => self._tag === "Interrupt"
378
+
379
+ /**
380
+ * @since 3.4.6
381
+ * @experimental
382
+ * @category MicroCause
383
+ */
384
+ export const causeSquash = <E>(self: MicroCause<E>): unknown =>
385
+ self._tag === "Fail" ? self.error : self._tag === "Die" ? self.defect : self
386
+
387
+ /**
388
+ * @since 3.4.6
389
+ * @experimental
390
+ * @category MicroCause
391
+ */
392
+ export const causeWithTrace: {
393
+ (trace: string): <E>(self: MicroCause<E>) => MicroCause<E>
394
+ <E>(self: MicroCause<E>, trace: string): MicroCause<E>
395
+ } = dual(2, <E>(self: MicroCause<E>, trace: string): MicroCause<E> => {
396
+ const traces = [...self.traces, trace]
397
+ switch (self._tag) {
398
+ case "Die":
399
+ return causeDie(self.defect, traces)
400
+ case "Interrupt":
401
+ return causeInterrupt(traces)
402
+ case "Fail":
403
+ return causeFail(self.error, traces)
404
+ }
405
+ })
406
+
407
+ // ----------------------------------------------------------------------------
408
+ // MicroFiber
409
+ // ----------------------------------------------------------------------------
410
+
411
+ /**
412
+ * @since 3.11.0
413
+ * @experimental
414
+ * @category MicroFiber
415
+ */
416
+ export const MicroFiberTypeId = Symbol.for("effect/Micro/MicroFiber")
417
+
418
+ /**
419
+ * @since 3.11.0
420
+ * @experimental
421
+ * @category MicroFiber
422
+ */
423
+ export type MicroFiberTypeId = typeof MicroFiberTypeId
424
+
425
+ /**
426
+ * @since 3.11.0
427
+ * @experimental
428
+ * @category MicroFiber
429
+ */
430
+ export interface MicroFiber<out A, out E = never> {
431
+ readonly [MicroFiberTypeId]: MicroFiber.Variance<A, E>
432
+
433
+ readonly currentOpCount: number
434
+ readonly getRef: <I, A>(ref: Context.Reference<I, A>) => A
435
+ readonly context: Context.Context<never>
436
+ readonly addObserver: (cb: (exit: MicroExit<A, E>) => void) => () => void
437
+ readonly unsafeInterrupt: () => void
438
+ readonly unsafePoll: () => MicroExit<A, E> | undefined
439
+ }
440
+
441
+ /**
442
+ * @since 3.11.0
443
+ * @experimental
444
+ * @category MicroFiber
445
+ */
446
+ export declare namespace MicroFiber {
447
+ /**
448
+ * @since 3.11.0
449
+ * @experimental
450
+ * @category MicroFiber
451
+ */
452
+ export interface Variance<out A, out E = never> {
453
+ readonly _A: Covariant<A>
454
+ readonly _E: Covariant<E>
455
+ }
456
+ }
457
+
458
+ const fiberVariance = {
459
+ _A: identity,
460
+ _E: identity
461
+ }
462
+
463
+ class MicroFiberImpl<in out A = any, in out E = any> implements MicroFiber<A, E> {
464
+ readonly [MicroFiberTypeId]: MicroFiber.Variance<A, E>
465
+
466
+ readonly _stack: Array<Primitive> = []
467
+ readonly _observers: Array<(exit: MicroExit<A, E>) => void> = []
468
+ _exit: MicroExit<A, E> | undefined
469
+ public _children: Set<MicroFiberImpl<any, any>> | undefined
470
+
471
+ public currentOpCount = 0
472
+
473
+ constructor(
474
+ public context: Context.Context<never>,
475
+ public interruptible = true
476
+ ) {
477
+ this[MicroFiberTypeId] = fiberVariance
478
+ }
479
+
480
+ getRef<I, A>(ref: Context.Reference<I, A>): A {
481
+ return InternalContext.unsafeGetReference(this.context, ref)
482
+ }
483
+
484
+ addObserver(cb: (exit: MicroExit<A, E>) => void): () => void {
485
+ if (this._exit) {
486
+ cb(this._exit)
487
+ return constVoid
488
+ }
489
+ this._observers.push(cb)
490
+ return () => {
491
+ const index = this._observers.indexOf(cb)
492
+ if (index >= 0) {
493
+ this._observers.splice(index, 1)
494
+ }
495
+ }
496
+ }
497
+
498
+ _interrupted = false
499
+ unsafeInterrupt(): void {
500
+ if (this._exit) {
501
+ return
502
+ }
503
+ this._interrupted = true
504
+ if (this.interruptible) {
505
+ this.evaluate(exitInterrupt as any)
506
+ }
507
+ }
508
+
509
+ unsafePoll(): MicroExit<A, E> | undefined {
510
+ return this._exit
511
+ }
512
+
513
+ evaluate(effect: Primitive): void {
514
+ if (this._exit) {
515
+ return
516
+ } else if (this._yielded !== undefined) {
517
+ const yielded = this._yielded as () => void
518
+ this._yielded = undefined
519
+ yielded()
520
+ }
521
+ const exit = this.runLoop(effect)
522
+ if (exit === Yield) {
523
+ return
524
+ }
525
+
526
+ // the interruptChildren middlware is added in Micro.fork, so it can be
527
+ // tree-shaken if not used
528
+ const interruptChildren = fiberMiddleware.interruptChildren && fiberMiddleware.interruptChildren(this)
529
+ if (interruptChildren !== undefined) {
530
+ return this.evaluate(flatMap(interruptChildren, () => exit) as any)
531
+ }
532
+
533
+ this._exit = exit
534
+ for (let i = 0; i < this._observers.length; i++) {
535
+ this._observers[i](exit)
536
+ }
537
+ this._observers.length = 0
538
+ }
539
+
540
+ runLoop(effect: Primitive): MicroExit<A, E> | Yield {
541
+ let yielding = false
542
+ let current: Primitive | Yield = effect
543
+ this.currentOpCount = 0
544
+ try {
545
+ while (true) {
546
+ this.currentOpCount++
547
+ if (!yielding && this.getRef(CurrentScheduler).shouldYield(this as any)) {
548
+ yielding = true
549
+ const prev = current
550
+ current = flatMap(yieldNow, () => prev as any) as any
551
+ }
552
+ current = (current as any)[evaluate](this)
553
+ if (current === Yield) {
554
+ const yielded = this._yielded!
555
+ if (MicroExitTypeId in yielded) {
556
+ this._yielded = undefined
557
+ return yielded
558
+ }
559
+ return Yield
560
+ }
561
+ }
562
+ } catch (error) {
563
+ if (!hasProperty(current, evaluate)) {
564
+ return exitDie(`MicroFiber.runLoop: Not a valid effect: ${String(current)}`)
565
+ }
566
+ return exitDie(error)
567
+ }
568
+ }
569
+
570
+ getCont<S extends successCont | failureCont>(
571
+ symbol: S
572
+ ): Primitive & Record<S, (value: any, fiber: MicroFiberImpl) => Primitive> | undefined {
573
+ while (true) {
574
+ const op = this._stack.pop()
575
+ if (!op) return undefined
576
+ const cont = op[ensureCont] && op[ensureCont](this)
577
+ if (cont) return { [symbol]: cont } as any
578
+ if (op[symbol]) return op as any
579
+ }
580
+ }
581
+
582
+ // cancel the yielded operation, or for the yielded exit value
583
+ _yielded: MicroExit<any, any> | (() => void) | undefined = undefined
584
+ yieldWith(value: MicroExit<any, any> | (() => void)): Yield {
585
+ this._yielded = value
586
+ return Yield
587
+ }
588
+
589
+ children(): Set<MicroFiber<any, any>> {
590
+ return this._children ??= new Set()
591
+ }
592
+ }
593
+
594
+ const fiberMiddleware = globalValue("effect/Micro/fiberMiddleware", () => ({
595
+ interruptChildren: undefined as ((fiber: MicroFiberImpl) => Micro<void> | undefined) | undefined
596
+ }))
597
+
598
+ const fiberInterruptChildren = (fiber: MicroFiberImpl) => {
599
+ if (fiber._children === undefined || fiber._children.size === 0) {
600
+ return undefined
601
+ }
602
+ return fiberInterruptAll(fiber._children)
603
+ }
604
+
605
+ /**
606
+ * @since 3.11.0
607
+ * @experimental
608
+ * @category MicroFiber
609
+ */
610
+ export const fiberAwait = <A, E>(self: MicroFiber<A, E>): Micro<MicroExit<A, E>> =>
611
+ async((resume) => sync(self.addObserver((exit) => resume(succeed(exit)))))
612
+
613
+ /**
614
+ * @since 3.11.2
615
+ * @experimental
616
+ * @category MicroFiber
617
+ */
618
+ export const fiberJoin = <A, E>(self: MicroFiber<A, E>): Micro<A, E> => flatten(fiberAwait(self))
619
+
620
+ /**
621
+ * @since 3.11.0
622
+ * @experimental
623
+ * @category MicroFiber
624
+ */
625
+ export const fiberInterrupt = <A, E>(self: MicroFiber<A, E>): Micro<void> =>
626
+ suspend(() => {
627
+ self.unsafeInterrupt()
628
+ return asVoid(fiberAwait(self))
629
+ })
630
+
631
+ /**
632
+ * @since 3.11.0
633
+ * @experimental
634
+ * @category MicroFiber
635
+ */
636
+ export const fiberInterruptAll = <A extends Iterable<MicroFiber<any, any>>>(fibers: A): Micro<void> =>
637
+ suspend(() => {
638
+ for (const fiber of fibers) fiber.unsafeInterrupt()
639
+ const iter = fibers[Symbol.iterator]()
640
+ const wait: Micro<void> = suspend(() => {
641
+ let result = iter.next()
642
+ while (!result.done) {
643
+ if (result.value.unsafePoll()) {
644
+ result = iter.next()
645
+ continue
646
+ }
647
+ const fiber = result.value
648
+ return async((resume) => {
649
+ fiber.addObserver((_) => {
650
+ resume(wait)
651
+ })
652
+ })
653
+ }
654
+ return exitVoid
655
+ })
656
+ return wait
657
+ })
658
+
659
+ const identifier = Symbol.for("effect/Micro/identifier")
660
+ type identifier = typeof identifier
661
+
662
+ const args = Symbol.for("effect/Micro/args")
663
+ type args = typeof args
664
+
665
+ const evaluate = Symbol.for("effect/Micro/evaluate")
666
+ type evaluate = typeof evaluate
667
+
668
+ const successCont = Symbol.for("effect/Micro/successCont")
669
+ type successCont = typeof successCont
670
+
671
+ const failureCont = Symbol.for("effect/Micro/failureCont")
672
+ type failureCont = typeof failureCont
673
+
674
+ const ensureCont = Symbol.for("effect/Micro/ensureCont")
675
+ type ensureCont = typeof ensureCont
676
+
677
+ const Yield = Symbol.for("effect/Micro/Yield")
678
+ type Yield = typeof Yield
679
+
680
+ interface Primitive {
681
+ readonly [identifier]: string
682
+ readonly [successCont]: ((value: unknown, fiber: MicroFiberImpl) => Primitive | Yield) | undefined
683
+ readonly [failureCont]:
684
+ | ((cause: MicroCause<unknown>, fiber: MicroFiberImpl) => Primitive | Yield)
685
+ | undefined
686
+ readonly [ensureCont]:
687
+ | ((fiber: MicroFiberImpl) =>
688
+ | ((value: unknown, fiber: MicroFiberImpl) => Primitive | Yield)
689
+ | undefined)
690
+ | undefined
691
+ [evaluate](fiber: MicroFiberImpl): Primitive | Yield
692
+ }
693
+
694
+ const microVariance = {
695
+ _A: identity,
696
+ _E: identity,
697
+ _R: identity
698
+ }
699
+
700
+ const MicroProto = {
701
+ ...Effectable.EffectPrototype,
702
+ _op: "Micro",
703
+ [TypeId]: microVariance,
704
+ pipe() {
705
+ return pipeArguments(this, arguments)
706
+ },
707
+ [Symbol.iterator]() {
708
+ return new SingleShotGen(new YieldWrap(this)) as any
709
+ },
710
+ toJSON(this: Primitive) {
711
+ return {
712
+ _id: "Micro",
713
+ op: this[identifier],
714
+ ...(args in this ? { args: this[args] } : undefined)
715
+ }
716
+ },
717
+ toString() {
718
+ return format(this)
719
+ },
720
+ [NodeInspectSymbol]() {
721
+ return format(this)
722
+ }
723
+ }
724
+
725
+ function defaultEvaluate(_fiber: MicroFiberImpl): Primitive | Yield {
726
+ return exitDie(`Micro.evaluate: Not implemented`) as any
727
+ }
728
+
729
+ const makePrimitiveProto = <Op extends string>(options: {
730
+ readonly op: Op
731
+ readonly eval?: (fiber: MicroFiberImpl) => Primitive | Micro<any, any, any> | Yield
732
+ readonly contA?: (this: Primitive, value: any, fiber: MicroFiberImpl) => Primitive | Micro<any, any, any> | Yield
733
+ readonly contE?: (
734
+ this: Primitive,
735
+ cause: MicroCause<any>,
736
+ fiber: MicroFiberImpl
737
+ ) => Primitive | Micro<any, any, any> | Yield
738
+ readonly ensure?: (this: Primitive, fiber: MicroFiberImpl) => void | ((value: any, fiber: MicroFiberImpl) => void)
739
+ }): Primitive => ({
740
+ ...MicroProto,
741
+ [identifier]: options.op,
742
+ [evaluate]: options.eval ?? defaultEvaluate,
743
+ [successCont]: options.contA,
744
+ [failureCont]: options.contE,
745
+ [ensureCont]: options.ensure
746
+ } as any)
747
+
748
+ const makePrimitive = <Fn extends (...args: Array<any>) => any, Single extends boolean = true>(options: {
749
+ readonly op: string
750
+ readonly single?: Single
751
+ readonly eval?: (
752
+ this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
753
+ fiber: MicroFiberImpl
754
+ ) => Primitive | Micro<any, any, any> | Yield
755
+ readonly contA?: (
756
+ this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
757
+ value: any,
758
+ fiber: MicroFiberImpl
759
+ ) => Primitive | Micro<any, any, any> | Yield
760
+ readonly contE?: (
761
+ this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
762
+ cause: MicroCause<any>,
763
+ fiber: MicroFiberImpl
764
+ ) => Primitive | Micro<any, any, any> | Yield
765
+ readonly ensure?: (
766
+ this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
767
+ fiber: MicroFiberImpl
768
+ ) => void | ((value: any, fiber: MicroFiberImpl) => void)
769
+ }): Fn => {
770
+ const Proto = makePrimitiveProto(options as any)
771
+ return function() {
772
+ const self = Object.create(Proto)
773
+ self[args] = options.single === false ? arguments : arguments[0]
774
+ return self
775
+ } as Fn
776
+ }
777
+
778
+ const makeExit = <Fn extends (...args: Array<any>) => any, Prop extends string>(options: {
779
+ readonly op: "Success" | "Failure"
780
+ readonly prop: Prop
781
+ readonly eval: (
782
+ this:
783
+ & MicroExit<unknown, unknown>
784
+ & { [args]: Parameters<Fn>[0] },
785
+ fiber: MicroFiberImpl<unknown, unknown>
786
+ ) => Primitive | Yield
787
+ }): Fn => {
788
+ const Proto = {
789
+ ...makePrimitiveProto(options),
790
+ [MicroExitTypeId]: MicroExitTypeId,
791
+ _tag: options.op,
792
+ get [options.prop](): any {
793
+ return (this as any)[args]
794
+ },
795
+ toJSON(this: any) {
796
+ return {
797
+ _id: "MicroExit",
798
+ _tag: options.op,
799
+ [options.prop]: this[args]
800
+ }
801
+ },
802
+ [Equal.symbol](this: any, that: any): boolean {
803
+ return isMicroExit(that) && that._tag === options.op &&
804
+ Equal.equals(this[args], (that as any)[args])
805
+ },
806
+ [Hash.symbol](this: any): number {
807
+ return Hash.cached(this, Hash.combine(Hash.string(options.op))(Hash.hash(this[args])))
808
+ }
809
+ }
810
+ return function(value: unknown) {
811
+ const self = Object.create(Proto)
812
+ self[args] = value
813
+ self[successCont] = undefined
814
+ self[failureCont] = undefined
815
+ self[ensureCont] = undefined
816
+ return self
817
+ } as Fn
818
+ }
819
+
820
+ /**
821
+ * Creates a `Micro` effect that will succeed with the specified constant value.
822
+ *
823
+ * @since 3.4.0
824
+ * @experimental
825
+ * @category constructors
826
+ */
827
+ export const succeed: <A>(value: A) => Micro<A> = makeExit({
828
+ op: "Success",
829
+ prop: "value",
830
+ eval(fiber) {
831
+ const cont = fiber.getCont(successCont)
832
+ return cont ? cont[successCont](this[args], fiber) : fiber.yieldWith(this)
833
+ }
834
+ })
835
+
836
+ /**
837
+ * Creates a `Micro` effect that will fail with the specified `MicroCause`.
838
+ *
839
+ * @since 3.4.6
840
+ * @experimental
841
+ * @category constructors
842
+ */
843
+ export const failCause: <E>(cause: MicroCause<E>) => Micro<never, E> = makeExit({
844
+ op: "Failure",
845
+ prop: "cause",
846
+ eval(fiber) {
847
+ let cont = fiber.getCont(failureCont)
848
+ while (causeIsInterrupt(this[args]) && cont && fiber.interruptible) {
849
+ cont = fiber.getCont(failureCont)
850
+ }
851
+ return cont ? cont[failureCont](this[args], fiber) : fiber.yieldWith(this)
852
+ }
853
+ })
854
+
855
+ /**
856
+ * Creates a `Micro` effect that fails with the given error.
857
+ *
858
+ * This results in a `Fail` variant of the `MicroCause` type, where the error is
859
+ * tracked at the type level.
860
+ *
861
+ * @since 3.4.0
862
+ * @experimental
863
+ * @category constructors
864
+ */
865
+ export const fail = <E>(error: E): Micro<never, E> => failCause(causeFail(error))
866
+
867
+ /**
868
+ * Creates a `Micro` effect that succeeds with a lazily evaluated value.
869
+ *
870
+ * If the evaluation of the value throws an error, the effect will fail with a
871
+ * `Die` variant of the `MicroCause` type.
872
+ *
873
+ * @since 3.4.0
874
+ * @experimental
875
+ * @category constructors
876
+ */
877
+ export const sync: <A>(evaluate: LazyArg<A>) => Micro<A> = makePrimitive({
878
+ op: "Sync",
879
+ eval(fiber): Primitive | Yield {
880
+ const value = this[args]()
881
+ const cont = fiber.getCont(successCont)
882
+ return cont ? cont[successCont](value, fiber) : fiber.yieldWith(exitSucceed(value))
883
+ }
884
+ })
885
+
886
+ /**
887
+ * Lazily creates a `Micro` effect from the given side-effect.
888
+ *
889
+ * @since 3.4.0
890
+ * @experimental
891
+ * @category constructors
892
+ */
893
+ export const suspend: <A, E, R>(evaluate: LazyArg<Micro<A, E, R>>) => Micro<A, E, R> = makePrimitive({
894
+ op: "Suspend",
895
+ eval(_fiber) {
896
+ return this[args]()
897
+ }
898
+ })
899
+
900
+ /**
901
+ * Pause the execution of the current `Micro` effect, and resume it on the next
902
+ * scheduler tick.
903
+ *
904
+ * @since 3.4.0
905
+ * @experimental
906
+ * @category constructors
907
+ */
908
+ export const yieldNowWith: (priority?: number) => Micro<void> = makePrimitive({
909
+ op: "Yield",
910
+ eval(fiber) {
911
+ let resumed = false
912
+ fiber.getRef(CurrentScheduler).scheduleTask(() => {
913
+ if (resumed) return
914
+ fiber.evaluate(exitVoid as any)
915
+ }, this[args] ?? 0)
916
+ return fiber.yieldWith(() => {
917
+ resumed = true
918
+ })
919
+ }
920
+ })
921
+
922
+ /**
923
+ * Pause the execution of the current `Micro` effect, and resume it on the next
924
+ * scheduler tick.
925
+ *
926
+ * @since 3.4.0
927
+ * @experimental
928
+ * @category constructors
929
+ */
930
+ export const yieldNow: Micro<void> = yieldNowWith(0)
931
+
932
+ /**
933
+ * Creates a `Micro` effect that will succeed with the value wrapped in `Some`.
934
+ *
935
+ * @since 3.4.0
936
+ * @experimental
937
+ * @category constructors
938
+ */
939
+ export const succeedSome = <A>(a: A): Micro<Option.Option<A>> => succeed(Option.some(a))
940
+
941
+ /**
942
+ * Creates a `Micro` effect that succeeds with `None`.
943
+ *
944
+ * @since 3.4.0
945
+ * @experimental
946
+ * @category constructors
947
+ */
948
+ export const succeedNone: Micro<Option.Option<never>> = succeed(Option.none())
949
+
950
+ /**
951
+ * Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
952
+ *
953
+ * @since 3.4.0
954
+ * @experimental
955
+ * @category constructors
956
+ */
957
+ export const failCauseSync = <E>(evaluate: LazyArg<MicroCause<E>>): Micro<never, E> =>
958
+ suspend(() => failCause(evaluate()))
959
+
960
+ /**
961
+ * Creates a `Micro` effect that will die with the specified error.
962
+ *
963
+ * This results in a `Die` variant of the `MicroCause` type, where the error is
964
+ * not tracked at the type level.
965
+ *
966
+ * @since 3.4.0
967
+ * @experimental
968
+ * @category constructors
969
+ */
970
+ export const die = (defect: unknown): Micro<never> => exitDie(defect)
971
+
972
+ /**
973
+ * Creates a `Micro` effect that will fail with the lazily evaluated error.
974
+ *
975
+ * This results in a `Fail` variant of the `MicroCause` type, where the error is
976
+ * tracked at the type level.
977
+ *
978
+ * @since 3.4.6
979
+ * @experimental
980
+ * @category constructors
981
+ */
982
+ export const failSync = <E>(error: LazyArg<E>): Micro<never, E> => suspend(() => fail(error()))
983
+
984
+ /**
985
+ * Converts an `Option` into a `Micro` effect, that will fail with
986
+ * `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
987
+ * value of the option.
988
+ *
989
+ * @since 3.4.0
990
+ * @experimental
991
+ * @category constructors
992
+ */
993
+ export const fromOption = <A>(option: Option.Option<A>): Micro<A, NoSuchElementException> =>
994
+ option._tag === "Some" ? succeed(option.value) : fail(new NoSuchElementException({}))
995
+
996
+ /**
997
+ * Converts an `Either` into a `Micro` effect, that will fail with the left side
998
+ * of the either if it is a `Left`. Otherwise, it will succeed with the right
999
+ * side of the either.
1000
+ *
1001
+ * @since 3.4.0
1002
+ * @experimental
1003
+ * @category constructors
1004
+ */
1005
+ export const fromEither = <R, L>(either: Either.Either<R, L>): Micro<R, L> =>
1006
+ either._tag === "Right" ? succeed(either.right) : fail(either.left)
1007
+
1008
+ const void_: Micro<void> = succeed(void 0)
1009
+ export {
1010
+ /**
1011
+ * A `Micro` effect that will succeed with `void` (`undefined`).
1012
+ *
1013
+ * @since 3.4.0
1014
+ * @experimental
1015
+ * @category constructors
1016
+ */
1017
+ void_ as void
1018
+ }
1019
+
1020
+ const try_ = <A, E>(options: {
1021
+ try: LazyArg<A>
1022
+ catch: (error: unknown) => E
1023
+ }): Micro<A, E> =>
1024
+ suspend(() => {
1025
+ try {
1026
+ return succeed(options.try())
1027
+ } catch (err) {
1028
+ return fail(options.catch(err))
1029
+ }
1030
+ })
1031
+ export {
1032
+ /**
1033
+ * The `Micro` equivalent of a try / catch block, which allows you to map
1034
+ * thrown errors to a specific error type.
1035
+ *
1036
+ * @example
1037
+ * ```ts
1038
+ * import { Micro } from "effect"
1039
+ *
1040
+ * Micro.try({
1041
+ * try: () => { throw new Error("boom") },
1042
+ * catch: (cause) => new Error("caught", { cause })
1043
+ * })
1044
+ * ```
1045
+ *
1046
+ * @since 3.4.0
1047
+ * @experimental
1048
+ * @category constructors
1049
+ */
1050
+ try_ as try
1051
+ }
1052
+
1053
+ /**
1054
+ * Wrap a `Promise` into a `Micro` effect.
1055
+ *
1056
+ * Any errors will result in a `Die` variant of the `MicroCause` type, where the
1057
+ * error is not tracked at the type level.
1058
+ *
1059
+ * @since 3.4.0
1060
+ * @experimental
1061
+ * @category constructors
1062
+ */
1063
+ export const promise = <A>(evaluate: (signal: AbortSignal) => PromiseLike<A>): Micro<A> =>
1064
+ asyncOptions<A>(function(resume, signal) {
1065
+ evaluate(signal!).then(
1066
+ (a) => resume(succeed(a)),
1067
+ (e) => resume(die(e))
1068
+ )
1069
+ }, evaluate.length !== 0)
1070
+
1071
+ /**
1072
+ * Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
1073
+ * converted into a specific error type.
1074
+ *
1075
+ * @example
1076
+ * ```ts
1077
+ * import { Micro } from "effect"
1078
+ *
1079
+ * Micro.tryPromise({
1080
+ * try: () => Promise.resolve("success"),
1081
+ * catch: (cause) => new Error("caught", { cause })
1082
+ * })
1083
+ * ```
1084
+ *
1085
+ * @since 3.4.0
1086
+ * @experimental
1087
+ * @category constructors
1088
+ */
1089
+ export const tryPromise = <A, E>(options: {
1090
+ readonly try: (signal: AbortSignal) => PromiseLike<A>
1091
+ readonly catch: (error: unknown) => E
1092
+ }): Micro<A, E> =>
1093
+ asyncOptions<A, E>(function(resume, signal) {
1094
+ try {
1095
+ options.try(signal!).then(
1096
+ (a) => resume(succeed(a)),
1097
+ (e) => resume(fail(options.catch(e)))
1098
+ )
1099
+ } catch (err) {
1100
+ resume(fail(options.catch(err)))
1101
+ }
1102
+ }, options.try.length !== 0)
1103
+
1104
+ /**
1105
+ * Create a `Micro` effect using the current `MicroFiber`.
1106
+ *
1107
+ * @since 3.4.0
1108
+ * @experimental
1109
+ * @category constructors
1110
+ */
1111
+ export const withMicroFiber: <A, E = never, R = never>(
1112
+ evaluate: (fiber: MicroFiberImpl<A, E>) => Micro<A, E, R>
1113
+ ) => Micro<A, E, R> = makePrimitive({
1114
+ op: "WithMicroFiber",
1115
+ eval(fiber) {
1116
+ return this[args](fiber)
1117
+ }
1118
+ })
1119
+
1120
+ /**
1121
+ * Flush any yielded effects that are waiting to be executed.
1122
+ *
1123
+ * @since 3.4.0
1124
+ * @experimental
1125
+ * @category constructors
1126
+ */
1127
+ export const yieldFlush: Micro<void> = withMicroFiber((fiber) => {
1128
+ fiber.getRef(CurrentScheduler).flush()
1129
+ return exitVoid
1130
+ })
1131
+
1132
+ const asyncOptions: <A, E = never, R = never>(
1133
+ register: (
1134
+ resume: (effect: Micro<A, E, R>) => void,
1135
+ signal?: AbortSignal
1136
+ ) => void | Micro<void, never, R>,
1137
+ withSignal: boolean
1138
+ ) => Micro<A, E, R> = makePrimitive({
1139
+ op: "Async",
1140
+ single: false,
1141
+ eval(fiber) {
1142
+ const register = this[args][0]
1143
+ let resumed = false
1144
+ let yielded: boolean | Primitive = false
1145
+ const controller = this[args][1] ? new AbortController() : undefined
1146
+ const onCancel = register((effect) => {
1147
+ if (resumed) return
1148
+ resumed = true
1149
+ if (yielded) {
1150
+ fiber.evaluate(effect as any)
1151
+ } else {
1152
+ yielded = effect as any
1153
+ }
1154
+ }, controller?.signal)
1155
+ if (yielded !== false) return yielded
1156
+ yielded = true
1157
+ fiber._yielded = () => {
1158
+ resumed = true
1159
+ }
1160
+ if (controller === undefined && onCancel === undefined) {
1161
+ return Yield
1162
+ }
1163
+ fiber._stack.push(asyncFinalizer(() => {
1164
+ resumed = true
1165
+ controller?.abort()
1166
+ return onCancel ?? exitVoid
1167
+ }))
1168
+ return Yield
1169
+ }
1170
+ })
1171
+ const asyncFinalizer: (onInterrupt: () => Micro<void, any, any>) => Primitive = makePrimitive({
1172
+ op: "AsyncFinalizer",
1173
+ ensure(fiber) {
1174
+ if (fiber.interruptible) {
1175
+ fiber.interruptible = false
1176
+ fiber._stack.push(setInterruptible(true))
1177
+ }
1178
+ },
1179
+ contE(cause, _fiber) {
1180
+ return causeIsInterrupt(cause)
1181
+ ? flatMap(this[args](), () => failCause(cause))
1182
+ : failCause(cause)
1183
+ }
1184
+ })
1185
+
1186
+ /**
1187
+ * Create a `Micro` effect from an asynchronous computation.
1188
+ *
1189
+ * You can return a cleanup effect that will be run when the effect is aborted.
1190
+ * It is also passed an `AbortSignal` that is triggered when the effect is
1191
+ * aborted.
1192
+ *
1193
+ * @since 3.4.0
1194
+ * @experimental
1195
+ * @category constructors
1196
+ */
1197
+ export const async = <A, E = never, R = never>(
1198
+ register: (
1199
+ resume: (effect: Micro<A, E, R>) => void,
1200
+ signal: AbortSignal
1201
+ ) => void | Micro<void, never, R>
1202
+ ): Micro<A, E, R> => asyncOptions(register as any, register.length >= 2)
1203
+
1204
+ /**
1205
+ * A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
1206
+ * the Javascript runtime from exiting.
1207
+ *
1208
+ * @since 3.4.0
1209
+ * @experimental
1210
+ * @category constructors
1211
+ */
1212
+ export const never: Micro<never> = async<never>(function() {
1213
+ const interval = setInterval(constVoid, 2147483646)
1214
+ return sync(() => clearInterval(interval))
1215
+ })
1216
+
1217
+ /**
1218
+ * @since 3.4.0
1219
+ * @experimental
1220
+ * @category constructors
1221
+ */
1222
+ export const gen = <Self, Eff extends YieldWrap<Micro<any, any, any>>, AEff>(
1223
+ ...args:
1224
+ | [self: Self, body: (this: Self) => Generator<Eff, AEff, never>]
1225
+ | [body: () => Generator<Eff, AEff, never>]
1226
+ ): Micro<
1227
+ AEff,
1228
+ [Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer E, infer _R>>] ? E : never,
1229
+ [Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer _E, infer R>>] ? R : never
1230
+ > => suspend(() => fromIterator(args.length === 1 ? args[0]() : args[1].call(args[0]) as any))
1231
+
1232
+ const fromIterator: (
1233
+ iterator: Iterator<any, YieldWrap<Micro<any, any, any>>>
1234
+ ) => Micro<any, any, any> = makePrimitive({
1235
+ op: "Iterator",
1236
+ contA(value, fiber) {
1237
+ const state = this[args].next(value)
1238
+ if (state.done) return succeed(state.value)
1239
+ fiber._stack.push(this)
1240
+ return yieldWrapGet(state.value)
1241
+ },
1242
+ eval(this: any, fiber: MicroFiberImpl) {
1243
+ return this[successCont](undefined, fiber)
1244
+ }
1245
+ })
1246
+
1247
+ // ----------------------------------------------------------------------------
1248
+ // mapping & sequencing
1249
+ // ----------------------------------------------------------------------------
1250
+
1251
+ /**
1252
+ * Create a `Micro` effect that will replace the success value of the given
1253
+ * effect.
1254
+ *
1255
+ * @since 3.4.0
1256
+ * @experimental
1257
+ * @category mapping & sequencing
1258
+ */
1259
+ export const as: {
1260
+ <A, B>(value: B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>
1261
+ <A, E, R, B>(self: Micro<A, E, R>, value: B): Micro<B, E, R>
1262
+ } = dual(2, <A, E, R, B>(self: Micro<A, E, R>, value: B): Micro<B, E, R> => map(self, (_) => value))
1263
+
1264
+ /**
1265
+ * Wrap the success value of this `Micro` effect in a `Some`.
1266
+ *
1267
+ * @since 3.4.0
1268
+ * @experimental
1269
+ * @category mapping & sequencing
1270
+ */
1271
+ export const asSome = <A, E, R>(self: Micro<A, E, R>): Micro<Option.Option<A>, E, R> => map(self, Option.some)
1272
+
1273
+ /**
1274
+ * Swap the error and success types of the `Micro` effect.
1275
+ *
1276
+ * @since 3.4.0
1277
+ * @experimental
1278
+ * @category mapping & sequencing
1279
+ */
1280
+ export const flip = <A, E, R>(self: Micro<A, E, R>): Micro<E, A, R> =>
1281
+ matchEffect(self, {
1282
+ onFailure: succeed,
1283
+ onSuccess: fail
1284
+ })
1285
+
1286
+ /**
1287
+ * A more flexible version of `flatMap` that combines `map` and `flatMap` into a
1288
+ * single API.
1289
+ *
1290
+ * It also lets you directly pass a `Micro` effect, which will be executed after
1291
+ * the current effect.
1292
+ *
1293
+ * @since 3.4.0
1294
+ * @experimental
1295
+ * @category mapping & sequencing
1296
+ */
1297
+ export const andThen: {
1298
+ <A, X>(
1299
+ f: (a: A) => X
1300
+ ): <E, R>(
1301
+ self: Micro<A, E, R>
1302
+ ) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
1303
+ : Micro<X, E, R>
1304
+ <X>(
1305
+ f: NotFunction<X>
1306
+ ): <A, E, R>(
1307
+ self: Micro<A, E, R>
1308
+ ) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
1309
+ : Micro<X, E, R>
1310
+ <A, E, R, X>(
1311
+ self: Micro<A, E, R>,
1312
+ f: (a: A) => X
1313
+ ): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
1314
+ : Micro<X, E, R>
1315
+ <A, E, R, X>(
1316
+ self: Micro<A, E, R>,
1317
+ f: NotFunction<X>
1318
+ ): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
1319
+ : Micro<X, E, R>
1320
+ } = dual(
1321
+ 2,
1322
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: any): Micro<B, E | E2, R | R2> =>
1323
+ flatMap(self, (a) => {
1324
+ const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f
1325
+ return isMicro(value) ? value : succeed(value)
1326
+ })
1327
+ )
1328
+
1329
+ /**
1330
+ * Execute a side effect from the success value of the `Micro` effect.
1331
+ *
1332
+ * It is similar to the `andThen` api, but the success value is ignored.
1333
+ *
1334
+ * @since 3.4.0
1335
+ * @experimental
1336
+ * @category mapping & sequencing
1337
+ */
1338
+ export const tap: {
1339
+ <A, X>(
1340
+ f: (a: NoInfer<A>) => X
1341
+ ): <E, R>(
1342
+ self: Micro<A, E, R>
1343
+ ) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
1344
+ : Micro<A, E, R>
1345
+ <X>(
1346
+ f: NotFunction<X>
1347
+ ): <A, E, R>(
1348
+ self: Micro<A, E, R>
1349
+ ) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
1350
+ : Micro<A, E, R>
1351
+ <A, E, R, X>(
1352
+ self: Micro<A, E, R>,
1353
+ f: (a: NoInfer<A>) => X
1354
+ ): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
1355
+ : Micro<A, E, R>
1356
+ <A, E, R, X>(
1357
+ self: Micro<A, E, R>,
1358
+ f: NotFunction<X>
1359
+ ): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
1360
+ : Micro<A, E, R>
1361
+ } = dual(
1362
+ 2,
1363
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (a: A) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2> =>
1364
+ flatMap(self, (a) => {
1365
+ const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f
1366
+ return isMicro(value) ? as(value, a) : succeed(a)
1367
+ })
1368
+ )
1369
+
1370
+ /**
1371
+ * Replace the success value of the `Micro` effect with `void`.
1372
+ *
1373
+ * @since 3.4.0
1374
+ * @experimental
1375
+ * @category mapping & sequencing
1376
+ */
1377
+ export const asVoid = <A, E, R>(self: Micro<A, E, R>): Micro<void, E, R> => flatMap(self, (_) => exitVoid)
1378
+
1379
+ /**
1380
+ * Access the `MicroExit` of the given `Micro` effect.
1381
+ *
1382
+ * @since 3.4.6
1383
+ * @experimental
1384
+ * @category mapping & sequencing
1385
+ */
1386
+ export const exit = <A, E, R>(self: Micro<A, E, R>): Micro<MicroExit<A, E>, never, R> =>
1387
+ matchCause(self, {
1388
+ onFailure: exitFailCause,
1389
+ onSuccess: exitSucceed
1390
+ })
1391
+
1392
+ /**
1393
+ * Replace the error type of the given `Micro` with the full `MicroCause` object.
1394
+ *
1395
+ * @since 3.4.0
1396
+ * @experimental
1397
+ * @category mapping & sequencing
1398
+ */
1399
+ export const sandbox = <A, E, R>(self: Micro<A, E, R>): Micro<A, MicroCause<E>, R> => catchAllCause(self, fail)
1400
+
1401
+ /**
1402
+ * Returns an effect that races all the specified effects,
1403
+ * yielding the value of the first effect to succeed with a value. Losers of
1404
+ * the race will be interrupted immediately
1405
+ *
1406
+ * @since 3.4.0
1407
+ * @experimental
1408
+ * @category sequencing
1409
+ */
1410
+ export const raceAll = <Eff extends Micro<any, any, any>>(
1411
+ all: Iterable<Eff>
1412
+ ): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
1413
+ withMicroFiber((parent) =>
1414
+ async((resume) => {
1415
+ const effects = Arr.fromIterable(all)
1416
+ const len = effects.length
1417
+ let doneCount = 0
1418
+ let done = false
1419
+ const fibers = new Set<MicroFiber<any, any>>()
1420
+ const causes: Array<MicroCause<any>> = []
1421
+ const onExit = (exit: MicroExit<any, any>) => {
1422
+ doneCount++
1423
+ if (exit._tag === "Failure") {
1424
+ causes.push(exit.cause)
1425
+ if (doneCount >= len) {
1426
+ resume(failCause(causes[0]))
1427
+ }
1428
+ return
1429
+ }
1430
+ done = true
1431
+ resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit))
1432
+ }
1433
+
1434
+ for (let i = 0; i < len; i++) {
1435
+ if (done) break
1436
+ const fiber = unsafeFork(parent, interruptible(effects[i]), true, true)
1437
+ fibers.add(fiber)
1438
+ fiber.addObserver((exit) => {
1439
+ fibers.delete(fiber)
1440
+ onExit(exit)
1441
+ })
1442
+ }
1443
+
1444
+ return fiberInterruptAll(fibers)
1445
+ })
1446
+ )
1447
+
1448
+ /**
1449
+ * Returns an effect that races all the specified effects,
1450
+ * yielding the value of the first effect to succeed or fail. Losers of
1451
+ * the race will be interrupted immediately.
1452
+ *
1453
+ * @since 3.4.0
1454
+ * @experimental
1455
+ * @category sequencing
1456
+ */
1457
+ export const raceAllFirst = <Eff extends Micro<any, any, any>>(
1458
+ all: Iterable<Eff>
1459
+ ): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
1460
+ withMicroFiber((parent) =>
1461
+ async((resume) => {
1462
+ let done = false
1463
+ const fibers = new Set<MicroFiber<any, any>>()
1464
+ const onExit = (exit: MicroExit<any, any>) => {
1465
+ done = true
1466
+ resume(fibers.size === 0 ? exit : flatMap(fiberInterruptAll(fibers), () => exit))
1467
+ }
1468
+
1469
+ for (const effect of all) {
1470
+ if (done) break
1471
+ const fiber = unsafeFork(parent, interruptible(effect), true, true)
1472
+ fibers.add(fiber)
1473
+ fiber.addObserver((exit) => {
1474
+ fibers.delete(fiber)
1475
+ onExit(exit)
1476
+ })
1477
+ }
1478
+
1479
+ return fiberInterruptAll(fibers)
1480
+ })
1481
+ )
1482
+
1483
+ /**
1484
+ * Returns an effect that races two effects, yielding the value of the first
1485
+ * effect to succeed. Losers of the race will be interrupted immediately.
1486
+ *
1487
+ * @since 3.4.0
1488
+ * @experimental
1489
+ * @category sequencing
1490
+ */
1491
+ export const race: {
1492
+ <A2, E2, R2>(that: Micro<A2, E2, R2>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
1493
+ <A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2>
1494
+ } = dual(
1495
+ 2,
1496
+ <A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2> =>
1497
+ raceAll([self, that])
1498
+ )
1499
+
1500
+ /**
1501
+ * Returns an effect that races two effects, yielding the value of the first
1502
+ * effect to succeed *or* fail. Losers of the race will be interrupted immediately.
1503
+ *
1504
+ * @since 3.4.0
1505
+ * @experimental
1506
+ * @category sequencing
1507
+ */
1508
+ export const raceFirst: {
1509
+ <A2, E2, R2>(that: Micro<A2, E2, R2>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
1510
+ <A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2>
1511
+ } = dual(
1512
+ 2,
1513
+ <A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2> =>
1514
+ raceAllFirst([self, that])
1515
+ )
1516
+
1517
+ /**
1518
+ * Map the success value of this `Micro` effect to another `Micro` effect, then
1519
+ * flatten the result.
1520
+ *
1521
+ * @since 3.4.0
1522
+ * @experimental
1523
+ * @category mapping & sequencing
1524
+ */
1525
+ export const flatMap: {
1526
+ <A, B, E2, R2>(
1527
+ f: (a: A) => Micro<B, E2, R2>
1528
+ ): <E, R>(self: Micro<A, E, R>) => Micro<B, E | E2, R | R2>
1529
+ <A, E, R, B, E2, R2>(
1530
+ self: Micro<A, E, R>,
1531
+ f: (a: A) => Micro<B, E2, R2>
1532
+ ): Micro<B, E | E2, R | R2>
1533
+ } = dual(
1534
+ 2,
1535
+ <A, E, R, B, E2, R2>(
1536
+ self: Micro<A, E, R>,
1537
+ f: (a: A) => Micro<B, E2, R2>
1538
+ ): Micro<B, E | E2, R | R2> => {
1539
+ const onSuccess = Object.create(OnSuccessProto)
1540
+ onSuccess[args] = self
1541
+ onSuccess[successCont] = f
1542
+ return onSuccess
1543
+ }
1544
+ )
1545
+ const OnSuccessProto = makePrimitiveProto({
1546
+ op: "OnSuccess",
1547
+ eval(this: any, fiber: MicroFiberImpl): Primitive {
1548
+ fiber._stack.push(this)
1549
+ return this[args]
1550
+ }
1551
+ })
1552
+
1553
+ // ----------------------------------------------------------------------------
1554
+ // mapping & sequencing
1555
+ // ----------------------------------------------------------------------------
1556
+
1557
+ /**
1558
+ * Flattens any nested `Micro` effects, merging the error and requirement types.
1559
+ *
1560
+ * @since 3.4.0
1561
+ * @experimental
1562
+ * @category mapping & sequencing
1563
+ */
1564
+ export const flatten = <A, E, R, E2, R2>(
1565
+ self: Micro<Micro<A, E, R>, E2, R2>
1566
+ ): Micro<A, E | E2, R | R2> => flatMap(self, identity)
1567
+
1568
+ /**
1569
+ * Transforms the success value of the `Micro` effect with the specified
1570
+ * function.
1571
+ *
1572
+ * @since 3.4.0
1573
+ * @experimental
1574
+ * @category mapping & sequencing
1575
+ */
1576
+ export const map: {
1577
+ <A, B>(f: (a: A) => B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>
1578
+ <A, E, R, B>(self: Micro<A, E, R>, f: (a: A) => B): Micro<B, E, R>
1579
+ } = dual(
1580
+ 2,
1581
+ <A, E, R, B>(self: Micro<A, E, R>, f: (a: A) => B): Micro<B, E, R> => flatMap(self, (a) => succeed(f(a)))
1582
+ )
1583
+
1584
+ // ----------------------------------------------------------------------------
1585
+ // MicroExit
1586
+ // ----------------------------------------------------------------------------
1587
+
1588
+ /**
1589
+ * The `MicroExit` type is used to represent the result of a `Micro` computation. It
1590
+ * can either be successful, containing a value of type `A`, or it can fail,
1591
+ * containing an error of type `E` wrapped in a `MicroCause`.
1592
+ *
1593
+ * @since 3.4.6
1594
+ * @experimental
1595
+ * @category MicroExit
1596
+ */
1597
+ export type MicroExit<A, E = never> =
1598
+ | MicroExit.Success<A, E>
1599
+ | MicroExit.Failure<A, E>
1600
+
1601
+ /**
1602
+ * @since 3.4.6
1603
+ * @experimental
1604
+ * @category MicroExit
1605
+ */
1606
+ export declare namespace MicroExit {
1607
+ /**
1608
+ * @since 3.4.6
1609
+ * @experimental
1610
+ * @category MicroExit
1611
+ */
1612
+ export interface Proto<out A, out E = never> extends Micro<A, E> {
1613
+ readonly [MicroExitTypeId]: MicroExitTypeId
1614
+ }
1615
+
1616
+ /**
1617
+ * @since 3.4.6
1618
+ * @experimental
1619
+ * @category MicroExit
1620
+ */
1621
+ export interface Success<out A, out E> extends Proto<A, E> {
1622
+ readonly _tag: "Success"
1623
+ readonly value: A
1624
+ }
1625
+
1626
+ /**
1627
+ * @since 3.4.6
1628
+ * @experimental
1629
+ * @category MicroExit
1630
+ */
1631
+ export interface Failure<out A, out E> extends Proto<A, E> {
1632
+ readonly _tag: "Failure"
1633
+ readonly cause: MicroCause<E>
1634
+ }
1635
+ }
1636
+
1637
+ /**
1638
+ * @since 3.4.6
1639
+ * @experimental
1640
+ * @category MicroExit
1641
+ */
1642
+ export const isMicroExit = (u: unknown): u is MicroExit<unknown, unknown> => hasProperty(u, MicroExitTypeId)
1643
+
1644
+ /**
1645
+ * @since 3.4.6
1646
+ * @experimental
1647
+ * @category MicroExit
1648
+ */
1649
+ export const exitSucceed: <A>(a: A) => MicroExit<A, never> = succeed as any
1650
+
1651
+ /**
1652
+ * @since 3.4.6
1653
+ * @experimental
1654
+ * @category MicroExit
1655
+ */
1656
+ export const exitFailCause: <E>(cause: MicroCause<E>) => MicroExit<never, E> = failCause as any
1657
+
1658
+ /**
1659
+ * @since 3.4.6
1660
+ * @experimental
1661
+ * @category MicroExit
1662
+ */
1663
+ export const exitInterrupt: MicroExit<never> = exitFailCause(causeInterrupt())
1664
+
1665
+ /**
1666
+ * @since 3.4.6
1667
+ * @experimental
1668
+ * @category MicroExit
1669
+ */
1670
+ export const exitFail = <E>(e: E): MicroExit<never, E> => exitFailCause(causeFail(e))
1671
+
1672
+ /**
1673
+ * @since 3.4.6
1674
+ * @experimental
1675
+ * @category MicroExit
1676
+ */
1677
+ export const exitDie = (defect: unknown): MicroExit<never> => exitFailCause(causeDie(defect))
1678
+
1679
+ /**
1680
+ * @since 3.4.6
1681
+ * @experimental
1682
+ * @category MicroExit
1683
+ */
1684
+ export const exitIsSuccess = <A, E>(
1685
+ self: MicroExit<A, E>
1686
+ ): self is MicroExit.Success<A, E> => self._tag === "Success"
1687
+
1688
+ /**
1689
+ * @since 3.4.6
1690
+ * @experimental
1691
+ * @category MicroExit
1692
+ */
1693
+ export const exitIsFailure = <A, E>(
1694
+ self: MicroExit<A, E>
1695
+ ): self is MicroExit.Failure<A, E> => self._tag === "Failure"
1696
+
1697
+ /**
1698
+ * @since 3.4.6
1699
+ * @experimental
1700
+ * @category MicroExit
1701
+ */
1702
+ export const exitIsInterrupt = <A, E>(
1703
+ self: MicroExit<A, E>
1704
+ ): self is MicroExit.Failure<A, E> & {
1705
+ readonly cause: MicroCause.Interrupt
1706
+ } => exitIsFailure(self) && self.cause._tag === "Interrupt"
1707
+
1708
+ /**
1709
+ * @since 3.4.6
1710
+ * @experimental
1711
+ * @category MicroExit
1712
+ */
1713
+ export const exitIsFail = <A, E>(
1714
+ self: MicroExit<A, E>
1715
+ ): self is MicroExit.Failure<A, E> & {
1716
+ readonly cause: MicroCause.Fail<E>
1717
+ } => exitIsFailure(self) && self.cause._tag === "Fail"
1718
+
1719
+ /**
1720
+ * @since 3.4.6
1721
+ * @experimental
1722
+ * @category MicroExit
1723
+ */
1724
+ export const exitIsDie = <A, E>(
1725
+ self: MicroExit<A, E>
1726
+ ): self is MicroExit.Failure<A, E> & {
1727
+ readonly cause: MicroCause.Die
1728
+ } => exitIsFailure(self) && self.cause._tag === "Die"
1729
+
1730
+ /**
1731
+ * @since 3.4.6
1732
+ * @experimental
1733
+ * @category MicroExit
1734
+ */
1735
+ export const exitVoid: MicroExit<void> = exitSucceed(void 0)
1736
+
1737
+ /**
1738
+ * @since 3.11.0
1739
+ * @experimental
1740
+ * @category MicroExit
1741
+ */
1742
+ export const exitVoidAll = <I extends Iterable<MicroExit<any, any>>>(
1743
+ exits: I
1744
+ ): MicroExit<void, I extends Iterable<MicroExit<infer _A, infer _E>> ? _E : never> => {
1745
+ for (const exit of exits) {
1746
+ if (exit._tag === "Failure") {
1747
+ return exit
1748
+ }
1749
+ }
1750
+ return exitVoid
1751
+ }
1752
+
1753
+ // ----------------------------------------------------------------------------
1754
+ // scheduler
1755
+ // ----------------------------------------------------------------------------
1756
+
1757
+ /**
1758
+ * @since 3.5.9
1759
+ * @experimental
1760
+ * @category scheduler
1761
+ */
1762
+ export interface MicroScheduler {
1763
+ readonly scheduleTask: (task: () => void, priority: number) => void
1764
+ readonly shouldYield: (fiber: MicroFiber<unknown, unknown>) => boolean
1765
+ readonly flush: () => void
1766
+ }
1767
+
1768
+ const setImmediate = "setImmediate" in globalThis
1769
+ ? globalThis.setImmediate
1770
+ : (f: () => void) => setTimeout(f, 0)
1771
+
1772
+ /**
1773
+ * @since 3.5.9
1774
+ * @experimental
1775
+ * @category scheduler
1776
+ */
1777
+ export class MicroSchedulerDefault implements MicroScheduler {
1778
+ private tasks: Array<() => void> = []
1779
+ private running = false
1780
+
1781
+ /**
1782
+ * @since 3.5.9
1783
+ */
1784
+ scheduleTask(task: () => void, _priority: number) {
1785
+ this.tasks.push(task)
1786
+ if (!this.running) {
1787
+ this.running = true
1788
+ setImmediate(this.afterScheduled)
1789
+ }
1790
+ }
1791
+
1792
+ /**
1793
+ * @since 3.5.9
1794
+ */
1795
+ afterScheduled = () => {
1796
+ this.running = false
1797
+ this.runTasks()
1798
+ }
1799
+
1800
+ /**
1801
+ * @since 3.5.9
1802
+ */
1803
+ runTasks() {
1804
+ const tasks = this.tasks
1805
+ this.tasks = []
1806
+ for (let i = 0, len = tasks.length; i < len; i++) {
1807
+ tasks[i]()
1808
+ }
1809
+ }
1810
+
1811
+ /**
1812
+ * @since 3.5.9
1813
+ */
1814
+ shouldYield(fiber: MicroFiber<unknown, unknown>) {
1815
+ return fiber.currentOpCount >= fiber.getRef(MaxOpsBeforeYield)
1816
+ }
1817
+
1818
+ /**
1819
+ * @since 3.5.9
1820
+ */
1821
+ flush() {
1822
+ while (this.tasks.length > 0) {
1823
+ this.runTasks()
1824
+ }
1825
+ }
1826
+ }
1827
+
1828
+ /**
1829
+ * Access the given `Context.Tag` from the environment.
1830
+ *
1831
+ * @since 3.4.0
1832
+ * @experimental
1833
+ * @category environment
1834
+ */
1835
+ export const service: {
1836
+ <I, S>(tag: Context.Reference<I, S>): Micro<S>
1837
+ <I, S>(tag: Context.Tag<I, S>): Micro<S, never, I>
1838
+ } =
1839
+ (<I, S>(tag: Context.Tag<I, S>): Micro<S, never, I> =>
1840
+ withMicroFiber((fiber) => succeed(Context.unsafeGet(fiber.context, tag)))) as any
1841
+
1842
+ /**
1843
+ * Access the given `Context.Tag` from the environment, without tracking the
1844
+ * dependency at the type level.
1845
+ *
1846
+ * It will return an `Option` of the service, depending on whether it is
1847
+ * available in the environment or not.
1848
+ *
1849
+ * @since 3.4.0
1850
+ * @experimental
1851
+ * @category environment
1852
+ */
1853
+ export const serviceOption = <I, S>(
1854
+ tag: Context.Tag<I, S>
1855
+ ): Micro<Option.Option<S>> => withMicroFiber((fiber) => succeed(Context.getOption(fiber.context, tag)))
1856
+
1857
+ /**
1858
+ * Update the Context with the given mapping function.
1859
+ *
1860
+ * @since 3.11.0
1861
+ * @experimental
1862
+ * @category environment
1863
+ */
1864
+ export const updateContext: {
1865
+ <R2, R>(
1866
+ f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
1867
+ ): <A, E>(self: Micro<A, E, R>) => Micro<A, E, R2>
1868
+ <A, E, R, R2>(self: Micro<A, E, R>, f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>): Micro<A, E, R2>
1869
+ } = dual(
1870
+ 2,
1871
+ <A, E, R, R2>(
1872
+ self: Micro<A, E, R>,
1873
+ f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
1874
+ ): Micro<A, E, R2> =>
1875
+ withMicroFiber<A, E, R2>((fiber) => {
1876
+ const prev = fiber.context as Context.Context<R2>
1877
+ fiber.context = f(prev)
1878
+ return onExit(
1879
+ self as any,
1880
+ () => {
1881
+ fiber.context = prev
1882
+ return void_
1883
+ }
1884
+ )
1885
+ })
1886
+ )
1887
+
1888
+ /**
1889
+ * Update the service for the given `Context.Tag` in the environment.
1890
+ *
1891
+ * @since 3.11.0
1892
+ * @experimental
1893
+ * @category environment
1894
+ */
1895
+ export const updateService: {
1896
+ <I, A>(
1897
+ tag: Context.Reference<I, A>,
1898
+ f: (value: A) => A
1899
+ ): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R>
1900
+ <I, A>(
1901
+ tag: Context.Tag<I, A>,
1902
+ f: (value: A) => A
1903
+ ): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R | I>
1904
+ <XA, E, R, I, A>(
1905
+ self: Micro<XA, E, R>,
1906
+ tag: Context.Reference<I, A>,
1907
+ f: (value: A) => A
1908
+ ): Micro<XA, E, R>
1909
+ <XA, E, R, I, A>(
1910
+ self: Micro<XA, E, R>,
1911
+ tag: Context.Tag<I, A>,
1912
+ f: (value: A) => A
1913
+ ): Micro<XA, E, R | I>
1914
+ } = dual(
1915
+ 3,
1916
+ <XA, E, R, I, A>(
1917
+ self: Micro<XA, E, R>,
1918
+ tag: Context.Reference<I, A>,
1919
+ f: (value: A) => A
1920
+ ): Micro<XA, E, R> =>
1921
+ withMicroFiber((fiber) => {
1922
+ const prev = Context.unsafeGet(fiber.context, tag)
1923
+ fiber.context = Context.add(fiber.context, tag, f(prev))
1924
+ return onExit(
1925
+ self,
1926
+ () => {
1927
+ fiber.context = Context.add(fiber.context, tag, prev)
1928
+ return void_
1929
+ }
1930
+ )
1931
+ })
1932
+ )
1933
+
1934
+ /**
1935
+ * Access the current `Context` from the environment.
1936
+ *
1937
+ * @since 3.4.0
1938
+ * @experimental
1939
+ * @category environment
1940
+ */
1941
+ export const context = <R>(): Micro<Context.Context<R>> => getContext as any
1942
+ const getContext = withMicroFiber((fiber) => succeed(fiber.context))
1943
+
1944
+ /**
1945
+ * Merge the given `Context` with the current context.
1946
+ *
1947
+ * @since 3.4.0
1948
+ * @experimental
1949
+ * @category environment
1950
+ */
1951
+ export const provideContext: {
1952
+ <XR>(
1953
+ context: Context.Context<XR>
1954
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, XR>>
1955
+ <A, E, R, XR>(
1956
+ self: Micro<A, E, R>,
1957
+ context: Context.Context<XR>
1958
+ ): Micro<A, E, Exclude<R, XR>>
1959
+ } = dual(
1960
+ 2,
1961
+ <A, E, R, XR>(
1962
+ self: Micro<A, E, R>,
1963
+ provided: Context.Context<XR>
1964
+ ): Micro<A, E, Exclude<R, XR>> => updateContext(self, Context.merge(provided)) as any
1965
+ )
1966
+
1967
+ /**
1968
+ * Add the provided service to the current context.
1969
+ *
1970
+ * @since 3.4.0
1971
+ * @experimental
1972
+ * @category environment
1973
+ */
1974
+ export const provideService: {
1975
+ <I, S>(
1976
+ tag: Context.Tag<I, S>,
1977
+ service: S
1978
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, I>>
1979
+ <A, E, R, I, S>(
1980
+ self: Micro<A, E, R>,
1981
+ tag: Context.Tag<I, S>,
1982
+ service: S
1983
+ ): Micro<A, E, Exclude<R, I>>
1984
+ } = dual(
1985
+ 3,
1986
+ <A, E, R, I, S>(
1987
+ self: Micro<A, E, R>,
1988
+ tag: Context.Tag<I, S>,
1989
+ service: S
1990
+ ): Micro<A, E, Exclude<R, I>> => updateContext(self, Context.add(tag, service)) as any
1991
+ )
1992
+
1993
+ /**
1994
+ * Create a service using the provided `Micro` effect, and add it to the
1995
+ * current context.
1996
+ *
1997
+ * @since 3.4.6
1998
+ * @experimental
1999
+ * @category environment
2000
+ */
2001
+ export const provideServiceEffect: {
2002
+ <I, S, E2, R2>(
2003
+ tag: Context.Tag<I, S>,
2004
+ acquire: Micro<S, E2, R2>
2005
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | E2, Exclude<R, I> | R2>
2006
+ <A, E, R, I, S, E2, R2>(
2007
+ self: Micro<A, E, R>,
2008
+ tag: Context.Tag<I, S>,
2009
+ acquire: Micro<S, E2, R2>
2010
+ ): Micro<A, E | E2, Exclude<R, I> | R2>
2011
+ } = dual(
2012
+ 3,
2013
+ <A, E, R, I, S, E2, R2>(
2014
+ self: Micro<A, E, R>,
2015
+ tag: Context.Tag<I, S>,
2016
+ acquire: Micro<S, E2, R2>
2017
+ ): Micro<A, E | E2, Exclude<R, I> | R2> => flatMap(acquire, (service) => provideService(self, tag, service))
2018
+ )
2019
+
2020
+ // ========================================================================
2021
+ // References
2022
+ // ========================================================================
2023
+
2024
+ /**
2025
+ * @since 3.11.0
2026
+ * @experimental
2027
+ * @category references
2028
+ */
2029
+ export class MaxOpsBeforeYield extends Context.Reference<MaxOpsBeforeYield>()<
2030
+ "effect/Micro/currentMaxOpsBeforeYield",
2031
+ number
2032
+ >(
2033
+ "effect/Micro/currentMaxOpsBeforeYield",
2034
+ { defaultValue: () => 2048 }
2035
+ ) {}
2036
+
2037
+ /**
2038
+ * @since 3.11.0
2039
+ * @experimental
2040
+ * @category environment refs
2041
+ */
2042
+ export class CurrentConcurrency extends Context.Reference<CurrentConcurrency>()<
2043
+ "effect/Micro/currentConcurrency",
2044
+ "unbounded" | number
2045
+ >(
2046
+ "effect/Micro/currentConcurrency",
2047
+ { defaultValue: () => "unbounded" }
2048
+ ) {}
2049
+
2050
+ /**
2051
+ * @since 3.11.0
2052
+ * @experimental
2053
+ * @category environment refs
2054
+ */
2055
+ export class CurrentScheduler extends Context.Reference<CurrentScheduler>()<
2056
+ "effect/Micro/currentScheduler",
2057
+ MicroScheduler
2058
+ >(
2059
+ "effect/Micro/currentScheduler",
2060
+ { defaultValue: () => new MicroSchedulerDefault() }
2061
+ ) {}
2062
+
2063
+ /**
2064
+ * If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
2065
+ * api to control the concurrency of that `Micro` when it is run.
2066
+ *
2067
+ * @example
2068
+ * ```ts
2069
+ * import * as Micro from "effect/Micro"
2070
+ *
2071
+ * Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
2072
+ * concurrency: "inherit"
2073
+ * }).pipe(
2074
+ * Micro.withConcurrency(2) // use a concurrency of 2
2075
+ * )
2076
+ * ```
2077
+ *
2078
+ * @since 3.4.0
2079
+ * @experimental
2080
+ * @category environment refs
2081
+ */
2082
+ export const withConcurrency: {
2083
+ (
2084
+ concurrency: "unbounded" | number
2085
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, R>
2086
+ <A, E, R>(
2087
+ self: Micro<A, E, R>,
2088
+ concurrency: "unbounded" | number
2089
+ ): Micro<A, E, R>
2090
+ } = dual(
2091
+ 2,
2092
+ <A, E, R>(
2093
+ self: Micro<A, E, R>,
2094
+ concurrency: "unbounded" | number
2095
+ ): Micro<A, E, R> => provideService(self, CurrentConcurrency, concurrency)
2096
+ )
2097
+
2098
+ // ----------------------------------------------------------------------------
2099
+ // zipping
2100
+ // ----------------------------------------------------------------------------
2101
+
2102
+ /**
2103
+ * Combine two `Micro` effects into a single effect that produces a tuple of
2104
+ * their results.
2105
+ *
2106
+ * @since 3.4.0
2107
+ * @experimental
2108
+ * @category zipping
2109
+ */
2110
+ export const zip: {
2111
+ <A2, E2, R2>(
2112
+ that: Micro<A2, E2, R2>,
2113
+ options?:
2114
+ | { readonly concurrent?: boolean | undefined }
2115
+ | undefined
2116
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<[A, A2], E2 | E, R2 | R>
2117
+ <A, E, R, A2, E2, R2>(
2118
+ self: Micro<A, E, R>,
2119
+ that: Micro<A2, E2, R2>,
2120
+ options?: { readonly concurrent?: boolean | undefined }
2121
+ ): Micro<[A, A2], E | E2, R | R2>
2122
+ } = dual((args) => isMicro(args[1]), <A, E, R, A2, E2, R2>(
2123
+ self: Micro<A, E, R>,
2124
+ that: Micro<A2, E2, R2>,
2125
+ options?: { readonly concurrent?: boolean | undefined }
2126
+ ): Micro<[A, A2], E | E2, R | R2> => zipWith(self, that, (a, a2) => [a, a2], options))
2127
+
2128
+ /**
2129
+ * The `Micro.zipWith` function combines two `Micro` effects and allows you to
2130
+ * apply a function to the results of the combined effects, transforming them
2131
+ * into a single value.
2132
+ *
2133
+ * @since 3.4.3
2134
+ * @experimental
2135
+ * @category zipping
2136
+ */
2137
+ export const zipWith: {
2138
+ <A2, E2, R2, A, B>(
2139
+ that: Micro<A2, E2, R2>,
2140
+ f: (a: A, b: A2) => B,
2141
+ options?: { readonly concurrent?: boolean | undefined }
2142
+ ): <E, R>(self: Micro<A, E, R>) => Micro<B, E2 | E, R2 | R>
2143
+ <A, E, R, A2, E2, R2, B>(
2144
+ self: Micro<A, E, R>,
2145
+ that: Micro<A2, E2, R2>,
2146
+ f: (a: A, b: A2) => B,
2147
+ options?: { readonly concurrent?: boolean | undefined }
2148
+ ): Micro<B, E2 | E, R2 | R>
2149
+ } = dual((args) => isMicro(args[1]), <A, E, R, A2, E2, R2, B>(
2150
+ self: Micro<A, E, R>,
2151
+ that: Micro<A2, E2, R2>,
2152
+ f: (a: A, b: A2) => B,
2153
+ options?: { readonly concurrent?: boolean | undefined }
2154
+ ): Micro<B, E2 | E, R2 | R> =>
2155
+ options?.concurrent
2156
+ // Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
2157
+ ? map(all([self, that], { concurrency: 2 }), ([a, a2]) => f(a, a2))
2158
+ : flatMap(self, (a) => map(that, (a2) => f(a, a2))))
2159
+
2160
+ // ----------------------------------------------------------------------------
2161
+ // filtering & conditionals
2162
+ // ----------------------------------------------------------------------------
2163
+
2164
+ /**
2165
+ * Filter the specified effect with the provided function, failing with specified
2166
+ * `MicroCause` if the predicate fails.
2167
+ *
2168
+ * In addition to the filtering capabilities discussed earlier, you have the option to further
2169
+ * refine and narrow down the type of the success channel by providing a
2170
+ *
2171
+ * @since 3.4.0
2172
+ * @experimental
2173
+ * @category filtering & conditionals
2174
+ */
2175
+ export const filterOrFailCause: {
2176
+ <A, B extends A, E2>(
2177
+ refinement: Refinement<A, B>,
2178
+ orFailWith: (a: NoInfer<A>) => MicroCause<E2>
2179
+ ): <E, R>(self: Micro<A, E, R>) => Micro<B, E2 | E, R>
2180
+ <A, E2>(
2181
+ predicate: Predicate<NoInfer<A>>,
2182
+ orFailWith: (a: NoInfer<A>) => MicroCause<E2>
2183
+ ): <E, R>(self: Micro<A, E, R>) => Micro<A, E2 | E, R>
2184
+ <A, E, R, B extends A, E2>(
2185
+ self: Micro<A, E, R>,
2186
+ refinement: Refinement<A, B>,
2187
+ orFailWith: (a: A) => MicroCause<E2>
2188
+ ): Micro<B, E | E2, R>
2189
+ <A, E, R, E2>(
2190
+ self: Micro<A, E, R>,
2191
+ predicate: Predicate<A>,
2192
+ orFailWith: (a: A) => MicroCause<E2>
2193
+ ): Micro<A, E | E2, R>
2194
+ } = dual((args) => isMicro(args[0]), <A, E, R, B extends A, E2>(
2195
+ self: Micro<A, E, R>,
2196
+ refinement: Refinement<A, B>,
2197
+ orFailWith: (a: A) => MicroCause<E2>
2198
+ ): Micro<B, E | E2, R> => flatMap(self, (a) => refinement(a) ? succeed(a) : failCause(orFailWith(a))))
2199
+
2200
+ /**
2201
+ * Filter the specified effect with the provided function, failing with specified
2202
+ * error if the predicate fails.
2203
+ *
2204
+ * In addition to the filtering capabilities discussed earlier, you have the option to further
2205
+ * refine and narrow down the type of the success channel by providing a
2206
+ *
2207
+ * @since 3.4.0
2208
+ * @experimental
2209
+ * @category filtering & conditionals
2210
+ */
2211
+ export const filterOrFail: {
2212
+ <A, B extends A, E2>(
2213
+ refinement: Refinement<A, B>,
2214
+ orFailWith: (a: NoInfer<A>) => E2
2215
+ ): <E, R>(self: Micro<A, E, R>) => Micro<B, E2 | E, R>
2216
+ <A, E2>(
2217
+ predicate: Predicate<NoInfer<A>>,
2218
+ orFailWith: (a: NoInfer<A>) => E2
2219
+ ): <E, R>(self: Micro<A, E, R>) => Micro<A, E2 | E, R>
2220
+ <A, E, R, B extends A, E2>(
2221
+ self: Micro<A, E, R>,
2222
+ refinement: Refinement<A, B>,
2223
+ orFailWith: (a: A) => E2
2224
+ ): Micro<B, E | E2, R>
2225
+ <A, E, R, E2>(self: Micro<A, E, R>, predicate: Predicate<A>, orFailWith: (a: A) => E2): Micro<A, E | E2, R>
2226
+ } = dual((args) => isMicro(args[0]), <A, E, R, B extends A, E2>(
2227
+ self: Micro<A, E, R>,
2228
+ refinement: Refinement<A, B>,
2229
+ orFailWith: (a: A) => E2
2230
+ ): Micro<B, E | E2, R> => flatMap(self, (a) => refinement(a) ? succeed(a) : fail(orFailWith(a))))
2231
+
2232
+ /**
2233
+ * The moral equivalent of `if (p) exp`.
2234
+ *
2235
+ * @since 3.4.0
2236
+ * @experimental
2237
+ * @category filtering & conditionals
2238
+ */
2239
+ export const when: {
2240
+ <E2 = never, R2 = never>(
2241
+ condition: LazyArg<boolean> | Micro<boolean, E2, R2>
2242
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<Option.Option<A>, E | E2, R | R2>
2243
+ <A, E, R, E2 = never, R2 = never>(
2244
+ self: Micro<A, E, R>,
2245
+ condition: LazyArg<boolean> | Micro<boolean, E2, R2>
2246
+ ): Micro<Option.Option<A>, E | E2, R | R2>
2247
+ } = dual(
2248
+ 2,
2249
+ <A, E, R, E2 = never, R2 = never>(
2250
+ self: Micro<A, E, R>,
2251
+ condition: LazyArg<boolean> | Micro<boolean, E2, R2>
2252
+ ): Micro<Option.Option<A>, E | E2, R | R2> =>
2253
+ flatMap(isMicro(condition) ? condition : sync(condition), (pass) => pass ? asSome(self) : succeedNone)
2254
+ )
2255
+
2256
+ // ----------------------------------------------------------------------------
2257
+ // repetition
2258
+ // ----------------------------------------------------------------------------
2259
+
2260
+ /**
2261
+ * Repeat the given `Micro` using the provided options.
2262
+ *
2263
+ * The `while` predicate will be checked after each iteration, and can use the
2264
+ * fall `MicroExit` of the effect to determine if the repetition should continue.
2265
+ *
2266
+ * @since 3.4.6
2267
+ * @experimental
2268
+ * @category repetition
2269
+ */
2270
+ export const repeatExit: {
2271
+ <A, E>(options: {
2272
+ while: Predicate<MicroExit<A, E>>
2273
+ times?: number | undefined
2274
+ schedule?: MicroSchedule | undefined
2275
+ }): <R>(self: Micro<A, E, R>) => Micro<A, E, R>
2276
+ <A, E, R>(self: Micro<A, E, R>, options: {
2277
+ while: Predicate<MicroExit<A, E>>
2278
+ times?: number | undefined
2279
+ schedule?: MicroSchedule | undefined
2280
+ }): Micro<A, E, R>
2281
+ } = dual(2, <A, E, R>(self: Micro<A, E, R>, options: {
2282
+ while: Predicate<MicroExit<A, E>>
2283
+ times?: number | undefined
2284
+ schedule?: MicroSchedule | undefined
2285
+ }): Micro<A, E, R> =>
2286
+ suspend(() => {
2287
+ const startedAt = options.schedule ? Date.now() : 0
2288
+ let attempt = 0
2289
+
2290
+ const loop: Micro<A, E, R> = flatMap(exit(self), (exit) => {
2291
+ if (options.while !== undefined && !options.while(exit)) {
2292
+ return exit
2293
+ } else if (options.times !== undefined && attempt >= options.times) {
2294
+ return exit
2295
+ }
2296
+ attempt++
2297
+ let delayEffect = yieldNow
2298
+ if (options.schedule !== undefined) {
2299
+ const elapsed = Date.now() - startedAt
2300
+ const duration = options.schedule(attempt, elapsed)
2301
+ if (Option.isNone(duration)) {
2302
+ return exit
2303
+ }
2304
+ delayEffect = sleep(duration.value)
2305
+ }
2306
+ return flatMap(delayEffect, () => loop)
2307
+ })
2308
+
2309
+ return loop
2310
+ }))
2311
+
2312
+ /**
2313
+ * Repeat the given `Micro` effect using the provided options. Only successful
2314
+ * results will be repeated.
2315
+ *
2316
+ * @since 3.4.0
2317
+ * @experimental
2318
+ * @category repetition
2319
+ */
2320
+ export const repeat: {
2321
+ <A, E>(
2322
+ options?: {
2323
+ while?: Predicate<A> | undefined
2324
+ times?: number | undefined
2325
+ schedule?: MicroSchedule | undefined
2326
+ } | undefined
2327
+ ): <R>(self: Micro<A, E, R>) => Micro<A, E, R>
2328
+ <A, E, R>(
2329
+ self: Micro<A, E, R>,
2330
+ options?: {
2331
+ while?: Predicate<A> | undefined
2332
+ times?: number | undefined
2333
+ schedule?: MicroSchedule | undefined
2334
+ } | undefined
2335
+ ): Micro<A, E, R>
2336
+ } = dual((args) => isMicro(args[0]), <A, E, R>(
2337
+ self: Micro<A, E, R>,
2338
+ options?: {
2339
+ while?: Predicate<A> | undefined
2340
+ times?: number | undefined
2341
+ schedule?: MicroSchedule | undefined
2342
+ } | undefined
2343
+ ): Micro<A, E, R> =>
2344
+ repeatExit(self, {
2345
+ ...options,
2346
+ while: (exit) => exit._tag === "Success" && (options?.while === undefined || options.while(exit.value))
2347
+ }))
2348
+
2349
+ /**
2350
+ * Replicates the given effect `n` times.
2351
+ *
2352
+ * @since 3.11.0
2353
+ * @experimental
2354
+ * @category repetition
2355
+ */
2356
+ export const replicate: {
2357
+ (n: number): <A, E, R>(self: Micro<A, E, R>) => Array<Micro<A, E, R>>
2358
+ <A, E, R>(self: Micro<A, E, R>, n: number): Array<Micro<A, E, R>>
2359
+ } = dual(
2360
+ 2,
2361
+ <A, E, R>(self: Micro<A, E, R>, n: number): Array<Micro<A, E, R>> => Array.from({ length: n }, () => self)
2362
+ )
2363
+
2364
+ /**
2365
+ * Performs this effect the specified number of times and collects the
2366
+ * results.
2367
+ *
2368
+ * @since 3.11.0
2369
+ * @category repetition
2370
+ */
2371
+ export const replicateEffect: {
2372
+ (
2373
+ n: number,
2374
+ options?: {
2375
+ readonly concurrency?: Concurrency | undefined
2376
+ readonly discard?: false | undefined
2377
+ }
2378
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<Array<A>, E, R>
2379
+ (
2380
+ n: number,
2381
+ options: {
2382
+ readonly concurrency?: Concurrency | undefined
2383
+ readonly discard: true
2384
+ }
2385
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<void, E, R>
2386
+ <A, E, R>(
2387
+ self: Micro<A, E, R>,
2388
+ n: number,
2389
+ options?: {
2390
+ readonly concurrency?: Concurrency | undefined
2391
+ readonly discard?: false | undefined
2392
+ }
2393
+ ): Micro<Array<A>, E, R>
2394
+ <A, E, R>(
2395
+ self: Micro<A, E, R>,
2396
+ n: number,
2397
+ options: {
2398
+ readonly concurrency?: Concurrency | undefined
2399
+ readonly discard: true
2400
+ }
2401
+ ): Micro<void, E, R>
2402
+ } = dual(
2403
+ (args) => isMicro(args[0]),
2404
+ <A, E, R>(
2405
+ self: Micro<A, E, R>,
2406
+ n: number,
2407
+ options: {
2408
+ readonly concurrency?: Concurrency | undefined
2409
+ readonly discard: true
2410
+ }
2411
+ ): Micro<void, E, R> => all(replicate(self, n), options)
2412
+ )
2413
+
2414
+ /**
2415
+ * Repeat the given `Micro` effect forever, only stopping if the effect fails.
2416
+ *
2417
+ * @since 3.4.0
2418
+ * @experimental
2419
+ * @category repetition
2420
+ */
2421
+ export const forever = <A, E, R>(self: Micro<A, E, R>): Micro<never, E, R> => repeat(self) as any
2422
+
2423
+ // ----------------------------------------------------------------------------
2424
+ // scheduling
2425
+ // ----------------------------------------------------------------------------
2426
+
2427
+ /**
2428
+ * The `MicroSchedule` type represents a function that can be used to calculate
2429
+ * the delay between repeats.
2430
+ *
2431
+ * The function takes the current attempt number and the elapsed time since the
2432
+ * first attempt, and returns the delay for the next attempt. If the function
2433
+ * returns `None`, the repetition will stop.
2434
+ *
2435
+ * @since 3.4.6
2436
+ * @experimental
2437
+ * @category scheduling
2438
+ */
2439
+ export type MicroSchedule = (attempt: number, elapsed: number) => Option.Option<number>
2440
+
2441
+ /**
2442
+ * Create a `MicroSchedule` that will stop repeating after the specified number
2443
+ * of attempts.
2444
+ *
2445
+ * @since 3.4.6
2446
+ * @experimental
2447
+ * @category scheduling
2448
+ */
2449
+ export const scheduleRecurs = (n: number): MicroSchedule => (attempt) => attempt <= n ? Option.some(0) : Option.none()
2450
+
2451
+ /**
2452
+ * Create a `MicroSchedule` that will generate a constant delay.
2453
+ *
2454
+ * @since 3.4.6
2455
+ * @experimental
2456
+ * @category scheduling
2457
+ */
2458
+ export const scheduleSpaced = (millis: number): MicroSchedule => () => Option.some(millis)
2459
+
2460
+ /**
2461
+ * Create a `MicroSchedule` that will generate a delay with an exponential backoff.
2462
+ *
2463
+ * @since 3.4.6
2464
+ * @experimental
2465
+ * @category scheduling
2466
+ */
2467
+ export const scheduleExponential = (baseMillis: number, factor = 2): MicroSchedule => (attempt) =>
2468
+ Option.some(Math.pow(factor, attempt) * baseMillis)
2469
+
2470
+ /**
2471
+ * Returns a new `MicroSchedule` with an added calculated delay to each delay
2472
+ * returned by this schedule.
2473
+ *
2474
+ * @since 3.4.6
2475
+ * @experimental
2476
+ * @category scheduling
2477
+ */
2478
+ export const scheduleAddDelay: {
2479
+ (f: () => number): (self: MicroSchedule) => MicroSchedule
2480
+ (self: MicroSchedule, f: () => number): MicroSchedule
2481
+ } = dual(
2482
+ 2,
2483
+ (self: MicroSchedule, f: () => number): MicroSchedule => (attempt, elapsed) =>
2484
+ Option.map(self(attempt, elapsed), (duration) => duration + f())
2485
+ )
2486
+
2487
+ /**
2488
+ * Transform a `MicroSchedule` to one that will have a delay that will never exceed
2489
+ * the specified maximum.
2490
+ *
2491
+ * @since 3.4.6
2492
+ * @experimental
2493
+ * @category scheduling
2494
+ */
2495
+ export const scheduleWithMaxDelay: {
2496
+ (max: number): (self: MicroSchedule) => MicroSchedule
2497
+ (self: MicroSchedule, max: number): MicroSchedule
2498
+ } = dual(
2499
+ 2,
2500
+ (self: MicroSchedule, max: number): MicroSchedule => (attempt, elapsed) =>
2501
+ Option.map(self(attempt, elapsed), (duration) => Math.min(duration, max))
2502
+ )
2503
+
2504
+ /**
2505
+ * Transform a `MicroSchedule` to one that will stop repeating after the specified
2506
+ * amount of time.
2507
+ *
2508
+ * @since 3.4.6
2509
+ * @experimental
2510
+ * @category scheduling
2511
+ */
2512
+ export const scheduleWithMaxElapsed: {
2513
+ (max: number): (self: MicroSchedule) => MicroSchedule
2514
+ (self: MicroSchedule, max: number): MicroSchedule
2515
+ } = dual(
2516
+ 2,
2517
+ (self: MicroSchedule, max: number): MicroSchedule => (attempt, elapsed) =>
2518
+ elapsed < max ? self(attempt, elapsed) : Option.none()
2519
+ )
2520
+
2521
+ /**
2522
+ * Combines two `MicroSchedule`s, by recurring if either schedule wants to
2523
+ * recur, using the minimum of the two durations between recurrences.
2524
+ *
2525
+ * @since 3.4.6
2526
+ * @experimental
2527
+ * @category scheduling
2528
+ */
2529
+ export const scheduleUnion: {
2530
+ (that: MicroSchedule): (self: MicroSchedule) => MicroSchedule
2531
+ (self: MicroSchedule, that: MicroSchedule): MicroSchedule
2532
+ } = dual(
2533
+ 2,
2534
+ (self: MicroSchedule, that: MicroSchedule): MicroSchedule => (attempt, elapsed) =>
2535
+ Option.zipWith(self(attempt, elapsed), that(attempt, elapsed), (d1, d2) => Math.min(d1, d2))
2536
+ )
2537
+
2538
+ /**
2539
+ * Combines two `MicroSchedule`s, by recurring only if both schedules want to
2540
+ * recur, using the maximum of the two durations between recurrences.
2541
+ *
2542
+ * @since 3.4.6
2543
+ * @experimental
2544
+ * @category scheduling
2545
+ */
2546
+ export const scheduleIntersect: {
2547
+ (that: MicroSchedule): (self: MicroSchedule) => MicroSchedule
2548
+ (self: MicroSchedule, that: MicroSchedule): MicroSchedule
2549
+ } = dual(
2550
+ 2,
2551
+ (self: MicroSchedule, that: MicroSchedule): MicroSchedule => (attempt, elapsed) =>
2552
+ Option.zipWith(self(attempt, elapsed), that(attempt, elapsed), (d1, d2) => Math.max(d1, d2))
2553
+ )
2554
+
2555
+ // ----------------------------------------------------------------------------
2556
+ // error handling
2557
+ // ----------------------------------------------------------------------------
2558
+
2559
+ /**
2560
+ * Catch the full `MicroCause` object of the given `Micro` effect, allowing you to
2561
+ * recover from any kind of cause.
2562
+ *
2563
+ * @since 3.4.6
2564
+ * @experimental
2565
+ * @category error handling
2566
+ */
2567
+ export const catchAllCause: {
2568
+ <E, B, E2, R2>(
2569
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2570
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A | B, E2, R | R2>
2571
+ <A, E, R, B, E2, R2>(
2572
+ self: Micro<A, E, R>,
2573
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2574
+ ): Micro<A | B, E2, R | R2>
2575
+ } = dual(
2576
+ 2,
2577
+ <A, E, R, B, E2, R2>(
2578
+ self: Micro<A, E, R>,
2579
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2580
+ ): Micro<A | B, E2, R | R2> => {
2581
+ const onFailure = Object.create(OnFailureProto)
2582
+ onFailure[args] = self
2583
+ onFailure[failureCont] = f
2584
+ return onFailure
2585
+ }
2586
+ )
2587
+ const OnFailureProto = makePrimitiveProto({
2588
+ op: "OnFailure",
2589
+ eval(this: any, fiber: MicroFiberImpl): Primitive {
2590
+ fiber._stack.push(this as any)
2591
+ return this[args]
2592
+ }
2593
+ })
2594
+
2595
+ /**
2596
+ * Selectively catch a `MicroCause` object of the given `Micro` effect,
2597
+ * using the provided predicate to determine if the failure should be caught.
2598
+ *
2599
+ * @since 3.4.6
2600
+ * @experimental
2601
+ * @category error handling
2602
+ */
2603
+ export const catchCauseIf: {
2604
+ <E, B, E2, R2, EB extends MicroCause<E>>(
2605
+ refinement: Refinement<MicroCause<E>, EB>,
2606
+ f: (cause: EB) => Micro<B, E2, R2>
2607
+ ): <A, R>(
2608
+ self: Micro<A, E, R>
2609
+ ) => Micro<A | B, Exclude<E, MicroCause.Error<EB>> | E2, R | R2>
2610
+ <E, B, E2, R2>(
2611
+ predicate: Predicate<MicroCause<NoInfer<E>>>,
2612
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2613
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A | B, E | E2, R | R2>
2614
+ <A, E, R, B, E2, R2, EB extends MicroCause<E>>(
2615
+ self: Micro<A, E, R>,
2616
+ refinement: Refinement<MicroCause<E>, EB>,
2617
+ f: (cause: EB) => Micro<B, E2, R2>
2618
+ ): Micro<A | B, Exclude<E, MicroCause.Error<EB>> | E2, R | R2>
2619
+ <A, E, R, B, E2, R2>(
2620
+ self: Micro<A, E, R>,
2621
+ predicate: Predicate<MicroCause<NoInfer<E>>>,
2622
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2623
+ ): Micro<A | B, E | E2, R | R2>
2624
+ } = dual(
2625
+ 3,
2626
+ <A, E, R, B, E2, R2>(
2627
+ self: Micro<A, E, R>,
2628
+ predicate: Predicate<MicroCause<E>>,
2629
+ f: (cause: MicroCause<E>) => Micro<B, E2, R2>
2630
+ ): Micro<A | B, E | E2, R | R2> =>
2631
+ catchAllCause(self, (cause) => predicate(cause) ? f(cause) : failCause(cause) as any)
2632
+ )
2633
+
2634
+ /**
2635
+ * Catch the error of the given `Micro` effect, allowing you to recover from it.
2636
+ *
2637
+ * It only catches expected errors.
2638
+ *
2639
+ * @since 3.4.6
2640
+ * @experimental
2641
+ * @category error handling
2642
+ */
2643
+ export const catchAll: {
2644
+ <E, B, E2, R2>(
2645
+ f: (e: NoInfer<E>) => Micro<B, E2, R2>
2646
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A | B, E2, R | R2>
2647
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (e: NoInfer<E>) => Micro<B, E2, R2>): Micro<A | B, E2, R | R2>
2648
+ } = dual(
2649
+ 2,
2650
+ <A, E, R, B, E2, R2>(
2651
+ self: Micro<A, E, R>,
2652
+ f: (a: NoInfer<E>) => Micro<B, E2, R2>
2653
+ ): Micro<A | B, E2, R | R2> => catchCauseIf(self, causeIsFail, (cause) => f(cause.error))
2654
+ )
2655
+
2656
+ /**
2657
+ * Catch any unexpected errors of the given `Micro` effect, allowing you to recover from them.
2658
+ *
2659
+ * @since 3.4.6
2660
+ * @experimental
2661
+ * @category error handling
2662
+ */
2663
+ export const catchAllDefect: {
2664
+ <E, B, E2, R2>(
2665
+ f: (defect: unknown) => Micro<B, E2, R2>
2666
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A | B, E | E2, R | R2>
2667
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (defect: unknown) => Micro<B, E2, R2>): Micro<A | B, E | E2, R | R2>
2668
+ } = dual(
2669
+ 2,
2670
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (defect: unknown) => Micro<B, E2, R2>): Micro<A | B, E | E2, R | R2> =>
2671
+ catchCauseIf(self, causeIsDie, (die) => f(die.defect))
2672
+ )
2673
+
2674
+ /**
2675
+ * Perform a side effect using the full `MicroCause` object of the given `Micro`.
2676
+ *
2677
+ * @since 3.4.6
2678
+ * @experimental
2679
+ * @category error handling
2680
+ */
2681
+ export const tapErrorCause: {
2682
+ <E, B, E2, R2>(
2683
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2684
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A, E | E2, R | R2>
2685
+ <A, E, R, B, E2, R2>(
2686
+ self: Micro<A, E, R>,
2687
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2688
+ ): Micro<A, E | E2, R | R2>
2689
+ } = dual(
2690
+ 2,
2691
+ <A, E, R, B, E2, R2>(
2692
+ self: Micro<A, E, R>,
2693
+ f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2694
+ ): Micro<A, E | E2, R | R2> => tapErrorCauseIf(self, constTrue, f)
2695
+ )
2696
+
2697
+ /**
2698
+ * Perform a side effect using if a `MicroCause` object matches the specified
2699
+ * predicate.
2700
+ *
2701
+ * @since 3.4.0
2702
+ * @experimental
2703
+ * @category error handling
2704
+ */
2705
+ export const tapErrorCauseIf: {
2706
+ <E, B, E2, R2, EB extends MicroCause<E>>(
2707
+ refinement: Refinement<MicroCause<E>, EB>,
2708
+ f: (a: EB) => Micro<B, E2, R2>
2709
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A, E | E2, R | R2>
2710
+ <E, B, E2, R2>(
2711
+ predicate: (cause: NoInfer<MicroCause<E>>) => boolean,
2712
+ f: (a: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2713
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A, E | E2, R | R2>
2714
+ <A, E, R, B, E2, R2, EB extends MicroCause<E>>(
2715
+ self: Micro<A, E, R>,
2716
+ refinement: Refinement<MicroCause<E>, EB>,
2717
+ f: (a: EB) => Micro<B, E2, R2>
2718
+ ): Micro<A, E | E2, R | R2>
2719
+ <A, E, R, B, E2, R2>(
2720
+ self: Micro<A, E, R>,
2721
+ predicate: (cause: NoInfer<MicroCause<E>>) => boolean,
2722
+ f: (a: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
2723
+ ): Micro<A, E | E2, R | R2>
2724
+ } = dual(
2725
+ 3,
2726
+ <A, E, R, B, E2, R2, EB extends MicroCause<E>>(
2727
+ self: Micro<A, E, R>,
2728
+ refinement: Refinement<MicroCause<E>, EB>,
2729
+ f: (a: EB) => Micro<B, E2, R2>
2730
+ ): Micro<A, E | E2, R | R2> => catchCauseIf(self, refinement, (cause) => andThen(f(cause), failCause(cause)))
2731
+ )
2732
+
2733
+ /**
2734
+ * Perform a side effect from expected errors of the given `Micro`.
2735
+ *
2736
+ * @since 3.4.6
2737
+ * @experimental
2738
+ * @category error handling
2739
+ */
2740
+ export const tapError: {
2741
+ <E, B, E2, R2>(
2742
+ f: (e: NoInfer<E>) => Micro<B, E2, R2>
2743
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A, E | E2, R | R2>
2744
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (e: NoInfer<E>) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2>
2745
+ } = dual(
2746
+ 2,
2747
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (e: NoInfer<E>) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2> =>
2748
+ tapErrorCauseIf(self, causeIsFail, (fail) => f(fail.error))
2749
+ )
2750
+
2751
+ /**
2752
+ * Perform a side effect from unexpected errors of the given `Micro`.
2753
+ *
2754
+ * @since 3.4.6
2755
+ * @experimental
2756
+ * @category error handling
2757
+ */
2758
+ export const tapDefect: {
2759
+ <E, B, E2, R2>(
2760
+ f: (defect: unknown) => Micro<B, E2, R2>
2761
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A, E | E2, R | R2>
2762
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (defect: unknown) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2>
2763
+ } = dual(
2764
+ 2,
2765
+ <A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (defect: unknown) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2> =>
2766
+ tapErrorCauseIf(self, causeIsDie, (die) => f(die.defect))
2767
+ )
2768
+
2769
+ /**
2770
+ * Catch any expected errors that match the specified predicate.
2771
+ *
2772
+ * @since 3.4.0
2773
+ * @experimental
2774
+ * @category error handling
2775
+ */
2776
+ export const catchIf: {
2777
+ <E, EB extends E, A2, E2, R2>(
2778
+ refinement: Refinement<NoInfer<E>, EB>,
2779
+ f: (e: EB) => Micro<A2, E2, R2>
2780
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A2 | A, E2 | Exclude<E, EB>, R2 | R>
2781
+ <E, A2, E2, R2>(
2782
+ predicate: Predicate<NoInfer<E>>,
2783
+ f: (e: NoInfer<E>) => Micro<A2, E2, R2>
2784
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A2 | A, E | E2, R2 | R>
2785
+ <A, E, R, EB extends E, A2, E2, R2>(
2786
+ self: Micro<A, E, R>,
2787
+ refinement: Refinement<E, EB>,
2788
+ f: (e: EB) => Micro<A2, E2, R2>
2789
+ ): Micro<A | A2, E2 | Exclude<E, EB>, R | R2>
2790
+ <A, E, R, A2, E2, R2>(
2791
+ self: Micro<A, E, R>,
2792
+ predicate: Predicate<E>,
2793
+ f: (e: E) => Micro<A2, E2, R2>
2794
+ ): Micro<A | A2, E | E2, R | R2>
2795
+ } = dual(
2796
+ 3,
2797
+ <A, E, R, A2, E2, R2>(
2798
+ self: Micro<A, E, R>,
2799
+ predicate: Predicate<E>,
2800
+ f: (e: E) => Micro<A2, E2, R2>
2801
+ ): Micro<A | A2, E | E2, R | R2> =>
2802
+ catchCauseIf(
2803
+ self,
2804
+ (f): f is MicroCause.Fail<E> => causeIsFail(f) && predicate(f.error),
2805
+ (fail) => f(fail.error)
2806
+ )
2807
+ )
2808
+
2809
+ /**
2810
+ * Recovers from the specified tagged error.
2811
+ *
2812
+ * @since 3.4.0
2813
+ * @experimental
2814
+ * @category error handling
2815
+ */
2816
+ export const catchTag: {
2817
+ <K extends E extends { _tag: string } ? E["_tag"] : never, E, A1, E1, R1>(
2818
+ k: K,
2819
+ f: (e: Extract<E, { _tag: K }>) => Micro<A1, E1, R1>
2820
+ ): <A, R>(self: Micro<A, E, R>) => Micro<A1 | A, E1 | Exclude<E, { _tag: K }>, R1 | R>
2821
+ <A, E, R, K extends E extends { _tag: string } ? E["_tag"] : never, R1, E1, A1>(
2822
+ self: Micro<A, E, R>,
2823
+ k: K,
2824
+ f: (e: Extract<E, { _tag: K }>) => Micro<A1, E1, R1>
2825
+ ): Micro<A | A1, E1 | Exclude<E, { _tag: K }>, R | R1>
2826
+ } = dual(3, <A, E, R, K extends E extends { _tag: string } ? E["_tag"] : never, R1, E1, A1>(
2827
+ self: Micro<A, E, R>,
2828
+ k: K,
2829
+ f: (e: Extract<E, { _tag: K }>) => Micro<A1, E1, R1>
2830
+ ): Micro<A | A1, E1 | Exclude<E, { _tag: K }>, R | R1> =>
2831
+ catchIf(self, isTagged(k) as Refinement<E, Extract<E, { _tag: K }>>, f) as any)
2832
+
2833
+ /**
2834
+ * Transform the full `MicroCause` object of the given `Micro` effect.
2835
+ *
2836
+ * @since 3.4.6
2837
+ * @experimental
2838
+ * @category error handling
2839
+ */
2840
+ export const mapErrorCause: {
2841
+ <E, E2>(f: (e: MicroCause<E>) => MicroCause<E2>): <A, R>(self: Micro<A, E, R>) => Micro<A, E2, R>
2842
+ <A, E, R, E2>(self: Micro<A, E, R>, f: (e: MicroCause<E>) => MicroCause<E2>): Micro<A, E2, R>
2843
+ } = dual(
2844
+ 2,
2845
+ <A, E, R, E2>(self: Micro<A, E, R>, f: (e: MicroCause<E>) => MicroCause<E2>): Micro<A, E2, R> =>
2846
+ catchAllCause(self, (cause) => failCause(f(cause)))
2847
+ )
2848
+
2849
+ /**
2850
+ * Transform any expected errors of the given `Micro` effect.
2851
+ *
2852
+ * @since 3.4.0
2853
+ * @experimental
2854
+ * @category error handling
2855
+ */
2856
+ export const mapError: {
2857
+ <E, E2>(f: (e: E) => E2): <A, R>(self: Micro<A, E, R>) => Micro<A, E2, R>
2858
+ <A, E, R, E2>(self: Micro<A, E, R>, f: (e: E) => E2): Micro<A, E2, R>
2859
+ } = dual(
2860
+ 2,
2861
+ <A, E, R, E2>(self: Micro<A, E, R>, f: (e: E) => E2): Micro<A, E2, R> => catchAll(self, (error) => fail(f(error)))
2862
+ )
2863
+
2864
+ /**
2865
+ * Elevate any expected errors of the given `Micro` effect to unexpected errors,
2866
+ * resulting in an error type of `never`.
2867
+ *
2868
+ * @since 3.4.0
2869
+ * @experimental
2870
+ * @category error handling
2871
+ */
2872
+ export const orDie = <A, E, R>(self: Micro<A, E, R>): Micro<A, never, R> => catchAll(self, die)
2873
+
2874
+ /**
2875
+ * Recover from all errors by succeeding with the given value.
2876
+ *
2877
+ * @since 3.4.0
2878
+ * @experimental
2879
+ * @category error handling
2880
+ */
2881
+ export const orElseSucceed: {
2882
+ <B>(f: LazyArg<B>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | B, never, R>
2883
+ <A, E, R, B>(self: Micro<A, E, R>, f: LazyArg<B>): Micro<A | B, never, R>
2884
+ } = dual(
2885
+ 2,
2886
+ <A, E, R, B>(self: Micro<A, E, R>, f: LazyArg<B>): Micro<A | B, never, R> => catchAll(self, (_) => sync(f))
2887
+ )
2888
+
2889
+ /**
2890
+ * Ignore any expected errors of the given `Micro` effect, returning `void`.
2891
+ *
2892
+ * @since 3.4.0
2893
+ * @experimental
2894
+ * @category error handling
2895
+ */
2896
+ export const ignore = <A, E, R>(self: Micro<A, E, R>): Micro<void, never, R> =>
2897
+ matchEffect(self, { onFailure: (_) => void_, onSuccess: (_) => void_ })
2898
+
2899
+ /**
2900
+ * Ignore any expected errors of the given `Micro` effect, returning `void`.
2901
+ *
2902
+ * @since 3.4.0
2903
+ * @experimental
2904
+ * @category error handling
2905
+ */
2906
+ export const ignoreLogged = <A, E, R>(self: Micro<A, E, R>): Micro<void, never, R> =>
2907
+ matchEffect(self, {
2908
+ // eslint-disable-next-line no-console
2909
+ onFailure: (error) => sync(() => console.error(error)),
2910
+ onSuccess: (_) => void_
2911
+ })
2912
+
2913
+ /**
2914
+ * Replace the success value of the given `Micro` effect with an `Option`,
2915
+ * wrapping the success value in `Some` and returning `None` if the effect fails
2916
+ * with an expected error.
2917
+ *
2918
+ * @since 3.4.0
2919
+ * @experimental
2920
+ * @category error handling
2921
+ */
2922
+ export const option = <A, E, R>(self: Micro<A, E, R>): Micro<Option.Option<A>, never, R> =>
2923
+ match(self, { onFailure: Option.none, onSuccess: Option.some })
2924
+
2925
+ /**
2926
+ * Replace the success value of the given `Micro` effect with an `Either`,
2927
+ * wrapping the success value in `Right` and wrapping any expected errors with
2928
+ * a `Left`.
2929
+ *
2930
+ * @since 3.4.0
2931
+ * @experimental
2932
+ * @category error handling
2933
+ */
2934
+ export const either = <A, E, R>(self: Micro<A, E, R>): Micro<Either.Either<A, E>, never, R> =>
2935
+ match(self, { onFailure: Either.left, onSuccess: Either.right })
2936
+
2937
+ /**
2938
+ * Retry the given `Micro` effect using the provided options.
2939
+ *
2940
+ * @since 3.4.0
2941
+ * @experimental
2942
+ * @category error handling
2943
+ */
2944
+ export const retry: {
2945
+ <A, E>(
2946
+ options?: {
2947
+ while?: Predicate<E> | undefined
2948
+ times?: number | undefined
2949
+ schedule?: MicroSchedule | undefined
2950
+ } | undefined
2951
+ ): <R>(self: Micro<A, E, R>) => Micro<A, E, R>
2952
+ <A, E, R>(
2953
+ self: Micro<A, E, R>,
2954
+ options?: {
2955
+ while?: Predicate<E> | undefined
2956
+ times?: number | undefined
2957
+ schedule?: MicroSchedule | undefined
2958
+ } | undefined
2959
+ ): Micro<A, E, R>
2960
+ } = dual((args) => isMicro(args[0]), <A, E, R>(
2961
+ self: Micro<A, E, R>,
2962
+ options?: {
2963
+ while?: Predicate<E> | undefined
2964
+ times?: number | undefined
2965
+ schedule?: MicroSchedule | undefined
2966
+ } | undefined
2967
+ ): Micro<A, E, R> =>
2968
+ repeatExit(self, {
2969
+ ...options,
2970
+ while: (exit) =>
2971
+ exit._tag === "Failure" && exit.cause._tag === "Fail" &&
2972
+ (options?.while === undefined || options.while(exit.cause.error))
2973
+ }))
2974
+
2975
+ /**
2976
+ * Add a stack trace to any failures that occur in the effect. The trace will be
2977
+ * added to the `traces` field of the `MicroCause` object.
2978
+ *
2979
+ * @since 3.4.0
2980
+ * @experimental
2981
+ * @category error handling
2982
+ */
2983
+ export const withTrace: {
2984
+ (name: string): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, R>
2985
+ <A, E, R>(self: Micro<A, E, R>, name: string): Micro<A, E, R>
2986
+ } = function() {
2987
+ const prevLimit = globalThis.Error.stackTraceLimit
2988
+ globalThis.Error.stackTraceLimit = 2
2989
+ const error = new globalThis.Error()
2990
+ globalThis.Error.stackTraceLimit = prevLimit
2991
+ function generate(name: string, cause: MicroCause<any>) {
2992
+ const stack = error.stack
2993
+ if (!stack) {
2994
+ return cause
2995
+ }
2996
+ const line = stack.split("\n")[2]?.trim().replace(/^at /, "")
2997
+ if (!line) {
2998
+ return cause
2999
+ }
3000
+ const lineMatch = line.match(/\((.*)\)$/)
3001
+ return causeWithTrace(cause, `at ${name} (${lineMatch ? lineMatch[1] : line})`)
3002
+ }
3003
+ const f = (name: string) => (self: Micro<any, any, any>) => onError(self, (cause) => failCause(generate(name, cause)))
3004
+ if (arguments.length === 2) {
3005
+ return f(arguments[1])(arguments[0])
3006
+ }
3007
+ return f(arguments[0])
3008
+ } as any
3009
+
3010
+ // ----------------------------------------------------------------------------
3011
+ // pattern matching
3012
+ // ----------------------------------------------------------------------------
3013
+
3014
+ /**
3015
+ * @since 3.4.6
3016
+ * @experimental
3017
+ * @category pattern matching
3018
+ */
3019
+ export const matchCauseEffect: {
3020
+ <E, A2, E2, R2, A, A3, E3, R3>(options: {
3021
+ readonly onFailure: (cause: MicroCause<E>) => Micro<A2, E2, R2>
3022
+ readonly onSuccess: (a: A) => Micro<A3, E3, R3>
3023
+ }): <R>(self: Micro<A, E, R>) => Micro<A2 | A3, E2 | E3, R2 | R3 | R>
3024
+ <A, E, R, A2, E2, R2, A3, E3, R3>(
3025
+ self: Micro<A, E, R>,
3026
+ options: {
3027
+ readonly onFailure: (cause: MicroCause<E>) => Micro<A2, E2, R2>
3028
+ readonly onSuccess: (a: A) => Micro<A3, E3, R3>
3029
+ }
3030
+ ): Micro<A2 | A3, E2 | E3, R2 | R3 | R>
3031
+ } = dual(
3032
+ 2,
3033
+ <A, E, R, A2, E2, R2, A3, E3, R3>(
3034
+ self: Micro<A, E, R>,
3035
+ options: {
3036
+ readonly onFailure: (cause: MicroCause<E>) => Micro<A2, E2, R2>
3037
+ readonly onSuccess: (a: A) => Micro<A3, E3, R3>
3038
+ }
3039
+ ): Micro<A2 | A3, E2 | E3, R2 | R3 | R> => {
3040
+ const primitive = Object.create(OnSuccessAndFailureProto)
3041
+ primitive[args] = self
3042
+ primitive[successCont] = options.onSuccess
3043
+ primitive[failureCont] = options.onFailure
3044
+ return primitive
3045
+ }
3046
+ )
3047
+ const OnSuccessAndFailureProto = makePrimitiveProto({
3048
+ op: "OnSuccessAndFailure",
3049
+ eval(this: any, fiber: MicroFiberImpl): Primitive {
3050
+ fiber._stack.push(this)
3051
+ return this[args]
3052
+ }
3053
+ })
3054
+
3055
+ /**
3056
+ * @since 3.4.6
3057
+ * @experimental
3058
+ * @category pattern matching
3059
+ */
3060
+ export const matchCause: {
3061
+ <E, A2, A, A3>(
3062
+ options: {
3063
+ readonly onFailure: (cause: MicroCause<E>) => A2
3064
+ readonly onSuccess: (a: A) => A3
3065
+ }
3066
+ ): <R>(self: Micro<A, E, R>) => Micro<A2 | A3, never, R>
3067
+ <A, E, R, A2, A3>(
3068
+ self: Micro<A, E, R>,
3069
+ options: {
3070
+ readonly onFailure: (cause: MicroCause<E>) => A2
3071
+ readonly onSuccess: (a: A) => A3
3072
+ }
3073
+ ): Micro<A2 | A3, never, R>
3074
+ } = dual(
3075
+ 2,
3076
+ <A, E, R, A2, A3>(
3077
+ self: Micro<A, E, R>,
3078
+ options: {
3079
+ readonly onFailure: (cause: MicroCause<E>) => A2
3080
+ readonly onSuccess: (a: A) => A3
3081
+ }
3082
+ ): Micro<A2 | A3, never, R> =>
3083
+ matchCauseEffect(self, {
3084
+ onFailure: (cause) => sync(() => options.onFailure(cause)),
3085
+ onSuccess: (value) => sync(() => options.onSuccess(value))
3086
+ })
3087
+ )
3088
+
3089
+ /**
3090
+ * @since 3.4.6
3091
+ * @experimental
3092
+ * @category pattern matching
3093
+ */
3094
+ export const matchEffect: {
3095
+ <E, A2, E2, R2, A, A3, E3, R3>(
3096
+ options: {
3097
+ readonly onFailure: (e: E) => Micro<A2, E2, R2>
3098
+ readonly onSuccess: (a: A) => Micro<A3, E3, R3>
3099
+ }
3100
+ ): <R>(self: Micro<A, E, R>) => Micro<A2 | A3, E2 | E3, R2 | R3 | R>
3101
+ <A, E, R, A2, E2, R2, A3, E3, R3>(
3102
+ self: Micro<A, E, R>,
3103
+ options: {
3104
+ readonly onFailure: (e: E) => Micro<A2, E2, R2>
3105
+ readonly onSuccess: (a: A) => Micro<A3, E3, R3>
3106
+ }
3107
+ ): Micro<A2 | A3, E2 | E3, R2 | R3 | R>
3108
+ } = dual(
3109
+ 2,
3110
+ <A, E, R, A2, E2, R2, A3, E3, R3>(
3111
+ self: Micro<A, E, R>,
3112
+ options: {
3113
+ readonly onFailure: (e: E) => Micro<A2, E2, R2>
3114
+ readonly onSuccess: (a: A) => Micro<A3, E3, R3>
3115
+ }
3116
+ ): Micro<A2 | A3, E2 | E3, R2 | R3 | R> =>
3117
+ matchCauseEffect(self, {
3118
+ onFailure: (cause) => cause._tag === "Fail" ? options.onFailure(cause.error) : failCause(cause),
3119
+ onSuccess: options.onSuccess
3120
+ })
3121
+ )
3122
+
3123
+ /**
3124
+ * @since 3.4.0
3125
+ * @experimental
3126
+ * @category pattern matching
3127
+ */
3128
+ export const match: {
3129
+ <E, A2, A, A3>(
3130
+ options: {
3131
+ readonly onFailure: (error: E) => A2
3132
+ readonly onSuccess: (value: A) => A3
3133
+ }
3134
+ ): <R>(self: Micro<A, E, R>) => Micro<A2 | A3, never, R>
3135
+ <A, E, R, A2, A3>(
3136
+ self: Micro<A, E, R>,
3137
+ options: {
3138
+ readonly onFailure: (error: E) => A2
3139
+ readonly onSuccess: (value: A) => A3
3140
+ }
3141
+ ): Micro<A2 | A3, never, R>
3142
+ } = dual(
3143
+ 2,
3144
+ <A, E, R, A2, A3>(
3145
+ self: Micro<A, E, R>,
3146
+ options: {
3147
+ readonly onFailure: (error: E) => A2
3148
+ readonly onSuccess: (value: A) => A3
3149
+ }
3150
+ ): Micro<A2 | A3, never, R> =>
3151
+ matchEffect(self, {
3152
+ onFailure: (error) => sync(() => options.onFailure(error)),
3153
+ onSuccess: (value) => sync(() => options.onSuccess(value))
3154
+ })
3155
+ )
3156
+
3157
+ // ----------------------------------------------------------------------------
3158
+ // delays & timeouts
3159
+ // ----------------------------------------------------------------------------
3160
+
3161
+ /**
3162
+ * Create a `Micro` effect that will sleep for the specified duration.
3163
+ *
3164
+ * @since 3.4.0
3165
+ * @experimental
3166
+ * @category delays & timeouts
3167
+ */
3168
+ export const sleep = (millis: number): Micro<void> =>
3169
+ async((resume) => {
3170
+ const timeout = setTimeout(() => {
3171
+ resume(void_)
3172
+ }, millis)
3173
+ return sync(() => {
3174
+ clearTimeout(timeout)
3175
+ })
3176
+ })
3177
+
3178
+ /**
3179
+ * Returns an effect that will delay the execution of this effect by the
3180
+ * specified duration.
3181
+ *
3182
+ * @since 3.4.0
3183
+ * @experimental
3184
+ * @category delays & timeouts
3185
+ */
3186
+ export const delay: {
3187
+ (millis: number): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, R>
3188
+ <A, E, R>(self: Micro<A, E, R>, millis: number): Micro<A, E, R>
3189
+ } = dual(
3190
+ 2,
3191
+ <A, E, R>(self: Micro<A, E, R>, millis: number): Micro<A, E, R> => andThen(sleep(millis), self)
3192
+ )
3193
+
3194
+ /**
3195
+ * Returns an effect that will timeout this effect, that will execute the
3196
+ * fallback effect if the timeout elapses before the effect has produced a value.
3197
+ *
3198
+ * If the timeout elapses, the running effect will be safely interrupted.
3199
+ *
3200
+ * @since 3.4.0
3201
+ * @experimental
3202
+ * @category delays & timeouts
3203
+ */
3204
+ export const timeoutOrElse: {
3205
+ <A2, E2, R2>(options: {
3206
+ readonly duration: number
3207
+ readonly onTimeout: LazyArg<Micro<A2, E2, R2>>
3208
+ }): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
3209
+ <A, E, R, A2, E2, R2>(self: Micro<A, E, R>, options: {
3210
+ readonly duration: number
3211
+ readonly onTimeout: LazyArg<Micro<A2, E2, R2>>
3212
+ }): Micro<A | A2, E | E2, R | R2>
3213
+ } = dual(
3214
+ 2,
3215
+ <A, E, R, A2, E2, R2>(self: Micro<A, E, R>, options: {
3216
+ readonly duration: number
3217
+ readonly onTimeout: LazyArg<Micro<A2, E2, R2>>
3218
+ }): Micro<A | A2, E | E2, R | R2> =>
3219
+ raceFirst(self, andThen(interruptible(sleep(options.duration)), options.onTimeout))
3220
+ )
3221
+
3222
+ /**
3223
+ * Returns an effect that will timeout this effect, that will fail with a
3224
+ * `TimeoutException` if the timeout elapses before the effect has produced a
3225
+ * value.
3226
+ *
3227
+ * If the timeout elapses, the running effect will be safely interrupted.
3228
+ *
3229
+ * @since 3.4.0
3230
+ * @experimental
3231
+ * @category delays & timeouts
3232
+ */
3233
+ export const timeout: {
3234
+ (millis: number): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | TimeoutException, R>
3235
+ <A, E, R>(self: Micro<A, E, R>, millis: number): Micro<A, E | TimeoutException, R>
3236
+ } = dual(
3237
+ 2,
3238
+ <A, E, R>(self: Micro<A, E, R>, millis: number): Micro<A, E | TimeoutException, R> =>
3239
+ timeoutOrElse(self, { duration: millis, onTimeout: () => fail(new TimeoutException()) })
3240
+ )
3241
+
3242
+ /**
3243
+ * Returns an effect that will timeout this effect, succeeding with a `None`
3244
+ * if the timeout elapses before the effect has produced a value; and `Some` of
3245
+ * the produced value otherwise.
3246
+ *
3247
+ * If the timeout elapses, the running effect will be safely interrupted.
3248
+ *
3249
+ * @since 3.4.0
3250
+ * @experimental
3251
+ * @category delays & timeouts
3252
+ */
3253
+ export const timeoutOption: {
3254
+ (millis: number): <A, E, R>(self: Micro<A, E, R>) => Micro<Option.Option<A>, E, R>
3255
+ <A, E, R>(self: Micro<A, E, R>, millis: number): Micro<Option.Option<A>, E, R>
3256
+ } = dual(
3257
+ 2,
3258
+ <A, E, R>(self: Micro<A, E, R>, millis: number): Micro<Option.Option<A>, E, R> =>
3259
+ raceFirst(
3260
+ asSome(self),
3261
+ as(interruptible(sleep(millis)), Option.none())
3262
+ )
3263
+ )
3264
+
3265
+ // ----------------------------------------------------------------------------
3266
+ // resources & finalization
3267
+ // ----------------------------------------------------------------------------
3268
+
3269
+ /**
3270
+ * @since 3.4.0
3271
+ * @experimental
3272
+ * @category resources & finalization
3273
+ */
3274
+ export const MicroScopeTypeId: unique symbol = Symbol.for("effect/Micro/MicroScope")
3275
+
3276
+ /**
3277
+ * @since 3.4.0
3278
+ * @experimental
3279
+ * @category resources & finalization
3280
+ */
3281
+ export type MicroScopeTypeId = typeof MicroScopeTypeId
3282
+
3283
+ /**
3284
+ * @since 3.4.0
3285
+ * @experimental
3286
+ * @category resources & finalization
3287
+ */
3288
+ export interface MicroScope {
3289
+ readonly [MicroScopeTypeId]: MicroScopeTypeId
3290
+ readonly addFinalizer: (finalizer: (exit: MicroExit<unknown, unknown>) => Micro<void>) => Micro<void>
3291
+ readonly fork: Micro<MicroScope.Closeable>
3292
+ }
3293
+
3294
+ /**
3295
+ * @since 3.4.0
3296
+ * @experimental
3297
+ * @category resources & finalization
3298
+ */
3299
+ export declare namespace MicroScope {
3300
+ /**
3301
+ * @since 3.4.0
3302
+ * @experimental
3303
+ * @category resources & finalization
3304
+ */
3305
+ export interface Closeable extends MicroScope {
3306
+ readonly close: (exit: MicroExit<any, any>) => Micro<void>
3307
+ }
3308
+ }
3309
+
3310
+ /**
3311
+ * @since 3.4.0
3312
+ * @experimental
3313
+ * @category resources & finalization
3314
+ */
3315
+ export const MicroScope: Context.Tag<MicroScope, MicroScope> = Context.GenericTag<MicroScope>("effect/Micro/MicroScope")
3316
+
3317
+ class MicroScopeImpl implements MicroScope.Closeable {
3318
+ readonly [MicroScopeTypeId]: MicroScopeTypeId
3319
+ state: {
3320
+ readonly _tag: "Open"
3321
+ readonly finalizers: Set<(exit: MicroExit<any, any>) => Micro<void>>
3322
+ } | {
3323
+ readonly _tag: "Closed"
3324
+ readonly exit: MicroExit<any, any>
3325
+ } = { _tag: "Open", finalizers: new Set() }
3326
+
3327
+ constructor() {
3328
+ this[MicroScopeTypeId] = MicroScopeTypeId
3329
+ }
3330
+
3331
+ unsafeAddFinalizer(finalizer: (exit: MicroExit<any, any>) => Micro<void>): void {
3332
+ if (this.state._tag === "Open") {
3333
+ this.state.finalizers.add(finalizer)
3334
+ }
3335
+ }
3336
+ addFinalizer(finalizer: (exit: MicroExit<any, any>) => Micro<void>): Micro<void> {
3337
+ return suspend(() => {
3338
+ if (this.state._tag === "Open") {
3339
+ this.state.finalizers.add(finalizer)
3340
+ return void_
3341
+ }
3342
+ return finalizer(this.state.exit)
3343
+ })
3344
+ }
3345
+ unsafeRemoveFinalizer(finalizer: (exit: MicroExit<any, any>) => Micro<void>): void {
3346
+ if (this.state._tag === "Open") {
3347
+ this.state.finalizers.delete(finalizer)
3348
+ }
3349
+ }
3350
+ close(microExit: MicroExit<any, any>): Micro<void> {
3351
+ return suspend(() => {
3352
+ if (this.state._tag === "Open") {
3353
+ const finalizers = Array.from(this.state.finalizers).reverse()
3354
+ this.state = { _tag: "Closed", exit: microExit }
3355
+ return flatMap(
3356
+ forEach(finalizers, (finalizer) => exit(finalizer(microExit))),
3357
+ exitVoidAll
3358
+ )
3359
+ }
3360
+ return void_
3361
+ })
3362
+ }
3363
+ get fork() {
3364
+ return sync(() => {
3365
+ const newScope = new MicroScopeImpl()
3366
+ if (this.state._tag === "Closed") {
3367
+ newScope.state = this.state
3368
+ return newScope
3369
+ }
3370
+ function fin(exit: MicroExit<any, any>) {
3371
+ return newScope.close(exit)
3372
+ }
3373
+ this.state.finalizers.add(fin)
3374
+ newScope.unsafeAddFinalizer((_) => sync(() => this.unsafeRemoveFinalizer(fin)))
3375
+ return newScope
3376
+ })
3377
+ }
3378
+ }
3379
+
3380
+ /**
3381
+ * @since 3.4.0
3382
+ * @experimental
3383
+ * @category resources & finalization
3384
+ */
3385
+ export const scopeMake: Micro<MicroScope.Closeable> = sync(() => new MicroScopeImpl())
3386
+
3387
+ /**
3388
+ * @since 3.4.0
3389
+ * @experimental
3390
+ * @category resources & finalization
3391
+ */
3392
+ export const scopeUnsafeMake = (): MicroScope.Closeable => new MicroScopeImpl()
3393
+
3394
+ /**
3395
+ * Access the current `MicroScope`.
3396
+ *
3397
+ * @since 3.4.0
3398
+ * @experimental
3399
+ * @category resources & finalization
3400
+ */
3401
+ export const scope: Micro<MicroScope, never, MicroScope> = service(MicroScope)
3402
+
3403
+ /**
3404
+ * Provide a `MicroScope` to an effect.
3405
+ *
3406
+ * @since 3.4.0
3407
+ * @experimental
3408
+ * @category resources & finalization
3409
+ */
3410
+ export const provideScope: {
3411
+ (scope: MicroScope): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, MicroScope>>
3412
+ <A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<A, E, Exclude<R, MicroScope>>
3413
+ } = dual(
3414
+ 2,
3415
+ <A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<A, E, Exclude<R, MicroScope>> =>
3416
+ provideService(self, MicroScope, scope)
3417
+ )
3418
+
3419
+ /**
3420
+ * Provide a `MicroScope` to the given effect, closing it after the effect has
3421
+ * finished executing.
3422
+ *
3423
+ * @since 3.4.0
3424
+ * @experimental
3425
+ * @category resources & finalization
3426
+ */
3427
+ export const scoped = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, Exclude<R, MicroScope>> =>
3428
+ suspend(() => {
3429
+ const scope = new MicroScopeImpl()
3430
+ return onExit(provideService(self, MicroScope, scope), (exit) => scope.close(exit))
3431
+ })
3432
+
3433
+ /**
3434
+ * Create a resource with a cleanup `Micro` effect, ensuring the cleanup is
3435
+ * executed when the `MicroScope` is closed.
3436
+ *
3437
+ * @since 3.4.0
3438
+ * @experimental
3439
+ * @category resources & finalization
3440
+ */
3441
+ export const acquireRelease = <A, E, R>(
3442
+ acquire: Micro<A, E, R>,
3443
+ release: (a: A, exit: MicroExit<unknown, unknown>) => Micro<void>
3444
+ ): Micro<A, E, R | MicroScope> =>
3445
+ uninterruptible(flatMap(
3446
+ scope,
3447
+ (scope) => tap(acquire, (a) => scope.addFinalizer((exit) => release(a, exit)))
3448
+ ))
3449
+
3450
+ /**
3451
+ * Add a finalizer to the current `MicroScope`.
3452
+ *
3453
+ * @since 3.4.0
3454
+ * @experimental
3455
+ * @category resources & finalization
3456
+ */
3457
+ export const addFinalizer = (
3458
+ finalizer: (exit: MicroExit<unknown, unknown>) => Micro<void>
3459
+ ): Micro<void, never, MicroScope> => flatMap(scope, (scope) => scope.addFinalizer(finalizer))
3460
+
3461
+ /**
3462
+ * When the `Micro` effect is completed, run the given finalizer effect with the
3463
+ * `MicroExit` of the executed effect.
3464
+ *
3465
+ * @since 3.4.6
3466
+ * @experimental
3467
+ * @category resources & finalization
3468
+ */
3469
+ export const onExit: {
3470
+ <A, E, XE, XR>(
3471
+ f: (exit: MicroExit<A, E>) => Micro<void, XE, XR>
3472
+ ): <R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
3473
+ <A, E, R, XE, XR>(
3474
+ self: Micro<A, E, R>,
3475
+ f: (exit: MicroExit<A, E>) => Micro<void, XE, XR>
3476
+ ): Micro<A, E | XE, R | XR>
3477
+ } = dual(
3478
+ 2,
3479
+ <A, E, R, XE, XR>(
3480
+ self: Micro<A, E, R>,
3481
+ f: (exit: MicroExit<A, E>) => Micro<void, XE, XR>
3482
+ ): Micro<A, E | XE, R | XR> =>
3483
+ uninterruptibleMask((restore) =>
3484
+ matchCauseEffect(restore(self), {
3485
+ onFailure: (cause) => flatMap(f(exitFailCause(cause)), () => failCause(cause)),
3486
+ onSuccess: (a) => flatMap(f(exitSucceed(a)), () => succeed(a))
3487
+ })
3488
+ )
3489
+ )
3490
+
3491
+ /**
3492
+ * Regardless of the result of the this `Micro` effect, run the finalizer effect.
3493
+ *
3494
+ * @since 3.4.0
3495
+ * @experimental
3496
+ * @category resources & finalization
3497
+ */
3498
+ export const ensuring: {
3499
+ <XE, XR>(
3500
+ finalizer: Micro<void, XE, XR>
3501
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
3502
+ <A, E, R, XE, XR>(
3503
+ self: Micro<A, E, R>,
3504
+ finalizer: Micro<void, XE, XR>
3505
+ ): Micro<A, E | XE, R | XR>
3506
+ } = dual(
3507
+ 2,
3508
+ <A, E, R, XE, XR>(
3509
+ self: Micro<A, E, R>,
3510
+ finalizer: Micro<void, XE, XR>
3511
+ ): Micro<A, E | XE, R | XR> => onExit(self, (_) => finalizer)
3512
+ )
3513
+
3514
+ /**
3515
+ * When the `Micro` effect is completed, run the given finalizer effect if it
3516
+ * matches the specified predicate.
3517
+ *
3518
+ * @since 3.4.6
3519
+ * @experimental
3520
+ * @category resources & finalization
3521
+ */
3522
+ export const onExitIf: {
3523
+ <A, E, XE, XR, B extends MicroExit<A, E>>(
3524
+ refinement: Refinement<MicroExit<A, E>, B>,
3525
+ f: (exit: B) => Micro<void, XE, XR>
3526
+ ): <R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
3527
+ <A, E, XE, XR>(
3528
+ predicate: Predicate<MicroExit<NoInfer<A>, NoInfer<E>>>,
3529
+ f: (exit: MicroExit<NoInfer<A>, NoInfer<E>>) => Micro<void, XE, XR>
3530
+ ): <R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
3531
+ <A, E, R, XE, XR, B extends MicroExit<A, E>>(
3532
+ self: Micro<A, E, R>,
3533
+ refinement: Refinement<MicroExit<A, E>, B>,
3534
+ f: (exit: B) => Micro<void, XE, XR>
3535
+ ): Micro<A, E | XE, R | XR>
3536
+ <A, E, R, XE, XR>(
3537
+ self: Micro<A, E, R>,
3538
+ predicate: Predicate<MicroExit<NoInfer<A>, NoInfer<E>>>,
3539
+ f: (exit: MicroExit<NoInfer<A>, NoInfer<E>>) => Micro<void, XE, XR>
3540
+ ): Micro<A, E | XE, R | XR>
3541
+ } = dual(
3542
+ 3,
3543
+ <A, E, R, XE, XR, B extends MicroExit<A, E>>(
3544
+ self: Micro<A, E, R>,
3545
+ refinement: Refinement<MicroExit<A, E>, B>,
3546
+ f: (exit: B) => Micro<void, XE, XR>
3547
+ ): Micro<A, E | XE, R | XR> => onExit(self, (exit) => (refinement(exit) ? f(exit) : exitVoid))
3548
+ )
3549
+
3550
+ /**
3551
+ * When the `Micro` effect fails, run the given finalizer effect with the
3552
+ * `MicroCause` of the executed effect.
3553
+ *
3554
+ * @since 3.4.6
3555
+ * @experimental
3556
+ * @category resources & finalization
3557
+ */
3558
+ export const onError: {
3559
+ <A, E, XE, XR>(
3560
+ f: (cause: MicroCause<NoInfer<E>>) => Micro<void, XE, XR>
3561
+ ): <R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
3562
+ <A, E, R, XE, XR>(
3563
+ self: Micro<A, E, R>,
3564
+ f: (cause: MicroCause<NoInfer<E>>) => Micro<void, XE, XR>
3565
+ ): Micro<A, E | XE, R | XR>
3566
+ } = dual(
3567
+ 2,
3568
+ <A, E, R, XE, XR>(
3569
+ self: Micro<A, E, R>,
3570
+ f: (cause: MicroCause<NoInfer<E>>) => Micro<void, XE, XR>
3571
+ ): Micro<A, E | XE, R | XR> => onExitIf(self, exitIsFailure, (exit) => f(exit.cause))
3572
+ )
3573
+
3574
+ /**
3575
+ * If this `Micro` effect is aborted, run the finalizer effect.
3576
+ *
3577
+ * @since 3.4.6
3578
+ * @experimental
3579
+ * @category resources & finalization
3580
+ */
3581
+ export const onInterrupt: {
3582
+ <XE, XR>(
3583
+ finalizer: Micro<void, XE, XR>
3584
+ ): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
3585
+ <A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR>
3586
+ } = dual(
3587
+ 2,
3588
+ <A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR> =>
3589
+ onExitIf(self, exitIsInterrupt, (_) => finalizer)
3590
+ )
3591
+
3592
+ /**
3593
+ * Acquire a resource, use it, and then release the resource when the `use`
3594
+ * effect has completed.
3595
+ *
3596
+ * @since 3.4.0
3597
+ * @experimental
3598
+ * @category resources & finalization
3599
+ */
3600
+ export const acquireUseRelease = <Resource, E, R, A, E2, R2, E3, R3>(
3601
+ acquire: Micro<Resource, E, R>,
3602
+ use: (a: Resource) => Micro<A, E2, R2>,
3603
+ release: (a: Resource, exit: MicroExit<A, E2>) => Micro<void, E3, R3>
3604
+ ): Micro<A, E | E2 | E3, R | R2 | R3> =>
3605
+ uninterruptibleMask((restore) =>
3606
+ flatMap(
3607
+ acquire,
3608
+ (a) =>
3609
+ flatMap(
3610
+ exit(restore(use(a))),
3611
+ (exit) => andThen(release(a, exit), exit)
3612
+ )
3613
+ )
3614
+ )
3615
+
3616
+ // ----------------------------------------------------------------------------
3617
+ // interruption
3618
+ // ----------------------------------------------------------------------------
3619
+
3620
+ /**
3621
+ * Abort the current `Micro` effect.
3622
+ *
3623
+ * @since 3.4.6
3624
+ * @experimental
3625
+ * @category interruption
3626
+ */
3627
+ export const interrupt: Micro<never> = failCause(causeInterrupt())
3628
+
3629
+ /**
3630
+ * Flag the effect as uninterruptible, which means that when the effect is
3631
+ * interrupted, it will be allowed to continue running until completion.
3632
+ *
3633
+ * @since 3.4.0
3634
+ * @experimental
3635
+ * @category flags
3636
+ */
3637
+ export const uninterruptible = <A, E, R>(
3638
+ self: Micro<A, E, R>
3639
+ ): Micro<A, E, R> =>
3640
+ withMicroFiber((fiber) => {
3641
+ if (!fiber.interruptible) return self
3642
+ fiber.interruptible = false
3643
+ fiber._stack.push(setInterruptible(true))
3644
+ return self
3645
+ })
3646
+
3647
+ const setInterruptible: (interruptible: boolean) => Primitive = makePrimitive({
3648
+ op: "SetInterruptible",
3649
+ ensure(fiber) {
3650
+ fiber.interruptible = this[args]
3651
+ if (fiber._interrupted && fiber.interruptible) {
3652
+ return () => exitInterrupt
3653
+ }
3654
+ }
3655
+ })
3656
+
3657
+ /**
3658
+ * Flag the effect as interruptible, which means that when the effect is
3659
+ * interrupted, it will be interrupted immediately.
3660
+ *
3661
+ * @since 3.4.0
3662
+ * @experimental
3663
+ * @category flags
3664
+ */
3665
+ export const interruptible = <A, E, R>(
3666
+ self: Micro<A, E, R>
3667
+ ): Micro<A, E, R> =>
3668
+ withMicroFiber((fiber) => {
3669
+ if (fiber.interruptible) return self
3670
+ fiber.interruptible = true
3671
+ fiber._stack.push(setInterruptible(false))
3672
+ if (fiber._interrupted) return exitInterrupt
3673
+ return self
3674
+ })
3675
+
3676
+ /**
3677
+ * Wrap the given `Micro` effect in an uninterruptible region, preventing the
3678
+ * effect from being aborted.
3679
+ *
3680
+ * You can use the `restore` function to restore a `Micro` effect to the
3681
+ * interruptibility state before the `uninterruptibleMask` was applied.
3682
+ *
3683
+ * @example
3684
+ * ```ts
3685
+ * import * as Micro from "effect/Micro"
3686
+ *
3687
+ * Micro.uninterruptibleMask((restore) =>
3688
+ * Micro.sleep(1000).pipe( // uninterruptible
3689
+ * Micro.andThen(restore(Micro.sleep(1000))) // interruptible
3690
+ * )
3691
+ * )
3692
+ * ```
3693
+ *
3694
+ * @since 3.4.0
3695
+ * @experimental
3696
+ * @category interruption
3697
+ */
3698
+ export const uninterruptibleMask = <A, E, R>(
3699
+ f: (
3700
+ restore: <A, E, R>(effect: Micro<A, E, R>) => Micro<A, E, R>
3701
+ ) => Micro<A, E, R>
3702
+ ): Micro<A, E, R> =>
3703
+ withMicroFiber((fiber) => {
3704
+ if (!fiber.interruptible) return f(identity)
3705
+ fiber.interruptible = false
3706
+ fiber._stack.push(setInterruptible(true))
3707
+ return f(interruptible)
3708
+ })
3709
+
3710
+ // ========================================================================
3711
+ // collecting & elements
3712
+ // ========================================================================
3713
+
3714
+ /**
3715
+ * @since 3.4.0
3716
+ * @experimental
3717
+ */
3718
+ export declare namespace All {
3719
+ /**
3720
+ * @since 3.4.0
3721
+ * @experimental
3722
+ */
3723
+ export type MicroAny = Micro<any, any, any>
3724
+
3725
+ /**
3726
+ * @since 3.4.0
3727
+ * @experimental
3728
+ */
3729
+ export type ReturnIterable<T extends Iterable<MicroAny>, Discard extends boolean> = [T] extends
3730
+ [Iterable<Micro<infer A, infer E, infer R>>] ? Micro<
3731
+ Discard extends true ? void : Array<A>,
3732
+ E,
3733
+ R
3734
+ >
3735
+ : never
3736
+
3737
+ /**
3738
+ * @since 3.4.0
3739
+ * @experimental
3740
+ */
3741
+ export type ReturnTuple<T extends ReadonlyArray<unknown>, Discard extends boolean> = Micro<
3742
+ Discard extends true ? void
3743
+ : T[number] extends never ? []
3744
+ : { -readonly [K in keyof T]: T[K] extends Micro<infer _A, infer _E, infer _R> ? _A : never },
3745
+ T[number] extends never ? never
3746
+ : T[number] extends Micro<infer _A, infer _E, infer _R> ? _E
3747
+ : never,
3748
+ T[number] extends never ? never
3749
+ : T[number] extends Micro<infer _A, infer _E, infer _R> ? _R
3750
+ : never
3751
+ > extends infer X ? X : never
3752
+
3753
+ /**
3754
+ * @since 3.4.0
3755
+ * @experimental
3756
+ */
3757
+ export type ReturnObject<T, Discard extends boolean> = [T] extends [{ [K: string]: MicroAny }] ? Micro<
3758
+ Discard extends true ? void :
3759
+ { -readonly [K in keyof T]: [T[K]] extends [Micro<infer _A, infer _E, infer _R>] ? _A : never },
3760
+ keyof T extends never ? never
3761
+ : T[keyof T] extends Micro<infer _A, infer _E, infer _R> ? _E
3762
+ : never,
3763
+ keyof T extends never ? never
3764
+ : T[keyof T] extends Micro<infer _A, infer _E, infer _R> ? _R
3765
+ : never
3766
+ >
3767
+ : never
3768
+
3769
+ /**
3770
+ * @since 3.4.0
3771
+ * @experimental
3772
+ */
3773
+ export type IsDiscard<A> = [Extract<A, { readonly discard: true }>] extends [never] ? false : true
3774
+
3775
+ /**
3776
+ * @since 3.4.0
3777
+ * @experimental
3778
+ */
3779
+ export type Return<
3780
+ Arg extends Iterable<MicroAny> | Record<string, MicroAny>,
3781
+ O extends NoExcessProperties<{
3782
+ readonly concurrency?: Concurrency | undefined
3783
+ readonly discard?: boolean | undefined
3784
+ }, O>
3785
+ > = [Arg] extends [ReadonlyArray<MicroAny>] ? ReturnTuple<Arg, IsDiscard<O>>
3786
+ : [Arg] extends [Iterable<MicroAny>] ? ReturnIterable<Arg, IsDiscard<O>>
3787
+ : [Arg] extends [Record<string, MicroAny>] ? ReturnObject<Arg, IsDiscard<O>>
3788
+ : never
3789
+ }
3790
+
3791
+ /**
3792
+ * Runs all the provided effects in sequence respecting the structure provided in input.
3793
+ *
3794
+ * Supports multiple arguments, a single argument tuple / array or record / struct.
3795
+ *
3796
+ * @since 3.4.0
3797
+ * @experimental
3798
+ * @category collecting & elements
3799
+ */
3800
+ export const all = <
3801
+ const Arg extends Iterable<Micro<any, any, any>> | Record<string, Micro<any, any, any>>,
3802
+ O extends NoExcessProperties<{
3803
+ readonly concurrency?: Concurrency | undefined
3804
+ readonly discard?: boolean | undefined
3805
+ }, O>
3806
+ >(arg: Arg, options?: O): All.Return<Arg, O> => {
3807
+ if (Array.isArray(arg) || isIterable(arg)) {
3808
+ return (forEach as any)(arg, identity, options)
3809
+ } else if (options?.discard) {
3810
+ return (forEach as any)(Object.values(arg), identity, options)
3811
+ }
3812
+ return suspend(() => {
3813
+ const out: Record<string, unknown> = {}
3814
+ return as(
3815
+ forEach(Object.entries(arg), ([key, effect]) =>
3816
+ map(effect, (value) => {
3817
+ out[key] = value
3818
+ }), {
3819
+ discard: true,
3820
+ concurrency: options?.concurrency
3821
+ }),
3822
+ out
3823
+ )
3824
+ }) as any
3825
+ }
3826
+
3827
+ /**
3828
+ * @since 3.11.0
3829
+ * @experimental
3830
+ * @category collecting & elements
3831
+ */
3832
+ export const whileLoop: <A, E, R>(options: {
3833
+ readonly while: LazyArg<boolean>
3834
+ readonly body: LazyArg<Micro<A, E, R>>
3835
+ readonly step: (a: A) => void
3836
+ }) => Micro<void, E, R> = makePrimitive({
3837
+ op: "While",
3838
+ contA(value, fiber) {
3839
+ this[args].step(value)
3840
+ if (this[args].while()) {
3841
+ fiber._stack.push(this)
3842
+ return this[args].body()
3843
+ }
3844
+ return exitVoid
3845
+ },
3846
+ eval(fiber) {
3847
+ if (this[args].while()) {
3848
+ fiber._stack.push(this)
3849
+ return this[args].body()
3850
+ }
3851
+ return exitVoid
3852
+ }
3853
+ })
3854
+
3855
+ /**
3856
+ * For each element of the provided iterable, run the effect and collect the
3857
+ * results.
3858
+ *
3859
+ * If the `discard` option is set to `true`, the results will be discarded and
3860
+ * the effect will return `void`.
3861
+ *
3862
+ * The `concurrency` option can be set to control how many effects are run
3863
+ * concurrently. By default, the effects are run sequentially.
3864
+ *
3865
+ * @since 3.4.0
3866
+ * @experimental
3867
+ * @category collecting & elements
3868
+ */
3869
+ export const forEach: {
3870
+ <A, B, E, R>(iterable: Iterable<A>, f: (a: A, index: number) => Micro<B, E, R>, options?: {
3871
+ readonly concurrency?: Concurrency | undefined
3872
+ readonly discard?: false | undefined
3873
+ }): Micro<Array<B>, E, R>
3874
+ <A, B, E, R>(iterable: Iterable<A>, f: (a: A, index: number) => Micro<B, E, R>, options: {
3875
+ readonly concurrency?: Concurrency | undefined
3876
+ readonly discard: true
3877
+ }): Micro<void, E, R>
3878
+ } = <
3879
+ A,
3880
+ B,
3881
+ E,
3882
+ R
3883
+ >(iterable: Iterable<A>, f: (a: A, index: number) => Micro<B, E, R>, options?: {
3884
+ readonly concurrency?: Concurrency | undefined
3885
+ readonly discard?: boolean | undefined
3886
+ }): Micro<any, E, R> =>
3887
+ withMicroFiber((parent) => {
3888
+ const concurrencyOption = options?.concurrency === "inherit"
3889
+ ? parent.getRef(CurrentConcurrency)
3890
+ : options?.concurrency ?? 1
3891
+ const concurrency = concurrencyOption === "unbounded"
3892
+ ? Number.POSITIVE_INFINITY
3893
+ : Math.max(1, concurrencyOption)
3894
+
3895
+ const items = Arr.fromIterable(iterable)
3896
+ let length = items.length
3897
+ if (length === 0) {
3898
+ return options?.discard ? void_ : succeed([])
3899
+ }
3900
+
3901
+ const out: Array<B> | undefined = options?.discard ? undefined : new Array(length)
3902
+ let index = 0
3903
+
3904
+ if (concurrency === 1) {
3905
+ return as(
3906
+ whileLoop({
3907
+ while: () => index < items.length,
3908
+ body: () => f(items[index], index),
3909
+ step: out ?
3910
+ (b) => out[index++] = b :
3911
+ (_) => index++
3912
+ }),
3913
+ out as any
3914
+ )
3915
+ }
3916
+ return async((resume) => {
3917
+ const fibers = new Set<MicroFiber<unknown, unknown>>()
3918
+ let result: MicroExit<any, any> | undefined = undefined
3919
+ let inProgress = 0
3920
+ let doneCount = 0
3921
+ let pumping = false
3922
+ let interrupted = false
3923
+ function pump() {
3924
+ pumping = true
3925
+ while (inProgress < concurrency && index < length) {
3926
+ const currentIndex = index
3927
+ const item = items[currentIndex]
3928
+ index++
3929
+ inProgress++
3930
+ try {
3931
+ const child = unsafeFork(parent, f(item, currentIndex), true, true)
3932
+ fibers.add(child)
3933
+ child.addObserver((exit) => {
3934
+ fibers.delete(child)
3935
+ if (interrupted) {
3936
+ return
3937
+ } else if (exit._tag === "Failure") {
3938
+ if (result === undefined) {
3939
+ result = exit
3940
+ length = index
3941
+ fibers.forEach((fiber) => fiber.unsafeInterrupt())
3942
+ }
3943
+ } else if (out !== undefined) {
3944
+ out[currentIndex] = exit.value
3945
+ }
3946
+ doneCount++
3947
+ inProgress--
3948
+ if (doneCount === length) {
3949
+ resume(result ?? succeed(out))
3950
+ } else if (!pumping && inProgress < concurrency) {
3951
+ pump()
3952
+ }
3953
+ })
3954
+ } catch (err) {
3955
+ result = exitDie(err)
3956
+ length = index
3957
+ fibers.forEach((fiber) => fiber.unsafeInterrupt())
3958
+ }
3959
+ }
3960
+ pumping = false
3961
+ }
3962
+ pump()
3963
+
3964
+ return suspend(() => {
3965
+ interrupted = true
3966
+ index = length
3967
+ return fiberInterruptAll(fibers)
3968
+ })
3969
+ })
3970
+ })
3971
+
3972
+ /**
3973
+ * Effectfully filter the elements of the provided iterable.
3974
+ *
3975
+ * Use the `concurrency` option to control how many elements are processed
3976
+ * concurrently.
3977
+ *
3978
+ * @since 3.4.0
3979
+ * @experimental
3980
+ * @category collecting & elements
3981
+ */
3982
+ export const filter = <A, E, R>(iterable: Iterable<A>, f: (a: NoInfer<A>) => Micro<boolean, E, R>, options?: {
3983
+ readonly concurrency?: Concurrency | undefined
3984
+ readonly negate?: boolean | undefined
3985
+ }): Micro<Array<A>, E, R> =>
3986
+ filterMap(iterable, (a) =>
3987
+ map(f(a), (pass) => {
3988
+ pass = options?.negate ? !pass : pass
3989
+ return pass ? Option.some(a) : Option.none()
3990
+ }), options)
3991
+
3992
+ /**
3993
+ * Effectfully filter the elements of the provided iterable.
3994
+ *
3995
+ * Use the `concurrency` option to control how many elements are processed
3996
+ * concurrently.
3997
+ *
3998
+ * @since 3.4.0
3999
+ * @experimental
4000
+ * @category collecting & elements
4001
+ */
4002
+ export const filterMap = <A, B, E, R>(
4003
+ iterable: Iterable<A>,
4004
+ f: (a: NoInfer<A>) => Micro<Option.Option<B>, E, R>,
4005
+ options?: {
4006
+ readonly concurrency?: Concurrency | undefined
4007
+ }
4008
+ ): Micro<Array<B>, E, R> =>
4009
+ suspend(() => {
4010
+ const out: Array<B> = []
4011
+ return as(
4012
+ forEach(iterable, (a) =>
4013
+ map(f(a), (o) => {
4014
+ if (o._tag === "Some") {
4015
+ out.push(o.value)
4016
+ }
4017
+ }), {
4018
+ discard: true,
4019
+ concurrency: options?.concurrency
4020
+ }),
4021
+ out
4022
+ )
4023
+ })
4024
+
4025
+ // ----------------------------------------------------------------------------
4026
+ // do notation
4027
+ // ----------------------------------------------------------------------------
4028
+
4029
+ /**
4030
+ * Start a do notation block.
4031
+ *
4032
+ * @since 3.4.0
4033
+ * @experimental
4034
+ * @category do notation
4035
+ */
4036
+ export const Do: Micro<{}> = succeed({})
4037
+
4038
+ /**
4039
+ * Bind the success value of this `Micro` effect to the provided name.
4040
+ *
4041
+ * @since 3.4.0
4042
+ * @experimental
4043
+ * @category do notation
4044
+ */
4045
+ export const bindTo: {
4046
+ <N extends string>(name: N): <A, E, R>(self: Micro<A, E, R>) => Micro<{ [K in N]: A }, E, R>
4047
+ <A, E, R, N extends string>(self: Micro<A, E, R>, name: N): Micro<{ [K in N]: A }, E, R>
4048
+ } = doNotation.bindTo<MicroTypeLambda>(map)
4049
+
4050
+ /**
4051
+ * Bind the success value of this `Micro` effect to the provided name.
4052
+ *
4053
+ * @since 3.4.0
4054
+ * @experimental
4055
+ * @category do notation
4056
+ */
4057
+ export const bind: {
4058
+ <N extends string, A extends Record<string, any>, B, E2, R2>(
4059
+ name: N,
4060
+ f: (a: NoInfer<A>) => Micro<B, E2, R2>
4061
+ ): <E, R>(self: Micro<A, E, R>) => Micro<Simplify<Omit<A, N> & { [K in N]: B }>, E | E2, R | R2>
4062
+ <A extends Record<string, any>, E, R, B, E2, R2, N extends string>(
4063
+ self: Micro<A, E, R>,
4064
+ name: N,
4065
+ f: (a: NoInfer<A>) => Micro<B, E2, R2>
4066
+ ): Micro<Simplify<Omit<A, N> & { [K in N]: B }>, E | E2, R | R2>
4067
+ } = doNotation.bind<MicroTypeLambda>(map, flatMap)
4068
+
4069
+ const let_: {
4070
+ <N extends string, A extends Record<string, any>, B>(
4071
+ name: N,
4072
+ f: (a: NoInfer<A>) => B
4073
+ ): <E, R>(self: Micro<A, E, R>) => Micro<Simplify<Omit<A, N> & { [K in N]: B }>, E, R>
4074
+ <A extends Record<string, any>, E, R, B, N extends string>(
4075
+ self: Micro<A, E, R>,
4076
+ name: N,
4077
+ f: (a: NoInfer<A>) => B
4078
+ ): Micro<Simplify<Omit<A, N> & { [K in N]: B }>, E, R>
4079
+ } = doNotation.let_<MicroTypeLambda>(map)
4080
+
4081
+ export {
4082
+ /**
4083
+ * Bind the result of a synchronous computation to the given name.
4084
+ *
4085
+ * @since 3.4.0
4086
+ * @experimental
4087
+ * @category do notation
4088
+ */
4089
+ let_ as let
4090
+ }
4091
+
4092
+ // ----------------------------------------------------------------------------
4093
+ // fibers & forking
4094
+ // ----------------------------------------------------------------------------
4095
+
4096
+ /**
4097
+ * Run the `Micro` effect in a new `MicroFiber` that can be awaited, joined, or
4098
+ * aborted.
4099
+ *
4100
+ * When the parent `Micro` finishes, this `Micro` will be aborted.
4101
+ *
4102
+ * @since 3.4.0
4103
+ * @experimental
4104
+ * @category fiber & forking
4105
+ */
4106
+ export const fork = <A, E, R>(
4107
+ self: Micro<A, E, R>
4108
+ ): Micro<MicroFiber<A, E>, never, R> =>
4109
+ withMicroFiber((fiber) => {
4110
+ fiberMiddleware.interruptChildren ??= fiberInterruptChildren
4111
+ return succeed(unsafeFork(fiber, self))
4112
+ })
4113
+
4114
+ const unsafeFork = <FA, FE, A, E, R>(
4115
+ parent: MicroFiberImpl<FA, FE>,
4116
+ effect: Micro<A, E, R>,
4117
+ immediate = false,
4118
+ daemon = false
4119
+ ): MicroFiber<A, E> => {
4120
+ const child = new MicroFiberImpl<A, E>(parent.context, parent.interruptible)
4121
+ if (!daemon) {
4122
+ parent.children().add(child)
4123
+ child.addObserver(() => parent.children().delete(child))
4124
+ }
4125
+ if (immediate) {
4126
+ child.evaluate(effect as any)
4127
+ } else {
4128
+ parent.getRef(CurrentScheduler).scheduleTask(() => child.evaluate(effect as any), 0)
4129
+ }
4130
+ return child
4131
+ }
4132
+
4133
+ /**
4134
+ * Run the `Micro` effect in a new `MicroFiber` that can be awaited, joined, or
4135
+ * aborted.
4136
+ *
4137
+ * It will not be aborted when the parent `Micro` finishes.
4138
+ *
4139
+ * @since 3.4.0
4140
+ * @experimental
4141
+ * @category fiber & forking
4142
+ */
4143
+ export const forkDaemon = <A, E, R>(
4144
+ self: Micro<A, E, R>
4145
+ ): Micro<MicroFiber<A, E>, never, R> => withMicroFiber((fiber) => succeed(unsafeFork(fiber, self, false, true)))
4146
+
4147
+ /**
4148
+ * Run the `Micro` effect in a new `MicroFiber` that can be awaited, joined, or
4149
+ * aborted.
4150
+ *
4151
+ * The lifetime of the handle will be attached to the provided `MicroScope`.
4152
+ *
4153
+ * @since 3.4.0
4154
+ * @experimental
4155
+ * @category fiber & forking
4156
+ */
4157
+ export const forkIn: {
4158
+ (scope: MicroScope): <A, E, R>(self: Micro<A, E, R>) => Micro<MicroFiber<A, E>, never, R>
4159
+ <A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<MicroFiber<A, E>, never, R>
4160
+ } = dual(
4161
+ 2,
4162
+ <A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<MicroFiber<A, E>, never, R> =>
4163
+ uninterruptibleMask((restore) =>
4164
+ flatMap(scope.fork, (scope) =>
4165
+ tap(
4166
+ restore(forkDaemon(onExit(self, (exit) => scope.close(exit)))),
4167
+ (fiber) => scope.addFinalizer((_) => fiberInterrupt(fiber))
4168
+ ))
4169
+ )
4170
+ )
4171
+
4172
+ /**
4173
+ * Run the `Micro` effect in a new `MicroFiber` that can be awaited, joined, or
4174
+ * aborted.
4175
+ *
4176
+ * The lifetime of the handle will be attached to the current `MicroScope`.
4177
+ *
4178
+ * @since 3.4.0
4179
+ * @experimental
4180
+ * @category fiber & forking
4181
+ */
4182
+ export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<MicroFiber<A, E>, never, R | MicroScope> =>
4183
+ flatMap(scope, (scope) => forkIn(self, scope))
4184
+
4185
+ // ----------------------------------------------------------------------------
4186
+ // execution
4187
+ // ----------------------------------------------------------------------------
4188
+
4189
+ /**
4190
+ * Execute the `Micro` effect and return a `MicroFiber` that can be awaited, joined,
4191
+ * or aborted.
4192
+ *
4193
+ * You can listen for the result by adding an observer using the handle's
4194
+ * `addObserver` method.
4195
+ *
4196
+ * @example
4197
+ * ```ts
4198
+ * import * as Micro from "effect/Micro"
4199
+ *
4200
+ * const handle = Micro.succeed(42).pipe(
4201
+ * Micro.delay(1000),
4202
+ * Micro.runFork
4203
+ * )
4204
+ *
4205
+ * handle.addObserver((exit) => {
4206
+ * console.log(exit)
4207
+ * })
4208
+ * ```
4209
+ *
4210
+ * @since 3.4.0
4211
+ * @experimental
4212
+ * @category execution
4213
+ */
4214
+ export const runFork = <A, E>(
4215
+ effect: Micro<A, E>,
4216
+ options?: {
4217
+ readonly signal?: AbortSignal | undefined
4218
+ readonly scheduler?: MicroScheduler | undefined
4219
+ } | undefined
4220
+ ): MicroFiberImpl<A, E> => {
4221
+ const fiber = new MicroFiberImpl<A, E>(CurrentScheduler.context(
4222
+ options?.scheduler ?? new MicroSchedulerDefault()
4223
+ ))
4224
+ fiber.evaluate(effect as any)
4225
+ if (options?.signal) {
4226
+ if (options.signal.aborted) {
4227
+ fiber.unsafeInterrupt()
4228
+ } else {
4229
+ const abort = () => fiber.unsafeInterrupt()
4230
+ options.signal.addEventListener("abort", abort, { once: true })
4231
+ fiber.addObserver(() => options.signal!.removeEventListener("abort", abort))
4232
+ }
4233
+ }
4234
+ return fiber
4235
+ }
4236
+
4237
+ /**
4238
+ * Execute the `Micro` effect and return a `Promise` that resolves with the
4239
+ * `MicroExit` of the computation.
4240
+ *
4241
+ * @since 3.4.6
4242
+ * @experimental
4243
+ * @category execution
4244
+ */
4245
+ export const runPromiseExit = <A, E>(
4246
+ effect: Micro<A, E>,
4247
+ options?: {
4248
+ readonly signal?: AbortSignal | undefined
4249
+ readonly scheduler?: MicroScheduler | undefined
4250
+ } | undefined
4251
+ ): Promise<MicroExit<A, E>> =>
4252
+ new Promise((resolve, _reject) => {
4253
+ const handle = runFork(effect, options)
4254
+ handle.addObserver(resolve)
4255
+ })
4256
+
4257
+ /**
4258
+ * Execute the `Micro` effect and return a `Promise` that resolves with the
4259
+ * successful value of the computation.
4260
+ *
4261
+ * @since 3.4.0
4262
+ * @experimental
4263
+ * @category execution
4264
+ */
4265
+ export const runPromise = <A, E>(
4266
+ effect: Micro<A, E>,
4267
+ options?: {
4268
+ readonly signal?: AbortSignal | undefined
4269
+ readonly scheduler?: MicroScheduler | undefined
4270
+ } | undefined
4271
+ ): Promise<A> =>
4272
+ runPromiseExit(effect, options).then((exit) => {
4273
+ if (exit._tag === "Failure") {
4274
+ throw exit.cause
4275
+ }
4276
+ return exit.value
4277
+ })
4278
+
4279
+ /**
4280
+ * Attempt to execute the `Micro` effect synchronously and return the `MicroExit`.
4281
+ *
4282
+ * If any asynchronous effects are encountered, the function will return a
4283
+ * `CauseDie` containing the `MicroFiber`.
4284
+ *
4285
+ * @since 3.4.6
4286
+ * @experimental
4287
+ * @category execution
4288
+ */
4289
+ export const runSyncExit = <A, E>(effect: Micro<A, E>): MicroExit<A, E> => {
4290
+ const scheduler = new MicroSchedulerDefault()
4291
+ const fiber = runFork(effect, { scheduler })
4292
+ scheduler.flush()
4293
+ return fiber._exit ?? exitDie(fiber)
4294
+ }
4295
+
4296
+ /**
4297
+ * Attempt to execute the `Micro` effect synchronously and return the success
4298
+ * value.
4299
+ *
4300
+ * @since 3.4.0
4301
+ * @experimental
4302
+ * @category execution
4303
+ */
4304
+ export const runSync = <A, E>(effect: Micro<A, E>): A => {
4305
+ const exit = runSyncExit(effect)
4306
+ if (exit._tag === "Failure") throw exit.cause
4307
+ return exit.value
4308
+ }
4309
+
4310
+ // ----------------------------------------------------------------------------
4311
+ // Errors
4312
+ // ----------------------------------------------------------------------------
4313
+
4314
+ /**
4315
+ * @since 3.4.0
4316
+ * @experimental
4317
+ * @category errors
4318
+ */
4319
+ export interface YieldableError extends Pipeable, Inspectable, Readonly<Error> {
4320
+ readonly [Effectable.EffectTypeId]: Effect.VarianceStruct<never, this, never>
4321
+ readonly [Effectable.StreamTypeId]: Stream.VarianceStruct<never, this, never>
4322
+ readonly [Effectable.SinkTypeId]: Sink.VarianceStruct<never, unknown, never, this, never>
4323
+ readonly [Effectable.ChannelTypeId]: Channel.VarianceStruct<never, unknown, this, unknown, never, unknown, never>
4324
+ readonly [TypeId]: Micro.Variance<never, this, never>
4325
+ [Symbol.iterator](): MicroIterator<Micro<never, this, never>>
4326
+ }
4327
+
4328
+ const YieldableError: new(message?: string) => YieldableError = (function() {
4329
+ class YieldableError extends globalThis.Error {}
4330
+ // @effect-diagnostics-next-line floatingEffect:off
4331
+ Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype, {
4332
+ [identifier]: "Failure",
4333
+ [evaluate]() {
4334
+ return fail(this)
4335
+ },
4336
+ toString(this: Error) {
4337
+ return this.message ? `${this.name}: ${this.message}` : this.name
4338
+ },
4339
+ toJSON() {
4340
+ return { ...this }
4341
+ },
4342
+ [NodeInspectSymbol](this: Error): string {
4343
+ const stack = this.stack
4344
+ if (stack) {
4345
+ return `${this.toString()}\n${stack.split("\n").slice(1).join("\n")}`
4346
+ }
4347
+ return this.toString()
4348
+ }
4349
+ })
4350
+ return YieldableError as any
4351
+ })()
4352
+
4353
+ /**
4354
+ * @since 3.4.0
4355
+ * @experimental
4356
+ * @category errors
4357
+ */
4358
+ export const Error: new<A extends Record<string, any> = {}>(
4359
+ args: Equals<A, {}> extends true ? void
4360
+ : { readonly [P in keyof A]: A[P] }
4361
+ ) => YieldableError & Readonly<A> = (function() {
4362
+ return class extends YieldableError {
4363
+ constructor(args: any) {
4364
+ super()
4365
+ if (args) {
4366
+ Object.assign(this, args)
4367
+ }
4368
+ }
4369
+ } as any
4370
+ })()
4371
+
4372
+ /**
4373
+ * @since 3.4.0
4374
+ * @experimental
4375
+ * @category errors
4376
+ */
4377
+ export const TaggedError = <Tag extends string>(tag: Tag): new<A extends Record<string, any> = {}>(
4378
+ args: Equals<A, {}> extends true ? void
4379
+ : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }
4380
+ ) => YieldableError & { readonly _tag: Tag } & Readonly<A> => {
4381
+ class Base extends Error<{}> {
4382
+ readonly _tag = tag
4383
+ }
4384
+ ;(Base.prototype as any).name = tag
4385
+ return Base as any
4386
+ }
4387
+
4388
+ /**
4389
+ * Represents a checked exception which occurs when an expected element was
4390
+ * unable to be found.
4391
+ *
4392
+ * @since 3.4.4
4393
+ * @experimental
4394
+ * @category errors
4395
+ */
4396
+ export class NoSuchElementException extends TaggedError("NoSuchElementException")<{ message?: string | undefined }> {}
4397
+
4398
+ /**
4399
+ * Represents a checked exception which occurs when a timeout occurs.
4400
+ *
4401
+ * @since 3.4.4
4402
+ * @experimental
4403
+ * @category errors
4404
+ */
4405
+ export class TimeoutException extends TaggedError("TimeoutException") {}