@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
@@ -0,0 +1,3842 @@
1
+ import * as RA from "../Array.js"
2
+ import * as Boolean from "../Boolean.js"
3
+ import type * as Cause from "../Cause.js"
4
+ import * as Chunk from "../Chunk.js"
5
+ import type * as Clock from "../Clock.js"
6
+ import type { ConfigProvider } from "../ConfigProvider.js"
7
+ import * as Context from "../Context.js"
8
+ import type { DefaultServices } from "../DefaultServices.js"
9
+ import type * as Duration from "../Duration.js"
10
+ import type * as Effect from "../Effect.js"
11
+ import * as Effectable from "../Effectable.js"
12
+ import type * as Either from "../Either.js"
13
+ import * as ExecutionStrategy from "../ExecutionStrategy.js"
14
+ import type * as Exit from "../Exit.js"
15
+ import type * as Fiber from "../Fiber.js"
16
+ import * as FiberId from "../FiberId.js"
17
+ import type * as FiberRef from "../FiberRef.js"
18
+ import * as FiberRefs from "../FiberRefs.js"
19
+ import * as FiberRefsPatch from "../FiberRefsPatch.js"
20
+ import * as FiberStatus from "../FiberStatus.js"
21
+ import type { LazyArg } from "../Function.js"
22
+ import { dual, identity, pipe } from "../Function.js"
23
+ import { globalValue } from "../GlobalValue.js"
24
+ import * as HashMap from "../HashMap.js"
25
+ import * as HashSet from "../HashSet.js"
26
+ import * as Inspectable from "../Inspectable.js"
27
+ import type { Logger } from "../Logger.js"
28
+ import * as LogLevel from "../LogLevel.js"
29
+ import type * as MetricLabel from "../MetricLabel.js"
30
+ import * as Micro from "../Micro.js"
31
+ import * as MRef from "../MutableRef.js"
32
+ import * as Option from "../Option.js"
33
+ import { pipeArguments } from "../Pipeable.js"
34
+ import * as Predicate from "../Predicate.js"
35
+ import type * as Random from "../Random.js"
36
+ import * as Ref from "../Ref.js"
37
+ import type { Entry, Request } from "../Request.js"
38
+ import type * as RequestBlock from "../RequestBlock.js"
39
+ import type * as RuntimeFlags from "../RuntimeFlags.js"
40
+ import * as RuntimeFlagsPatch from "../RuntimeFlagsPatch.js"
41
+ import { currentScheduler, type Scheduler } from "../Scheduler.js"
42
+ import type * as Scope from "../Scope.js"
43
+ import type * as Supervisor from "../Supervisor.js"
44
+ import type * as Tracer from "../Tracer.js"
45
+ import type { Concurrency, NoExcessProperties, NoInfer } from "../Types.js"
46
+ import { internalCall, yieldWrapGet } from "../Utils.js"
47
+ import * as RequestBlock_ from "./blockedRequests.js"
48
+ import * as internalCause from "./cause.js"
49
+ import * as clock from "./clock.js"
50
+ import { currentRequestMap } from "./completedRequestMap.js"
51
+ import * as concurrency from "./concurrency.js"
52
+ import { configProviderTag } from "./configProvider.js"
53
+ import * as internalEffect from "./core-effect.js"
54
+ import * as core from "./core.js"
55
+ import * as defaultServices from "./defaultServices.js"
56
+ import { consoleTag } from "./defaultServices/console.js"
57
+ import * as executionStrategy from "./executionStrategy.js"
58
+ import * as internalFiber from "./fiber.js"
59
+ import * as FiberMessage from "./fiberMessage.js"
60
+ import * as fiberRefs from "./fiberRefs.js"
61
+ import * as fiberScope from "./fiberScope.js"
62
+ import * as internalLogger from "./logger.js"
63
+ import * as metric from "./metric.js"
64
+ import * as metricBoundaries from "./metric/boundaries.js"
65
+ import * as metricLabel from "./metric/label.js"
66
+ import * as OpCodes from "./opCodes/effect.js"
67
+ import { randomTag } from "./random.js"
68
+ import { complete } from "./request.js"
69
+ import * as runtimeFlags_ from "./runtimeFlags.js"
70
+ import { OpSupervision } from "./runtimeFlags.js"
71
+ import * as supervisor from "./supervisor.js"
72
+ import * as SupervisorPatch from "./supervisor/patch.js"
73
+ import * as tracer from "./tracer.js"
74
+ import * as version from "./version.js"
75
+
76
+ /** @internal */
77
+ export const fiberStarted = metric.counter("effect_fiber_started", { incremental: true })
78
+ /** @internal */
79
+ export const fiberActive = metric.counter("effect_fiber_active")
80
+ /** @internal */
81
+ export const fiberSuccesses = metric.counter("effect_fiber_successes", { incremental: true })
82
+ /** @internal */
83
+ export const fiberFailures = metric.counter("effect_fiber_failures", { incremental: true })
84
+ /** @internal */
85
+ export const fiberLifetimes = metric.tagged(
86
+ metric.histogram(
87
+ "effect_fiber_lifetimes",
88
+ metricBoundaries.exponential({
89
+ start: 0.5,
90
+ factor: 2,
91
+ count: 35
92
+ })
93
+ ),
94
+ "time_unit",
95
+ "milliseconds"
96
+ )
97
+
98
+ /** @internal */
99
+ type EvaluationSignal =
100
+ | EvaluationSignalContinue
101
+ | EvaluationSignalDone
102
+ | EvaluationSignalYieldNow
103
+
104
+ /** @internal */
105
+ const EvaluationSignalContinue = "Continue" as const
106
+
107
+ /** @internal */
108
+ type EvaluationSignalContinue = typeof EvaluationSignalContinue
109
+
110
+ /** @internal */
111
+ const EvaluationSignalDone = "Done" as const
112
+
113
+ /** @internal */
114
+ type EvaluationSignalDone = typeof EvaluationSignalDone
115
+
116
+ /** @internal */
117
+ const EvaluationSignalYieldNow = "Yield" as const
118
+
119
+ /** @internal */
120
+ type EvaluationSignalYieldNow = typeof EvaluationSignalYieldNow
121
+
122
+ const runtimeFiberVariance = {
123
+ /* c8 ignore next */
124
+ _E: (_: never) => _,
125
+ /* c8 ignore next */
126
+ _A: (_: never) => _
127
+ }
128
+
129
+ const absurd = (_: never): never => {
130
+ throw new Error(
131
+ `BUG: FiberRuntime - ${
132
+ Inspectable.toStringUnknown(_)
133
+ } - please report an issue at https://github.com/Effect-TS/effect/issues`
134
+ )
135
+ }
136
+
137
+ const YieldedOp = Symbol.for("effect/internal/fiberRuntime/YieldedOp")
138
+ type YieldedOp = typeof YieldedOp
139
+ const yieldedOpChannel: {
140
+ currentOp: core.Primitive | null
141
+ } = globalValue("effect/internal/fiberRuntime/yieldedOpChannel", () => ({
142
+ currentOp: null
143
+ }))
144
+
145
+ const contOpSuccess = {
146
+ [OpCodes.OP_ON_SUCCESS]: (
147
+ _: FiberRuntime<any, any>,
148
+ cont: core.OnSuccess,
149
+ value: unknown
150
+ ) => {
151
+ return internalCall(() => cont.effect_instruction_i1(value))
152
+ },
153
+ ["OnStep"]: (
154
+ _: FiberRuntime<any, any>,
155
+ _cont: core.OnStep,
156
+ value: unknown
157
+ ) => {
158
+ return core.exitSucceed(core.exitSucceed(value))
159
+ },
160
+ [OpCodes.OP_ON_SUCCESS_AND_FAILURE]: (
161
+ _: FiberRuntime<any, any>,
162
+ cont: core.OnSuccessAndFailure,
163
+ value: unknown
164
+ ) => {
165
+ return internalCall(() => cont.effect_instruction_i2(value))
166
+ },
167
+ [OpCodes.OP_REVERT_FLAGS]: (
168
+ self: FiberRuntime<any, any>,
169
+ cont: core.RevertFlags,
170
+ value: unknown
171
+ ) => {
172
+ self.patchRuntimeFlags(self.currentRuntimeFlags, cont.patch)
173
+ if (runtimeFlags_.interruptible(self.currentRuntimeFlags) && self.isInterrupted()) {
174
+ return core.exitFailCause(self.getInterruptedCause())
175
+ } else {
176
+ return core.exitSucceed(value)
177
+ }
178
+ },
179
+ [OpCodes.OP_WHILE]: (
180
+ self: FiberRuntime<any, any>,
181
+ cont: core.While,
182
+ value: unknown
183
+ ) => {
184
+ internalCall(() => cont.effect_instruction_i2(value))
185
+ if (internalCall(() => cont.effect_instruction_i0())) {
186
+ self.pushStack(cont)
187
+ return internalCall(() => cont.effect_instruction_i1())
188
+ } else {
189
+ return core.void
190
+ }
191
+ },
192
+ [OpCodes.OP_ITERATOR]: (
193
+ self: FiberRuntime<any, any>,
194
+ cont: core.FromIterator,
195
+ value: unknown
196
+ ) => {
197
+ while (true) {
198
+ const state = internalCall(() => cont.effect_instruction_i0.next(value))
199
+ if (state.done) {
200
+ return core.exitSucceed(state.value)
201
+ }
202
+ const primitive = yieldWrapGet(state.value)
203
+ if (!core.exitIsExit(primitive)) {
204
+ self.pushStack(cont)
205
+ return primitive
206
+ } else if (primitive._tag === "Failure") {
207
+ return primitive
208
+ }
209
+ value = primitive.value
210
+ }
211
+ }
212
+ }
213
+
214
+ const drainQueueWhileRunningTable = {
215
+ [FiberMessage.OP_INTERRUPT_SIGNAL]: (
216
+ self: FiberRuntime<any, any>,
217
+ runtimeFlags: RuntimeFlags.RuntimeFlags,
218
+ cur: Effect.Effect<any, any, any>,
219
+ message: FiberMessage.FiberMessage & { _tag: FiberMessage.OP_INTERRUPT_SIGNAL }
220
+ ) => {
221
+ self.processNewInterruptSignal(message.cause)
222
+ return runtimeFlags_.interruptible(runtimeFlags) ? core.exitFailCause(message.cause) : cur
223
+ },
224
+ [FiberMessage.OP_RESUME]: (
225
+ _self: FiberRuntime<any, any>,
226
+ _runtimeFlags: RuntimeFlags.RuntimeFlags,
227
+ _cur: Effect.Effect<any, any, any>,
228
+ _message: FiberMessage.FiberMessage
229
+ ) => {
230
+ throw new Error("It is illegal to have multiple concurrent run loops in a single fiber")
231
+ },
232
+ [FiberMessage.OP_STATEFUL]: (
233
+ self: FiberRuntime<any, any>,
234
+ runtimeFlags: RuntimeFlags.RuntimeFlags,
235
+ cur: Effect.Effect<any, any, any>,
236
+ message: FiberMessage.FiberMessage & { _tag: FiberMessage.OP_STATEFUL }
237
+ ) => {
238
+ message.onFiber(self, FiberStatus.running(runtimeFlags))
239
+ return cur
240
+ },
241
+ [FiberMessage.OP_YIELD_NOW]: (
242
+ _self: FiberRuntime<any, any>,
243
+ _runtimeFlags: RuntimeFlags.RuntimeFlags,
244
+ cur: Effect.Effect<any, any, any>,
245
+ _message: FiberMessage.FiberMessage & { _tag: FiberMessage.OP_YIELD_NOW }
246
+ ) => {
247
+ return core.flatMap(core.yieldNow(), () => cur)
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Executes all requests, submitting requests to each data source in parallel.
253
+ */
254
+ const runBlockedRequests = (self: RequestBlock.RequestBlock) =>
255
+ core.forEachSequentialDiscard(
256
+ RequestBlock_.flatten(self),
257
+ (requestsByRequestResolver) =>
258
+ forEachConcurrentDiscard(
259
+ RequestBlock_.sequentialCollectionToChunk(requestsByRequestResolver),
260
+ ([dataSource, sequential]) => {
261
+ const map = new Map<Request<any, any>, Entry<any>>()
262
+ const arr: Array<Array<Entry<any>>> = []
263
+ for (const block of sequential) {
264
+ arr.push(Chunk.toReadonlyArray(block) as any)
265
+ for (const entry of block) {
266
+ map.set(entry.request as Request<any, any>, entry)
267
+ }
268
+ }
269
+ const flat = arr.flat()
270
+ return core.fiberRefLocally(
271
+ invokeWithInterrupt(dataSource.runAll(arr), flat, () =>
272
+ flat.forEach((entry) => {
273
+ entry.listeners.interrupted = true
274
+ })),
275
+ currentRequestMap,
276
+ map
277
+ )
278
+ },
279
+ false,
280
+ false
281
+ )
282
+ )
283
+
284
+ /** @internal */
285
+ export interface Snapshot {
286
+ refs: FiberRefs.FiberRefs
287
+ flags: RuntimeFlags.RuntimeFlags
288
+ }
289
+
290
+ const _version = version.getCurrentVersion()
291
+
292
+ /** @internal */
293
+ export class FiberRuntime<in out A, in out E = never> extends Effectable.Class<A, E>
294
+ implements Fiber.RuntimeFiber<A, E>
295
+ {
296
+ readonly [internalFiber.FiberTypeId] = internalFiber.fiberVariance
297
+ readonly [internalFiber.RuntimeFiberTypeId] = runtimeFiberVariance
298
+ private _fiberRefs: FiberRefs.FiberRefs
299
+ private _fiberId: FiberId.Runtime
300
+ private _queue = new Array<FiberMessage.FiberMessage>()
301
+ private _children: Set<FiberRuntime<any, any>> | null = null
302
+ private _observers = new Array<(exit: Exit.Exit<A, E>) => void>()
303
+ private _running = false
304
+ private _stack: Array<core.Continuation> = []
305
+ private _asyncInterruptor: ((effect: Effect.Effect<any, any, any>) => any) | null = null
306
+ private _asyncBlockingOn: FiberId.FiberId | null = null
307
+ private _exitValue: Exit.Exit<A, E> | null = null
308
+ private _steps: Array<Snapshot> = []
309
+ private _isYielding = false
310
+
311
+ public currentRuntimeFlags: RuntimeFlags.RuntimeFlags
312
+ public currentOpCount: number = 0
313
+ public currentSupervisor!: Supervisor.Supervisor<any>
314
+ public currentScheduler!: Scheduler
315
+ public currentTracer!: Tracer.Tracer
316
+ public currentSpan!: Tracer.AnySpan | undefined
317
+ public currentContext!: Context.Context<never>
318
+ public currentDefaultServices!: Context.Context<DefaultServices>
319
+
320
+ constructor(
321
+ fiberId: FiberId.Runtime,
322
+ fiberRefs0: FiberRefs.FiberRefs,
323
+ runtimeFlags0: RuntimeFlags.RuntimeFlags
324
+ ) {
325
+ super()
326
+ this.currentRuntimeFlags = runtimeFlags0
327
+ this._fiberId = fiberId
328
+ this._fiberRefs = fiberRefs0
329
+ if (runtimeFlags_.runtimeMetrics(runtimeFlags0)) {
330
+ const tags = this.getFiberRef(core.currentMetricLabels)
331
+ fiberStarted.unsafeUpdate(1, tags)
332
+ fiberActive.unsafeUpdate(1, tags)
333
+ }
334
+ this.refreshRefCache()
335
+ }
336
+
337
+ commit(): Effect.Effect<A, E, never> {
338
+ return internalFiber.join(this)
339
+ }
340
+
341
+ /**
342
+ * The identity of the fiber.
343
+ */
344
+ id(): FiberId.Runtime {
345
+ return this._fiberId
346
+ }
347
+
348
+ /**
349
+ * Begins execution of the effect associated with this fiber on in the
350
+ * background. This can be called to "kick off" execution of a fiber after
351
+ * it has been created.
352
+ */
353
+ resume<A, E>(effect: Effect.Effect<A, E, any>): void {
354
+ this.tell(FiberMessage.resume(effect))
355
+ }
356
+
357
+ /**
358
+ * The status of the fiber.
359
+ */
360
+ get status(): Effect.Effect<FiberStatus.FiberStatus> {
361
+ return this.ask((_, status) => status)
362
+ }
363
+
364
+ /**
365
+ * Gets the fiber runtime flags.
366
+ */
367
+ get runtimeFlags(): Effect.Effect<RuntimeFlags.RuntimeFlags> {
368
+ return this.ask((state, status) => {
369
+ if (FiberStatus.isDone(status)) {
370
+ return state.currentRuntimeFlags
371
+ }
372
+ return status.runtimeFlags
373
+ })
374
+ }
375
+
376
+ /**
377
+ * Returns the current `FiberScope` for the fiber.
378
+ */
379
+ scope(): fiberScope.FiberScope {
380
+ return fiberScope.unsafeMake(this)
381
+ }
382
+
383
+ /**
384
+ * Retrieves the immediate children of the fiber.
385
+ */
386
+ get children(): Effect.Effect<Array<Fiber.RuntimeFiber<any, any>>> {
387
+ return this.ask((fiber) => Array.from(fiber.getChildren()))
388
+ }
389
+
390
+ /**
391
+ * Gets the fiber's set of children.
392
+ */
393
+ getChildren(): Set<FiberRuntime<any, any>> {
394
+ if (this._children === null) {
395
+ this._children = new Set()
396
+ }
397
+ return this._children
398
+ }
399
+
400
+ /**
401
+ * Retrieves the interrupted cause of the fiber, which will be `Cause.empty`
402
+ * if the fiber has not been interrupted.
403
+ *
404
+ * **NOTE**: This method is safe to invoke on any fiber, but if not invoked
405
+ * on this fiber, then values derived from the fiber's state (including the
406
+ * log annotations and log level) may not be up-to-date.
407
+ */
408
+ getInterruptedCause() {
409
+ return this.getFiberRef(core.currentInterruptedCause)
410
+ }
411
+
412
+ /**
413
+ * Retrieves the whole set of fiber refs.
414
+ */
415
+ fiberRefs(): Effect.Effect<FiberRefs.FiberRefs> {
416
+ return this.ask((fiber) => fiber.getFiberRefs())
417
+ }
418
+
419
+ /**
420
+ * Returns an effect that will contain information computed from the fiber
421
+ * state and status while running on the fiber.
422
+ *
423
+ * This allows the outside world to interact safely with mutable fiber state
424
+ * without locks or immutable data.
425
+ */
426
+ ask<Z>(
427
+ f: (runtime: FiberRuntime<any, any>, status: FiberStatus.FiberStatus) => Z
428
+ ): Effect.Effect<Z> {
429
+ return core.suspend(() => {
430
+ const deferred = core.deferredUnsafeMake<Z>(this._fiberId)
431
+ this.tell(
432
+ FiberMessage.stateful((fiber, status) => {
433
+ core.deferredUnsafeDone(deferred, core.sync(() => f(fiber, status)))
434
+ })
435
+ )
436
+ return core.deferredAwait(deferred)
437
+ })
438
+ }
439
+
440
+ /**
441
+ * Adds a message to be processed by the fiber on the fiber.
442
+ */
443
+ tell(message: FiberMessage.FiberMessage): void {
444
+ this._queue.push(message)
445
+ if (!this._running) {
446
+ this._running = true
447
+ this.drainQueueLaterOnExecutor()
448
+ }
449
+ }
450
+
451
+ get await(): Effect.Effect<Exit.Exit<A, E>> {
452
+ return core.async((resume) => {
453
+ const cb = (exit: Exit.Exit<A, E>) => resume(core.succeed(exit))
454
+ this.tell(
455
+ FiberMessage.stateful((fiber, _) => {
456
+ if (fiber._exitValue !== null) {
457
+ cb(this._exitValue!)
458
+ } else {
459
+ fiber.addObserver(cb)
460
+ }
461
+ })
462
+ )
463
+ return core.sync(() =>
464
+ this.tell(
465
+ FiberMessage.stateful((fiber, _) => {
466
+ fiber.removeObserver(cb)
467
+ })
468
+ )
469
+ )
470
+ }, this.id())
471
+ }
472
+
473
+ get inheritAll(): Effect.Effect<void> {
474
+ return core.withFiberRuntime((parentFiber, parentStatus) => {
475
+ const parentFiberId = parentFiber.id()
476
+ const parentFiberRefs = parentFiber.getFiberRefs()
477
+ const parentRuntimeFlags = parentStatus.runtimeFlags
478
+ const childFiberRefs = this.getFiberRefs()
479
+ const updatedFiberRefs = fiberRefs.joinAs(parentFiberRefs, parentFiberId, childFiberRefs)
480
+
481
+ parentFiber.setFiberRefs(updatedFiberRefs)
482
+
483
+ const updatedRuntimeFlags = parentFiber.getFiberRef(currentRuntimeFlags)
484
+
485
+ const patch = pipe(
486
+ runtimeFlags_.diff(parentRuntimeFlags, updatedRuntimeFlags),
487
+ // Do not inherit WindDown or Interruption!
488
+ RuntimeFlagsPatch.exclude(runtimeFlags_.Interruption),
489
+ RuntimeFlagsPatch.exclude(runtimeFlags_.WindDown)
490
+ )
491
+
492
+ return core.updateRuntimeFlags(patch)
493
+ })
494
+ }
495
+
496
+ /**
497
+ * Tentatively observes the fiber, but returns immediately if it is not
498
+ * already done.
499
+ */
500
+ get poll(): Effect.Effect<Option.Option<Exit.Exit<A, E>>> {
501
+ return core.sync(() => Option.fromNullable(this._exitValue))
502
+ }
503
+
504
+ /**
505
+ * Unsafely observes the fiber, but returns immediately if it is not
506
+ * already done.
507
+ */
508
+ unsafePoll(): Exit.Exit<A, E> | null {
509
+ return this._exitValue
510
+ }
511
+
512
+ /**
513
+ * In the background, interrupts the fiber as if interrupted from the specified fiber.
514
+ */
515
+ interruptAsFork(fiberId: FiberId.FiberId): Effect.Effect<void> {
516
+ return core.sync(() => this.tell(FiberMessage.interruptSignal(internalCause.interrupt(fiberId))))
517
+ }
518
+
519
+ /**
520
+ * In the background, interrupts the fiber as if interrupted from the specified fiber.
521
+ */
522
+ unsafeInterruptAsFork(fiberId: FiberId.FiberId) {
523
+ this.tell(FiberMessage.interruptSignal(internalCause.interrupt(fiberId)))
524
+ }
525
+
526
+ /**
527
+ * Adds an observer to the list of observers.
528
+ *
529
+ * **NOTE**: This method must be invoked by the fiber itself.
530
+ */
531
+ addObserver(observer: (exit: Exit.Exit<A, E>) => void): void {
532
+ if (this._exitValue !== null) {
533
+ observer(this._exitValue!)
534
+ } else {
535
+ this._observers.push(observer)
536
+ }
537
+ }
538
+
539
+ /**
540
+ * Removes the specified observer from the list of observers that will be
541
+ * notified when the fiber exits.
542
+ *
543
+ * **NOTE**: This method must be invoked by the fiber itself.
544
+ */
545
+ removeObserver(observer: (exit: Exit.Exit<A, E>) => void): void {
546
+ this._observers = this._observers.filter((o) => o !== observer)
547
+ }
548
+ /**
549
+ * Retrieves all fiber refs of the fiber.
550
+ *
551
+ * **NOTE**: This method is safe to invoke on any fiber, but if not invoked
552
+ * on this fiber, then values derived from the fiber's state (including the
553
+ * log annotations and log level) may not be up-to-date.
554
+ */
555
+ getFiberRefs(): FiberRefs.FiberRefs {
556
+ this.setFiberRef(currentRuntimeFlags, this.currentRuntimeFlags)
557
+ return this._fiberRefs
558
+ }
559
+
560
+ /**
561
+ * Deletes the specified fiber ref.
562
+ *
563
+ * **NOTE**: This method must be invoked by the fiber itself.
564
+ */
565
+ unsafeDeleteFiberRef<X>(fiberRef: FiberRef.FiberRef<X>): void {
566
+ this._fiberRefs = fiberRefs.delete_(this._fiberRefs, fiberRef)
567
+ }
568
+
569
+ /**
570
+ * Retrieves the state of the fiber ref, or else its initial value.
571
+ *
572
+ * **NOTE**: This method is safe to invoke on any fiber, but if not invoked
573
+ * on this fiber, then values derived from the fiber's state (including the
574
+ * log annotations and log level) may not be up-to-date.
575
+ */
576
+ getFiberRef<X>(fiberRef: FiberRef.FiberRef<X>): X {
577
+ if (this._fiberRefs.locals.has(fiberRef)) {
578
+ return this._fiberRefs.locals.get(fiberRef)![0][1] as X
579
+ }
580
+ return fiberRef.initial
581
+ }
582
+
583
+ /**
584
+ * Sets the fiber ref to the specified value.
585
+ *
586
+ * **NOTE**: This method must be invoked by the fiber itself.
587
+ */
588
+ setFiberRef<X>(fiberRef: FiberRef.FiberRef<X>, value: X): void {
589
+ this._fiberRefs = fiberRefs.updateAs(this._fiberRefs, {
590
+ fiberId: this._fiberId,
591
+ fiberRef,
592
+ value
593
+ })
594
+ this.refreshRefCache()
595
+ }
596
+
597
+ refreshRefCache() {
598
+ this.currentDefaultServices = this.getFiberRef(defaultServices.currentServices)
599
+ this.currentTracer = this.currentDefaultServices.unsafeMap.get(tracer.tracerTag.key)
600
+ this.currentSupervisor = this.getFiberRef(currentSupervisor)
601
+ this.currentScheduler = this.getFiberRef(currentScheduler)
602
+ this.currentContext = this.getFiberRef(core.currentContext)
603
+ this.currentSpan = this.currentContext.unsafeMap.get(tracer.spanTag.key)
604
+ }
605
+
606
+ /**
607
+ * Wholesale replaces all fiber refs of this fiber.
608
+ *
609
+ * **NOTE**: This method must be invoked by the fiber itself.
610
+ */
611
+ setFiberRefs(fiberRefs: FiberRefs.FiberRefs): void {
612
+ this._fiberRefs = fiberRefs
613
+ this.refreshRefCache()
614
+ }
615
+
616
+ /**
617
+ * Adds a reference to the specified fiber inside the children set.
618
+ *
619
+ * **NOTE**: This method must be invoked by the fiber itself.
620
+ */
621
+ addChild(child: FiberRuntime<any, any>) {
622
+ this.getChildren().add(child)
623
+ }
624
+
625
+ /**
626
+ * Removes a reference to the specified fiber inside the children set.
627
+ *
628
+ * **NOTE**: This method must be invoked by the fiber itself.
629
+ */
630
+ removeChild(child: FiberRuntime<any, any>) {
631
+ this.getChildren().delete(child)
632
+ }
633
+
634
+ /**
635
+ * Transfers all children of this fiber that are currently running to the
636
+ * specified fiber scope.
637
+ *
638
+ * **NOTE**: This method must be invoked by the fiber itself after it has
639
+ * evaluated the effects but prior to exiting.
640
+ */
641
+ transferChildren(scope: fiberScope.FiberScope) {
642
+ const children = this._children
643
+ // Clear the children of the current fiber
644
+ this._children = null
645
+ if (children !== null && children.size > 0) {
646
+ for (const child of children) {
647
+ // If the child is still running, add it to the scope
648
+ if (child._exitValue === null) {
649
+ scope.add(this.currentRuntimeFlags, child)
650
+ }
651
+ }
652
+ }
653
+ }
654
+
655
+ /**
656
+ * On the current thread, executes all messages in the fiber's inbox. This
657
+ * method may return before all work is done, in the event the fiber executes
658
+ * an asynchronous operation.
659
+ *
660
+ * **NOTE**: This method must be invoked by the fiber itself.
661
+ */
662
+ drainQueueOnCurrentThread() {
663
+ let recurse = true
664
+ while (recurse) {
665
+ let evaluationSignal: EvaluationSignal = EvaluationSignalContinue
666
+ const prev = (globalThis as any)[internalFiber.currentFiberURI]
667
+ ;(globalThis as any)[internalFiber.currentFiberURI] = this
668
+ try {
669
+ while (evaluationSignal === EvaluationSignalContinue) {
670
+ evaluationSignal = this._queue.length === 0 ?
671
+ EvaluationSignalDone :
672
+ this.evaluateMessageWhileSuspended(this._queue.splice(0, 1)[0]!)
673
+ }
674
+ } finally {
675
+ this._running = false
676
+ ;(globalThis as any)[internalFiber.currentFiberURI] = prev
677
+ }
678
+ // Maybe someone added something to the queue between us checking, and us
679
+ // giving up the drain. If so, we need to restart the draining, but only
680
+ // if we beat everyone else to the restart:
681
+ if (this._queue.length > 0 && !this._running) {
682
+ this._running = true
683
+ if (evaluationSignal === EvaluationSignalYieldNow) {
684
+ this.drainQueueLaterOnExecutor()
685
+ recurse = false
686
+ } else {
687
+ recurse = true
688
+ }
689
+ } else {
690
+ recurse = false
691
+ }
692
+ }
693
+ }
694
+
695
+ /**
696
+ * Schedules the execution of all messages in the fiber's inbox.
697
+ *
698
+ * This method will return immediately after the scheduling
699
+ * operation is completed, but potentially before such messages have been
700
+ * executed.
701
+ *
702
+ * **NOTE**: This method must be invoked by the fiber itself.
703
+ */
704
+ drainQueueLaterOnExecutor() {
705
+ this.currentScheduler.scheduleTask(
706
+ this.run,
707
+ this.getFiberRef(core.currentSchedulingPriority)
708
+ )
709
+ }
710
+
711
+ /**
712
+ * Drains the fiber's message queue while the fiber is actively running,
713
+ * returning the next effect to execute, which may be the input effect if no
714
+ * additional effect needs to be executed.
715
+ *
716
+ * **NOTE**: This method must be invoked by the fiber itself.
717
+ */
718
+ drainQueueWhileRunning(
719
+ runtimeFlags: RuntimeFlags.RuntimeFlags,
720
+ cur0: Effect.Effect<any, any, any>
721
+ ) {
722
+ let cur = cur0
723
+ while (this._queue.length > 0) {
724
+ const message = this._queue.splice(0, 1)[0]
725
+ // @ts-expect-error
726
+ cur = drainQueueWhileRunningTable[message._tag](this, runtimeFlags, cur, message)
727
+ }
728
+ return cur
729
+ }
730
+
731
+ /**
732
+ * Determines if the fiber is interrupted.
733
+ *
734
+ * **NOTE**: This method is safe to invoke on any fiber, but if not invoked
735
+ * on this fiber, then values derived from the fiber's state (including the
736
+ * log annotations and log level) may not be up-to-date.
737
+ */
738
+ isInterrupted(): boolean {
739
+ return !internalCause.isEmpty(this.getFiberRef(core.currentInterruptedCause))
740
+ }
741
+
742
+ /**
743
+ * Adds an interruptor to the set of interruptors that are interrupting this
744
+ * fiber.
745
+ *
746
+ * **NOTE**: This method must be invoked by the fiber itself.
747
+ */
748
+ addInterruptedCause(cause: Cause.Cause<never>) {
749
+ const oldSC = this.getFiberRef(core.currentInterruptedCause)
750
+ this.setFiberRef(core.currentInterruptedCause, internalCause.sequential(oldSC, cause))
751
+ }
752
+
753
+ /**
754
+ * Processes a new incoming interrupt signal.
755
+ *
756
+ * **NOTE**: This method must be invoked by the fiber itself.
757
+ */
758
+ processNewInterruptSignal(cause: Cause.Cause<never>): void {
759
+ this.addInterruptedCause(cause)
760
+ this.sendInterruptSignalToAllChildren()
761
+ }
762
+
763
+ /**
764
+ * Interrupts all children of the current fiber, returning an effect that will
765
+ * await the exit of the children. This method will return null if the fiber
766
+ * has no children.
767
+ *
768
+ * **NOTE**: This method must be invoked by the fiber itself.
769
+ */
770
+ sendInterruptSignalToAllChildren(): boolean {
771
+ if (this._children === null || this._children.size === 0) {
772
+ return false
773
+ }
774
+ let told = false
775
+ for (const child of this._children) {
776
+ child.tell(FiberMessage.interruptSignal(internalCause.interrupt(this.id())))
777
+ told = true
778
+ }
779
+ return told
780
+ }
781
+
782
+ /**
783
+ * Interrupts all children of the current fiber, returning an effect that will
784
+ * await the exit of the children. This method will return null if the fiber
785
+ * has no children.
786
+ *
787
+ * **NOTE**: This method must be invoked by the fiber itself.
788
+ */
789
+ interruptAllChildren() {
790
+ if (this.sendInterruptSignalToAllChildren()) {
791
+ const it = this._children!.values()
792
+ this._children = null
793
+ let isDone = false
794
+ const body = () => {
795
+ const next = it.next()
796
+ if (!next.done) {
797
+ return core.asVoid(next.value.await)
798
+ } else {
799
+ return core.sync(() => {
800
+ isDone = true
801
+ })
802
+ }
803
+ }
804
+ return core.whileLoop({
805
+ while: () => !isDone,
806
+ body,
807
+ step: () => {
808
+ //
809
+ }
810
+ })
811
+ }
812
+ return null
813
+ }
814
+
815
+ reportExitValue(exit: Exit.Exit<A, E>) {
816
+ if (runtimeFlags_.runtimeMetrics(this.currentRuntimeFlags)) {
817
+ const tags = this.getFiberRef(core.currentMetricLabels)
818
+ const startTimeMillis = this.id().startTimeMillis
819
+ const endTimeMillis = Date.now()
820
+ fiberLifetimes.unsafeUpdate(endTimeMillis - startTimeMillis, tags)
821
+ fiberActive.unsafeUpdate(-1, tags)
822
+ switch (exit._tag) {
823
+ case OpCodes.OP_SUCCESS: {
824
+ fiberSuccesses.unsafeUpdate(1, tags)
825
+ break
826
+ }
827
+ case OpCodes.OP_FAILURE: {
828
+ fiberFailures.unsafeUpdate(1, tags)
829
+ break
830
+ }
831
+ }
832
+ }
833
+ if (exit._tag === "Failure") {
834
+ const level = this.getFiberRef(core.currentUnhandledErrorLogLevel)
835
+ if (!internalCause.isInterruptedOnly(exit.cause) && level._tag === "Some") {
836
+ this.log("Fiber terminated with an unhandled error", exit.cause, level)
837
+ }
838
+ }
839
+ }
840
+
841
+ setExitValue(exit: Exit.Exit<A, E>) {
842
+ this._exitValue = exit
843
+ this.reportExitValue(exit)
844
+ for (let i = this._observers.length - 1; i >= 0; i--) {
845
+ this._observers[i](exit)
846
+ }
847
+ this._observers = []
848
+ }
849
+
850
+ getLoggers() {
851
+ return this.getFiberRef(currentLoggers)
852
+ }
853
+
854
+ log(
855
+ message: unknown,
856
+ cause: Cause.Cause<any>,
857
+ overrideLogLevel: Option.Option<LogLevel.LogLevel>
858
+ ): void {
859
+ const logLevel = Option.isSome(overrideLogLevel) ?
860
+ overrideLogLevel.value :
861
+ this.getFiberRef(core.currentLogLevel)
862
+ const minimumLogLevel = this.getFiberRef(currentMinimumLogLevel)
863
+ if (LogLevel.greaterThan(minimumLogLevel, logLevel)) {
864
+ return
865
+ }
866
+ const spans = this.getFiberRef(core.currentLogSpan)
867
+ const annotations = this.getFiberRef(core.currentLogAnnotations)
868
+ const loggers = this.getLoggers()
869
+ const contextMap = this.getFiberRefs()
870
+ if (HashSet.size(loggers) > 0) {
871
+ const clockService = Context.get(this.getFiberRef(defaultServices.currentServices), clock.clockTag)
872
+ const date = new Date(clockService.unsafeCurrentTimeMillis())
873
+ Inspectable.withRedactableContext(contextMap, () => {
874
+ for (const logger of loggers) {
875
+ logger.log({
876
+ fiberId: this.id(),
877
+ logLevel,
878
+ message,
879
+ cause,
880
+ context: contextMap,
881
+ spans,
882
+ annotations,
883
+ date
884
+ })
885
+ }
886
+ })
887
+ }
888
+ }
889
+
890
+ /**
891
+ * Evaluates a single message on the current thread, while the fiber is
892
+ * suspended. This method should only be called while evaluation of the
893
+ * fiber's effect is suspended due to an asynchronous operation.
894
+ *
895
+ * **NOTE**: This method must be invoked by the fiber itself.
896
+ */
897
+ evaluateMessageWhileSuspended(message: FiberMessage.FiberMessage): EvaluationSignal {
898
+ switch (message._tag) {
899
+ case FiberMessage.OP_YIELD_NOW: {
900
+ return EvaluationSignalYieldNow
901
+ }
902
+ case FiberMessage.OP_INTERRUPT_SIGNAL: {
903
+ this.processNewInterruptSignal(message.cause)
904
+ if (this._asyncInterruptor !== null) {
905
+ this._asyncInterruptor(core.exitFailCause(message.cause))
906
+ this._asyncInterruptor = null
907
+ }
908
+ return EvaluationSignalContinue
909
+ }
910
+ case FiberMessage.OP_RESUME: {
911
+ this._asyncInterruptor = null
912
+ this._asyncBlockingOn = null
913
+ this.evaluateEffect(message.effect)
914
+ return EvaluationSignalContinue
915
+ }
916
+ case FiberMessage.OP_STATEFUL: {
917
+ message.onFiber(
918
+ this,
919
+ this._exitValue !== null ?
920
+ FiberStatus.done :
921
+ FiberStatus.suspended(this.currentRuntimeFlags, this._asyncBlockingOn!)
922
+ )
923
+ return EvaluationSignalContinue
924
+ }
925
+ default: {
926
+ return absurd(message)
927
+ }
928
+ }
929
+ }
930
+
931
+ /**
932
+ * Evaluates an effect until completion, potentially asynchronously.
933
+ *
934
+ * **NOTE**: This method must be invoked by the fiber itself.
935
+ */
936
+ evaluateEffect(effect0: Effect.Effect<any, any, any>) {
937
+ this.currentSupervisor.onResume(this)
938
+ try {
939
+ let effect: Effect.Effect<any, any, any> | null =
940
+ runtimeFlags_.interruptible(this.currentRuntimeFlags) && this.isInterrupted() ?
941
+ core.exitFailCause(this.getInterruptedCause()) :
942
+ effect0
943
+ while (effect !== null) {
944
+ const eff: Effect.Effect<any, any, any> = effect
945
+ const exit = this.runLoop(eff)
946
+ if (exit === YieldedOp) {
947
+ const op = yieldedOpChannel.currentOp!
948
+ yieldedOpChannel.currentOp = null
949
+ if (op._op === OpCodes.OP_YIELD) {
950
+ if (runtimeFlags_.cooperativeYielding(this.currentRuntimeFlags)) {
951
+ this.tell(FiberMessage.yieldNow())
952
+ this.tell(FiberMessage.resume(core.exitVoid))
953
+ effect = null
954
+ } else {
955
+ effect = core.exitVoid
956
+ }
957
+ } else if (op._op === OpCodes.OP_ASYNC) {
958
+ // Terminate this evaluation, async resumption will continue evaluation:
959
+ effect = null
960
+ }
961
+ } else {
962
+ this.currentRuntimeFlags = pipe(this.currentRuntimeFlags, runtimeFlags_.enable(runtimeFlags_.WindDown))
963
+ const interruption = this.interruptAllChildren()
964
+ if (interruption !== null) {
965
+ effect = core.flatMap(interruption, () => exit)
966
+ } else {
967
+ if (this._queue.length === 0) {
968
+ // No more messages to process, so we will allow the fiber to end life:
969
+ this.setExitValue(exit)
970
+ } else {
971
+ // There are messages, possibly added by the final op executed by
972
+ // the fiber. To be safe, we should execute those now before we
973
+ // allow the fiber to end life:
974
+ this.tell(FiberMessage.resume(exit))
975
+ }
976
+ effect = null
977
+ }
978
+ }
979
+ }
980
+ } finally {
981
+ this.currentSupervisor.onSuspend(this)
982
+ }
983
+ }
984
+
985
+ /**
986
+ * Begins execution of the effect associated with this fiber on the current
987
+ * thread. This can be called to "kick off" execution of a fiber after it has
988
+ * been created, in hopes that the effect can be executed synchronously.
989
+ *
990
+ * This is not the normal way of starting a fiber, but it is useful when the
991
+ * express goal of executing the fiber is to synchronously produce its exit.
992
+ */
993
+ start<R>(effect: Effect.Effect<A, E, R>): void {
994
+ if (!this._running) {
995
+ this._running = true
996
+ const prev = (globalThis as any)[internalFiber.currentFiberURI]
997
+ ;(globalThis as any)[internalFiber.currentFiberURI] = this
998
+ try {
999
+ this.evaluateEffect(effect)
1000
+ } finally {
1001
+ this._running = false
1002
+ ;(globalThis as any)[internalFiber.currentFiberURI] = prev
1003
+ // Because we're special casing `start`, we have to be responsible
1004
+ // for spinning up the fiber if there were new messages added to
1005
+ // the queue between the completion of the effect and the transition
1006
+ // to the not running state.
1007
+ if (this._queue.length > 0) {
1008
+ this.drainQueueLaterOnExecutor()
1009
+ }
1010
+ }
1011
+ } else {
1012
+ this.tell(FiberMessage.resume(effect))
1013
+ }
1014
+ }
1015
+
1016
+ /**
1017
+ * Begins execution of the effect associated with this fiber on in the
1018
+ * background, and on the correct thread pool. This can be called to "kick
1019
+ * off" execution of a fiber after it has been created, in hopes that the
1020
+ * effect can be executed synchronously.
1021
+ */
1022
+ startFork<R>(effect: Effect.Effect<A, E, R>): void {
1023
+ this.tell(FiberMessage.resume(effect))
1024
+ }
1025
+
1026
+ /**
1027
+ * Takes the current runtime flags, patches them to return the new runtime
1028
+ * flags, and then makes any changes necessary to fiber state based on the
1029
+ * specified patch.
1030
+ *
1031
+ * **NOTE**: This method must be invoked by the fiber itself.
1032
+ */
1033
+ patchRuntimeFlags(oldRuntimeFlags: RuntimeFlags.RuntimeFlags, patch: RuntimeFlagsPatch.RuntimeFlagsPatch) {
1034
+ const newRuntimeFlags = runtimeFlags_.patch(oldRuntimeFlags, patch)
1035
+ ;(globalThis as any)[internalFiber.currentFiberURI] = this
1036
+ this.currentRuntimeFlags = newRuntimeFlags
1037
+ return newRuntimeFlags
1038
+ }
1039
+
1040
+ /**
1041
+ * Initiates an asynchronous operation, by building a callback that will
1042
+ * resume execution, and then feeding that callback to the registration
1043
+ * function, handling error cases and repeated resumptions appropriately.
1044
+ *
1045
+ * **NOTE**: This method must be invoked by the fiber itself.
1046
+ */
1047
+ initiateAsync(
1048
+ runtimeFlags: RuntimeFlags.RuntimeFlags,
1049
+ asyncRegister: (resume: (effect: Effect.Effect<any, any, any>) => void) => void
1050
+ ) {
1051
+ let alreadyCalled = false
1052
+ const callback = (effect: Effect.Effect<any, any, any>) => {
1053
+ if (!alreadyCalled) {
1054
+ alreadyCalled = true
1055
+ this.tell(FiberMessage.resume(effect))
1056
+ }
1057
+ }
1058
+ if (runtimeFlags_.interruptible(runtimeFlags)) {
1059
+ this._asyncInterruptor = callback
1060
+ }
1061
+ try {
1062
+ asyncRegister(callback)
1063
+ } catch (e) {
1064
+ callback(core.failCause(internalCause.die(e)))
1065
+ }
1066
+ }
1067
+
1068
+ pushStack(cont: core.Continuation) {
1069
+ this._stack.push(cont)
1070
+ if (cont._op === "OnStep") {
1071
+ this._steps.push({ refs: this.getFiberRefs(), flags: this.currentRuntimeFlags })
1072
+ }
1073
+ }
1074
+
1075
+ popStack() {
1076
+ const item = this._stack.pop()
1077
+ if (item) {
1078
+ if (item._op === "OnStep") {
1079
+ this._steps.pop()
1080
+ }
1081
+ return item
1082
+ }
1083
+ return
1084
+ }
1085
+
1086
+ getNextSuccessCont() {
1087
+ let frame = this.popStack()
1088
+ while (frame) {
1089
+ if (frame._op !== OpCodes.OP_ON_FAILURE) {
1090
+ return frame
1091
+ }
1092
+ frame = this.popStack()
1093
+ }
1094
+ }
1095
+
1096
+ getNextFailCont() {
1097
+ let frame = this.popStack()
1098
+ while (frame) {
1099
+ if (frame._op !== OpCodes.OP_ON_SUCCESS && frame._op !== OpCodes.OP_WHILE && frame._op !== OpCodes.OP_ITERATOR) {
1100
+ return frame
1101
+ }
1102
+ frame = this.popStack()
1103
+ }
1104
+ }
1105
+
1106
+ [OpCodes.OP_TAG](op: core.Primitive & { _op: OpCodes.OP_SYNC }) {
1107
+ return core.sync(() => Context.unsafeGet(this.currentContext, op as unknown as Context.Tag<any, any>))
1108
+ }
1109
+
1110
+ ["Left"](op: core.Primitive & { _op: "Left" }) {
1111
+ return core.fail(op.left)
1112
+ }
1113
+
1114
+ ["None"](_: core.Primitive & { _op: "None" }) {
1115
+ return core.fail(new core.NoSuchElementException())
1116
+ }
1117
+
1118
+ ["Right"](op: core.Primitive & { _op: "Right" }) {
1119
+ return core.exitSucceed(op.right)
1120
+ }
1121
+
1122
+ ["Some"](op: core.Primitive & { _op: "Some" }) {
1123
+ return core.exitSucceed(op.value)
1124
+ }
1125
+
1126
+ ["Micro"](op: Micro.Micro<any, any, never> & { _op: "Micro" }) {
1127
+ return core.unsafeAsync<any, any>((microResume) => {
1128
+ let resume = microResume
1129
+ const fiber = Micro.runFork(Micro.provideContext(op, this.currentContext))
1130
+ fiber.addObserver((exit) => {
1131
+ if (exit._tag === "Success") {
1132
+ return resume(core.exitSucceed(exit.value))
1133
+ }
1134
+ switch (exit.cause._tag) {
1135
+ case "Interrupt": {
1136
+ return resume(core.exitFailCause(internalCause.interrupt(FiberId.none)))
1137
+ }
1138
+ case "Fail": {
1139
+ return resume(core.fail(exit.cause.error))
1140
+ }
1141
+ case "Die": {
1142
+ return resume(core.die(exit.cause.defect))
1143
+ }
1144
+ }
1145
+ })
1146
+ return core.unsafeAsync<void>((abortResume) => {
1147
+ resume = (_: any) => {
1148
+ abortResume(core.void)
1149
+ }
1150
+ fiber.unsafeInterrupt()
1151
+ })
1152
+ })
1153
+ }
1154
+
1155
+ [OpCodes.OP_SYNC](op: core.Primitive & { _op: OpCodes.OP_SYNC }) {
1156
+ const value = internalCall(() => op.effect_instruction_i0())
1157
+ const cont = this.getNextSuccessCont()
1158
+ if (cont !== undefined) {
1159
+ if (!(cont._op in contOpSuccess)) {
1160
+ // @ts-expect-error
1161
+ absurd(cont)
1162
+ }
1163
+ // @ts-expect-error
1164
+ return contOpSuccess[cont._op](this, cont, value)
1165
+ } else {
1166
+ yieldedOpChannel.currentOp = core.exitSucceed(value) as any
1167
+ return YieldedOp
1168
+ }
1169
+ }
1170
+
1171
+ [OpCodes.OP_SUCCESS](op: core.Primitive & { _op: OpCodes.OP_SUCCESS }) {
1172
+ const oldCur = op
1173
+ const cont = this.getNextSuccessCont()
1174
+ if (cont !== undefined) {
1175
+ if (!(cont._op in contOpSuccess)) {
1176
+ // @ts-expect-error
1177
+ absurd(cont)
1178
+ }
1179
+ // @ts-expect-error
1180
+ return contOpSuccess[cont._op](this, cont, oldCur.effect_instruction_i0)
1181
+ } else {
1182
+ yieldedOpChannel.currentOp = oldCur
1183
+ return YieldedOp
1184
+ }
1185
+ }
1186
+
1187
+ [OpCodes.OP_FAILURE](op: core.Primitive & { _op: OpCodes.OP_FAILURE }) {
1188
+ const cause = op.effect_instruction_i0
1189
+ const cont = this.getNextFailCont()
1190
+ if (cont !== undefined) {
1191
+ switch (cont._op) {
1192
+ case OpCodes.OP_ON_FAILURE:
1193
+ case OpCodes.OP_ON_SUCCESS_AND_FAILURE: {
1194
+ if (!(runtimeFlags_.interruptible(this.currentRuntimeFlags) && this.isInterrupted())) {
1195
+ return internalCall(() => cont.effect_instruction_i1(cause))
1196
+ } else {
1197
+ return core.exitFailCause(internalCause.stripFailures(cause))
1198
+ }
1199
+ }
1200
+ case "OnStep": {
1201
+ if (!(runtimeFlags_.interruptible(this.currentRuntimeFlags) && this.isInterrupted())) {
1202
+ return core.exitSucceed(core.exitFailCause(cause))
1203
+ } else {
1204
+ return core.exitFailCause(internalCause.stripFailures(cause))
1205
+ }
1206
+ }
1207
+ case OpCodes.OP_REVERT_FLAGS: {
1208
+ this.patchRuntimeFlags(this.currentRuntimeFlags, cont.patch)
1209
+ if (runtimeFlags_.interruptible(this.currentRuntimeFlags) && this.isInterrupted()) {
1210
+ return core.exitFailCause(internalCause.sequential(cause, this.getInterruptedCause()))
1211
+ } else {
1212
+ return core.exitFailCause(cause)
1213
+ }
1214
+ }
1215
+ default: {
1216
+ absurd(cont)
1217
+ }
1218
+ }
1219
+ } else {
1220
+ yieldedOpChannel.currentOp = core.exitFailCause(cause) as any
1221
+ return YieldedOp
1222
+ }
1223
+ }
1224
+
1225
+ [OpCodes.OP_WITH_RUNTIME](op: core.Primitive & { _op: OpCodes.OP_WITH_RUNTIME }) {
1226
+ return internalCall(() =>
1227
+ op.effect_instruction_i0(
1228
+ this as FiberRuntime<unknown, unknown>,
1229
+ FiberStatus.running(this.currentRuntimeFlags) as FiberStatus.Running
1230
+ )
1231
+ )
1232
+ }
1233
+
1234
+ ["Blocked"](op: core.Primitive & { _op: "Blocked" }) {
1235
+ const refs = this.getFiberRefs()
1236
+ const flags = this.currentRuntimeFlags
1237
+ if (this._steps.length > 0) {
1238
+ const frames: Array<core.Continuation> = []
1239
+ const snap = this._steps[this._steps.length - 1]
1240
+ let frame = this.popStack()
1241
+ while (frame && frame._op !== "OnStep") {
1242
+ frames.push(frame)
1243
+ frame = this.popStack()
1244
+ }
1245
+ this.setFiberRefs(snap.refs)
1246
+ this.currentRuntimeFlags = snap.flags
1247
+ const patchRefs = FiberRefsPatch.diff(snap.refs, refs)
1248
+ const patchFlags = runtimeFlags_.diff(snap.flags, flags)
1249
+ return core.exitSucceed(core.blocked(
1250
+ op.effect_instruction_i0,
1251
+ core.withFiberRuntime<unknown, unknown>((newFiber) => {
1252
+ while (frames.length > 0) {
1253
+ newFiber.pushStack(frames.pop()!)
1254
+ }
1255
+ newFiber.setFiberRefs(
1256
+ FiberRefsPatch.patch(newFiber.id(), newFiber.getFiberRefs())(patchRefs)
1257
+ )
1258
+ newFiber.currentRuntimeFlags = runtimeFlags_.patch(patchFlags)(newFiber.currentRuntimeFlags)
1259
+ return op.effect_instruction_i1
1260
+ })
1261
+ ))
1262
+ }
1263
+ return core.uninterruptibleMask((restore) =>
1264
+ core.flatMap(
1265
+ forkDaemon(core.runRequestBlock(op.effect_instruction_i0)),
1266
+ () => restore(op.effect_instruction_i1)
1267
+ )
1268
+ )
1269
+ }
1270
+
1271
+ ["RunBlocked"](op: core.Primitive & { _op: "RunBlocked" }) {
1272
+ return runBlockedRequests(op.effect_instruction_i0)
1273
+ }
1274
+
1275
+ [OpCodes.OP_UPDATE_RUNTIME_FLAGS](op: core.Primitive & { _op: OpCodes.OP_UPDATE_RUNTIME_FLAGS }) {
1276
+ const updateFlags = op.effect_instruction_i0
1277
+ const oldRuntimeFlags = this.currentRuntimeFlags
1278
+ const newRuntimeFlags = runtimeFlags_.patch(oldRuntimeFlags, updateFlags)
1279
+ // One more chance to short circuit: if we're immediately going
1280
+ // to interrupt. Interruption will cause immediate reversion of
1281
+ // the flag, so as long as we "peek ahead", there's no need to
1282
+ // set them to begin with.
1283
+ if (runtimeFlags_.interruptible(newRuntimeFlags) && this.isInterrupted()) {
1284
+ return core.exitFailCause(this.getInterruptedCause())
1285
+ } else {
1286
+ // Impossible to short circuit, so record the changes
1287
+ this.patchRuntimeFlags(this.currentRuntimeFlags, updateFlags)
1288
+ if (op.effect_instruction_i1) {
1289
+ // Since we updated the flags, we need to revert them
1290
+ const revertFlags = runtimeFlags_.diff(newRuntimeFlags, oldRuntimeFlags)
1291
+ this.pushStack(new core.RevertFlags(revertFlags, op))
1292
+ return internalCall(() => op.effect_instruction_i1!(oldRuntimeFlags))
1293
+ } else {
1294
+ return core.exitVoid
1295
+ }
1296
+ }
1297
+ }
1298
+
1299
+ [OpCodes.OP_ON_SUCCESS](op: core.Primitive & { _op: OpCodes.OP_ON_SUCCESS }) {
1300
+ this.pushStack(op)
1301
+ return op.effect_instruction_i0
1302
+ }
1303
+
1304
+ ["OnStep"](op: core.Primitive & { _op: "OnStep" }) {
1305
+ this.pushStack(op)
1306
+ return op.effect_instruction_i0
1307
+ }
1308
+
1309
+ [OpCodes.OP_ON_FAILURE](op: core.Primitive & { _op: OpCodes.OP_ON_FAILURE }) {
1310
+ this.pushStack(op)
1311
+ return op.effect_instruction_i0
1312
+ }
1313
+
1314
+ [OpCodes.OP_ON_SUCCESS_AND_FAILURE](op: core.Primitive & { _op: OpCodes.OP_ON_SUCCESS_AND_FAILURE }) {
1315
+ this.pushStack(op)
1316
+ return op.effect_instruction_i0
1317
+ }
1318
+
1319
+ [OpCodes.OP_ASYNC](op: core.Primitive & { _op: OpCodes.OP_ASYNC }) {
1320
+ this._asyncBlockingOn = op.effect_instruction_i1
1321
+ this.initiateAsync(this.currentRuntimeFlags, op.effect_instruction_i0)
1322
+ yieldedOpChannel.currentOp = op
1323
+ return YieldedOp
1324
+ }
1325
+
1326
+ [OpCodes.OP_YIELD](op: core.Primitive & { op: OpCodes.OP_YIELD }) {
1327
+ this._isYielding = false
1328
+ yieldedOpChannel.currentOp = op
1329
+ return YieldedOp
1330
+ }
1331
+
1332
+ [OpCodes.OP_WHILE](op: core.Primitive & { _op: OpCodes.OP_WHILE }) {
1333
+ const check = op.effect_instruction_i0
1334
+ const body = op.effect_instruction_i1
1335
+ if (check()) {
1336
+ this.pushStack(op)
1337
+ return body()
1338
+ } else {
1339
+ return core.exitVoid
1340
+ }
1341
+ }
1342
+
1343
+ [OpCodes.OP_ITERATOR](op: core.Primitive & { _op: OpCodes.OP_ITERATOR }) {
1344
+ return contOpSuccess[OpCodes.OP_ITERATOR](this, op, undefined)
1345
+ }
1346
+
1347
+ [OpCodes.OP_COMMIT](op: core.Primitive & { _op: OpCodes.OP_COMMIT }) {
1348
+ return internalCall(() => op.commit())
1349
+ }
1350
+
1351
+ /**
1352
+ * The main run-loop for evaluating effects.
1353
+ *
1354
+ * **NOTE**: This method must be invoked by the fiber itself.
1355
+ */
1356
+ runLoop(effect0: Effect.Effect<any, any, any>): Exit.Exit<any, any> | YieldedOp {
1357
+ let cur: Effect.Effect<any, any, any> | YieldedOp = effect0
1358
+ this.currentOpCount = 0
1359
+
1360
+ while (true) {
1361
+ if ((this.currentRuntimeFlags & OpSupervision) !== 0) {
1362
+ this.currentSupervisor.onEffect(this, cur)
1363
+ }
1364
+ if (this._queue.length > 0) {
1365
+ cur = this.drainQueueWhileRunning(this.currentRuntimeFlags, cur)
1366
+ }
1367
+ if (!this._isYielding) {
1368
+ this.currentOpCount += 1
1369
+ const shouldYield = this.currentScheduler.shouldYield(this)
1370
+ if (shouldYield !== false) {
1371
+ this._isYielding = true
1372
+ this.currentOpCount = 0
1373
+ const oldCur = cur
1374
+ cur = core.flatMap(core.yieldNow({ priority: shouldYield }), () => oldCur)
1375
+ }
1376
+ }
1377
+ try {
1378
+ // @ts-expect-error
1379
+ cur = this.currentTracer.context(
1380
+ () => {
1381
+ if (_version !== (cur as core.Primitive)[core.EffectTypeId]._V) {
1382
+ const level = this.getFiberRef(core.currentVersionMismatchErrorLogLevel)
1383
+ if (level._tag === "Some") {
1384
+ const effectVersion = (cur as core.Primitive)[core.EffectTypeId]._V
1385
+ this.log(
1386
+ `Executing an Effect versioned ${effectVersion} with a Runtime of version ${version.getCurrentVersion()}, you may want to dedupe the effect dependencies, you can use the language service plugin to detect this at compile time: https://github.com/Effect-TS/language-service`,
1387
+ internalCause.empty,
1388
+ level
1389
+ )
1390
+ }
1391
+ }
1392
+ // @ts-expect-error
1393
+ return this[(cur as core.Primitive)._op](cur as core.Primitive)
1394
+ },
1395
+ this
1396
+ )
1397
+
1398
+ if (cur === YieldedOp) {
1399
+ const op = yieldedOpChannel.currentOp!
1400
+ if (
1401
+ op._op === OpCodes.OP_YIELD ||
1402
+ op._op === OpCodes.OP_ASYNC
1403
+ ) {
1404
+ return YieldedOp
1405
+ }
1406
+
1407
+ yieldedOpChannel.currentOp = null
1408
+ return (
1409
+ op._op === OpCodes.OP_SUCCESS ||
1410
+ op._op === OpCodes.OP_FAILURE
1411
+ ) ?
1412
+ op as unknown as Exit.Exit<A, E> :
1413
+ core.exitFailCause(internalCause.die(op))
1414
+ }
1415
+ } catch (e) {
1416
+ if (cur !== YieldedOp && !Predicate.hasProperty(cur, "_op") || !((cur as core.Primitive)._op in this)) {
1417
+ cur = core.dieMessage(`Not a valid effect: ${Inspectable.toStringUnknown(cur)}`)
1418
+ } else if (core.isInterruptedException(e)) {
1419
+ cur = core.exitFailCause(
1420
+ internalCause.sequential(internalCause.die(e), internalCause.interrupt(FiberId.none))
1421
+ )
1422
+ } else {
1423
+ cur = core.die(e)
1424
+ }
1425
+ }
1426
+ }
1427
+ }
1428
+
1429
+ run = () => {
1430
+ this.drainQueueOnCurrentThread()
1431
+ }
1432
+ }
1433
+
1434
+ // circular with Logger
1435
+
1436
+ /** @internal */
1437
+ export const currentMinimumLogLevel: FiberRef.FiberRef<LogLevel.LogLevel> = globalValue(
1438
+ "effect/FiberRef/currentMinimumLogLevel",
1439
+ () => core.fiberRefUnsafeMake<LogLevel.LogLevel>(LogLevel.fromLiteral("Info"))
1440
+ )
1441
+
1442
+ /** @internal */
1443
+ export const loggerWithConsoleLog = <M, O>(self: Logger<M, O>): Logger<M, void> =>
1444
+ internalLogger.makeLogger((opts) => {
1445
+ const services = FiberRefs.getOrDefault(opts.context, defaultServices.currentServices)
1446
+ Context.get(services, consoleTag).unsafe.log(self.log(opts))
1447
+ })
1448
+
1449
+ /** @internal */
1450
+ export const loggerWithLeveledLog = <M, O>(self: Logger<M, O>): Logger<M, void> =>
1451
+ internalLogger.makeLogger((opts) => {
1452
+ const services = FiberRefs.getOrDefault(opts.context, defaultServices.currentServices)
1453
+ const unsafeLogger = Context.get(services, consoleTag).unsafe
1454
+ switch (opts.logLevel._tag) {
1455
+ case "Debug":
1456
+ return unsafeLogger.debug(self.log(opts))
1457
+ case "Info":
1458
+ return unsafeLogger.info(self.log(opts))
1459
+ case "Trace":
1460
+ return unsafeLogger.trace(self.log(opts))
1461
+ case "Warning":
1462
+ return unsafeLogger.warn(self.log(opts))
1463
+ case "Error":
1464
+ case "Fatal":
1465
+ return unsafeLogger.error(self.log(opts))
1466
+ default:
1467
+ return unsafeLogger.log(self.log(opts))
1468
+ }
1469
+ })
1470
+
1471
+ /** @internal */
1472
+ export const loggerWithConsoleError = <M, O>(self: Logger<M, O>): Logger<M, void> =>
1473
+ internalLogger.makeLogger((opts) => {
1474
+ const services = FiberRefs.getOrDefault(opts.context, defaultServices.currentServices)
1475
+ Context.get(services, consoleTag).unsafe.error(self.log(opts))
1476
+ })
1477
+
1478
+ /** @internal */
1479
+ export const defaultLogger: Logger<unknown, void> = globalValue(
1480
+ Symbol.for("effect/Logger/defaultLogger"),
1481
+ () => loggerWithConsoleLog(internalLogger.stringLogger)
1482
+ )
1483
+
1484
+ /** @internal */
1485
+ export const jsonLogger: Logger<unknown, void> = globalValue(
1486
+ Symbol.for("effect/Logger/jsonLogger"),
1487
+ () => loggerWithConsoleLog(internalLogger.jsonLogger)
1488
+ )
1489
+
1490
+ /** @internal */
1491
+ export const logFmtLogger: Logger<unknown, void> = globalValue(
1492
+ Symbol.for("effect/Logger/logFmtLogger"),
1493
+ () => loggerWithConsoleLog(internalLogger.logfmtLogger)
1494
+ )
1495
+
1496
+ /** @internal */
1497
+ export const prettyLogger: Logger<unknown, void> = globalValue(
1498
+ Symbol.for("effect/Logger/prettyLogger"),
1499
+ () => internalLogger.prettyLoggerDefault
1500
+ )
1501
+
1502
+ /** @internal */
1503
+ export const structuredLogger: Logger<unknown, void> = globalValue(
1504
+ Symbol.for("effect/Logger/structuredLogger"),
1505
+ () => loggerWithConsoleLog(internalLogger.structuredLogger)
1506
+ )
1507
+
1508
+ /** @internal */
1509
+ export const tracerLogger = globalValue(
1510
+ Symbol.for("effect/Logger/tracerLogger"),
1511
+ () =>
1512
+ internalLogger.makeLogger<unknown, void>(({
1513
+ annotations,
1514
+ cause,
1515
+ context,
1516
+ fiberId,
1517
+ logLevel,
1518
+ message
1519
+ }) => {
1520
+ const span = Context.getOption(
1521
+ fiberRefs.getOrDefault(context, core.currentContext),
1522
+ tracer.spanTag
1523
+ )
1524
+ if (span._tag === "None" || span.value._tag === "ExternalSpan") {
1525
+ return
1526
+ }
1527
+ const clockService = Context.unsafeGet(
1528
+ fiberRefs.getOrDefault(context, defaultServices.currentServices),
1529
+ clock.clockTag
1530
+ )
1531
+
1532
+ const attributes: Record<string, unknown> = {}
1533
+ for (const [key, value] of annotations) {
1534
+ attributes[key] = value
1535
+ }
1536
+ attributes["effect.fiberId"] = FiberId.threadName(fiberId)
1537
+ attributes["effect.logLevel"] = logLevel.label
1538
+
1539
+ if (cause !== null && cause._tag !== "Empty") {
1540
+ attributes["effect.cause"] = internalCause.pretty(cause, { renderErrorCause: true })
1541
+ }
1542
+
1543
+ span.value.event(
1544
+ Inspectable.toStringUnknown(Array.isArray(message) && message.length === 1 ? message[0] : message),
1545
+ clockService.unsafeCurrentTimeNanos(),
1546
+ attributes
1547
+ )
1548
+ })
1549
+ )
1550
+
1551
+ /** @internal */
1552
+ export const loggerWithSpanAnnotations = <Message, Output>(self: Logger<Message, Output>): Logger<Message, Output> =>
1553
+ internalLogger.mapInputOptions(self, (options: Logger.Options<Message>) => {
1554
+ const span = Option.flatMap(fiberRefs.get(options.context, core.currentContext), Context.getOption(tracer.spanTag))
1555
+ if (span._tag === "None") {
1556
+ return options
1557
+ }
1558
+ return {
1559
+ ...options,
1560
+ annotations: pipe(
1561
+ options.annotations,
1562
+ HashMap.set("effect.traceId", span.value.traceId as unknown),
1563
+ HashMap.set("effect.spanId", span.value.spanId as unknown),
1564
+ span.value._tag === "Span" ? HashMap.set("effect.spanName", span.value.name as unknown) : identity
1565
+ )
1566
+ }
1567
+ })
1568
+
1569
+ /** @internal */
1570
+ export const currentLoggers: FiberRef.FiberRef<
1571
+ HashSet.HashSet<Logger<unknown, any>>
1572
+ > = globalValue(
1573
+ Symbol.for("effect/FiberRef/currentLoggers"),
1574
+ () => core.fiberRefUnsafeMakeHashSet(HashSet.make(defaultLogger, tracerLogger))
1575
+ )
1576
+
1577
+ /** @internal */
1578
+ export const batchedLogger = dual<
1579
+ <Output, R>(
1580
+ window: Duration.DurationInput,
1581
+ f: (messages: Array<NoInfer<Output>>) => Effect.Effect<void, never, R>
1582
+ ) => <Message>(
1583
+ self: Logger<Message, Output>
1584
+ ) => Effect.Effect<Logger<Message, void>, never, Scope.Scope | R>,
1585
+ <Message, Output, R>(
1586
+ self: Logger<Message, Output>,
1587
+ window: Duration.DurationInput,
1588
+ f: (messages: Array<NoInfer<Output>>) => Effect.Effect<void, never, R>
1589
+ ) => Effect.Effect<Logger<Message, void>, never, Scope.Scope | R>
1590
+ >(3, <Message, Output, R>(
1591
+ self: Logger<Message, Output>,
1592
+ window: Duration.DurationInput,
1593
+ f: (messages: Array<NoInfer<Output>>) => Effect.Effect<void, never, R>
1594
+ ): Effect.Effect<Logger<Message, void>, never, Scope.Scope | R> =>
1595
+ core.flatMap(scope, (scope) => {
1596
+ let buffer: Array<Output> = []
1597
+ const flush = core.suspend(() => {
1598
+ if (buffer.length === 0) {
1599
+ return core.void
1600
+ }
1601
+ const arr = buffer
1602
+ buffer = []
1603
+ return f(arr)
1604
+ })
1605
+
1606
+ return core.uninterruptibleMask((restore) =>
1607
+ pipe(
1608
+ internalEffect.sleep(window),
1609
+ core.zipRight(flush),
1610
+ internalEffect.forever,
1611
+ restore,
1612
+ forkDaemon,
1613
+ core.flatMap((fiber) => core.scopeAddFinalizer(scope, core.interruptFiber(fiber))),
1614
+ core.zipRight(addFinalizer(() => flush)),
1615
+ core.as(
1616
+ internalLogger.makeLogger((options) => {
1617
+ buffer.push(self.log(options))
1618
+ })
1619
+ )
1620
+ )
1621
+ )
1622
+ }))
1623
+
1624
+ export const annotateLogsScoped: {
1625
+ (key: string, value: unknown): Effect.Effect<void, never, Scope.Scope>
1626
+ (values: Record<string, unknown>): Effect.Effect<void, never, Scope.Scope>
1627
+ } = function() {
1628
+ if (typeof arguments[0] === "string") {
1629
+ return fiberRefLocallyScopedWith(
1630
+ core.currentLogAnnotations,
1631
+ HashMap.set(arguments[0], arguments[1])
1632
+ )
1633
+ }
1634
+ const entries = Object.entries(arguments[0])
1635
+ return fiberRefLocallyScopedWith(
1636
+ core.currentLogAnnotations,
1637
+ HashMap.mutate((annotations) => {
1638
+ for (let i = 0; i < entries.length; i++) {
1639
+ const [key, value] = entries[i]
1640
+ HashMap.set(annotations, key, value)
1641
+ }
1642
+ return annotations
1643
+ })
1644
+ )
1645
+ }
1646
+
1647
+ /** @internal */
1648
+ export const whenLogLevel = dual<
1649
+ (
1650
+ level: LogLevel.LogLevel | LogLevel.Literal
1651
+ ) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R>,
1652
+ <A, E, R>(
1653
+ effect: Effect.Effect<A, E, R>,
1654
+ level: LogLevel.LogLevel | LogLevel.Literal
1655
+ ) => Effect.Effect<Option.Option<A>, E, R>
1656
+ >(2, (effect, level) => {
1657
+ const requiredLogLevel = typeof level === "string" ? LogLevel.fromLiteral(level) : level
1658
+
1659
+ return core.withFiberRuntime((fiberState) => {
1660
+ const minimumLogLevel = fiberState.getFiberRef(currentMinimumLogLevel)
1661
+
1662
+ // Imitate the behaviour of `FiberRuntime.log`
1663
+ if (LogLevel.greaterThan(minimumLogLevel, requiredLogLevel)) {
1664
+ return core.succeed(Option.none())
1665
+ }
1666
+
1667
+ return core.map(effect, Option.some)
1668
+ })
1669
+ })
1670
+
1671
+ // circular with Effect
1672
+
1673
+ /* @internal */
1674
+ export const acquireRelease: {
1675
+ <A, X, R2>(
1676
+ release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<X, never, R2>
1677
+ ): <E, R>(acquire: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R2 | R | Scope.Scope>
1678
+ <A, E, R, X, R2>(
1679
+ acquire: Effect.Effect<A, E, R>,
1680
+ release: (a: A, exit: Exit.Exit<unknown, unknown>) => Effect.Effect<X, never, R2>
1681
+ ): Effect.Effect<A, E, R2 | R | Scope.Scope>
1682
+ } = dual((args) => core.isEffect(args[0]), (acquire, release) =>
1683
+ core.uninterruptible(
1684
+ core.tap(acquire, (a) => addFinalizer((exit) => release(a, exit)))
1685
+ ))
1686
+
1687
+ /* @internal */
1688
+ export const acquireReleaseInterruptible: {
1689
+ <X, R2>(
1690
+ release: (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<X, never, R2>
1691
+ ): <A, E, R>(acquire: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Scope.Scope | R2 | R>
1692
+ <A, E, R, X, R2>(
1693
+ acquire: Effect.Effect<A, E, R>,
1694
+ release: (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<X, never, R2>
1695
+ ): Effect.Effect<A, E, Scope.Scope | R2 | R>
1696
+ } = dual((args) => core.isEffect(args[0]), (acquire, release) =>
1697
+ ensuring(
1698
+ acquire,
1699
+ addFinalizer((exit) => release(exit))
1700
+ ))
1701
+
1702
+ /* @internal */
1703
+ export const addFinalizer = <X, R>(
1704
+ finalizer: (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<X, never, R>
1705
+ ): Effect.Effect<void, never, R | Scope.Scope> =>
1706
+ core.withFiberRuntime(
1707
+ (runtime) => {
1708
+ const acquireRefs = runtime.getFiberRefs()
1709
+ const acquireFlags = runtimeFlags_.disable(runtime.currentRuntimeFlags, runtimeFlags_.Interruption)
1710
+ return core.flatMap(scope, (scope) =>
1711
+ core.scopeAddFinalizerExit(scope, (exit) =>
1712
+ core.withFiberRuntime((runtimeFinalizer) => {
1713
+ const preRefs = runtimeFinalizer.getFiberRefs()
1714
+ const preFlags = runtimeFinalizer.currentRuntimeFlags
1715
+ const patchRefs = FiberRefsPatch.diff(preRefs, acquireRefs)
1716
+ const patchFlags = runtimeFlags_.diff(preFlags, acquireFlags)
1717
+ const inverseRefs = FiberRefsPatch.diff(acquireRefs, preRefs)
1718
+ runtimeFinalizer.setFiberRefs(
1719
+ FiberRefsPatch.patch(patchRefs, runtimeFinalizer.id(), acquireRefs)
1720
+ )
1721
+
1722
+ return ensuring(
1723
+ core.withRuntimeFlags(finalizer(exit) as Effect.Effect<X>, patchFlags),
1724
+ core.sync(() => {
1725
+ runtimeFinalizer.setFiberRefs(
1726
+ FiberRefsPatch.patch(inverseRefs, runtimeFinalizer.id(), runtimeFinalizer.getFiberRefs())
1727
+ )
1728
+ })
1729
+ )
1730
+ })))
1731
+ }
1732
+ )
1733
+
1734
+ /* @internal */
1735
+ export const daemonChildren = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> => {
1736
+ const forkScope = core.fiberRefLocally(core.currentForkScopeOverride, Option.some(fiberScope.globalScope))
1737
+ return forkScope(self)
1738
+ }
1739
+
1740
+ /** @internal */
1741
+ const _existsParFound = Symbol.for("effect/Effect/existsPar/found")
1742
+
1743
+ /* @internal */
1744
+ export const exists: {
1745
+ <A, E, R>(predicate: (a: A, i: number) => Effect.Effect<boolean, E, R>, options?: {
1746
+ readonly concurrency?: Concurrency | undefined
1747
+ readonly batching?: boolean | "inherit" | undefined
1748
+ readonly concurrentFinalizers?: boolean | undefined
1749
+ }): (elements: Iterable<A>) => Effect.Effect<boolean, E, R>
1750
+ <A, E, R>(elements: Iterable<A>, predicate: (a: A, i: number) => Effect.Effect<boolean, E, R>, options?: {
1751
+ readonly concurrency?: Concurrency | undefined
1752
+ readonly batching?: boolean | "inherit" | undefined
1753
+ readonly concurrentFinalizers?: boolean | undefined
1754
+ }): Effect.Effect<boolean, E, R>
1755
+ } = dual(
1756
+ (args) => Predicate.isIterable(args[0]) && !core.isEffect(args[0]),
1757
+ <A, E, R>(elements: Iterable<A>, predicate: (a: A, i: number) => Effect.Effect<boolean, E, R>, options?: {
1758
+ readonly concurrency?: Concurrency | undefined
1759
+ readonly batching?: boolean | "inherit" | undefined
1760
+ }) =>
1761
+ concurrency.matchSimple(
1762
+ options?.concurrency,
1763
+ () => core.suspend(() => existsLoop(elements[Symbol.iterator](), 0, predicate)),
1764
+ () =>
1765
+ core.matchEffect(
1766
+ forEach(
1767
+ elements,
1768
+ (a, i) => core.if_(predicate(a, i), { onTrue: () => core.fail(_existsParFound), onFalse: () => core.void }),
1769
+ options
1770
+ ),
1771
+ {
1772
+ onFailure: (e) => e === _existsParFound ? core.succeed(true) : core.fail(e),
1773
+ onSuccess: () => core.succeed(false)
1774
+ }
1775
+ )
1776
+ )
1777
+ )
1778
+
1779
+ const existsLoop = <A, E, R>(
1780
+ iterator: Iterator<A>,
1781
+ index: number,
1782
+ f: (a: A, i: number) => Effect.Effect<boolean, E, R>
1783
+ ): Effect.Effect<boolean, E, R> => {
1784
+ const next = iterator.next()
1785
+ if (next.done) {
1786
+ return core.succeed(false)
1787
+ }
1788
+ return core.flatMap(
1789
+ f(next.value, index),
1790
+ (b) => b ? core.succeed(b) : existsLoop(iterator, index + 1, f)
1791
+ )
1792
+ }
1793
+
1794
+ /* @internal */
1795
+ export const filter = dual<
1796
+ <A, E, R>(
1797
+ predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R>,
1798
+ options?: {
1799
+ readonly concurrency?: Concurrency | undefined
1800
+ readonly batching?: boolean | "inherit" | undefined
1801
+ readonly negate?: boolean | undefined
1802
+ readonly concurrentFinalizers?: boolean | undefined
1803
+ }
1804
+ ) => (elements: Iterable<A>) => Effect.Effect<Array<A>, E, R>,
1805
+ <A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R>, options?: {
1806
+ readonly concurrency?: Concurrency | undefined
1807
+ readonly batching?: boolean | "inherit" | undefined
1808
+ readonly negate?: boolean | undefined
1809
+ readonly concurrentFinalizers?: boolean | undefined
1810
+ }) => Effect.Effect<Array<A>, E, R>
1811
+ >(
1812
+ (args) => Predicate.isIterable(args[0]) && !core.isEffect(args[0]),
1813
+ <A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R>, options?: {
1814
+ readonly concurrency?: Concurrency | undefined
1815
+ readonly batching?: boolean | "inherit" | undefined
1816
+ readonly negate?: boolean | undefined
1817
+ readonly concurrentFinalizers?: boolean | undefined
1818
+ }) => {
1819
+ const predicate_ = options?.negate ? (a: A, i: number) => core.map(predicate(a, i), Boolean.not) : predicate
1820
+ return concurrency.matchSimple(
1821
+ options?.concurrency,
1822
+ () =>
1823
+ core.suspend(() =>
1824
+ RA.fromIterable(elements).reduceRight(
1825
+ (effect, a, i) =>
1826
+ core.zipWith(
1827
+ effect,
1828
+ core.suspend(() => predicate_(a, i)),
1829
+ (list, b) => b ? [a, ...list] : list
1830
+ ),
1831
+ core.sync(() => new Array<A>()) as Effect.Effect<Array<A>, E, R>
1832
+ )
1833
+ ),
1834
+ () =>
1835
+ core.map(
1836
+ forEach(
1837
+ elements,
1838
+ (a, i) => core.map(predicate_(a, i), (b) => (b ? Option.some(a) : Option.none())),
1839
+ options
1840
+ ),
1841
+ RA.getSomes
1842
+ )
1843
+ )
1844
+ }
1845
+ )
1846
+
1847
+ // === all
1848
+
1849
+ const allResolveInput = (
1850
+ input: Iterable<Effect.Effect<any, any, any>> | Record<string, Effect.Effect<any, any, any>>
1851
+ ): [Iterable<Effect.Effect<any, any, any>>, Option.Option<(as: ReadonlyArray<any>) => any>] => {
1852
+ if (Array.isArray(input) || Predicate.isIterable(input)) {
1853
+ return [input, Option.none()]
1854
+ }
1855
+ const keys = Object.keys(input)
1856
+ const size = keys.length
1857
+ return [
1858
+ keys.map((k) => input[k]),
1859
+ Option.some((values: ReadonlyArray<any>) => {
1860
+ const res = {}
1861
+ for (let i = 0; i < size; i++) {
1862
+ ;(res as any)[keys[i]] = values[i]
1863
+ }
1864
+ return res
1865
+ })
1866
+ ]
1867
+ }
1868
+
1869
+ const allValidate = (
1870
+ effects: Iterable<Effect.Effect<any, any, any>>,
1871
+ reconcile: Option.Option<(as: ReadonlyArray<any>) => any>,
1872
+ options?: {
1873
+ readonly concurrency?: Concurrency | undefined
1874
+ readonly batching?: boolean | "inherit" | undefined
1875
+ readonly discard?: boolean | undefined
1876
+ readonly mode?: "default" | "validate" | "either" | undefined
1877
+ readonly concurrentFinalizers?: boolean | undefined
1878
+ }
1879
+ ) => {
1880
+ const eitherEffects: Array<Effect.Effect<Either.Either<unknown, unknown>, never, unknown>> = []
1881
+ for (const effect of effects) {
1882
+ eitherEffects.push(core.either(effect))
1883
+ }
1884
+ return core.flatMap(
1885
+ forEach(eitherEffects, identity, {
1886
+ concurrency: options?.concurrency,
1887
+ batching: options?.batching,
1888
+ concurrentFinalizers: options?.concurrentFinalizers
1889
+ }),
1890
+ (eithers) => {
1891
+ const none = Option.none()
1892
+ const size = eithers.length
1893
+ const errors: Array<unknown> = new Array(size)
1894
+ const successes: Array<unknown> = new Array(size)
1895
+ let errored = false
1896
+ for (let i = 0; i < size; i++) {
1897
+ const either = eithers[i] as Either.Either<unknown, unknown>
1898
+ if (either._tag === "Left") {
1899
+ errors[i] = Option.some(either.left)
1900
+ errored = true
1901
+ } else {
1902
+ successes[i] = either.right
1903
+ errors[i] = none
1904
+ }
1905
+ }
1906
+ if (errored) {
1907
+ return reconcile._tag === "Some" ?
1908
+ core.fail(reconcile.value(errors)) :
1909
+ core.fail(errors)
1910
+ } else if (options?.discard) {
1911
+ return core.void
1912
+ }
1913
+ return reconcile._tag === "Some" ?
1914
+ core.succeed(reconcile.value(successes)) :
1915
+ core.succeed(successes)
1916
+ }
1917
+ )
1918
+ }
1919
+
1920
+ const allEither = (
1921
+ effects: Iterable<Effect.Effect<any, any, any>>,
1922
+ reconcile: Option.Option<(as: ReadonlyArray<any>) => any>,
1923
+ options?: {
1924
+ readonly concurrency?: Concurrency | undefined
1925
+ readonly batching?: boolean | "inherit" | undefined
1926
+ readonly discard?: boolean | undefined
1927
+ readonly mode?: "default" | "validate" | "either" | undefined
1928
+ readonly concurrentFinalizers?: boolean | undefined
1929
+ }
1930
+ ) => {
1931
+ const eitherEffects: Array<Effect.Effect<Either.Either<unknown, unknown>, never, unknown>> = []
1932
+ for (const effect of effects) {
1933
+ eitherEffects.push(core.either(effect))
1934
+ }
1935
+
1936
+ if (options?.discard) {
1937
+ return forEach(eitherEffects, identity, {
1938
+ concurrency: options?.concurrency,
1939
+ batching: options?.batching,
1940
+ discard: true,
1941
+ concurrentFinalizers: options?.concurrentFinalizers
1942
+ })
1943
+ }
1944
+
1945
+ return core.map(
1946
+ forEach(eitherEffects, identity, {
1947
+ concurrency: options?.concurrency,
1948
+ batching: options?.batching,
1949
+ concurrentFinalizers: options?.concurrentFinalizers
1950
+ }),
1951
+ (eithers) =>
1952
+ reconcile._tag === "Some" ?
1953
+ reconcile.value(eithers) :
1954
+ eithers
1955
+ )
1956
+ }
1957
+
1958
+ /* @internal */
1959
+ export const all = <
1960
+ const Arg extends Iterable<Effect.Effect<any, any, any>> | Record<string, Effect.Effect<any, any, any>>,
1961
+ O extends NoExcessProperties<{
1962
+ readonly concurrency?: Concurrency | undefined
1963
+ readonly batching?: boolean | "inherit" | undefined
1964
+ readonly discard?: boolean | undefined
1965
+ readonly mode?: "default" | "validate" | "either" | undefined
1966
+ readonly concurrentFinalizers?: boolean | undefined
1967
+ }, O>
1968
+ >(
1969
+ arg: Arg,
1970
+ options?: O
1971
+ ): Effect.All.Return<Arg, O> => {
1972
+ const [effects, reconcile] = allResolveInput(arg)
1973
+
1974
+ if (options?.mode === "validate") {
1975
+ return allValidate(effects, reconcile, options) as any
1976
+ } else if (options?.mode === "either") {
1977
+ return allEither(effects, reconcile, options) as any
1978
+ }
1979
+
1980
+ return options?.discard !== true && reconcile._tag === "Some"
1981
+ ? core.map(
1982
+ forEach(effects, identity, options as any),
1983
+ reconcile.value
1984
+ ) as any
1985
+ : forEach(effects, identity, options as any) as any
1986
+ }
1987
+
1988
+ /* @internal */
1989
+ export const allWith = <
1990
+ O extends NoExcessProperties<{
1991
+ readonly concurrency?: Concurrency | undefined
1992
+ readonly batching?: boolean | "inherit" | undefined
1993
+ readonly discard?: boolean | undefined
1994
+ readonly mode?: "default" | "validate" | "either" | undefined
1995
+ readonly concurrentFinalizers?: boolean | undefined
1996
+ }, O>
1997
+ >(options?: O) =>
1998
+ <const Arg extends Iterable<Effect.Effect<any, any, any>> | Record<string, Effect.Effect<any, any, any>>>(
1999
+ arg: Arg
2000
+ ): Effect.All.Return<Arg, O> => all(arg, options)
2001
+
2002
+ /* @internal */
2003
+ export const allSuccesses = <Eff extends Effect.Effect<any, any, any>>(
2004
+ elements: Iterable<Eff>,
2005
+ options?: {
2006
+ readonly concurrency?: Concurrency | undefined
2007
+ readonly batching?: boolean | "inherit" | undefined
2008
+ readonly concurrentFinalizers?: boolean | undefined
2009
+ }
2010
+ ): Effect.Effect<Array<Effect.Effect.Success<Eff>>, never, Effect.Effect.Context<Eff>> =>
2011
+ core.map(
2012
+ all(RA.fromIterable(elements).map(core.exit), options),
2013
+ RA.filterMap((exit) => core.exitIsSuccess(exit) ? Option.some(exit.effect_instruction_i0) : Option.none())
2014
+ )
2015
+
2016
+ /* @internal */
2017
+ export const replicate = dual<
2018
+ (n: number) => <A, E, R>(self: Effect.Effect<A, E, R>) => Array<Effect.Effect<A, E, R>>,
2019
+ <A, E, R>(self: Effect.Effect<A, E, R>, n: number) => Array<Effect.Effect<A, E, R>>
2020
+ >(2, (self, n) => Array.from({ length: n }, () => self))
2021
+
2022
+ /* @internal */
2023
+ export const replicateEffect: {
2024
+ (
2025
+ n: number,
2026
+ options?: {
2027
+ readonly concurrency?: Concurrency | undefined
2028
+ readonly batching?: boolean | "inherit" | undefined
2029
+ readonly discard?: false | undefined
2030
+ readonly concurrentFinalizers?: boolean | undefined
2031
+ }
2032
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<Array<A>, E, R>
2033
+ (
2034
+ n: number,
2035
+ options: {
2036
+ readonly concurrency?: Concurrency | undefined
2037
+ readonly batching?: boolean | "inherit" | undefined
2038
+ readonly discard: true
2039
+ readonly concurrentFinalizers?: boolean | undefined
2040
+ }
2041
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<void, E, R>
2042
+ <A, E, R>(
2043
+ self: Effect.Effect<A, E, R>,
2044
+ n: number,
2045
+ options?: {
2046
+ readonly concurrency?: Concurrency | undefined
2047
+ readonly batching?: boolean | "inherit" | undefined
2048
+ readonly discard?: false | undefined
2049
+ readonly concurrentFinalizers?: boolean | undefined
2050
+ }
2051
+ ): Effect.Effect<Array<A>, E, R>
2052
+ <A, E, R>(
2053
+ self: Effect.Effect<A, E, R>,
2054
+ n: number,
2055
+ options: {
2056
+ readonly concurrency?: Concurrency | undefined
2057
+ readonly batching?: boolean | "inherit" | undefined
2058
+ readonly discard: true
2059
+ readonly concurrentFinalizers?: boolean | undefined
2060
+ }
2061
+ ): Effect.Effect<void, E, R>
2062
+ } = dual(
2063
+ (args) => core.isEffect(args[0]),
2064
+ (self, n, options) => all(replicate(self, n), options)
2065
+ )
2066
+
2067
+ /* @internal */
2068
+ export const forEach: {
2069
+ <B, E, R, S extends Iterable<any>>(
2070
+ f: (a: RA.ReadonlyArray.Infer<S>, i: number) => Effect.Effect<B, E, R>,
2071
+ options?: {
2072
+ readonly concurrency?: Concurrency | undefined
2073
+ readonly batching?: boolean | "inherit" | undefined
2074
+ readonly discard?: false | undefined
2075
+ readonly concurrentFinalizers?: boolean | undefined
2076
+ } | undefined
2077
+ ): (
2078
+ self: S
2079
+ ) => Effect.Effect<RA.ReadonlyArray.With<S, B>, E, R>
2080
+ <A, B, E, R>(
2081
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2082
+ options: {
2083
+ readonly concurrency?: Concurrency | undefined
2084
+ readonly batching?: boolean | "inherit" | undefined
2085
+ readonly discard: true
2086
+ readonly concurrentFinalizers?: boolean | undefined
2087
+ }
2088
+ ): (self: Iterable<A>) => Effect.Effect<void, E, R>
2089
+ <A, B, E, R>(
2090
+ self: RA.NonEmptyReadonlyArray<A>,
2091
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2092
+ options?: {
2093
+ readonly concurrency?: Concurrency | undefined
2094
+ readonly batching?: boolean | "inherit" | undefined
2095
+ readonly discard?: false | undefined
2096
+ readonly concurrentFinalizers?: boolean | undefined
2097
+ } | undefined
2098
+ ): Effect.Effect<RA.NonEmptyArray<B>, E, R>
2099
+ <A, B, E, R>(
2100
+ self: Iterable<A>,
2101
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2102
+ options?: {
2103
+ readonly concurrency?: Concurrency | undefined
2104
+ readonly batching?: boolean | "inherit" | undefined
2105
+ readonly discard?: false | undefined
2106
+ readonly concurrentFinalizers?: boolean | undefined
2107
+ } | undefined
2108
+ ): Effect.Effect<Array<B>, E, R>
2109
+ <A, B, E, R>(
2110
+ self: Iterable<A>,
2111
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2112
+ options: {
2113
+ readonly concurrency?: Concurrency | undefined
2114
+ readonly batching?: boolean | "inherit" | undefined
2115
+ readonly discard: true
2116
+ readonly concurrentFinalizers?: boolean | undefined
2117
+ }
2118
+ ): Effect.Effect<void, E, R>
2119
+ } = dual((args) => Predicate.isIterable(args[0]), <A, R, E, B>(
2120
+ self: Iterable<A>,
2121
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2122
+ options?: {
2123
+ readonly concurrency?: Concurrency | undefined
2124
+ readonly batching?: boolean | "inherit" | undefined
2125
+ readonly discard?: boolean | undefined
2126
+ readonly concurrentFinalizers?: boolean | undefined
2127
+ }
2128
+ ) =>
2129
+ core.withFiberRuntime<A | void, E, R>((r) => {
2130
+ const isRequestBatchingEnabled = options?.batching === true ||
2131
+ (options?.batching === "inherit" && r.getFiberRef(core.currentRequestBatching))
2132
+
2133
+ if (options?.discard) {
2134
+ return concurrency.match(
2135
+ options.concurrency,
2136
+ () =>
2137
+ finalizersMaskInternal(ExecutionStrategy.sequential, options?.concurrentFinalizers)((restore) =>
2138
+ isRequestBatchingEnabled
2139
+ ? forEachConcurrentDiscard(self, (a, i) => restore(f(a, i)), true, false, 1)
2140
+ : core.forEachSequentialDiscard(self, (a, i) => restore(f(a, i)))
2141
+ ),
2142
+ () =>
2143
+ finalizersMaskInternal(ExecutionStrategy.parallel, options?.concurrentFinalizers)((restore) =>
2144
+ forEachConcurrentDiscard(self, (a, i) => restore(f(a, i)), isRequestBatchingEnabled, false)
2145
+ ),
2146
+ (n) =>
2147
+ finalizersMaskInternal(ExecutionStrategy.parallelN(n), options?.concurrentFinalizers)((restore) =>
2148
+ forEachConcurrentDiscard(self, (a, i) => restore(f(a, i)), isRequestBatchingEnabled, false, n)
2149
+ )
2150
+ )
2151
+ }
2152
+
2153
+ return concurrency.match(
2154
+ options?.concurrency,
2155
+ () =>
2156
+ finalizersMaskInternal(ExecutionStrategy.sequential, options?.concurrentFinalizers)((restore) =>
2157
+ isRequestBatchingEnabled
2158
+ ? forEachParN(self, 1, (a, i) => restore(f(a, i)), true)
2159
+ : core.forEachSequential(self, (a, i) => restore(f(a, i)))
2160
+ ),
2161
+ () =>
2162
+ finalizersMaskInternal(ExecutionStrategy.parallel, options?.concurrentFinalizers)((restore) =>
2163
+ forEachParUnbounded(self, (a, i) => restore(f(a, i)), isRequestBatchingEnabled)
2164
+ ),
2165
+ (n) =>
2166
+ finalizersMaskInternal(ExecutionStrategy.parallelN(n), options?.concurrentFinalizers)((restore) =>
2167
+ forEachParN(self, n, (a, i) => restore(f(a, i)), isRequestBatchingEnabled)
2168
+ )
2169
+ )
2170
+ }))
2171
+
2172
+ /* @internal */
2173
+ export const forEachParUnbounded = <A, B, E, R>(
2174
+ self: Iterable<A>,
2175
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2176
+ batching: boolean
2177
+ ): Effect.Effect<Array<B>, E, R> =>
2178
+ core.suspend(() => {
2179
+ const as = RA.fromIterable(self)
2180
+ const array = new Array<B>(as.length)
2181
+ const fn = (a: A, i: number) => core.flatMap(f(a, i), (b) => core.sync(() => array[i] = b))
2182
+ return core.zipRight(forEachConcurrentDiscard(as, fn, batching, false), core.succeed(array))
2183
+ })
2184
+
2185
+ /** @internal */
2186
+ export const forEachConcurrentDiscard = <A, X, E, R>(
2187
+ self: Iterable<A>,
2188
+ f: (a: A, i: number) => Effect.Effect<X, E, R>,
2189
+ batching: boolean,
2190
+ processAll: boolean,
2191
+ n?: number
2192
+ ): Effect.Effect<void, E, R> =>
2193
+ core.uninterruptibleMask((restore) =>
2194
+ core.transplant((graft) =>
2195
+ core.withFiberRuntime<void, E, R>((parent) => {
2196
+ let todos = Array.from(self).reverse()
2197
+ let target = todos.length
2198
+ if (target === 0) {
2199
+ return core.void
2200
+ }
2201
+ let counter = 0
2202
+ let interrupted = false
2203
+ const fibersCount = n ? Math.min(todos.length, n) : todos.length
2204
+ const fibers = new Set<FiberRuntime<Exit.Exit<X, E> | Effect.Blocked<X, E>>>()
2205
+ const results = new Array()
2206
+ const interruptAll = () =>
2207
+ fibers.forEach((fiber) => {
2208
+ fiber.currentScheduler.scheduleTask(() => {
2209
+ fiber.unsafeInterruptAsFork(parent.id())
2210
+ }, 0)
2211
+ })
2212
+ const startOrder = new Array<FiberRuntime<Exit.Exit<X, E> | Effect.Blocked<X, E>>>()
2213
+ const joinOrder = new Array<FiberRuntime<Exit.Exit<X, E> | Effect.Blocked<X, E>>>()
2214
+ const residual = new Array<core.Blocked>()
2215
+ const collectExits = () => {
2216
+ const exits: Array<Exit.Exit<any, E>> = results
2217
+ .filter(({ exit }) => exit._tag === "Failure")
2218
+ .sort((a, b) => a.index < b.index ? -1 : a.index === b.index ? 0 : 1)
2219
+ .map(({ exit }) => exit)
2220
+ if (exits.length === 0) {
2221
+ exits.push(core.exitVoid)
2222
+ }
2223
+ return exits
2224
+ }
2225
+ const runFiber = <A, E, R>(eff: Effect.Effect<A, E, R>, interruptImmediately = false) => {
2226
+ const runnable = core.uninterruptible(graft(eff))
2227
+ const fiber = unsafeForkUnstarted(
2228
+ runnable,
2229
+ parent,
2230
+ parent.currentRuntimeFlags,
2231
+ fiberScope.globalScope
2232
+ )
2233
+ parent.currentScheduler.scheduleTask(() => {
2234
+ if (interruptImmediately) {
2235
+ fiber.unsafeInterruptAsFork(parent.id())
2236
+ }
2237
+ fiber.resume(runnable)
2238
+ }, 0)
2239
+ return fiber
2240
+ }
2241
+ const onInterruptSignal = () => {
2242
+ if (!processAll) {
2243
+ target -= todos.length
2244
+ todos = []
2245
+ }
2246
+ interrupted = true
2247
+ interruptAll()
2248
+ }
2249
+ const stepOrExit = batching ? core.step : core.exit
2250
+ const processingFiber = runFiber(
2251
+ core.async<any, any, any>((resume) => {
2252
+ const pushResult = <X, E>(res: Exit.Exit<X, E> | Effect.Blocked<X, E>, index: number) => {
2253
+ if (res._op === "Blocked") {
2254
+ residual.push(res as core.Blocked)
2255
+ } else {
2256
+ results.push({ index, exit: res })
2257
+ if (res._op === "Failure" && !interrupted) {
2258
+ onInterruptSignal()
2259
+ }
2260
+ }
2261
+ }
2262
+ const next = () => {
2263
+ if (todos.length > 0) {
2264
+ const a = todos.pop()!
2265
+ let index = counter++
2266
+ const returnNextElement = () => {
2267
+ const a = todos.pop()!
2268
+ index = counter++
2269
+ return core.flatMap(core.yieldNow(), () =>
2270
+ core.flatMap(
2271
+ stepOrExit(restore(f(a, index))),
2272
+ onRes
2273
+ ))
2274
+ }
2275
+ const onRes = (
2276
+ res: Exit.Exit<X, E> | Effect.Blocked<X, E>
2277
+ ): Effect.Effect<Exit.Exit<X, E> | Effect.Blocked<X, E>, never, R> => {
2278
+ if (todos.length > 0) {
2279
+ pushResult(res, index)
2280
+ if (todos.length > 0) {
2281
+ return returnNextElement()
2282
+ }
2283
+ }
2284
+ return core.succeed(res)
2285
+ }
2286
+ const todo = core.flatMap(
2287
+ stepOrExit(restore(f(a, index))),
2288
+ onRes
2289
+ )
2290
+ const fiber = runFiber(todo)
2291
+ startOrder.push(fiber)
2292
+ fibers.add(fiber)
2293
+ if (interrupted) {
2294
+ fiber.currentScheduler.scheduleTask(() => {
2295
+ fiber.unsafeInterruptAsFork(parent.id())
2296
+ }, 0)
2297
+ }
2298
+ fiber.addObserver((wrapped) => {
2299
+ let exit: Exit.Exit<any, any> | core.Blocked
2300
+ if (wrapped._op === "Failure") {
2301
+ exit = wrapped
2302
+ } else {
2303
+ exit = wrapped.effect_instruction_i0 as any
2304
+ }
2305
+ joinOrder.push(fiber)
2306
+ fibers.delete(fiber)
2307
+ pushResult(exit, index)
2308
+ if (results.length === target) {
2309
+ resume(core.succeed(Option.getOrElse(
2310
+ core.exitCollectAll(collectExits(), { parallel: true }),
2311
+ () => core.exitVoid
2312
+ )))
2313
+ } else if (residual.length + results.length === target) {
2314
+ const exits = collectExits()
2315
+ const requests = residual.map((blocked) => blocked.effect_instruction_i0).reduce(RequestBlock_.par)
2316
+ resume(core.succeed(core.blocked(
2317
+ requests,
2318
+ forEachConcurrentDiscard(
2319
+ [
2320
+ Option.getOrElse(
2321
+ core.exitCollectAll(exits, { parallel: true }),
2322
+ () => core.exitVoid
2323
+ ),
2324
+ ...residual.map((blocked) => blocked.effect_instruction_i1)
2325
+ ],
2326
+ (i) => i,
2327
+ batching,
2328
+ true,
2329
+ n
2330
+ )
2331
+ )))
2332
+ } else {
2333
+ next()
2334
+ }
2335
+ })
2336
+ }
2337
+ }
2338
+ for (let i = 0; i < fibersCount; i++) {
2339
+ next()
2340
+ }
2341
+ })
2342
+ )
2343
+ return core.asVoid(
2344
+ core.onExit(
2345
+ core.flatten(restore(internalFiber.join(processingFiber))),
2346
+ core.exitMatch({
2347
+ onFailure: (cause) => {
2348
+ onInterruptSignal()
2349
+ const target = residual.length + 1
2350
+ const concurrency = Math.min(typeof n === "number" ? n : residual.length, residual.length)
2351
+ const toPop = Array.from(residual)
2352
+ return core.async<any, any>((cb) => {
2353
+ const exits: Array<Exit.Exit<any, any>> = []
2354
+ let count = 0
2355
+ let index = 0
2356
+ const check = (index: number, hitNext: boolean) => (exit: Exit.Exit<any, any>) => {
2357
+ exits[index] = exit
2358
+ count++
2359
+ if (count === target) {
2360
+ cb(core.exitSucceed(core.exitFailCause(cause)))
2361
+ }
2362
+ if (toPop.length > 0 && hitNext) {
2363
+ next()
2364
+ }
2365
+ }
2366
+ const next = () => {
2367
+ runFiber(toPop.pop()!, true).addObserver(check(index, true))
2368
+ index++
2369
+ }
2370
+ processingFiber.addObserver(check(index, false))
2371
+ index++
2372
+ for (let i = 0; i < concurrency; i++) {
2373
+ next()
2374
+ }
2375
+ }) as any
2376
+ },
2377
+ onSuccess: () => core.forEachSequential(joinOrder, (f) => f.inheritAll)
2378
+ })
2379
+ )
2380
+ )
2381
+ })
2382
+ )
2383
+ )
2384
+
2385
+ /* @internal */
2386
+ export const forEachParN = <A, B, E, R>(
2387
+ self: Iterable<A>,
2388
+ n: number,
2389
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2390
+ batching: boolean
2391
+ ): Effect.Effect<Array<B>, E, R> =>
2392
+ core.suspend(() => {
2393
+ const as = RA.fromIterable(self)
2394
+ const array = new Array<B>(as.length)
2395
+ const fn = (a: A, i: number) => core.map(f(a, i), (b) => array[i] = b)
2396
+ return core.zipRight(forEachConcurrentDiscard(as, fn, batching, false, n), core.succeed(array))
2397
+ })
2398
+
2399
+ /* @internal */
2400
+ export const fork = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Fiber.RuntimeFiber<A, E>, never, R> =>
2401
+ core.withFiberRuntime((state, status) => core.succeed(unsafeFork(self, state, status.runtimeFlags)))
2402
+
2403
+ /* @internal */
2404
+ export const forkDaemon = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Fiber.RuntimeFiber<A, E>, never, R> =>
2405
+ forkWithScopeOverride(self, fiberScope.globalScope)
2406
+
2407
+ /* @internal */
2408
+ export const forkWithErrorHandler = dual<
2409
+ <E, X>(
2410
+ handler: (e: E) => Effect.Effect<X>
2411
+ ) => <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<Fiber.RuntimeFiber<A, E>, never, R>,
2412
+ <A, E, R, X>(
2413
+ self: Effect.Effect<A, E, R>,
2414
+ handler: (e: E) => Effect.Effect<X>
2415
+ ) => Effect.Effect<Fiber.RuntimeFiber<A, E>, never, R>
2416
+ >(2, (self, handler) =>
2417
+ fork(core.onError(self, (cause) => {
2418
+ const either = internalCause.failureOrCause(cause)
2419
+ switch (either._tag) {
2420
+ case "Left":
2421
+ return handler(either.left)
2422
+ case "Right":
2423
+ return core.failCause(either.right)
2424
+ }
2425
+ })))
2426
+
2427
+ /** @internal */
2428
+ export const unsafeFork = <A, E, R, E2, B>(
2429
+ effect: Effect.Effect<A, E, R>,
2430
+ parentFiber: FiberRuntime<B, E2>,
2431
+ parentRuntimeFlags: RuntimeFlags.RuntimeFlags,
2432
+ overrideScope: fiberScope.FiberScope | null = null
2433
+ ): FiberRuntime<A, E> => {
2434
+ const childFiber = unsafeMakeChildFiber(effect, parentFiber, parentRuntimeFlags, overrideScope)
2435
+ childFiber.resume(effect)
2436
+ return childFiber
2437
+ }
2438
+
2439
+ /** @internal */
2440
+ export const unsafeForkUnstarted = <A, E, R, E2, B>(
2441
+ effect: Effect.Effect<A, E, R>,
2442
+ parentFiber: FiberRuntime<B, E2>,
2443
+ parentRuntimeFlags: RuntimeFlags.RuntimeFlags,
2444
+ overrideScope: fiberScope.FiberScope | null = null
2445
+ ): FiberRuntime<A, E> => {
2446
+ const childFiber = unsafeMakeChildFiber(effect, parentFiber, parentRuntimeFlags, overrideScope)
2447
+ return childFiber
2448
+ }
2449
+
2450
+ /** @internal */
2451
+ export const unsafeMakeChildFiber = <A, E, R, E2, B>(
2452
+ effect: Effect.Effect<A, E, R>,
2453
+ parentFiber: FiberRuntime<B, E2>,
2454
+ parentRuntimeFlags: RuntimeFlags.RuntimeFlags,
2455
+ overrideScope: fiberScope.FiberScope | null = null
2456
+ ): FiberRuntime<A, E> => {
2457
+ const childId = FiberId.unsafeMake()
2458
+ const parentFiberRefs = parentFiber.getFiberRefs()
2459
+ const childFiberRefs = fiberRefs.forkAs(parentFiberRefs, childId)
2460
+ const childFiber = new FiberRuntime<A, E>(childId, childFiberRefs, parentRuntimeFlags)
2461
+ const childContext = fiberRefs.getOrDefault(
2462
+ childFiberRefs,
2463
+ core.currentContext as unknown as FiberRef.FiberRef<Context.Context<R>>
2464
+ )
2465
+ const supervisor = childFiber.currentSupervisor
2466
+
2467
+ supervisor.onStart(
2468
+ childContext,
2469
+ effect,
2470
+ Option.some(parentFiber),
2471
+ childFiber
2472
+ )
2473
+
2474
+ childFiber.addObserver((exit) => supervisor.onEnd(exit, childFiber))
2475
+
2476
+ const parentScope = overrideScope !== null ? overrideScope : pipe(
2477
+ parentFiber.getFiberRef(core.currentForkScopeOverride),
2478
+ Option.getOrElse(() => parentFiber.scope())
2479
+ )
2480
+
2481
+ parentScope.add(parentRuntimeFlags, childFiber)
2482
+
2483
+ return childFiber
2484
+ }
2485
+
2486
+ /* @internal */
2487
+ const forkWithScopeOverride = <A, E, R>(
2488
+ self: Effect.Effect<A, E, R>,
2489
+ scopeOverride: fiberScope.FiberScope
2490
+ ): Effect.Effect<Fiber.RuntimeFiber<A, E>, never, R> =>
2491
+ core.withFiberRuntime((parentFiber, parentStatus) =>
2492
+ core.succeed(unsafeFork(self, parentFiber, parentStatus.runtimeFlags, scopeOverride))
2493
+ )
2494
+
2495
+ /* @internal */
2496
+ export const mergeAll = dual<
2497
+ <Z, Eff extends Effect.Effect<any, any, any>>(
2498
+ zero: Z,
2499
+ f: (z: Z, a: Effect.Effect.Success<Eff>, i: number) => Z,
2500
+ options?: {
2501
+ readonly concurrency?: Concurrency | undefined
2502
+ readonly batching?: boolean | "inherit" | undefined
2503
+ readonly concurrentFinalizers?: boolean | undefined
2504
+ }
2505
+ ) => (elements: Iterable<Eff>) => Effect.Effect<Z, Effect.Effect.Error<Eff>, Effect.Effect.Context<Eff>>,
2506
+ <Eff extends Effect.Effect<any, any, any>, Z>(
2507
+ elements: Iterable<Eff>,
2508
+ zero: Z,
2509
+ f: (z: Z, a: Effect.Effect.Success<Eff>, i: number) => Z,
2510
+ options?: {
2511
+ readonly concurrency?: Concurrency | undefined
2512
+ readonly batching?: boolean | "inherit" | undefined
2513
+ readonly concurrentFinalizers?: boolean | undefined
2514
+ }
2515
+ ) => Effect.Effect<Z, Effect.Effect.Error<Eff>, Effect.Effect.Context<Eff>>
2516
+ >(
2517
+ (args) => Predicate.isFunction(args[2]),
2518
+ <A, E, R, Z>(elements: Iterable<Effect.Effect<A, E, R>>, zero: Z, f: (z: Z, a: A, i: number) => Z, options?: {
2519
+ readonly concurrency?: Concurrency | undefined
2520
+ readonly batching?: boolean | "inherit" | undefined
2521
+ readonly concurrentFinalizers?: boolean | undefined
2522
+ }) =>
2523
+ concurrency.matchSimple(
2524
+ options?.concurrency,
2525
+ () =>
2526
+ RA.fromIterable(elements).reduce(
2527
+ (acc, a, i) => core.zipWith(acc, a, (acc, a) => f(acc, a, i)),
2528
+ core.succeed(zero) as Effect.Effect<Z, E, R>
2529
+ ),
2530
+ () =>
2531
+ core.flatMap(Ref.make(zero), (acc) =>
2532
+ core.flatMap(
2533
+ forEach(
2534
+ elements,
2535
+ (effect, i) => core.flatMap(effect, (a) => Ref.update(acc, (b) => f(b, a, i))),
2536
+ options
2537
+ ),
2538
+ () => Ref.get(acc)
2539
+ ))
2540
+ )
2541
+ )
2542
+
2543
+ /* @internal */
2544
+ export const partition = dual<
2545
+ <A, B, E, R>(
2546
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2547
+ options?: {
2548
+ readonly concurrency?: Concurrency | undefined
2549
+ readonly batching?: boolean | "inherit" | undefined
2550
+ readonly concurrentFinalizers?: boolean | undefined
2551
+ }
2552
+ ) => (elements: Iterable<A>) => Effect.Effect<[excluded: Array<E>, satisfying: Array<B>], never, R>,
2553
+ <A, B, E, R>(
2554
+ elements: Iterable<A>,
2555
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2556
+ options?: {
2557
+ readonly concurrency?: Concurrency | undefined
2558
+ readonly batching?: boolean | "inherit" | undefined
2559
+ readonly concurrentFinalizers?: boolean | undefined
2560
+ }
2561
+ ) => Effect.Effect<[excluded: Array<E>, satisfying: Array<B>], never, R>
2562
+ >((args) => Predicate.isIterable(args[0]), (elements, f, options) =>
2563
+ pipe(
2564
+ forEach(elements, (a, i) => core.either(f(a, i)), options),
2565
+ core.map((chunk) => core.partitionMap(chunk, identity))
2566
+ ))
2567
+
2568
+ /* @internal */
2569
+ export const validateAll = dual<
2570
+ {
2571
+ <A, B, E, R>(
2572
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2573
+ options?: {
2574
+ readonly concurrency?: Concurrency | undefined
2575
+ readonly batching?: boolean | "inherit" | undefined
2576
+ readonly discard?: false | undefined
2577
+ readonly concurrentFinalizers?: boolean | undefined
2578
+ }
2579
+ ): (elements: Iterable<A>) => Effect.Effect<Array<B>, RA.NonEmptyArray<E>, R>
2580
+ <A, B, E, R>(
2581
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2582
+ options: {
2583
+ readonly concurrency?: Concurrency | undefined
2584
+ readonly batching?: boolean | "inherit" | undefined
2585
+ readonly discard: true
2586
+ readonly concurrentFinalizers?: boolean | undefined
2587
+ }
2588
+ ): (elements: Iterable<A>) => Effect.Effect<void, RA.NonEmptyArray<E>, R>
2589
+ },
2590
+ {
2591
+ <A, B, E, R>(
2592
+ elements: Iterable<A>,
2593
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2594
+ options?: {
2595
+ readonly concurrency?: Concurrency | undefined
2596
+ readonly batching?: boolean | "inherit" | undefined
2597
+ readonly discard?: false | undefined
2598
+ readonly concurrentFinalizers?: boolean | undefined
2599
+ }
2600
+ ): Effect.Effect<Array<B>, RA.NonEmptyArray<E>, R>
2601
+ <A, B, E, R>(
2602
+ elements: Iterable<A>,
2603
+ f: (a: A, i: number) => Effect.Effect<B, E, R>,
2604
+ options: {
2605
+ readonly concurrency?: Concurrency | undefined
2606
+ readonly batching?: boolean | "inherit" | undefined
2607
+ readonly discard: true
2608
+ readonly concurrentFinalizers?: boolean | undefined
2609
+ }
2610
+ ): Effect.Effect<void, RA.NonEmptyArray<E>, R>
2611
+ }
2612
+ >(
2613
+ (args) => Predicate.isIterable(args[0]),
2614
+ <A, B, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect.Effect<B, E, R>, options?: {
2615
+ readonly concurrency?: Concurrency | undefined
2616
+ readonly batching?: boolean | "inherit" | undefined
2617
+ readonly discard?: boolean | undefined
2618
+ readonly concurrentFinalizers?: boolean | undefined
2619
+ }): Effect.Effect<any, RA.NonEmptyArray<E>, R> =>
2620
+ core.flatMap(
2621
+ partition(elements, f, {
2622
+ concurrency: options?.concurrency,
2623
+ batching: options?.batching,
2624
+ concurrentFinalizers: options?.concurrentFinalizers
2625
+ }),
2626
+ ([es, bs]) =>
2627
+ RA.isNonEmptyArray(es)
2628
+ ? core.fail(es)
2629
+ : options?.discard
2630
+ ? core.void
2631
+ : core.succeed(bs)
2632
+ )
2633
+ )
2634
+
2635
+ /* @internal */
2636
+ export const raceAll: <Eff extends Effect.Effect<any, any, any>>(
2637
+ all: Iterable<Eff>
2638
+ ) => Effect.Effect<Effect.Effect.Success<Eff>, Effect.Effect.Error<Eff>, Effect.Effect.Context<Eff>> = <
2639
+ A,
2640
+ E,
2641
+ R
2642
+ >(all: Iterable<Effect.Effect<A, E, R>>): Effect.Effect<A, E, R> =>
2643
+ core.withFiberRuntime((state, status) =>
2644
+ core.async<A, E, R>((resume) => {
2645
+ const fibers = new Set<FiberRuntime<A, E>>()
2646
+ let winner: FiberRuntime<A, E> | undefined
2647
+ let failures: Cause.Cause<E> = internalCause.empty
2648
+ const interruptAll = () => {
2649
+ for (const fiber of fibers) {
2650
+ fiber.unsafeInterruptAsFork(state.id())
2651
+ }
2652
+ }
2653
+ let latch = false
2654
+ let empty = true
2655
+ for (const self of all) {
2656
+ empty = false
2657
+ const fiber = unsafeFork(
2658
+ core.interruptible(self),
2659
+ state,
2660
+ status.runtimeFlags
2661
+ )
2662
+ fibers.add(fiber)
2663
+ fiber.addObserver((exit) => {
2664
+ fibers.delete(fiber)
2665
+ if (!winner) {
2666
+ if (exit._tag === "Success") {
2667
+ latch = true
2668
+ winner = fiber
2669
+ failures = internalCause.empty
2670
+ interruptAll()
2671
+ } else {
2672
+ failures = internalCause.parallel(exit.cause, failures)
2673
+ }
2674
+ }
2675
+ if (latch && fibers.size === 0) {
2676
+ resume(
2677
+ winner ? core.zipRight(internalFiber.inheritAll(winner), winner.unsafePoll()!) : core.failCause(failures)
2678
+ )
2679
+ }
2680
+ })
2681
+ if (winner) break
2682
+ }
2683
+ if (empty) {
2684
+ return resume(core.dieSync(() => new core.IllegalArgumentException(`Received an empty collection of effects`)))
2685
+ }
2686
+ latch = true
2687
+ return internalFiber.interruptAllAs(fibers, state.id())
2688
+ })
2689
+ )
2690
+
2691
+ /* @internal */
2692
+ export const reduceEffect = dual<
2693
+ <Z, E, R, Eff extends Effect.Effect<any, any, any>>(
2694
+ zero: Effect.Effect<Z, E, R>,
2695
+ f: (z: NoInfer<Z>, a: Effect.Effect.Success<Eff>, i: number) => Z,
2696
+ options?: {
2697
+ readonly concurrency?: Concurrency | undefined
2698
+ readonly batching?: boolean | "inherit" | undefined
2699
+ readonly concurrentFinalizers?: boolean | undefined
2700
+ }
2701
+ ) => (elements: Iterable<Eff>) => Effect.Effect<Z, E | Effect.Effect.Error<Eff>, R | Effect.Effect.Context<Eff>>,
2702
+ <Eff extends Effect.Effect<any, any, any>, Z, E, R>(
2703
+ elements: Iterable<Eff>,
2704
+ zero: Effect.Effect<Z, E, R>,
2705
+ f: (z: NoInfer<Z>, a: Effect.Effect.Success<Eff>, i: number) => Z,
2706
+ options?: {
2707
+ readonly concurrency?: Concurrency | undefined
2708
+ readonly batching?: boolean | "inherit" | undefined
2709
+ readonly concurrentFinalizers?: boolean | undefined
2710
+ }
2711
+ ) => Effect.Effect<Z, E | Effect.Effect.Error<Eff>, R | Effect.Effect.Context<Eff>>
2712
+ >((args) => Predicate.isIterable(args[0]) && !core.isEffect(args[0]), <A, E, R, Z>(
2713
+ elements: Iterable<Effect.Effect<A, E, R>>,
2714
+ zero: Effect.Effect<Z, E, R>,
2715
+ f: (z: NoInfer<Z>, a: NoInfer<A>, i: number) => Z,
2716
+ options?: {
2717
+ readonly concurrency?: Concurrency | undefined
2718
+ readonly batching?: boolean | "inherit" | undefined
2719
+ readonly concurrentFinalizers?: boolean | undefined
2720
+ }
2721
+ ) =>
2722
+ concurrency.matchSimple(
2723
+ options?.concurrency,
2724
+ () => RA.fromIterable(elements).reduce((acc, a, i) => core.zipWith(acc, a, (acc, a) => f(acc, a, i)), zero),
2725
+ () =>
2726
+ core.suspend(() =>
2727
+ pipe(
2728
+ mergeAll(
2729
+ [zero, ...elements],
2730
+ Option.none<Z>(),
2731
+ (acc, elem, i) => {
2732
+ switch (acc._tag) {
2733
+ case "None": {
2734
+ return Option.some(elem as Z)
2735
+ }
2736
+ case "Some": {
2737
+ return Option.some(f(acc.value, elem as A, i))
2738
+ }
2739
+ }
2740
+ },
2741
+ options
2742
+ ),
2743
+ core.map((option) => {
2744
+ switch (option._tag) {
2745
+ case "None": {
2746
+ throw new Error(
2747
+ "BUG: Effect.reduceEffect - please report an issue at https://github.com/Effect-TS/effect/issues"
2748
+ )
2749
+ }
2750
+ case "Some": {
2751
+ return option.value
2752
+ }
2753
+ }
2754
+ })
2755
+ )
2756
+ )
2757
+ ))
2758
+
2759
+ /* @internal */
2760
+ export const parallelFinalizers = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
2761
+ core.contextWithEffect((context) =>
2762
+ Option.match(Context.getOption(context, scopeTag), {
2763
+ onNone: () => self,
2764
+ onSome: (scope) => {
2765
+ switch (scope.strategy._tag) {
2766
+ case "Parallel":
2767
+ return self
2768
+ case "Sequential":
2769
+ case "ParallelN":
2770
+ return core.flatMap(
2771
+ core.scopeFork(scope, ExecutionStrategy.parallel),
2772
+ (inner) => scopeExtend(self, inner)
2773
+ )
2774
+ }
2775
+ }
2776
+ })
2777
+ )
2778
+
2779
+ /* @internal */
2780
+ export const parallelNFinalizers =
2781
+ (parallelism: number) => <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
2782
+ core.contextWithEffect((context) =>
2783
+ Option.match(Context.getOption(context, scopeTag), {
2784
+ onNone: () => self,
2785
+ onSome: (scope) => {
2786
+ if (scope.strategy._tag === "ParallelN" && scope.strategy.parallelism === parallelism) {
2787
+ return self
2788
+ }
2789
+ return core.flatMap(
2790
+ core.scopeFork(scope, ExecutionStrategy.parallelN(parallelism)),
2791
+ (inner) => scopeExtend(self, inner)
2792
+ )
2793
+ }
2794
+ })
2795
+ )
2796
+
2797
+ /* @internal */
2798
+ export const finalizersMask = (strategy: ExecutionStrategy.ExecutionStrategy) =>
2799
+ <A, E, R>(
2800
+ self: (
2801
+ restore: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1>
2802
+ ) => Effect.Effect<A, E, R>
2803
+ ): Effect.Effect<A, E, R> => finalizersMaskInternal(strategy, true)(self)
2804
+
2805
+ /* @internal */
2806
+ export const finalizersMaskInternal =
2807
+ (strategy: ExecutionStrategy.ExecutionStrategy, concurrentFinalizers?: boolean | undefined) =>
2808
+ <A, E, R>(
2809
+ self: (
2810
+ restore: <A1, E1, R1>(self: Effect.Effect<A1, E1, R1>) => Effect.Effect<A1, E1, R1>
2811
+ ) => Effect.Effect<A, E, R>
2812
+ ): Effect.Effect<A, E, R> =>
2813
+ core.contextWithEffect((context) =>
2814
+ Option.match(Context.getOption(context, scopeTag), {
2815
+ onNone: () => self(identity),
2816
+ onSome: (scope) => {
2817
+ if (concurrentFinalizers === true) {
2818
+ const patch = strategy._tag === "Parallel"
2819
+ ? parallelFinalizers
2820
+ : strategy._tag === "Sequential"
2821
+ ? sequentialFinalizers
2822
+ : parallelNFinalizers(strategy.parallelism)
2823
+ switch (scope.strategy._tag) {
2824
+ case "Parallel":
2825
+ return patch(self(parallelFinalizers))
2826
+ case "Sequential":
2827
+ return patch(self(sequentialFinalizers))
2828
+ case "ParallelN":
2829
+ return patch(self(parallelNFinalizers(scope.strategy.parallelism)))
2830
+ }
2831
+ } else {
2832
+ return self(identity)
2833
+ }
2834
+ }
2835
+ })
2836
+ )
2837
+
2838
+ /* @internal */
2839
+ export const scopeWith = <A, E, R>(
2840
+ f: (scope: Scope.Scope) => Effect.Effect<A, E, R>
2841
+ ): Effect.Effect<A, E, R | Scope.Scope> => core.flatMap(scopeTag, f)
2842
+
2843
+ /** @internal */
2844
+ export const scopedWith = <A, E, R>(
2845
+ f: (scope: Scope.Scope) => Effect.Effect<A, E, R>
2846
+ ): Effect.Effect<A, E, R> => core.flatMap(scopeMake(), (scope) => core.onExit(f(scope), (exit) => scope.close(exit)))
2847
+
2848
+ /* @internal */
2849
+ export const scopedEffect = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, Exclude<R, Scope.Scope>> =>
2850
+ core.flatMap(scopeMake(), (scope) => scopeUse(effect, scope))
2851
+
2852
+ /* @internal */
2853
+ export const sequentialFinalizers = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
2854
+ core.contextWithEffect((context) =>
2855
+ Option.match(Context.getOption(context, scopeTag), {
2856
+ onNone: () => self,
2857
+ onSome: (scope) => {
2858
+ switch (scope.strategy._tag) {
2859
+ case "Sequential":
2860
+ return self
2861
+ case "Parallel":
2862
+ case "ParallelN":
2863
+ return core.flatMap(
2864
+ core.scopeFork(scope, ExecutionStrategy.sequential),
2865
+ (inner) => scopeExtend(self, inner)
2866
+ )
2867
+ }
2868
+ }
2869
+ })
2870
+ )
2871
+
2872
+ /* @internal */
2873
+ export const tagMetricsScoped = (key: string, value: string): Effect.Effect<void, never, Scope.Scope> =>
2874
+ labelMetricsScoped([metricLabel.make(key, value)])
2875
+
2876
+ /* @internal */
2877
+ export const labelMetricsScoped = (
2878
+ labels: Iterable<MetricLabel.MetricLabel>
2879
+ ): Effect.Effect<void, never, Scope.Scope> =>
2880
+ fiberRefLocallyScopedWith(core.currentMetricLabels, (old) => RA.union(old, labels))
2881
+
2882
+ /* @internal */
2883
+ export const using = dual<
2884
+ <A, A2, E2, R2>(
2885
+ use: (a: A) => Effect.Effect<A2, E2, R2>
2886
+ ) => <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2, E | E2, Exclude<R, Scope.Scope> | R2>,
2887
+ <A, E, R, A2, E2, R2>(
2888
+ self: Effect.Effect<A, E, R>,
2889
+ use: (a: A) => Effect.Effect<A2, E2, R2>
2890
+ ) => Effect.Effect<A2, E | E2, Exclude<R, Scope.Scope> | R2>
2891
+ >(2, (self, use) => scopedWith((scope) => core.flatMap(scopeExtend(self, scope), use)))
2892
+
2893
+ /** @internal */
2894
+ export const validate = dual<
2895
+ <B, E1, R1>(
2896
+ that: Effect.Effect<B, E1, R1>,
2897
+ options?: {
2898
+ readonly concurrent?: boolean | undefined
2899
+ readonly batching?: boolean | "inherit" | undefined
2900
+ readonly concurrentFinalizers?: boolean | undefined
2901
+ }
2902
+ ) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<[A, B], E | E1, R | R1>,
2903
+ <A, E, R, B, E1, R1>(
2904
+ self: Effect.Effect<A, E, R>,
2905
+ that: Effect.Effect<B, E1, R1>,
2906
+ options?: {
2907
+ readonly concurrent?: boolean | undefined
2908
+ readonly batching?: boolean | "inherit" | undefined
2909
+ readonly concurrentFinalizers?: boolean | undefined
2910
+ }
2911
+ ) => Effect.Effect<[A, B], E | E1, R | R1>
2912
+ >(
2913
+ (args) => core.isEffect(args[1]),
2914
+ (self, that, options) => validateWith(self, that, (a, b) => [a, b], options)
2915
+ )
2916
+
2917
+ /** @internal */
2918
+ export const validateWith = dual<
2919
+ <B, E1, R1, A, C>(
2920
+ that: Effect.Effect<B, E1, R1>,
2921
+ f: (a: A, b: B) => C,
2922
+ options?: {
2923
+ readonly concurrent?: boolean | undefined
2924
+ readonly batching?: boolean | "inherit" | undefined
2925
+ readonly concurrentFinalizers?: boolean | undefined
2926
+ }
2927
+ ) => <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<C, E | E1, R | R1>,
2928
+ <A, E, R, B, E1, R1, C>(
2929
+ self: Effect.Effect<A, E, R>,
2930
+ that: Effect.Effect<B, E1, R1>,
2931
+ f: (a: A, b: B) => C,
2932
+ options?: {
2933
+ readonly concurrent?: boolean | undefined
2934
+ readonly batching?: boolean | "inherit" | undefined
2935
+ readonly concurrentFinalizers?: boolean | undefined
2936
+ }
2937
+ ) => Effect.Effect<C, E | E1, R | R1>
2938
+ >((args) => core.isEffect(args[1]), (self, that, f, options) =>
2939
+ core.flatten(zipWithOptions(
2940
+ core.exit(self),
2941
+ core.exit(that),
2942
+ (ea, eb) =>
2943
+ core.exitZipWith(ea, eb, {
2944
+ onSuccess: f,
2945
+ onFailure: (ca, cb) => options?.concurrent ? internalCause.parallel(ca, cb) : internalCause.sequential(ca, cb)
2946
+ }),
2947
+ options
2948
+ )))
2949
+
2950
+ /* @internal */
2951
+ export const validateAllPar = dual<
2952
+ <A, B, E, R>(
2953
+ f: (a: A) => Effect.Effect<B, E, R>
2954
+ ) => (elements: Iterable<A>) => Effect.Effect<Array<B>, Array<E>, R>,
2955
+ <A, B, E, R>(
2956
+ elements: Iterable<A>,
2957
+ f: (a: A) => Effect.Effect<B, E, R>
2958
+ ) => Effect.Effect<Array<B>, Array<E>, R>
2959
+ >(2, (elements, f) =>
2960
+ core.flatMap(
2961
+ partition(elements, f),
2962
+ ([es, bs]) =>
2963
+ es.length === 0
2964
+ ? core.succeed(bs)
2965
+ : core.fail(es)
2966
+ ))
2967
+
2968
+ /* @internal */
2969
+ export const validateAllParDiscard = dual<
2970
+ <A, B, E, R>(
2971
+ f: (a: A) => Effect.Effect<B, E, R>
2972
+ ) => (elements: Iterable<A>) => Effect.Effect<void, Array<E>, R>,
2973
+ <A, B, E, R>(elements: Iterable<A>, f: (a: A) => Effect.Effect<B, E, R>) => Effect.Effect<void, Array<E>, R>
2974
+ >(2, (elements, f) =>
2975
+ core.flatMap(
2976
+ partition(elements, f),
2977
+ ([es, _]) =>
2978
+ es.length === 0
2979
+ ? core.void
2980
+ : core.fail(es)
2981
+ ))
2982
+
2983
+ /* @internal */
2984
+ export const validateFirst = dual<
2985
+ <A, B, E, R>(f: (a: A, i: number) => Effect.Effect<B, E, R>, options?: {
2986
+ readonly concurrency?: Concurrency | undefined
2987
+ readonly batching?: boolean | "inherit" | undefined
2988
+ readonly concurrentFinalizers?: boolean | undefined
2989
+ }) => (elements: Iterable<A>) => Effect.Effect<B, Array<E>, R>,
2990
+ <A, B, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect.Effect<B, E, R>, options?: {
2991
+ readonly concurrency?: Concurrency | undefined
2992
+ readonly batching?: boolean | "inherit" | undefined
2993
+ readonly concurrentFinalizers?: boolean | undefined
2994
+ }) => Effect.Effect<B, Array<E>, R>
2995
+ >(
2996
+ (args) => Predicate.isIterable(args[0]),
2997
+ (elements, f, options) => core.flip(forEach(elements, (a, i) => core.flip(f(a, i)), options))
2998
+ )
2999
+
3000
+ /* @internal */
3001
+ export const withClockScoped = <C extends Clock.Clock>(c: C) =>
3002
+ fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(clock.clockTag, c))
3003
+
3004
+ /* @internal */
3005
+ export const withRandomScoped = <A extends Random.Random>(value: A) =>
3006
+ fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(randomTag, value))
3007
+
3008
+ /* @internal */
3009
+ export const withConfigProviderScoped = (provider: ConfigProvider) =>
3010
+ fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(configProviderTag, provider))
3011
+
3012
+ /* @internal */
3013
+ export const withEarlyRelease = <A, E, R>(
3014
+ self: Effect.Effect<A, E, R>
3015
+ ): Effect.Effect<[Effect.Effect<void>, A], E, R | Scope.Scope> =>
3016
+ scopeWith((parent) =>
3017
+ core.flatMap(core.scopeFork(parent, executionStrategy.sequential), (child) =>
3018
+ pipe(
3019
+ self,
3020
+ scopeExtend(child),
3021
+ core.map((value) => [
3022
+ core.fiberIdWith((fiberId) => core.scopeClose(child, core.exitInterrupt(fiberId))),
3023
+ value
3024
+ ])
3025
+ ))
3026
+ )
3027
+
3028
+ /** @internal */
3029
+ export const zipOptions = dual<
3030
+ <A2, E2, R2>(
3031
+ that: Effect.Effect<A2, E2, R2>,
3032
+ options?: {
3033
+ readonly concurrent?: boolean | undefined
3034
+ readonly batching?: boolean | "inherit" | undefined
3035
+ readonly concurrentFinalizers?: boolean | undefined
3036
+ }
3037
+ ) => <A, E, R>(
3038
+ self: Effect.Effect<A, E, R>
3039
+ ) => Effect.Effect<[A, A2], E | E2, R | R2>,
3040
+ <A, E, R, A2, E2, R2>(
3041
+ self: Effect.Effect<A, E, R>,
3042
+ that: Effect.Effect<A2, E2, R2>,
3043
+ options?: {
3044
+ readonly concurrent?: boolean | undefined
3045
+ readonly batching?: boolean | "inherit" | undefined
3046
+ readonly concurrentFinalizers?: boolean | undefined
3047
+ }
3048
+ ) => Effect.Effect<[A, A2], E | E2, R | R2>
3049
+ >((args) => core.isEffect(args[1]), (
3050
+ self,
3051
+ that,
3052
+ options
3053
+ ) => zipWithOptions(self, that, (a, b) => [a, b], options))
3054
+
3055
+ /** @internal */
3056
+ export const zipLeftOptions = dual<
3057
+ <A2, E2, R2>(
3058
+ that: Effect.Effect<A2, E2, R2>,
3059
+ options?: {
3060
+ readonly concurrent?: boolean | undefined
3061
+ readonly batching?: boolean | "inherit" | undefined
3062
+ readonly concurrentFinalizers?: boolean | undefined
3063
+ }
3064
+ ) => <A, E, R>(
3065
+ self: Effect.Effect<A, E, R>
3066
+ ) => Effect.Effect<A, E | E2, R | R2>,
3067
+ <A, E, R, A2, E2, R2>(
3068
+ self: Effect.Effect<A, E, R>,
3069
+ that: Effect.Effect<A2, E2, R2>,
3070
+ options?: {
3071
+ readonly concurrent?: boolean | undefined
3072
+ readonly batching?: boolean | "inherit" | undefined
3073
+ readonly concurrentFinalizers?: boolean | undefined
3074
+ }
3075
+ ) => Effect.Effect<A, E | E2, R | R2>
3076
+ >(
3077
+ (args) => core.isEffect(args[1]),
3078
+ (self, that, options) => {
3079
+ if (options?.concurrent !== true && (options?.batching === undefined || options.batching === false)) {
3080
+ return core.zipLeft(self, that)
3081
+ }
3082
+ return zipWithOptions(self, that, (a, _) => a, options)
3083
+ }
3084
+ )
3085
+
3086
+ /** @internal */
3087
+ export const zipRightOptions: {
3088
+ <A2, E2, R2>(
3089
+ that: Effect.Effect<A2, E2, R2>,
3090
+ options?: {
3091
+ readonly concurrent?: boolean | undefined
3092
+ readonly batching?: boolean | "inherit" | undefined
3093
+ readonly concurrentFinalizers?: boolean | undefined
3094
+ }
3095
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2, E2 | E, R2 | R>
3096
+ <A, E, R, A2, E2, R2>(
3097
+ self: Effect.Effect<A, E, R>,
3098
+ that: Effect.Effect<A2, E2, R2>,
3099
+ options?: {
3100
+ readonly concurrent?: boolean | undefined
3101
+ readonly batching?: boolean | "inherit" | undefined
3102
+ readonly concurrentFinalizers?: boolean | undefined
3103
+ }
3104
+ ): Effect.Effect<A2, E2 | E, R2 | R>
3105
+ } = dual((args) => core.isEffect(args[1]), <A, E, R, A2, E2, R2>(
3106
+ self: Effect.Effect<A, E, R>,
3107
+ that: Effect.Effect<A2, E2, R2>,
3108
+ options?: {
3109
+ readonly concurrent?: boolean | undefined
3110
+ readonly batching?: boolean | "inherit" | undefined
3111
+ readonly concurrentFinalizers?: boolean | undefined
3112
+ }
3113
+ ): Effect.Effect<A2, E2 | E, R2 | R> => {
3114
+ if (options?.concurrent !== true && (options?.batching === undefined || options.batching === false)) {
3115
+ return core.zipRight(self, that)
3116
+ }
3117
+ return zipWithOptions(self, that, (_, b) => b, options)
3118
+ })
3119
+
3120
+ /** @internal */
3121
+ export const zipWithOptions: {
3122
+ <A2, E2, R2, A, B>(
3123
+ that: Effect.Effect<A2, E2, R2>,
3124
+ f: (a: A, b: A2) => B,
3125
+ options?: {
3126
+ readonly concurrent?: boolean | undefined
3127
+ readonly batching?: boolean | "inherit" | undefined
3128
+ readonly concurrentFinalizers?: boolean | undefined
3129
+ }
3130
+ ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E2 | E, R2 | R>
3131
+ <A, E, R, A2, E2, R2, B>(
3132
+ self: Effect.Effect<A, E, R>,
3133
+ that: Effect.Effect<A2, E2, R2>,
3134
+ f: (a: A, b: A2) => B,
3135
+ options?: {
3136
+ readonly concurrent?: boolean | undefined
3137
+ readonly batching?: boolean | "inherit" | undefined
3138
+ readonly concurrentFinalizers?: boolean | undefined
3139
+ }
3140
+ ): Effect.Effect<B, E2 | E, R2 | R>
3141
+ } = dual((args) => core.isEffect(args[1]), <A, E, R, A2, E2, R2, B>(
3142
+ self: Effect.Effect<A, E, R>,
3143
+ that: Effect.Effect<A2, E2, R2>,
3144
+ f: (a: A, b: A2) => B,
3145
+ options?: {
3146
+ readonly concurrent?: boolean | undefined
3147
+ readonly batching?: boolean | "inherit" | undefined
3148
+ readonly concurrentFinalizers?: boolean | undefined
3149
+ }
3150
+ ): Effect.Effect<B, E2 | E, R2 | R> =>
3151
+ core.map(
3152
+ all([self, that], {
3153
+ concurrency: options?.concurrent ? 2 : 1,
3154
+ batching: options?.batching,
3155
+ concurrentFinalizers: options?.concurrentFinalizers
3156
+ }),
3157
+ ([a, a2]) => f(a, a2)
3158
+ ))
3159
+
3160
+ /* @internal */
3161
+ export const withRuntimeFlagsScoped = (
3162
+ update: RuntimeFlagsPatch.RuntimeFlagsPatch
3163
+ ): Effect.Effect<void, never, Scope.Scope> => {
3164
+ if (update === RuntimeFlagsPatch.empty) {
3165
+ return core.void
3166
+ }
3167
+ return pipe(
3168
+ core.runtimeFlags,
3169
+ core.flatMap((runtimeFlags) => {
3170
+ const updatedRuntimeFlags = runtimeFlags_.patch(runtimeFlags, update)
3171
+ const revertRuntimeFlags = runtimeFlags_.diff(updatedRuntimeFlags, runtimeFlags)
3172
+ return pipe(
3173
+ core.updateRuntimeFlags(update),
3174
+ core.zipRight(addFinalizer(() => core.updateRuntimeFlags(revertRuntimeFlags))),
3175
+ core.asVoid
3176
+ )
3177
+ }),
3178
+ core.uninterruptible
3179
+ )
3180
+ }
3181
+
3182
+ // circular with Scope
3183
+
3184
+ /** @internal */
3185
+ export const scopeTag = Context.GenericTag<Scope.Scope>("effect/Scope")
3186
+
3187
+ /* @internal */
3188
+ export const scope: Effect.Effect<Scope.Scope, never, Scope.Scope> = scopeTag
3189
+
3190
+ /** @internal */
3191
+ export interface ScopeImpl extends Scope.CloseableScope {
3192
+ state: {
3193
+ readonly _tag: "Open"
3194
+ readonly finalizers: Map<{}, Scope.Scope.Finalizer>
3195
+ } | {
3196
+ readonly _tag: "Closed"
3197
+ readonly exit: Exit.Exit<unknown, unknown>
3198
+ }
3199
+ }
3200
+
3201
+ const scopeUnsafeAddFinalizer = (scope: ScopeImpl, fin: Scope.Scope.Finalizer): void => {
3202
+ if (scope.state._tag === "Open") {
3203
+ scope.state.finalizers.set({}, fin)
3204
+ }
3205
+ }
3206
+
3207
+ const ScopeImplProto: Omit<ScopeImpl, "strategy" | "state"> = {
3208
+ [core.ScopeTypeId]: core.ScopeTypeId,
3209
+ [core.CloseableScopeTypeId]: core.CloseableScopeTypeId,
3210
+ pipe() {
3211
+ return pipeArguments(this, arguments)
3212
+ },
3213
+ fork(this: ScopeImpl, strategy) {
3214
+ return core.sync(() => {
3215
+ const newScope = scopeUnsafeMake(strategy)
3216
+ if (this.state._tag === "Closed") {
3217
+ newScope.state = this.state
3218
+ return newScope
3219
+ }
3220
+ const key = {}
3221
+ const fin = (exit: Exit.Exit<unknown, unknown>) => newScope.close(exit)
3222
+ this.state.finalizers.set(key, fin)
3223
+ scopeUnsafeAddFinalizer(newScope, (_) =>
3224
+ core.sync(() => {
3225
+ if (this.state._tag === "Open") {
3226
+ this.state.finalizers.delete(key)
3227
+ }
3228
+ }))
3229
+ return newScope
3230
+ })
3231
+ },
3232
+ close(this: ScopeImpl, exit) {
3233
+ return core.suspend(() => {
3234
+ if (this.state._tag === "Closed") {
3235
+ return core.void
3236
+ }
3237
+ const finalizers = Array.from(this.state.finalizers.values()).reverse()
3238
+ this.state = { _tag: "Closed", exit }
3239
+ if (finalizers.length === 0) {
3240
+ return core.void
3241
+ }
3242
+ return executionStrategy.isSequential(this.strategy) ?
3243
+ pipe(
3244
+ core.forEachSequential(finalizers, (fin) => core.exit(fin(exit))),
3245
+ core.flatMap((results) =>
3246
+ pipe(
3247
+ core.exitCollectAll(results),
3248
+ Option.map(core.exitAsVoid),
3249
+ Option.getOrElse(() => core.exitVoid)
3250
+ )
3251
+ )
3252
+ ) :
3253
+ executionStrategy.isParallel(this.strategy) ?
3254
+ pipe(
3255
+ forEachParUnbounded(finalizers, (fin) => core.exit(fin(exit)), false),
3256
+ core.flatMap((results) =>
3257
+ pipe(
3258
+ core.exitCollectAll(results, { parallel: true }),
3259
+ Option.map(core.exitAsVoid),
3260
+ Option.getOrElse(() => core.exitVoid)
3261
+ )
3262
+ )
3263
+ ) :
3264
+ pipe(
3265
+ forEachParN(finalizers, this.strategy.parallelism, (fin) => core.exit(fin(exit)), false),
3266
+ core.flatMap((results) =>
3267
+ pipe(
3268
+ core.exitCollectAll(results, { parallel: true }),
3269
+ Option.map(core.exitAsVoid),
3270
+ Option.getOrElse(() => core.exitVoid)
3271
+ )
3272
+ )
3273
+ )
3274
+ })
3275
+ },
3276
+ addFinalizer(this: ScopeImpl, fin) {
3277
+ return core.suspend(() => {
3278
+ if (this.state._tag === "Closed") {
3279
+ return fin(this.state.exit)
3280
+ }
3281
+ this.state.finalizers.set({}, fin)
3282
+ return core.void
3283
+ })
3284
+ }
3285
+ }
3286
+
3287
+ const scopeUnsafeMake = (
3288
+ strategy: ExecutionStrategy.ExecutionStrategy = executionStrategy.sequential
3289
+ ): ScopeImpl => {
3290
+ const scope = Object.create(ScopeImplProto)
3291
+ scope.strategy = strategy
3292
+ scope.state = { _tag: "Open", finalizers: new Map() }
3293
+ return scope
3294
+ }
3295
+
3296
+ /* @internal */
3297
+ export const scopeMake = (
3298
+ strategy: ExecutionStrategy.ExecutionStrategy = executionStrategy.sequential
3299
+ ): Effect.Effect<Scope.Scope.Closeable> => core.sync(() => scopeUnsafeMake(strategy))
3300
+
3301
+ /* @internal */
3302
+ export const scopeExtend = dual<
3303
+ (scope: Scope.Scope) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Scope.Scope>>,
3304
+ <A, E, R>(effect: Effect.Effect<A, E, R>, scope: Scope.Scope) => Effect.Effect<A, E, Exclude<R, Scope.Scope>>
3305
+ >(
3306
+ 2,
3307
+ <A, E, R>(effect: Effect.Effect<A, E, R>, scope: Scope.Scope) =>
3308
+ core.mapInputContext<A, E, R, Exclude<R, Scope.Scope>>(
3309
+ effect,
3310
+ // @ts-expect-error
3311
+ Context.merge(Context.make(scopeTag, scope))
3312
+ )
3313
+ )
3314
+
3315
+ /* @internal */
3316
+ export const scopeUse = dual<
3317
+ (
3318
+ scope: Scope.Scope.Closeable
3319
+ ) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Scope.Scope>>,
3320
+ <A, E, R>(
3321
+ effect: Effect.Effect<A, E, R>,
3322
+ scope: Scope.Scope.Closeable
3323
+ ) => Effect.Effect<A, E, Exclude<R, Scope.Scope>>
3324
+ >(2, (effect, scope) =>
3325
+ pipe(
3326
+ effect,
3327
+ scopeExtend(scope),
3328
+ core.onExit((exit) => scope.close(exit))
3329
+ ))
3330
+
3331
+ // circular with Supervisor
3332
+
3333
+ /** @internal */
3334
+ export const fiberRefUnsafeMakeSupervisor = (
3335
+ initial: Supervisor.Supervisor<any>
3336
+ ): FiberRef.FiberRef<Supervisor.Supervisor<any>> =>
3337
+ core.fiberRefUnsafeMakePatch(initial, {
3338
+ differ: SupervisorPatch.differ,
3339
+ fork: SupervisorPatch.empty
3340
+ })
3341
+
3342
+ // circular with FiberRef
3343
+
3344
+ /* @internal */
3345
+ export const fiberRefLocallyScoped = dual<
3346
+ <A>(value: A) => (self: FiberRef.FiberRef<A>) => Effect.Effect<void, never, Scope.Scope>,
3347
+ <A>(self: FiberRef.FiberRef<A>, value: A) => Effect.Effect<void, never, Scope.Scope>
3348
+ >(2, (self, value) =>
3349
+ core.asVoid(
3350
+ acquireRelease(
3351
+ core.flatMap(
3352
+ core.fiberRefGet(self),
3353
+ (oldValue) => core.as(core.fiberRefSet(self, value), oldValue)
3354
+ ),
3355
+ (oldValue) => core.fiberRefSet(self, oldValue)
3356
+ )
3357
+ ))
3358
+
3359
+ /* @internal */
3360
+ export const fiberRefLocallyScopedWith = dual<
3361
+ <A>(f: (a: A) => A) => (self: FiberRef.FiberRef<A>) => Effect.Effect<void, never, Scope.Scope>,
3362
+ <A>(self: FiberRef.FiberRef<A>, f: (a: A) => A) => Effect.Effect<void, never, Scope.Scope>
3363
+ >(2, (self, f) => core.fiberRefGetWith(self, (a) => fiberRefLocallyScoped(self, f(a))))
3364
+
3365
+ /* @internal */
3366
+ export const fiberRefMake = <A>(
3367
+ initial: A,
3368
+ options?: {
3369
+ readonly fork?: ((a: A) => A) | undefined
3370
+ readonly join?: ((left: A, right: A) => A) | undefined
3371
+ }
3372
+ ): Effect.Effect<FiberRef.FiberRef<A>, never, Scope.Scope> =>
3373
+ fiberRefMakeWith(() => core.fiberRefUnsafeMake(initial, options))
3374
+
3375
+ /* @internal */
3376
+ export const fiberRefMakeWith = <Value>(
3377
+ ref: LazyArg<FiberRef.FiberRef<Value>>
3378
+ ): Effect.Effect<FiberRef.FiberRef<Value>, never, Scope.Scope> =>
3379
+ acquireRelease(
3380
+ core.tap(core.sync(ref), (ref) => core.fiberRefUpdate(ref, identity)),
3381
+ (fiberRef) => core.fiberRefDelete(fiberRef)
3382
+ )
3383
+
3384
+ /* @internal */
3385
+ export const fiberRefMakeContext = <A>(
3386
+ initial: Context.Context<A>
3387
+ ): Effect.Effect<FiberRef.FiberRef<Context.Context<A>>, never, Scope.Scope> =>
3388
+ fiberRefMakeWith(() => core.fiberRefUnsafeMakeContext(initial))
3389
+
3390
+ /* @internal */
3391
+ export const fiberRefMakeRuntimeFlags = (
3392
+ initial: RuntimeFlags.RuntimeFlags
3393
+ ): Effect.Effect<FiberRef.FiberRef<RuntimeFlags.RuntimeFlags>, never, Scope.Scope> =>
3394
+ fiberRefMakeWith(() => core.fiberRefUnsafeMakeRuntimeFlags(initial))
3395
+
3396
+ /** @internal */
3397
+ export const currentRuntimeFlags: FiberRef.FiberRef<RuntimeFlags.RuntimeFlags> = core.fiberRefUnsafeMakeRuntimeFlags(
3398
+ runtimeFlags_.none
3399
+ )
3400
+
3401
+ /** @internal */
3402
+ export const currentSupervisor: FiberRef.FiberRef<Supervisor.Supervisor<any>> = fiberRefUnsafeMakeSupervisor(
3403
+ supervisor.none
3404
+ )
3405
+
3406
+ // circular with Fiber
3407
+
3408
+ /* @internal */
3409
+ export const fiberAwaitAll = <const T extends Iterable<Fiber.Fiber<any, any>>>(
3410
+ fibers: T
3411
+ ): Effect.Effect<
3412
+ [T] extends [ReadonlyArray<infer U>]
3413
+ ? number extends T["length"] ? Array<U extends Fiber.Fiber<infer A, infer E> ? Exit.Exit<A, E> : never>
3414
+ : { -readonly [K in keyof T]: T[K] extends Fiber.Fiber<infer A, infer E> ? Exit.Exit<A, E> : never }
3415
+ : Array<T extends Iterable<infer U> ? U extends Fiber.Fiber<infer A, infer E> ? Exit.Exit<A, E> : never : never>
3416
+ > => forEach(fibers, internalFiber._await) as any
3417
+
3418
+ /** @internal */
3419
+ export const fiberAll = <A, E>(fibers: Iterable<Fiber.Fiber<A, E>>): Fiber.Fiber<Array<A>, E> => {
3420
+ const _fiberAll = {
3421
+ ...Effectable.CommitPrototype,
3422
+ commit() {
3423
+ return internalFiber.join(this)
3424
+ },
3425
+ [internalFiber.FiberTypeId]: internalFiber.fiberVariance,
3426
+ id: () =>
3427
+ RA.fromIterable(fibers).reduce((id, fiber) => FiberId.combine(id, fiber.id()), FiberId.none as FiberId.FiberId),
3428
+ await: core.exit(forEachParUnbounded(fibers, (fiber) => core.flatten(fiber.await), false)),
3429
+ children: core.map(forEachParUnbounded(fibers, (fiber) => fiber.children, false), RA.flatten),
3430
+ inheritAll: core.forEachSequentialDiscard(fibers, (fiber) => fiber.inheritAll),
3431
+ poll: core.map(
3432
+ core.forEachSequential(fibers, (fiber) => fiber.poll),
3433
+ RA.reduceRight(
3434
+ Option.some<Exit.Exit<Array<A>, E>>(core.exitSucceed(new Array())),
3435
+ (optionB, optionA) => {
3436
+ switch (optionA._tag) {
3437
+ case "None": {
3438
+ return Option.none()
3439
+ }
3440
+ case "Some": {
3441
+ switch (optionB._tag) {
3442
+ case "None": {
3443
+ return Option.none()
3444
+ }
3445
+ case "Some": {
3446
+ return Option.some(
3447
+ core.exitZipWith(optionA.value, optionB.value, {
3448
+ onSuccess: (a, chunk) => [a, ...chunk],
3449
+ onFailure: internalCause.parallel
3450
+ })
3451
+ )
3452
+ }
3453
+ }
3454
+ }
3455
+ }
3456
+ }
3457
+ )
3458
+ ),
3459
+ interruptAsFork: (fiberId: FiberId.FiberId) =>
3460
+ core.forEachSequentialDiscard(fibers, (fiber) => fiber.interruptAsFork(fiberId))
3461
+ }
3462
+ return _fiberAll
3463
+ }
3464
+
3465
+ /* @internal */
3466
+ export const fiberInterruptFork = <A, E>(self: Fiber.Fiber<A, E>): Effect.Effect<void> =>
3467
+ core.asVoid(forkDaemon(core.interruptFiber(self)))
3468
+
3469
+ /* @internal */
3470
+ export const fiberJoinAll = <A, E>(fibers: Iterable<Fiber.Fiber<A, E>>): Effect.Effect<Array<A>, E> =>
3471
+ internalFiber.join(fiberAll(fibers))
3472
+
3473
+ /* @internal */
3474
+ export const fiberScoped = <A, E>(self: Fiber.Fiber<A, E>): Effect.Effect<Fiber.Fiber<A, E>, never, Scope.Scope> =>
3475
+ acquireRelease(core.succeed(self), core.interruptFiber)
3476
+
3477
+ //
3478
+ // circular race
3479
+ //
3480
+
3481
+ /** @internal */
3482
+ export const raceWith = dual<
3483
+ <A1, E1, R1, E, A, A2, E2, R2, A3, E3, R3>(
3484
+ other: Effect.Effect<A1, E1, R1>,
3485
+ options: {
3486
+ readonly onSelfDone: (exit: Exit.Exit<A, E>, fiber: Fiber.Fiber<A1, E1>) => Effect.Effect<A2, E2, R2>
3487
+ readonly onOtherDone: (exit: Exit.Exit<A1, E1>, fiber: Fiber.Fiber<A, E>) => Effect.Effect<A3, E3, R3>
3488
+ }
3489
+ ) => <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A3, E2 | E3, R | R1 | R2 | R3>,
3490
+ <A, E, R, A1, E1, R1, A2, E2, R2, A3, E3, R3>(
3491
+ self: Effect.Effect<A, E, R>,
3492
+ other: Effect.Effect<A1, E1, R1>,
3493
+ options: {
3494
+ readonly onSelfDone: (exit: Exit.Exit<A, E>, fiber: Fiber.Fiber<A1, E1>) => Effect.Effect<A2, E2, R2>
3495
+ readonly onOtherDone: (exit: Exit.Exit<A1, E1>, fiber: Fiber.Fiber<A, E>) => Effect.Effect<A3, E3, R3>
3496
+ }
3497
+ ) => Effect.Effect<A2 | A3, E2 | E3, R | R1 | R2 | R3>
3498
+ >(3, (self, other, options) =>
3499
+ raceFibersWith(self, other, {
3500
+ onSelfWin: (winner, loser) =>
3501
+ core.flatMap(winner.await, (exit) => {
3502
+ switch (exit._tag) {
3503
+ case OpCodes.OP_SUCCESS: {
3504
+ return core.flatMap(
3505
+ winner.inheritAll,
3506
+ () => options.onSelfDone(exit, loser)
3507
+ )
3508
+ }
3509
+ case OpCodes.OP_FAILURE: {
3510
+ return options.onSelfDone(exit, loser)
3511
+ }
3512
+ }
3513
+ }),
3514
+ onOtherWin: (winner, loser) =>
3515
+ core.flatMap(winner.await, (exit) => {
3516
+ switch (exit._tag) {
3517
+ case OpCodes.OP_SUCCESS: {
3518
+ return core.flatMap(
3519
+ winner.inheritAll,
3520
+ () => options.onOtherDone(exit, loser)
3521
+ )
3522
+ }
3523
+ case OpCodes.OP_FAILURE: {
3524
+ return options.onOtherDone(exit, loser)
3525
+ }
3526
+ }
3527
+ })
3528
+ }))
3529
+
3530
+ /** @internal */
3531
+ export const disconnect = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
3532
+ core.uninterruptibleMask((restore) =>
3533
+ core.fiberIdWith((fiberId) =>
3534
+ core.flatMap(forkDaemon(restore(self)), (fiber) =>
3535
+ pipe(
3536
+ restore(internalFiber.join(fiber)),
3537
+ core.onInterrupt(() => pipe(fiber, internalFiber.interruptAsFork(fiberId)))
3538
+ ))
3539
+ )
3540
+ )
3541
+
3542
+ /** @internal */
3543
+ export const race = dual<
3544
+ <A2, E2, R2>(
3545
+ that: Effect.Effect<A2, E2, R2>
3546
+ ) => <A, E, R>(
3547
+ self: Effect.Effect<A, E, R>
3548
+ ) => Effect.Effect<A | A2, E | E2, R | R2>,
3549
+ <A, E, R, A2, E2, R2>(
3550
+ self: Effect.Effect<A, E, R>,
3551
+ that: Effect.Effect<A2, E2, R2>
3552
+ ) => Effect.Effect<A | A2, E | E2, R | R2>
3553
+ >(
3554
+ 2,
3555
+ (self, that) =>
3556
+ core.fiberIdWith((parentFiberId) =>
3557
+ raceWith(self, that, {
3558
+ onSelfDone: (exit, right) =>
3559
+ core.exitMatchEffect(exit, {
3560
+ onFailure: (cause) =>
3561
+ pipe(
3562
+ internalFiber.join(right),
3563
+ internalEffect.mapErrorCause((cause2) => internalCause.parallel(cause, cause2))
3564
+ ),
3565
+ onSuccess: (value) =>
3566
+ pipe(
3567
+ right,
3568
+ core.interruptAsFiber(parentFiberId),
3569
+ core.as(value)
3570
+ )
3571
+ }),
3572
+ onOtherDone: (exit, left) =>
3573
+ core.exitMatchEffect(exit, {
3574
+ onFailure: (cause) =>
3575
+ pipe(
3576
+ internalFiber.join(left),
3577
+ internalEffect.mapErrorCause((cause2) => internalCause.parallel(cause2, cause))
3578
+ ),
3579
+ onSuccess: (value) =>
3580
+ pipe(
3581
+ left,
3582
+ core.interruptAsFiber(parentFiberId),
3583
+ core.as(value)
3584
+ )
3585
+ })
3586
+ })
3587
+ )
3588
+ )
3589
+
3590
+ /** @internal */
3591
+ export const raceFibersWith = dual<
3592
+ <A1, E1, R1, E, A, A2, E2, R2, A3, E3, R3>(
3593
+ other: Effect.Effect<A1, E1, R1>,
3594
+ options: {
3595
+ readonly onSelfWin: (
3596
+ winner: Fiber.RuntimeFiber<A, E>,
3597
+ loser: Fiber.RuntimeFiber<A1, E1>
3598
+ ) => Effect.Effect<A2, E2, R2>
3599
+ readonly onOtherWin: (
3600
+ winner: Fiber.RuntimeFiber<A1, E1>,
3601
+ loser: Fiber.RuntimeFiber<A, E>
3602
+ ) => Effect.Effect<A3, E3, R3>
3603
+ readonly selfScope?: fiberScope.FiberScope | undefined
3604
+ readonly otherScope?: fiberScope.FiberScope | undefined
3605
+ }
3606
+ ) => <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A3, E2 | E3, R | R1 | R2 | R3>,
3607
+ <A, E, R, A1, E1, R1, A2, E2, R2, A3, E3, R3>(
3608
+ self: Effect.Effect<A, E, R>,
3609
+ other: Effect.Effect<A1, E1, R1>,
3610
+ options: {
3611
+ readonly onSelfWin: (
3612
+ winner: Fiber.RuntimeFiber<A, E>,
3613
+ loser: Fiber.RuntimeFiber<A1, E1>
3614
+ ) => Effect.Effect<A2, E2, R2>
3615
+ readonly onOtherWin: (
3616
+ winner: Fiber.RuntimeFiber<A1, E1>,
3617
+ loser: Fiber.RuntimeFiber<A, E>
3618
+ ) => Effect.Effect<A3, E3, R3>
3619
+ readonly selfScope?: fiberScope.FiberScope | undefined
3620
+ readonly otherScope?: fiberScope.FiberScope | undefined
3621
+ }
3622
+ ) => Effect.Effect<A2 | A3, E2 | E3, R | R1 | R2 | R3>
3623
+ >(3, <A, E, R, A1, E1, R1, A2, E2, R2, A3, E3, R3>(
3624
+ self: Effect.Effect<A, E, R>,
3625
+ other: Effect.Effect<A1, E1, R1>,
3626
+ options: {
3627
+ readonly onSelfWin: (
3628
+ winner: Fiber.RuntimeFiber<A, E>,
3629
+ loser: Fiber.RuntimeFiber<A1, E1>
3630
+ ) => Effect.Effect<A2, E2, R2>
3631
+ readonly onOtherWin: (
3632
+ winner: Fiber.RuntimeFiber<A1, E1>,
3633
+ loser: Fiber.RuntimeFiber<A, E>
3634
+ ) => Effect.Effect<A3, E3, R3>
3635
+ readonly selfScope?: fiberScope.FiberScope | undefined
3636
+ readonly otherScope?: fiberScope.FiberScope | undefined
3637
+ }
3638
+ ) =>
3639
+ core.withFiberRuntime((parentFiber, parentStatus) => {
3640
+ const parentRuntimeFlags = parentStatus.runtimeFlags
3641
+ const raceIndicator = MRef.make(true)
3642
+ const leftFiber: FiberRuntime<A, E> = unsafeMakeChildFiber(
3643
+ self,
3644
+ parentFiber,
3645
+ parentRuntimeFlags,
3646
+ options.selfScope
3647
+ )
3648
+ const rightFiber: FiberRuntime<A1, E1> = unsafeMakeChildFiber(
3649
+ other,
3650
+ parentFiber,
3651
+ parentRuntimeFlags,
3652
+ options.otherScope
3653
+ )
3654
+ return core.async((cb) => {
3655
+ leftFiber.addObserver(() => completeRace(leftFiber, rightFiber, options.onSelfWin, raceIndicator, cb))
3656
+ rightFiber.addObserver(() => completeRace(rightFiber, leftFiber, options.onOtherWin, raceIndicator, cb))
3657
+ leftFiber.startFork(self)
3658
+ rightFiber.startFork(other)
3659
+ }, FiberId.combine(leftFiber.id(), rightFiber.id()))
3660
+ }))
3661
+
3662
+ const completeRace = <A2, A3, E2, E3, R, R1, R2, R3>(
3663
+ winner: Fiber.RuntimeFiber<any, any>,
3664
+ loser: Fiber.RuntimeFiber<any, any>,
3665
+ cont: (winner: Fiber.RuntimeFiber<any, any>, loser: Fiber.RuntimeFiber<any, any>) => Effect.Effect<any, any, any>,
3666
+ ab: MRef.MutableRef<boolean>,
3667
+ cb: (_: Effect.Effect<A2 | A3, E2 | E3, R | R1 | R2 | R3>) => void
3668
+ ): void => {
3669
+ if (MRef.compareAndSet(true, false)(ab)) {
3670
+ cb(cont(winner, loser))
3671
+ }
3672
+ }
3673
+
3674
+ /** @internal */
3675
+ export const ensuring: {
3676
+ <X, R1>(
3677
+ finalizer: Effect.Effect<X, never, R1>
3678
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R1 | R>
3679
+ <A, E, R, X, R1>(self: Effect.Effect<A, E, R>, finalizer: Effect.Effect<X, never, R1>): Effect.Effect<A, E, R1 | R>
3680
+ } = dual(
3681
+ 2,
3682
+ <A, E, R, X, R1>(self: Effect.Effect<A, E, R>, finalizer: Effect.Effect<X, never, R1>): Effect.Effect<A, E, R1 | R> =>
3683
+ core.uninterruptibleMask((restore) =>
3684
+ core.matchCauseEffect(restore(self), {
3685
+ onFailure: (cause1) =>
3686
+ core.matchCauseEffect(finalizer, {
3687
+ onFailure: (cause2) => core.failCause(internalCause.sequential(cause1, cause2)),
3688
+ onSuccess: () => core.failCause(cause1)
3689
+ }),
3690
+ onSuccess: (a) => core.as(finalizer, a)
3691
+ })
3692
+ )
3693
+ )
3694
+
3695
+ /** @internal */
3696
+ export const invokeWithInterrupt: <A, E, R>(
3697
+ self: Effect.Effect<A, E, R>,
3698
+ entries: ReadonlyArray<Entry<unknown>>,
3699
+ onInterrupt?: () => void
3700
+ ) => Effect.Effect<void, E, R> = <A, E, R>(
3701
+ self: Effect.Effect<A, E, R>,
3702
+ entries: ReadonlyArray<Entry<unknown>>,
3703
+ onInterrupt?: () => void
3704
+ ) =>
3705
+ core.fiberIdWith((id) =>
3706
+ core.flatMap(
3707
+ core.flatMap(
3708
+ forkDaemon(core.interruptible(self)),
3709
+ (processing) =>
3710
+ core.async<void, E>((cb) => {
3711
+ const counts = entries.map((_) => _.listeners.count)
3712
+ const checkDone = () => {
3713
+ if (counts.every((count) => count === 0)) {
3714
+ if (
3715
+ entries.every((_) => {
3716
+ if (_.result.state.current._tag === "Pending") {
3717
+ return true
3718
+ } else if (
3719
+ _.result.state.current._tag === "Done" &&
3720
+ core.exitIsExit(_.result.state.current.effect) &&
3721
+ _.result.state.current.effect._tag === "Failure" &&
3722
+ internalCause.isInterrupted(_.result.state.current.effect.cause)
3723
+ ) {
3724
+ return true
3725
+ } else {
3726
+ return false
3727
+ }
3728
+ })
3729
+ ) {
3730
+ cleanup.forEach((f) => f())
3731
+ onInterrupt?.()
3732
+ cb(core.interruptFiber(processing))
3733
+ }
3734
+ }
3735
+ }
3736
+ processing.addObserver((exit) => {
3737
+ cleanup.forEach((f) => f())
3738
+ cb(exit)
3739
+ })
3740
+ const cleanup = entries.map((r, i) => {
3741
+ const observer = (count: number) => {
3742
+ counts[i] = count
3743
+ checkDone()
3744
+ }
3745
+ r.listeners.addObserver(observer)
3746
+ return () => r.listeners.removeObserver(observer)
3747
+ })
3748
+ checkDone()
3749
+ return core.sync(() => {
3750
+ cleanup.forEach((f) => f())
3751
+ })
3752
+ })
3753
+ ),
3754
+ () =>
3755
+ core.suspend(() => {
3756
+ const residual = entries.flatMap((entry) => {
3757
+ if (!entry.state.completed) {
3758
+ return [entry]
3759
+ }
3760
+ return []
3761
+ })
3762
+ return core.forEachSequentialDiscard(
3763
+ residual,
3764
+ (entry) => complete(entry.request as any, core.exitInterrupt(id))
3765
+ )
3766
+ })
3767
+ )
3768
+ )
3769
+
3770
+ /** @internal */
3771
+ export const interruptWhenPossible = dual<
3772
+ (all: Iterable<Request<any, any>>) => <A, E, R>(
3773
+ self: Effect.Effect<A, E, R>
3774
+ ) => Effect.Effect<void, E, R>,
3775
+ <A, E, R>(
3776
+ self: Effect.Effect<A, E, R>,
3777
+ all: Iterable<Request<any, any>>
3778
+ ) => Effect.Effect<void, E, R>
3779
+ >(2, (self, all) =>
3780
+ core.fiberRefGetWith(
3781
+ currentRequestMap,
3782
+ (map) =>
3783
+ core.suspend(() => {
3784
+ const entries = RA.fromIterable(all).flatMap((_) => map.has(_) ? [map.get(_)!] : [])
3785
+ return invokeWithInterrupt(self, entries)
3786
+ })
3787
+ ))
3788
+
3789
+ // circular Tracer
3790
+
3791
+ /** @internal */
3792
+ export const makeSpanScoped = (
3793
+ name: string,
3794
+ options?: Tracer.SpanOptions | undefined
3795
+ ): Effect.Effect<Tracer.Span, never, Scope.Scope> => {
3796
+ options = tracer.addSpanStackTrace(options)
3797
+ return core.uninterruptible(
3798
+ core.withFiberRuntime((fiber) => {
3799
+ const scope = Context.unsafeGet(fiber.getFiberRef(core.currentContext), scopeTag)
3800
+ const span = internalEffect.unsafeMakeSpan(fiber, name, options)
3801
+ const timingEnabled = fiber.getFiberRef(core.currentTracerTimingEnabled)
3802
+ const clock_ = Context.get(fiber.getFiberRef(defaultServices.currentServices), clock.clockTag)
3803
+ return core.as(
3804
+ core.scopeAddFinalizerExit(scope, (exit) => internalEffect.endSpan(span, exit, clock_, timingEnabled)),
3805
+ span
3806
+ )
3807
+ })
3808
+ )
3809
+ }
3810
+
3811
+ /* @internal */
3812
+ export const withTracerScoped = (value: Tracer.Tracer): Effect.Effect<void, never, Scope.Scope> =>
3813
+ fiberRefLocallyScopedWith(defaultServices.currentServices, Context.add(tracer.tracerTag, value))
3814
+
3815
+ /** @internal */
3816
+ export const withSpanScoped: {
3817
+ (
3818
+ name: string,
3819
+ options?: Tracer.SpanOptions
3820
+ ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Scope.Scope | Exclude<R, Tracer.ParentSpan>>
3821
+ <A, E, R>(
3822
+ self: Effect.Effect<A, E, R>,
3823
+ name: string,
3824
+ options?: Tracer.SpanOptions
3825
+ ): Effect.Effect<A, E, Scope.Scope | Exclude<R, Tracer.ParentSpan>>
3826
+ } = function() {
3827
+ const dataFirst = typeof arguments[0] !== "string"
3828
+ const name = dataFirst ? arguments[1] : arguments[0]
3829
+ const options = tracer.addSpanStackTrace(dataFirst ? arguments[2] : arguments[1])
3830
+ if (dataFirst) {
3831
+ const self = arguments[0]
3832
+ return core.flatMap(
3833
+ makeSpanScoped(name, tracer.addSpanStackTrace(options)),
3834
+ (span) => internalEffect.provideService(self, tracer.spanTag, span)
3835
+ )
3836
+ }
3837
+ return (self: Effect.Effect<any, any, any>) =>
3838
+ core.flatMap(
3839
+ makeSpanScoped(name, tracer.addSpanStackTrace(options)),
3840
+ (span) => internalEffect.provideService(self, tracer.spanTag, span)
3841
+ )
3842
+ } as any