effect 3.10.19 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/cjs/BigDecimal.js +125 -24
  2. package/dist/cjs/BigDecimal.js.map +1 -1
  3. package/dist/cjs/Channel.js +44 -4
  4. package/dist/cjs/Channel.js.map +1 -1
  5. package/dist/cjs/Config.js +8 -1
  6. package/dist/cjs/Config.js.map +1 -1
  7. package/dist/cjs/Context.js +26 -1
  8. package/dist/cjs/Context.js.map +1 -1
  9. package/dist/cjs/Cron.js +75 -67
  10. package/dist/cjs/Cron.js.map +1 -1
  11. package/dist/cjs/DateTime.js +114 -664
  12. package/dist/cjs/DateTime.js.map +1 -1
  13. package/dist/cjs/Effect.js +82 -4
  14. package/dist/cjs/Effect.js.map +1 -1
  15. package/dist/cjs/Inspectable.js +8 -4
  16. package/dist/cjs/Inspectable.js.map +1 -1
  17. package/dist/cjs/JSONSchema.js.map +1 -1
  18. package/dist/cjs/Micro.js +1099 -1072
  19. package/dist/cjs/Micro.js.map +1 -1
  20. package/dist/cjs/STM.js.map +1 -1
  21. package/dist/cjs/Schema.js +57 -8
  22. package/dist/cjs/Schema.js.map +1 -1
  23. package/dist/cjs/Sink.js +9 -1
  24. package/dist/cjs/Sink.js.map +1 -1
  25. package/dist/cjs/Stream.js +25 -7
  26. package/dist/cjs/Stream.js.map +1 -1
  27. package/dist/cjs/Utils.js +7 -1
  28. package/dist/cjs/Utils.js.map +1 -1
  29. package/dist/cjs/internal/channel/channelExecutor.js +5 -9
  30. package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
  31. package/dist/cjs/internal/channel.js +156 -130
  32. package/dist/cjs/internal/channel.js.map +1 -1
  33. package/dist/cjs/internal/config.js +13 -4
  34. package/dist/cjs/internal/config.js.map +1 -1
  35. package/dist/cjs/internal/context.js +46 -3
  36. package/dist/cjs/internal/context.js.map +1 -1
  37. package/dist/cjs/internal/dateTime.js +747 -0
  38. package/dist/cjs/internal/dateTime.js.map +1 -0
  39. package/dist/cjs/internal/fiberRuntime.js +34 -11
  40. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  41. package/dist/cjs/internal/groupBy.js +9 -3
  42. package/dist/cjs/internal/groupBy.js.map +1 -1
  43. package/dist/cjs/internal/layer.js +1 -1
  44. package/dist/cjs/internal/layer.js.map +1 -1
  45. package/dist/cjs/internal/mailbox.js +1 -1
  46. package/dist/cjs/internal/mailbox.js.map +1 -1
  47. package/dist/cjs/internal/sink.js +25 -21
  48. package/dist/cjs/internal/sink.js.map +1 -1
  49. package/dist/cjs/internal/stream.js +70 -71
  50. package/dist/cjs/internal/stream.js.map +1 -1
  51. package/dist/cjs/internal/version.js +1 -1
  52. package/dist/cjs/internal/version.js.map +1 -1
  53. package/dist/dts/BigDecimal.d.ts +56 -1
  54. package/dist/dts/BigDecimal.d.ts.map +1 -1
  55. package/dist/dts/Channel.d.ts +66 -5
  56. package/dist/dts/Channel.d.ts.map +1 -1
  57. package/dist/dts/Config.d.ts +23 -1
  58. package/dist/dts/Config.d.ts.map +1 -1
  59. package/dist/dts/Context.d.ts +111 -0
  60. package/dist/dts/Context.d.ts.map +1 -1
  61. package/dist/dts/Cron.d.ts +15 -6
  62. package/dist/dts/Cron.d.ts.map +1 -1
  63. package/dist/dts/DateTime.d.ts +40 -49
  64. package/dist/dts/DateTime.d.ts.map +1 -1
  65. package/dist/dts/Effect.d.ts +88 -1
  66. package/dist/dts/Effect.d.ts.map +1 -1
  67. package/dist/dts/Inspectable.d.ts.map +1 -1
  68. package/dist/dts/JSONSchema.d.ts +1 -0
  69. package/dist/dts/JSONSchema.d.ts.map +1 -1
  70. package/dist/dts/Micro.d.ts +875 -872
  71. package/dist/dts/Micro.d.ts.map +1 -1
  72. package/dist/dts/STM.d.ts +2 -0
  73. package/dist/dts/STM.d.ts.map +1 -1
  74. package/dist/dts/Schema.d.ts +32 -0
  75. package/dist/dts/Schema.d.ts.map +1 -1
  76. package/dist/dts/Sink.d.ts +8 -0
  77. package/dist/dts/Sink.d.ts.map +1 -1
  78. package/dist/dts/Stream.d.ts +50 -32
  79. package/dist/dts/Stream.d.ts.map +1 -1
  80. package/dist/dts/Utils.d.ts +4 -0
  81. package/dist/dts/Utils.d.ts.map +1 -1
  82. package/dist/dts/internal/context.d.ts +1 -1
  83. package/dist/dts/internal/context.d.ts.map +1 -1
  84. package/dist/dts/internal/dateTime.d.ts +2 -0
  85. package/dist/dts/internal/dateTime.d.ts.map +1 -0
  86. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  87. package/dist/dts/internal/stream.d.ts.map +1 -1
  88. package/dist/esm/BigDecimal.js +119 -20
  89. package/dist/esm/BigDecimal.js.map +1 -1
  90. package/dist/esm/Channel.js +42 -2
  91. package/dist/esm/Channel.js.map +1 -1
  92. package/dist/esm/Config.js +7 -0
  93. package/dist/esm/Config.js.map +1 -1
  94. package/dist/esm/Context.js +25 -0
  95. package/dist/esm/Context.js.map +1 -1
  96. package/dist/esm/Cron.js +75 -67
  97. package/dist/esm/Cron.js.map +1 -1
  98. package/dist/esm/DateTime.js +112 -627
  99. package/dist/esm/DateTime.js.map +1 -1
  100. package/dist/esm/Effect.js +77 -0
  101. package/dist/esm/Effect.js.map +1 -1
  102. package/dist/esm/Inspectable.js +8 -4
  103. package/dist/esm/Inspectable.js.map +1 -1
  104. package/dist/esm/JSONSchema.js.map +1 -1
  105. package/dist/esm/Micro.js +1077 -1047
  106. package/dist/esm/Micro.js.map +1 -1
  107. package/dist/esm/STM.js.map +1 -1
  108. package/dist/esm/Schema.js +54 -0
  109. package/dist/esm/Schema.js.map +1 -1
  110. package/dist/esm/Sink.js +8 -0
  111. package/dist/esm/Sink.js.map +1 -1
  112. package/dist/esm/Stream.js +23 -5
  113. package/dist/esm/Stream.js.map +1 -1
  114. package/dist/esm/Utils.js +5 -0
  115. package/dist/esm/Utils.js.map +1 -1
  116. package/dist/esm/internal/channel/channelExecutor.js +5 -7
  117. package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
  118. package/dist/esm/internal/channel.js +152 -129
  119. package/dist/esm/internal/channel.js.map +1 -1
  120. package/dist/esm/internal/config.js +11 -3
  121. package/dist/esm/internal/config.js.map +1 -1
  122. package/dist/esm/internal/context.js +42 -2
  123. package/dist/esm/internal/context.js.map +1 -1
  124. package/dist/esm/internal/dateTime.js +704 -0
  125. package/dist/esm/internal/dateTime.js.map +1 -0
  126. package/dist/esm/internal/fiberRuntime.js +31 -9
  127. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  128. package/dist/esm/internal/groupBy.js +9 -3
  129. package/dist/esm/internal/groupBy.js.map +1 -1
  130. package/dist/esm/internal/layer.js +1 -1
  131. package/dist/esm/internal/layer.js.map +1 -1
  132. package/dist/esm/internal/mailbox.js +1 -1
  133. package/dist/esm/internal/mailbox.js.map +1 -1
  134. package/dist/esm/internal/sink.js +23 -20
  135. package/dist/esm/internal/sink.js.map +1 -1
  136. package/dist/esm/internal/stream.js +66 -69
  137. package/dist/esm/internal/stream.js.map +1 -1
  138. package/dist/esm/internal/version.js +1 -1
  139. package/dist/esm/internal/version.js.map +1 -1
  140. package/package.json +1 -1
  141. package/src/BigDecimal.ts +131 -21
  142. package/src/Channel.ts +81 -5
  143. package/src/Config.ts +24 -1
  144. package/src/Context.ts +119 -0
  145. package/src/Cron.ts +85 -68
  146. package/src/DateTime.ts +155 -757
  147. package/src/Effect.ts +340 -1
  148. package/src/Inspectable.ts +11 -7
  149. package/src/JSONSchema.ts +1 -0
  150. package/src/Micro.ts +2005 -1757
  151. package/src/STM.ts +2 -0
  152. package/src/Schema.ts +60 -0
  153. package/src/Sink.ts +11 -0
  154. package/src/Stream.ts +55 -44
  155. package/src/Utils.ts +8 -0
  156. package/src/internal/channel/channelExecutor.ts +37 -33
  157. package/src/internal/channel.ts +504 -467
  158. package/src/internal/config.ts +18 -6
  159. package/src/internal/context.ts +56 -4
  160. package/src/internal/dateTime.ts +1126 -0
  161. package/src/internal/fiberRuntime.ts +35 -16
  162. package/src/internal/groupBy.ts +13 -22
  163. package/src/internal/layer.ts +5 -8
  164. package/src/internal/mailbox.ts +6 -4
  165. package/src/internal/sink.ts +55 -35
  166. package/src/internal/stream.ts +299 -299
  167. package/src/internal/version.ts +1 -1
package/dist/cjs/Micro.js CHANGED
@@ -3,23 +3,33 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.locally = exports.let = exports.isMicroCause = exports.isMicro = exports.isHandle = exports.interruptible = exports.interrupt = exports.ignoreLogged = exports.ignore = exports.getEnvRef = exports.gen = exports.fromOption = exports.fromExitSync = exports.fromExit = exports.fromEither = exports.forkScoped = exports.forkIn = exports.forkDaemon = exports.fork = exports.forever = exports.forEach = exports.flip = exports.flatten = exports.flatMap = exports.filterOrFailCause = exports.filterOrFail = exports.filterMap = exports.filter = exports.failSync = exports.failCauseSync = exports.failCause = exports.fail = exports.exitVoid = exports.exitSucceed = exports.exitIsSuccess = exports.exitIsInterrupt = exports.exitIsFailure = exports.exitIsFail = exports.exitIsDie = exports.exitInterrupt = exports.exitFailCause = exports.exitFail = exports.exitDie = exports.exit = exports.envUnsafeMakeEmpty = exports.envSet = exports.envRefMake = exports.envMutate = exports.envMake = exports.envGet = exports.ensuring = exports.either = exports.die = exports.delay = exports.currentScheduler = exports.currentMaxDepthBeforeYield = exports.currentContext = exports.currentConcurrency = exports.currentAbortSignal = exports.currentAbortController = exports.context = exports.causeWithTrace = exports.causeSquash = exports.causeIsInterrupt = exports.causeIsFail = exports.causeIsDie = exports.causeInterrupt = exports.causeFail = exports.causeDie = exports.catchTag = exports.catchIf = exports.catchCauseIf = exports.catchAllDefect = exports.catchAllCause = exports.catchAll = exports.bindTo = exports.bind = exports.async = exports.asVoid = exports.asSome = exports.as = exports.andThen = exports.all = exports.addFinalizer = exports.acquireUseRelease = exports.acquireRelease = exports.TypeId = exports.TimeoutException = exports.TaggedError = exports.NoSuchElementException = exports.MicroScopeTypeId = exports.MicroScope = exports.MicroSchedulerDefault = exports.MicroCauseTypeId = exports.HandleTypeId = exports.Error = exports.EnvTypeId = exports.EnvRefTypeId = exports.Do = exports.Class = void 0;
7
- exports.zipWith = exports.zip = exports.yieldWithPriority = exports.yieldNow = exports.yieldFlush = exports.withTrace = exports.withConcurrency = exports.when = exports.void = exports.uninterruptibleMask = exports.uninterruptible = exports.tryPromise = exports.try = exports.timeoutOrElse = exports.timeoutOption = exports.timeout = exports.tapErrorCauseIf = exports.tapErrorCause = exports.tapError = exports.tapDefect = exports.tap = exports.sync = exports.suspend = exports.succeedSome = exports.succeedNone = exports.succeed = exports.sleep = exports.serviceOption = exports.service = exports.scoped = exports.scopeUnsafeMake = exports.scopeMake = exports.scope = exports.scheduleWithMaxElapsed = exports.scheduleWithMaxDelay = exports.scheduleUnion = exports.scheduleSpaced = exports.scheduleRecurs = exports.scheduleIntersect = exports.scheduleExponential = exports.scheduleAddDelay = exports.sandbox = exports.runSyncExit = exports.runSync = exports.runSymbol = exports.runPromiseExit = exports.runPromise = exports.runFork = exports.retry = exports.repeatExit = exports.repeat = exports.raceFirst = exports.raceAllFirst = exports.raceAll = exports.race = exports.provideServiceEffect = exports.provideService = exports.provideScope = exports.provideContext = exports.promise = exports.orElseSucceed = exports.orDie = exports.option = exports.onInterrupt = exports.onExitIf = exports.onExit = exports.onError = exports.never = exports.matchEffect = exports.matchCauseEffect = exports.matchCause = exports.match = exports.mapErrorCause = exports.mapError = exports.map = exports.make = void 0;
6
+ exports.onExitIf = exports.onExit = exports.onError = exports.never = exports.matchEffect = exports.matchCauseEffect = exports.matchCause = exports.match = exports.mapErrorCause = exports.mapError = exports.map = exports.let = exports.isMicroExit = exports.isMicroCause = exports.isMicro = exports.interruptible = exports.interrupt = exports.ignoreLogged = exports.ignore = exports.gen = exports.fromOption = exports.fromEither = exports.forkScoped = exports.forkIn = exports.forkDaemon = exports.fork = exports.forever = exports.forEach = exports.flip = exports.flatten = exports.flatMap = exports.filterOrFailCause = exports.filterOrFail = exports.filterMap = exports.filter = exports.fiberInterruptAll = exports.fiberInterrupt = exports.fiberAwait = exports.failSync = exports.failCauseSync = exports.failCause = exports.fail = exports.exitVoidAll = exports.exitVoid = exports.exitSucceed = exports.exitIsSuccess = exports.exitIsInterrupt = exports.exitIsFailure = exports.exitIsFail = exports.exitIsDie = exports.exitInterrupt = exports.exitFailCause = exports.exitFail = exports.exitDie = exports.exit = exports.ensuring = exports.either = exports.die = exports.delay = exports.context = exports.causeWithTrace = exports.causeSquash = exports.causeIsInterrupt = exports.causeIsFail = exports.causeIsDie = exports.causeInterrupt = exports.causeFail = exports.causeDie = exports.catchTag = exports.catchIf = exports.catchCauseIf = exports.catchAllDefect = exports.catchAllCause = exports.catchAll = exports.bindTo = exports.bind = exports.async = exports.asVoid = exports.asSome = exports.as = exports.andThen = exports.all = exports.addFinalizer = exports.acquireUseRelease = exports.acquireRelease = exports.TypeId = exports.TimeoutException = exports.TaggedError = exports.NoSuchElementException = exports.MicroScopeTypeId = exports.MicroScope = exports.MicroSchedulerDefault = exports.MicroExitTypeId = exports.MicroCauseTypeId = exports.MaxOpsBeforeYield = exports.FiberTypeId = exports.Error = exports.Do = exports.CurrentScheduler = exports.CurrentConcurrency = void 0;
7
+ exports.zipWith = exports.zip = exports.yieldNowWith = exports.yieldNow = exports.yieldFlush = exports.withTrace = exports.withFiber = exports.withConcurrency = exports.whileLoop = exports.when = exports.void = exports.updateService = exports.updateContext = exports.uninterruptibleMask = exports.uninterruptible = exports.tryPromise = exports.try = exports.timeoutOrElse = exports.timeoutOption = exports.timeout = exports.tapErrorCauseIf = exports.tapErrorCause = exports.tapError = exports.tapDefect = exports.tap = exports.sync = exports.suspend = exports.succeedSome = exports.succeedNone = exports.succeed = exports.sleep = exports.serviceOption = exports.service = exports.scoped = exports.scopeUnsafeMake = exports.scopeMake = exports.scope = exports.scheduleWithMaxElapsed = exports.scheduleWithMaxDelay = exports.scheduleUnion = exports.scheduleSpaced = exports.scheduleRecurs = exports.scheduleIntersect = exports.scheduleExponential = exports.scheduleAddDelay = exports.sandbox = exports.runSyncExit = exports.runSync = exports.runPromiseExit = exports.runPromise = exports.runFork = exports.retry = exports.replicateEffect = exports.replicate = exports.repeatExit = exports.repeat = exports.raceFirst = exports.raceAllFirst = exports.raceAll = exports.race = exports.provideServiceEffect = exports.provideService = exports.provideScope = exports.provideContext = exports.promise = exports.orElseSucceed = exports.orDie = exports.option = exports.onInterrupt = void 0;
8
+ var Arr = _interopRequireWildcard(require("effect/Array"));
8
9
  var Context = _interopRequireWildcard(require("./Context.js"));
9
10
  var Effectable = _interopRequireWildcard(require("./Effectable.js"));
10
11
  var Either = _interopRequireWildcard(require("./Either.js"));
12
+ var Equal = _interopRequireWildcard(require("./Equal.js"));
11
13
  var _Function = require("./Function.js");
12
14
  var _GlobalValue = require("./GlobalValue.js");
15
+ var Hash = _interopRequireWildcard(require("./Hash.js"));
13
16
  var _Inspectable = require("./Inspectable.js");
17
+ var InternalContext = _interopRequireWildcard(require("./internal/context.js"));
14
18
  var doNotation = _interopRequireWildcard(require("./internal/doNotation.js"));
15
19
  var _effectable = require("./internal/effectable.js");
16
- var _singleShotGen = require("./internal/singleShotGen.js");
17
20
  var Option = _interopRequireWildcard(require("./Option.js"));
18
21
  var _Pipeable = require("./Pipeable.js");
19
22
  var _Predicate = require("./Predicate.js");
20
23
  var _Utils = require("./Utils.js");
21
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
25
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
26
+ /**
27
+ * A lightweight alternative to the `Effect` data type, with a subset of the functionality.
28
+ *
29
+ * @since 3.4.0
30
+ * @experimental
31
+ */
32
+
23
33
  /**
24
34
  * @since 3.4.0
25
35
  * @experimental
@@ -29,9 +39,9 @@ const TypeId = exports.TypeId = /*#__PURE__*/Symbol.for("effect/Micro");
29
39
  /**
30
40
  * @since 3.4.0
31
41
  * @experimental
32
- * @category symbols
42
+ * @category MicroExit
33
43
  */
34
- const runSymbol = exports.runSymbol = /*#__PURE__*/Symbol.for("effect/Micro/runSymbol");
44
+ const MicroExitTypeId = exports.MicroExitTypeId = /*#__PURE__*/Symbol.for("effect/Micro/MicroExit");
35
45
  /**
36
46
  * @since 3.4.0
37
47
  * @experimental
@@ -39,41 +49,6 @@ const runSymbol = exports.runSymbol = /*#__PURE__*/Symbol.for("effect/Micro/runS
39
49
  */
40
50
  const isMicro = u => typeof u === "object" && u !== null && TypeId in u;
41
51
  // ----------------------------------------------------------------------------
42
- // Microable
43
- // ----------------------------------------------------------------------------
44
- exports.isMicro = isMicro;
45
- const MicroProto = {
46
- ...Effectable.EffectPrototype,
47
- _op: "Micro",
48
- [TypeId]: {
49
- _A: _Function.identity,
50
- _E: _Function.identity,
51
- _R: _Function.identity
52
- },
53
- [Symbol.iterator]() {
54
- return new _singleShotGen.SingleShotGen(new _Utils.YieldWrap(this));
55
- }
56
- };
57
- const MicroBase = /*#__PURE__*/function () {
58
- function Base() {}
59
- Base.prototype = MicroProto;
60
- return Base;
61
- }();
62
- /**
63
- * @since 3.8.4
64
- * @experimental
65
- * @category constructors
66
- */
67
- class Class extends MicroBase {
68
- /**
69
- * @since 3.8.4
70
- * @experimental
71
- */
72
- [runSymbol](env, onExit) {
73
- this.asMicro()[runSymbol](env, onExit);
74
- }
75
- }
76
- // ----------------------------------------------------------------------------
77
52
  // MicroCause
78
53
  // ----------------------------------------------------------------------------
79
54
  /**
@@ -81,7 +56,7 @@ class Class extends MicroBase {
81
56
  * @experimental
82
57
  * @category MicroCause
83
58
  */
84
- exports.Class = Class;
59
+ exports.isMicro = isMicro;
85
60
  const MicroCauseTypeId = exports.MicroCauseTypeId = /*#__PURE__*/Symbol.for("effect/Micro/MicroCause");
86
61
  /**
87
62
  * @since 3.6.6
@@ -216,989 +191,1113 @@ const causeWithTrace = exports.causeWithTrace = /*#__PURE__*/(0, _Function.dual)
216
191
  return causeFail(self.error, traces);
217
192
  }
218
193
  });
194
+ // ----------------------------------------------------------------------------
195
+ // Fiber
196
+ // ----------------------------------------------------------------------------
219
197
  /**
220
- * @since 3.4.6
221
- * @experimental
222
- * @category MicroExit
223
- */
224
- const exitInterrupt = exports.exitInterrupt = /*#__PURE__*/Either.left( /*#__PURE__*/causeInterrupt());
225
- /**
226
- * @since 3.4.6
227
- * @experimental
228
- * @category MicroExit
229
- */
230
- const exitSucceed = exports.exitSucceed = Either.right;
231
- /**
232
- * @since 3.4.6
233
- * @experimental
234
- * @category MicroExit
235
- */
236
- const exitFail = e => Either.left(causeFail(e));
237
- /**
238
- * @since 3.4.6
239
- * @experimental
240
- * @category MicroExit
241
- */
242
- exports.exitFail = exitFail;
243
- const exitDie = defect => Either.left(causeDie(defect));
244
- /**
245
- * @since 3.4.6
246
- * @experimental
247
- * @category MicroExit
248
- */
249
- exports.exitDie = exitDie;
250
- const exitFailCause = exports.exitFailCause = Either.left;
251
- /**
252
- * @since 3.4.6
253
- * @experimental
254
- * @category MicroExit
255
- */
256
- const exitIsSuccess = exports.exitIsSuccess = Either.isRight;
257
- /**
258
- * @since 3.4.6
259
- * @experimental
260
- * @category MicroExit
261
- */
262
- const exitIsFailure = exports.exitIsFailure = Either.isLeft;
263
- /**
264
- * @since 3.4.6
265
- * @experimental
266
- * @category MicroExit
267
- */
268
- const exitIsInterrupt = self => exitIsFailure(self) && self.left._tag === "Interrupt";
269
- /**
270
- * @since 3.4.6
198
+ * @since 3.11.0
271
199
  * @experimental
272
- * @category MicroExit
200
+ * @category Fiber
273
201
  */
274
- exports.exitIsInterrupt = exitIsInterrupt;
275
- const exitIsFail = self => exitIsFailure(self) && self.left._tag === "Fail";
202
+ const FiberTypeId = exports.FiberTypeId = /*#__PURE__*/Symbol.for("effect/Micro/Fiber");
203
+ const fiberVariance = {
204
+ _A: _Function.identity,
205
+ _E: _Function.identity
206
+ };
207
+ class FiberImpl {
208
+ context;
209
+ interruptible;
210
+ [FiberTypeId];
211
+ _stack = [];
212
+ _observers = [];
213
+ _exit;
214
+ _children;
215
+ currentOpCount = 0;
216
+ constructor(context, interruptible = true) {
217
+ this.context = context;
218
+ this.interruptible = interruptible;
219
+ this[FiberTypeId] = fiberVariance;
220
+ }
221
+ getRef(ref) {
222
+ return InternalContext.unsafeGetReference(this.context, ref);
223
+ }
224
+ addObserver(cb) {
225
+ if (this._exit) {
226
+ cb(this._exit);
227
+ return _Function.constVoid;
228
+ }
229
+ this._observers.push(cb);
230
+ return () => {
231
+ const index = this._observers.indexOf(cb);
232
+ if (index >= 0) {
233
+ this._observers.splice(index, 1);
234
+ }
235
+ };
236
+ }
237
+ _interrupted = false;
238
+ unsafeInterrupt() {
239
+ if (this._exit) {
240
+ return;
241
+ }
242
+ this._interrupted = true;
243
+ if (this.interruptible) {
244
+ this.evaluate(exitInterrupt);
245
+ }
246
+ }
247
+ unsafePoll() {
248
+ return this._exit;
249
+ }
250
+ evaluate(effect) {
251
+ if (this._exit) {
252
+ return;
253
+ } else if (this._yielded !== undefined) {
254
+ const yielded = this._yielded;
255
+ this._yielded = undefined;
256
+ yielded();
257
+ }
258
+ const exit = this.runLoop(effect);
259
+ if (exit === Yield) {
260
+ return;
261
+ }
262
+ // the interruptChildren middlware is added in Micro.fork, so it can be
263
+ // tree-shaken if not used
264
+ const interruptChildren = fiberMiddleware.interruptChildren && fiberMiddleware.interruptChildren(this);
265
+ if (interruptChildren !== undefined) {
266
+ return this.evaluate(flatMap(interruptChildren, () => exit));
267
+ }
268
+ this._exit = exit;
269
+ for (let i = 0; i < this._observers.length; i++) {
270
+ this._observers[i](exit);
271
+ }
272
+ this._observers.length = 0;
273
+ }
274
+ runLoop(effect) {
275
+ let yielding = false;
276
+ let current = effect;
277
+ this.currentOpCount = 0;
278
+ try {
279
+ while (true) {
280
+ this.currentOpCount++;
281
+ if (!yielding && this.getRef(CurrentScheduler).shouldYield(this)) {
282
+ yielding = true;
283
+ const prev = current;
284
+ current = flatMap(yieldNow, () => prev);
285
+ }
286
+ current = current[evaluate](this);
287
+ if (current === Yield) {
288
+ const yielded = this._yielded;
289
+ if (MicroExitTypeId in yielded) {
290
+ this._yielded = undefined;
291
+ return yielded;
292
+ }
293
+ return Yield;
294
+ }
295
+ }
296
+ } catch (error) {
297
+ if (!(0, _Predicate.hasProperty)(current, evaluate)) {
298
+ return exitDie(`Micro/Fiber.runLoop: Not a valid effect: ${String(current)}`);
299
+ }
300
+ return exitDie(error);
301
+ }
302
+ }
303
+ getCont(symbol) {
304
+ while (true) {
305
+ const op = this._stack.pop();
306
+ if (!op) return undefined;
307
+ const cont = op[ensureCont] && op[ensureCont](this);
308
+ if (cont) return {
309
+ [symbol]: cont
310
+ };
311
+ if (op[symbol]) return op;
312
+ }
313
+ }
314
+ // cancel the yielded operation, or for the yielded exit value
315
+ _yielded = undefined;
316
+ yieldWith(value) {
317
+ this._yielded = value;
318
+ return Yield;
319
+ }
320
+ children() {
321
+ return this._children ??= new Set();
322
+ }
323
+ }
324
+ const fiberMiddleware = /*#__PURE__*/(0, _GlobalValue.globalValue)("effect/Micro/fiberMiddleware", () => ({
325
+ interruptChildren: undefined
326
+ }));
327
+ const fiberInterruptChildren = fiber => {
328
+ if (fiber._children === undefined || fiber._children.size === 0) {
329
+ return undefined;
330
+ }
331
+ return fiberInterruptAll(fiber._children);
332
+ };
276
333
  /**
277
- * @since 3.4.6
334
+ * @since 3.11.0
278
335
  * @experimental
279
- * @category MicroExit
336
+ * @category Fiber
280
337
  */
281
- exports.exitIsFail = exitIsFail;
282
- const exitIsDie = self => exitIsFailure(self) && self.left._tag === "Die";
338
+ const fiberAwait = self => async(resume => sync(self.addObserver(exit => resume(succeed(exit)))));
283
339
  /**
284
- * @since 3.4.6
340
+ * @since 3.11.0
285
341
  * @experimental
286
- * @category MicroExit
342
+ * @category Fiber
287
343
  */
288
- exports.exitIsDie = exitIsDie;
289
- const exitVoid = exports.exitVoid = /*#__PURE__*/exitSucceed(void 0);
290
- // ----------------------------------------------------------------------------
291
- // env
292
- // ----------------------------------------------------------------------------
344
+ exports.fiberAwait = fiberAwait;
345
+ const fiberInterrupt = self => suspend(() => {
346
+ self.unsafeInterrupt();
347
+ return asVoid(fiberAwait(self));
348
+ });
293
349
  /**
294
- * @since 3.4.0
350
+ * @since 3.11.0
295
351
  * @experimental
296
- * @category environment
352
+ * @category Fiber
297
353
  */
298
- const EnvTypeId = exports.EnvTypeId = /*#__PURE__*/Symbol.for("effect/Micro/Env");
299
- const EnvProto = {
300
- [EnvTypeId]: {
301
- _R: _Function.identity
302
- },
354
+ exports.fiberInterrupt = fiberInterrupt;
355
+ const fiberInterruptAll = fibers => suspend(() => {
356
+ for (const fiber of fibers) fiber.unsafeInterrupt();
357
+ const iter = fibers[Symbol.iterator]();
358
+ const wait = suspend(() => {
359
+ let result = iter.next();
360
+ while (!result.done) {
361
+ if (result.value.unsafePoll()) {
362
+ result = iter.next();
363
+ continue;
364
+ }
365
+ const fiber = result.value;
366
+ return async(resume => {
367
+ fiber.addObserver(_ => {
368
+ resume(wait);
369
+ });
370
+ });
371
+ }
372
+ return exitVoid;
373
+ });
374
+ return wait;
375
+ });
376
+ exports.fiberInterruptAll = fiberInterruptAll;
377
+ const identifier = /*#__PURE__*/Symbol.for("effect/Micro/identifier");
378
+ const args = /*#__PURE__*/Symbol.for("effect/Micro/args");
379
+ const evaluate = /*#__PURE__*/Symbol.for("effect/Micro/evaluate");
380
+ const successCont = /*#__PURE__*/Symbol.for("effect/Micro/successCont");
381
+ const failureCont = /*#__PURE__*/Symbol.for("effect/Micro/failureCont");
382
+ const ensureCont = /*#__PURE__*/Symbol.for("effect/Micro/ensureCont");
383
+ const Yield = /*#__PURE__*/Symbol.for("effect/Micro/Yield");
384
+ const microVariance = {
385
+ _A: _Function.identity,
386
+ _E: _Function.identity,
387
+ _R: _Function.identity
388
+ };
389
+ const MicroProto = {
390
+ ...Effectable.EffectPrototype,
391
+ _op: "Micro",
392
+ [TypeId]: microVariance,
303
393
  pipe() {
304
394
  return (0, _Pipeable.pipeArguments)(this, arguments);
395
+ },
396
+ [Symbol.iterator]() {
397
+ return new _Utils.SingleShotGen(new _Utils.YieldWrap(this));
398
+ },
399
+ toJSON() {
400
+ return {
401
+ _id: "effect/Micro",
402
+ op: this[identifier],
403
+ ...(args in this ? {
404
+ args: this[args]
405
+ } : undefined)
406
+ };
407
+ },
408
+ toString() {
409
+ return (0, _Inspectable.format)(this);
410
+ },
411
+ [_Inspectable.NodeInspectSymbol]() {
412
+ return (0, _Inspectable.format)(this);
305
413
  }
306
414
  };
307
- /**
308
- * @since 3.4.0
309
- * @experimental
310
- * @category environment
311
- */
312
- const envMake = refs => {
313
- const self = Object.create(EnvProto);
314
- self.refs = refs;
315
- return self;
415
+ function defaultEvaluate(_fiber) {
416
+ return exitDie(`Micro.evaluate: Not implemented`);
417
+ }
418
+ const makePrimitiveProto = options => ({
419
+ ...MicroProto,
420
+ [identifier]: options.op,
421
+ [evaluate]: options.eval ?? defaultEvaluate,
422
+ [successCont]: options.contA,
423
+ [failureCont]: options.contE,
424
+ [ensureCont]: options.ensure
425
+ });
426
+ const makePrimitive = options => {
427
+ const Proto = makePrimitiveProto(options);
428
+ return function () {
429
+ const self = Object.create(Proto);
430
+ self[args] = options.single === false ? arguments : arguments[0];
431
+ return self;
432
+ };
433
+ };
434
+ const makeExit = options => {
435
+ const Proto = {
436
+ ...makePrimitiveProto(options),
437
+ [MicroExitTypeId]: MicroExitTypeId,
438
+ _tag: options.op,
439
+ get [options.prop]() {
440
+ return this[args];
441
+ },
442
+ toJSON() {
443
+ return {
444
+ _id: "effect/Micro/Exit",
445
+ _tag: options.op,
446
+ [options.prop]: this[args]
447
+ };
448
+ },
449
+ [Equal.symbol](that) {
450
+ return isMicroExit(that) && that._tag === options.op && Equal.equals(this[args], that[args]);
451
+ },
452
+ [Hash.symbol]() {
453
+ return Hash.cached(this, Hash.combine(Hash.string(options.op))(Hash.hash(this[args])));
454
+ }
455
+ };
456
+ return function (value) {
457
+ const self = Object.create(Proto);
458
+ self[args] = value;
459
+ self[successCont] = undefined;
460
+ self[failureCont] = undefined;
461
+ self[ensureCont] = undefined;
462
+ return self;
463
+ };
316
464
  };
317
465
  /**
466
+ * Creates a `Micro` effect that will succeed with the specified constant value.
467
+ *
318
468
  * @since 3.4.0
319
469
  * @experimental
320
- * @category environment
470
+ * @category constructors
321
471
  */
322
- exports.envMake = envMake;
323
- const envUnsafeMakeEmpty = () => {
324
- const controller = new AbortController();
325
- const refs = Object.create(null);
326
- refs[currentAbortController.key] = controller;
327
- refs[currentAbortSignal.key] = controller.signal;
328
- refs[currentScheduler.key] = new MicroSchedulerDefault();
329
- return envMake(refs);
330
- };
472
+ const succeed = exports.succeed = /*#__PURE__*/makeExit({
473
+ op: "Success",
474
+ prop: "value",
475
+ eval(fiber) {
476
+ const cont = fiber.getCont(successCont);
477
+ return cont ? cont[successCont](this[args], fiber) : fiber.yieldWith(this);
478
+ }
479
+ });
331
480
  /**
332
- * @since 3.4.0
481
+ * Creates a `Micro` effect that will fail with the specified `MicroCause`.
482
+ *
483
+ * @since 3.4.6
333
484
  * @experimental
334
- * @category environment
485
+ * @category constructors
335
486
  */
336
- exports.envUnsafeMakeEmpty = envUnsafeMakeEmpty;
337
- const envGet = exports.envGet = /*#__PURE__*/(0, _Function.dual)(2, (self, ref) => ref.key in self.refs ? self.refs[ref.key] : ref.initial);
487
+ const failCause = exports.failCause = /*#__PURE__*/makeExit({
488
+ op: "Failure",
489
+ prop: "cause",
490
+ eval(fiber) {
491
+ let cont = fiber.getCont(failureCont);
492
+ while (causeIsInterrupt(this[args]) && cont && fiber.interruptible) {
493
+ cont = fiber.getCont(failureCont);
494
+ }
495
+ return cont ? cont[failureCont](this[args], fiber) : fiber.yieldWith(this);
496
+ }
497
+ });
338
498
  /**
499
+ * Creates a `Micro` effect that will fail with the specified error.
500
+ *
501
+ * This will result in a `CauseFail`, where the error is tracked at the
502
+ * type level.
503
+ *
339
504
  * @since 3.4.0
340
505
  * @experimental
341
- * @category environment
506
+ * @category constructors
342
507
  */
343
- const envSet = exports.envSet = /*#__PURE__*/(0, _Function.dual)(3, (self, ref, value) => {
344
- const refs = Object.assign(Object.create(null), self.refs);
345
- refs[ref.key] = value;
346
- return envMake(refs);
347
- });
508
+ const fail = error => failCause(causeFail(error));
348
509
  /**
510
+ * Creates a `Micro` effect that will succeed with the lazily evaluated value.
511
+ *
512
+ * If the evaluation of the value throws an error, the effect will fail with
513
+ * `CauseDie`.
514
+ *
349
515
  * @since 3.4.0
350
516
  * @experimental
351
- * @category environment
517
+ * @category constructors
352
518
  */
353
- const envMutate = exports.envMutate = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => envMake(f(Object.assign(Object.create(null), self.refs))));
519
+ exports.fail = fail;
520
+ const sync = exports.sync = /*#__PURE__*/makePrimitive({
521
+ op: "Sync",
522
+ eval(fiber) {
523
+ const value = this[args]();
524
+ const cont = fiber.getCont(successCont);
525
+ return cont ? cont[successCont](value, fiber) : fiber.yieldWith(exitSucceed(value));
526
+ }
527
+ });
354
528
  /**
355
- * Access the given `Context.Tag` from the environment.
529
+ * Lazily creates a `Micro` effect from the given side-effect.
356
530
  *
357
531
  * @since 3.4.0
358
532
  * @experimental
359
- * @category environment
533
+ * @category constructors
360
534
  */
361
- const service = tag => make(function (env, onExit) {
362
- onExit(exitSucceed(Context.get(envGet(env, currentContext), tag)));
535
+ const suspend = exports.suspend = /*#__PURE__*/makePrimitive({
536
+ op: "Suspend",
537
+ eval(_fiber) {
538
+ return this[args]();
539
+ }
363
540
  });
364
541
  /**
365
- * Access the given `Context.Tag` from the environment, without tracking the
366
- * dependency at the type level.
367
- *
368
- * It will return an `Option` of the service, depending on whether it is
369
- * available in the environment or not.
542
+ * Pause the execution of the current `Micro` effect, and resume it on the next
543
+ * scheduler tick.
370
544
  *
371
545
  * @since 3.4.0
372
546
  * @experimental
373
- * @category environment
547
+ * @category constructors
374
548
  */
375
- exports.service = service;
376
- const serviceOption = tag => make(function (env, onExit) {
377
- onExit(exitSucceed(Context.getOption(envGet(env, currentContext), tag)));
549
+ const yieldNowWith = exports.yieldNowWith = /*#__PURE__*/makePrimitive({
550
+ op: "Yield",
551
+ eval(fiber) {
552
+ let resumed = false;
553
+ fiber.getRef(CurrentScheduler).scheduleTask(() => {
554
+ if (resumed) return;
555
+ fiber.evaluate(exitVoid);
556
+ }, this[args] ?? 0);
557
+ return fiber.yieldWith(() => {
558
+ resumed = true;
559
+ });
560
+ }
378
561
  });
379
562
  /**
380
- * Retrieve the current value of the given `EnvRef`.
563
+ * Pause the execution of the current `Micro` effect, and resume it on the next
564
+ * scheduler tick.
381
565
  *
382
566
  * @since 3.4.0
383
567
  * @experimental
384
- * @category environment
568
+ * @category constructors
385
569
  */
386
- exports.serviceOption = serviceOption;
387
- const getEnvRef = envRef => make((env, onExit) => onExit(Either.right(envGet(env, envRef))));
570
+ const yieldNow = exports.yieldNow = /*#__PURE__*/yieldNowWith(0);
388
571
  /**
389
- * Set the value of the given `EnvRef` for the duration of the effect.
572
+ * Creates a `Micro` effect that will succeed with `Option.Some` of the value.
390
573
  *
391
574
  * @since 3.4.0
392
575
  * @experimental
393
- * @category environment
576
+ * @category constructors
394
577
  */
395
- exports.getEnvRef = getEnvRef;
396
- const locally = exports.locally = /*#__PURE__*/(0, _Function.dual)(3, (self, fiberRef, value) => make((env, onExit) => self[runSymbol](envSet(env, fiberRef, value), onExit)));
578
+ const succeedSome = a => succeed(Option.some(a));
397
579
  /**
398
- * Access the current `Context` from the environment.
580
+ * Creates a `Micro` effect that will succeed with `Option.None`.
399
581
  *
400
582
  * @since 3.4.0
401
583
  * @experimental
402
- * @category environment
584
+ * @category constructors
403
585
  */
404
- const context = () => getEnvRef(currentContext);
586
+ exports.succeedSome = succeedSome;
587
+ const succeedNone = exports.succeedNone = /*#__PURE__*/succeed( /*#__PURE__*/Option.none());
405
588
  /**
406
- * Merge the given `Context` with the current context.
589
+ * Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
407
590
  *
408
591
  * @since 3.4.0
409
592
  * @experimental
410
- * @category environment
593
+ * @category constructors
411
594
  */
412
- exports.context = context;
413
- const provideContext = exports.provideContext = /*#__PURE__*/(0, _Function.dual)(2, (self, provided) => make(function (env, onExit) {
414
- const context = envGet(env, currentContext);
415
- const nextEnv = envSet(env, currentContext, Context.merge(context, provided));
416
- self[runSymbol](nextEnv, onExit);
417
- }));
595
+ const failCauseSync = evaluate => suspend(() => failCause(evaluate()));
418
596
  /**
419
- * Add the provided service to the current context.
597
+ * Creates a `Micro` effect that will die with the specified error.
598
+ *
599
+ * This will result in a `CauseDie`, where the error is not tracked at
600
+ * the type level.
420
601
  *
421
602
  * @since 3.4.0
422
603
  * @experimental
423
- * @category environment
604
+ * @category constructors
424
605
  */
425
- const provideService = exports.provideService = /*#__PURE__*/(0, _Function.dual)(3, (self, tag, service) => make(function (env, onExit) {
426
- const context = envGet(env, currentContext);
427
- const nextEnv = envSet(env, currentContext, Context.add(context, tag, service));
428
- self[runSymbol](nextEnv, onExit);
429
- }));
606
+ exports.failCauseSync = failCauseSync;
607
+ const die = defect => exitDie(defect);
430
608
  /**
431
- * Create a service using the provided `Micro` effect, and add it to the
432
- * current context.
609
+ * Creates a `Micro` effect that will fail with the lazily evaluated error.
610
+ *
611
+ * This will result in a `CauseFail`, where the error is tracked at the
612
+ * type level.
433
613
  *
434
614
  * @since 3.4.6
435
615
  * @experimental
436
- * @category environment
616
+ * @category constructors
437
617
  */
438
- const provideServiceEffect = exports.provideServiceEffect = /*#__PURE__*/(0, _Function.dual)(3, (self, tag, acquire) => flatMap(acquire, service => provideService(self, tag, service)));
439
- const setImmediate = "setImmediate" in globalThis ? globalThis.setImmediate : f => setTimeout(f, 0);
440
- /**
441
- * @since 3.5.9
442
- * @experimental
443
- * @category scheduler
444
- */
445
- class MicroSchedulerDefault {
446
- tasks = [];
447
- running = false;
448
- /**
449
- * @since 3.5.9
450
- */
451
- scheduleTask(task, _priority) {
452
- this.tasks.push(task);
453
- if (!this.running) {
454
- this.running = true;
455
- setImmediate(this.afterScheduled);
456
- }
457
- }
458
- /**
459
- * @since 3.5.9
460
- */
461
- afterScheduled = () => {
462
- this.running = false;
463
- this.runTasks();
464
- };
465
- /**
466
- * @since 3.5.9
467
- */
468
- runTasks() {
469
- const tasks = this.tasks;
470
- this.tasks = [];
471
- for (let i = 0, len = tasks.length; i < len; i++) {
472
- tasks[i]();
473
- }
474
- }
475
- /**
476
- * @since 3.5.9
477
- */
478
- shouldYield(_env) {
479
- return false;
480
- }
481
- /**
482
- * @since 3.5.9
483
- */
484
- flush() {
485
- while (this.tasks.length > 0) {
486
- this.runTasks();
487
- }
488
- }
489
- }
490
- // ========================================================================
491
- // Env refs
492
- // ========================================================================
618
+ exports.die = die;
619
+ const failSync = error => suspend(() => fail(error()));
493
620
  /**
621
+ * Converts an `Option` into a `Micro` effect, that will fail with
622
+ * `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
623
+ * value of the option.
624
+ *
494
625
  * @since 3.4.0
495
626
  * @experimental
496
- * @category environment
627
+ * @category constructors
497
628
  */
498
- exports.MicroSchedulerDefault = MicroSchedulerDefault;
499
- const EnvRefTypeId = exports.EnvRefTypeId = /*#__PURE__*/Symbol.for("effect/Micro/EnvRef");
500
- const EnvRefProto = {
501
- ...MicroProto,
502
- [EnvRefTypeId]: EnvRefTypeId,
503
- [runSymbol](env, onExit) {
504
- getEnvRef(this)[runSymbol](env, onExit);
505
- }
506
- };
629
+ exports.failSync = failSync;
630
+ const fromOption = option => option._tag === "Some" ? succeed(option.value) : fail(new NoSuchElementException({}));
507
631
  /**
632
+ * Converts an `Either` into a `Micro` effect, that will fail with the left side
633
+ * of the either if it is a `Left`. Otherwise, it will succeed with the right
634
+ * side of the either.
635
+ *
508
636
  * @since 3.4.0
509
637
  * @experimental
510
- * @category environment refs
638
+ * @category constructors
511
639
  */
512
- const envRefMake = (key, initial) => (0, _GlobalValue.globalValue)(key, () => {
513
- const self = Object.create(EnvRefProto);
514
- self.key = key;
515
- self.initial = initial();
516
- return self;
640
+ exports.fromOption = fromOption;
641
+ const fromEither = either => either._tag === "Right" ? succeed(either.right) : fail(either.left);
642
+ exports.fromEither = fromEither;
643
+ const void_ = exports.void = /*#__PURE__*/succeed(void 0);
644
+ const try_ = options => suspend(() => {
645
+ try {
646
+ return succeed(options.try());
647
+ } catch (err) {
648
+ return fail(options.catch(err));
649
+ }
517
650
  });
651
+ exports.try = try_;
518
652
  /**
653
+ * Wrap a `Promise` into a `Micro` effect. Any errors will result in a
654
+ * `CauseDie`.
655
+ *
519
656
  * @since 3.4.0
520
657
  * @experimental
521
- * @category environment refs
522
- */
523
- exports.envRefMake = envRefMake;
524
- const currentAbortController = exports.currentAbortController = /*#__PURE__*/envRefMake("effect/Micro/currentAbortController", () => undefined);
525
- /**
526
- * @since 3.4.0
527
- * @experimental
528
- * @category environment refs
529
- */
530
- const currentAbortSignal = exports.currentAbortSignal = /*#__PURE__*/envRefMake("effect/Micro/currentAbortSignal", () => undefined);
531
- /**
532
- * @since 3.4.0
533
- * @experimental
534
- * @category environment refs
535
- */
536
- const currentContext = exports.currentContext = /*#__PURE__*/envRefMake("effect/Micro/currentContext", () => Context.empty());
537
- /**
538
- * @since 3.4.0
539
- * @experimental
540
- * @category environment refs
658
+ * @category constructors
541
659
  */
542
- const currentConcurrency = exports.currentConcurrency = /*#__PURE__*/envRefMake("effect/Micro/currentConcurrency", () => "unbounded");
660
+ const promise = evaluate => asyncOptions(function (resume, signal) {
661
+ evaluate(signal).then(a => resume(succeed(a)), e => resume(die(e)));
662
+ }, evaluate.length !== 0);
543
663
  /**
664
+ * Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
665
+ * converted into a specific error type.
666
+ *
544
667
  * @since 3.4.0
545
668
  * @experimental
546
- * @category environment refs
669
+ * @category constructors
670
+ * @example
671
+ * ```ts
672
+ * import { Micro } from "effect"
673
+ *
674
+ * Micro.tryPromise({
675
+ * try: () => Promise.resolve("success"),
676
+ * catch: (cause) => new Error("caught", { cause })
677
+ * })
678
+ * ```
547
679
  */
548
- const currentMaxDepthBeforeYield = exports.currentMaxDepthBeforeYield = /*#__PURE__*/envRefMake("effect/Micro/currentMaxDepthBeforeYield", () => 2048);
549
- const currentInterruptible = /*#__PURE__*/envRefMake("effect/Micro/currentInterruptible", () => true);
680
+ exports.promise = promise;
681
+ const tryPromise = options => asyncOptions(function (resume, signal) {
682
+ try {
683
+ options.try(signal).then(a => resume(succeed(a)), e => resume(fail(options.catch(e))));
684
+ } catch (err) {
685
+ resume(fail(options.catch(err)));
686
+ }
687
+ }, options.try.length !== 0);
550
688
  /**
689
+ * Create a `Micro` effect using the current `Fiber`.
690
+ *
551
691
  * @since 3.4.0
552
692
  * @experimental
553
- * @category environment refs
693
+ * @category constructors
554
694
  */
555
- const currentScheduler = exports.currentScheduler = /*#__PURE__*/envRefMake("effect/Micro/currentScheduler", () => new MicroSchedulerDefault());
695
+ exports.tryPromise = tryPromise;
696
+ const withFiber = exports.withFiber = /*#__PURE__*/makePrimitive({
697
+ op: "WithFiber",
698
+ eval(fiber) {
699
+ return this[args](fiber);
700
+ }
701
+ });
556
702
  /**
557
- * If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
558
- * api to control the concurrency of that `Micro` when it is run.
703
+ * Flush any yielded effects that are waiting to be executed.
559
704
  *
560
705
  * @since 3.4.0
561
706
  * @experimental
562
- * @category environment refs
563
- * @example
564
- * ```ts
565
- * import * as Micro from "effect/Micro"
566
- *
567
- * Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
568
- * concurrency: "inherit"
569
- * }).pipe(
570
- * Micro.withConcurrency(2) // use a concurrency of 2
571
- * )
572
- * ```
707
+ * @category constructors
573
708
  */
574
- const withConcurrency = exports.withConcurrency = /*#__PURE__*/(0, _Function.dual)(2, (self, concurrency) => locally(self, currentConcurrency, concurrency));
575
- // ----------------------------------------------------------------------------
576
- // constructors
577
- // ----------------------------------------------------------------------------
578
- const microDepthState = /*#__PURE__*/(0, _GlobalValue.globalValue)("effect/Micro/microDepthState", () => ({
579
- depth: 0,
580
- maxDepthBeforeYield: currentMaxDepthBeforeYield.initial
581
- }));
582
- const unsafeMake = run => {
583
- const self = Object.create(MicroProto);
584
- self[runSymbol] = run;
585
- return self;
586
- };
587
- const unsafeMakeOptions = (run, checkAbort) => unsafeMake(function execute(env, onExit) {
588
- if (checkAbort && env.refs[currentInterruptible.key] !== false && env.refs[currentAbortSignal.key].aborted) {
589
- return onExit(exitInterrupt);
590
- }
591
- microDepthState.depth++;
592
- if (microDepthState.depth === 1) {
593
- microDepthState.maxDepthBeforeYield = envGet(env, currentMaxDepthBeforeYield);
709
+ const yieldFlush = exports.yieldFlush = /*#__PURE__*/withFiber(fiber => {
710
+ fiber.getRef(CurrentScheduler).flush();
711
+ return exitVoid;
712
+ });
713
+ const asyncOptions = /*#__PURE__*/makePrimitive({
714
+ op: "Async",
715
+ single: false,
716
+ eval(fiber) {
717
+ const register = this[args][0];
718
+ let resumed = false;
719
+ let yielded = false;
720
+ const controller = this[args][1] ? new AbortController() : undefined;
721
+ const onCancel = register(effect => {
722
+ if (resumed) return;
723
+ resumed = true;
724
+ if (yielded) {
725
+ fiber.evaluate(effect);
726
+ } else {
727
+ yielded = effect;
728
+ }
729
+ }, controller?.signal);
730
+ if (yielded !== false) return yielded;
731
+ yielded = true;
732
+ fiber._yielded = () => {
733
+ resumed = true;
734
+ };
735
+ if (controller === undefined && onCancel === undefined) {
736
+ return Yield;
737
+ }
738
+ fiber._stack.push(asyncFinalizer(() => {
739
+ resumed = true;
740
+ controller?.abort();
741
+ return onCancel ?? exitVoid;
742
+ }));
743
+ return Yield;
594
744
  }
595
- const scheduler = env.refs[currentScheduler.key];
596
- if (microDepthState.depth >= microDepthState.maxDepthBeforeYield || scheduler.shouldYield(env)) {
597
- scheduler.scheduleTask(() => execute(env, onExit), 0);
598
- } else {
599
- try {
600
- run(env, onExit);
601
- } catch (err) {
602
- onExit(exitDie(err));
745
+ });
746
+ const asyncFinalizer = /*#__PURE__*/makePrimitive({
747
+ op: "AsyncFinalizer",
748
+ ensure(fiber) {
749
+ if (fiber.interruptible) {
750
+ fiber.interruptible = false;
751
+ fiber._stack.push(setInterruptible(true));
603
752
  }
753
+ },
754
+ contE(cause, _fiber) {
755
+ return causeIsInterrupt(cause) ? flatMap(this[args](), () => failCause(cause)) : failCause(cause);
604
756
  }
605
- microDepthState.depth--;
606
757
  });
607
758
  /**
608
- * A low-level constructor for creating a `Micro` effect. It takes a function
609
- * that receives an environment and a callback which should be called with the
610
- * result of the effect.
759
+ * Create a `Micro` effect from an asynchronous computation.
760
+ *
761
+ * You can return a cleanup effect that will be run when the effect is aborted.
762
+ * It is also passed an `AbortSignal` that is triggered when the effect is
763
+ * aborted.
611
764
  *
612
765
  * @since 3.4.0
613
766
  * @experimental
614
767
  * @category constructors
615
768
  */
616
- const make = run => unsafeMakeOptions(run, true);
769
+ const async = register => asyncOptions(register, register.length >= 2);
617
770
  /**
618
- * Converts a `MicroExit` into a `Micro` effect.
771
+ * A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
772
+ * the Javascript runtime from exiting.
619
773
  *
620
- * @since 3.4.6
774
+ * @since 3.4.0
621
775
  * @experimental
622
776
  * @category constructors
623
777
  */
624
- exports.make = make;
625
- const fromExit = self => make(function (_env, onExit) {
626
- onExit(self);
778
+ exports.async = async;
779
+ const never = exports.never = /*#__PURE__*/async(function () {
780
+ const interval = setInterval(_Function.constVoid, 2147483646);
781
+ return sync(() => clearInterval(interval));
627
782
  });
628
783
  /**
629
- * Converts a lazy `MicroExit` into a `Micro` effect.
630
- *
631
- * @since 3.4.6
784
+ * @since 3.4.0
632
785
  * @experimental
633
786
  * @category constructors
634
787
  */
635
- exports.fromExit = fromExit;
636
- const fromExitSync = self => make(function (_env, onExit) {
637
- onExit(self());
788
+ const gen = (...args) => suspend(() => fromIterator(args.length === 1 ? args[0]() : args[1].call(args[0])));
789
+ exports.gen = gen;
790
+ const fromIterator = /*#__PURE__*/makePrimitive({
791
+ op: "Iterator",
792
+ contA(value, fiber) {
793
+ const state = this[args].next(value);
794
+ if (state.done) return succeed(state.value);
795
+ fiber._stack.push(this);
796
+ return (0, _Utils.yieldWrapGet)(state.value);
797
+ },
798
+ eval(fiber) {
799
+ return this[successCont](undefined, fiber);
800
+ }
638
801
  });
802
+ // ----------------------------------------------------------------------------
803
+ // mapping & sequencing
804
+ // ----------------------------------------------------------------------------
639
805
  /**
640
- * Creates a `Micro` effect that will succeed with the specified constant value.
806
+ * Create a `Micro` effect that will replace the success value of the given
807
+ * effect.
641
808
  *
642
809
  * @since 3.4.0
643
810
  * @experimental
644
- * @category constructors
811
+ * @category mapping & sequencing
645
812
  */
646
- exports.fromExitSync = fromExitSync;
647
- const succeed = a => fromExit(exitSucceed(a));
813
+ const as = exports.as = /*#__PURE__*/(0, _Function.dual)(2, (self, value) => map(self, _ => value));
648
814
  /**
649
- * Creates a `Micro` effect that will succeed with `Option.Some` of the value.
815
+ * Wrap the success value of this `Micro` effect in an `Option.Some`.
650
816
  *
651
817
  * @since 3.4.0
652
818
  * @experimental
653
- * @category constructors
819
+ * @category mapping & sequencing
654
820
  */
655
- exports.succeed = succeed;
656
- const succeedSome = a => succeed(Option.some(a));
821
+ const asSome = self => map(self, Option.some);
657
822
  /**
658
- * Creates a `Micro` effect that will succeed with `Option.None`.
823
+ * Swap the error and success types of the `Micro` effect.
659
824
  *
660
825
  * @since 3.4.0
661
826
  * @experimental
662
- * @category constructors
827
+ * @category mapping & sequencing
663
828
  */
664
- exports.succeedSome = succeedSome;
665
- const succeedNone = exports.succeedNone = /*#__PURE__*/succeed( /*#__PURE__*/Option.none());
829
+ exports.asSome = asSome;
830
+ const flip = self => matchEffect(self, {
831
+ onFailure: succeed,
832
+ onSuccess: fail
833
+ });
666
834
  /**
667
- * Creates a `Micro` effect that will fail with the specified error.
835
+ * A more flexible version of `flatMap`, that combines `map` and `flatMap` into
836
+ * a single api.
668
837
  *
669
- * This will result in a `CauseFail`, where the error is tracked at the
670
- * type level.
838
+ * It also allows you to pass in a `Micro` effect directly, which will be
839
+ * executed after the current effect.
671
840
  *
672
841
  * @since 3.4.0
673
842
  * @experimental
674
- * @category constructors
843
+ * @category mapping & sequencing
675
844
  */
676
- const fail = e => fromExit(exitFail(e));
845
+ exports.flip = flip;
846
+ const andThen = exports.andThen = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => flatMap(self, a => {
847
+ const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f;
848
+ return isMicro(value) ? value : succeed(value);
849
+ }));
677
850
  /**
678
- * Creates a `Micro` effect that will fail with the lazily evaluated error.
851
+ * Execute a side effect from the success value of the `Micro` effect.
679
852
  *
680
- * This will result in a `CauseFail`, where the error is tracked at the
681
- * type level.
853
+ * It is similar to the `andThen` api, but the success value is ignored.
682
854
  *
683
855
  * @since 3.4.0
684
856
  * @experimental
685
- * @category constructors
857
+ * @category mapping & sequencing
686
858
  */
687
- exports.fail = fail;
688
- const failSync = e => make(function (_env, onExit) {
689
- onExit(exitFail(e()));
690
- });
859
+ const tap = exports.tap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => flatMap(self, a => {
860
+ const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f;
861
+ return isMicro(value) ? as(value, a) : succeed(a);
862
+ }));
691
863
  /**
692
- * Creates a `Micro` effect that will die with the specified error.
693
- *
694
- * This will result in a `CauseDie`, where the error is not tracked at
695
- * the type level.
864
+ * Replace the success value of the `Micro` effect with `void`.
696
865
  *
697
866
  * @since 3.4.0
698
867
  * @experimental
699
- * @category constructors
700
- */
701
- exports.failSync = failSync;
702
- const die = defect => fromExit(exitDie(defect));
703
- /**
704
- * Creates a `Micro` effect that will fail with the specified `MicroCause`.
705
- *
706
- * @since 3.4.6
707
- * @experimental
708
- * @category constructors
868
+ * @category mapping & sequencing
709
869
  */
710
- exports.die = die;
711
- const failCause = cause => fromExit(exitFailCause(cause));
870
+ const asVoid = self => flatMap(self, _ => exitVoid);
712
871
  /**
713
- * Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
872
+ * Access the `MicroExit` of the given `Micro` effect.
714
873
  *
715
874
  * @since 3.4.6
716
875
  * @experimental
717
- * @category constructors
876
+ * @category mapping & sequencing
718
877
  */
719
- exports.failCause = failCause;
720
- const failCauseSync = cause => fromExitSync(() => exitFailCause(cause()));
878
+ exports.asVoid = asVoid;
879
+ const exit = self => matchCause(self, {
880
+ onFailure: exitFailCause,
881
+ onSuccess: exitSucceed
882
+ });
721
883
  /**
722
- * Creates a `Micro` effect that will succeed with the lazily evaluated value.
723
- *
724
- * If the evaluation of the value throws an error, the effect will fail with
725
- * `CauseDie`.
884
+ * Replace the error type of the given `Micro` with the full `MicroCause` object.
726
885
  *
727
886
  * @since 3.4.0
728
887
  * @experimental
729
- * @category constructors
888
+ * @category mapping & sequencing
730
889
  */
731
- exports.failCauseSync = failCauseSync;
732
- const sync = evaluate => make(function (_env, onExit) {
733
- onExit(exitSucceed(evaluate()));
734
- });
890
+ exports.exit = exit;
891
+ const sandbox = self => catchAllCause(self, fail);
735
892
  /**
736
- * Converts an `Option` into a `Micro` effect, that will fail with
737
- * `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
738
- * value of the option.
893
+ * Returns an effect that races all the specified effects,
894
+ * yielding the value of the first effect to succeed with a value. Losers of
895
+ * the race will be interrupted immediately
739
896
  *
740
897
  * @since 3.4.0
741
898
  * @experimental
742
- * @category constructors
899
+ * @category sequencing
743
900
  */
744
- exports.sync = sync;
745
- const fromOption = option => make(function (_env, onExit) {
746
- onExit(option._tag === "Some" ? exitSucceed(option.value) : exitFail(new NoSuchElementException({})));
747
- });
748
- /**
749
- * Converts an `Either` into a `Micro` effect, that will fail with the left side
750
- * of the either if it is a `Left`. Otherwise, it will succeed with the right
751
- * side of the either.
901
+ exports.sandbox = sandbox;
902
+ const raceAll = all => withFiber(parent => async(resume => {
903
+ const effects = Arr.fromIterable(all);
904
+ const len = effects.length;
905
+ let doneCount = 0;
906
+ let done = false;
907
+ const fibers = new Set();
908
+ const causes = [];
909
+ const onExit = exit => {
910
+ doneCount++;
911
+ if (exit._tag === "Failure") {
912
+ causes.push(exit.cause);
913
+ if (doneCount >= len) {
914
+ resume(failCause(causes[0]));
915
+ }
916
+ return;
917
+ }
918
+ done = true;
919
+ resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit));
920
+ };
921
+ for (let i = 0; i < len; i++) {
922
+ if (done) break;
923
+ const fiber = unsafeFork(parent, interruptible(effects[i]), true, true);
924
+ fibers.add(fiber);
925
+ fiber.addObserver(exit => {
926
+ fibers.delete(fiber);
927
+ onExit(exit);
928
+ });
929
+ }
930
+ return fiberInterruptAll(fibers);
931
+ }));
932
+ /**
933
+ * Returns an effect that races all the specified effects,
934
+ * yielding the value of the first effect to succeed or fail. Losers of
935
+ * the race will be interrupted immediately
752
936
  *
753
937
  * @since 3.4.0
754
938
  * @experimental
755
- * @category constructors
939
+ * @category sequencing
756
940
  */
757
- exports.fromOption = fromOption;
758
- const fromEither = either => make(function (_env, onExit) {
759
- onExit(either._tag === "Right" ? either : exitFail(either.left));
760
- });
941
+ exports.raceAll = raceAll;
942
+ const raceAllFirst = all => withFiber(parent => async(resume => {
943
+ let done = false;
944
+ const fibers = new Set();
945
+ const onExit = exit => {
946
+ done = true;
947
+ resume(fibers.size === 0 ? exit : flatMap(fiberInterruptAll(fibers), () => exit));
948
+ };
949
+ for (const effect of all) {
950
+ if (done) break;
951
+ const fiber = unsafeFork(parent, interruptible(effect), true, true);
952
+ fibers.add(fiber);
953
+ fiber.addObserver(exit => {
954
+ fibers.delete(fiber);
955
+ onExit(exit);
956
+ });
957
+ }
958
+ return fiberInterruptAll(fibers);
959
+ }));
761
960
  /**
762
- * Lazily creates a `Micro` effect from the given side-effect.
961
+ * Returns an effect that races two effects, yielding the value of the first
962
+ * effect to succeed. Losers of the race will be interrupted immediately
763
963
  *
764
964
  * @since 3.4.0
765
965
  * @experimental
766
- * @category constructors
966
+ * @category sequencing
767
967
  */
768
- exports.fromEither = fromEither;
769
- const suspend = evaluate => make(function (env, onExit) {
770
- evaluate()[runSymbol](env, onExit);
771
- });
772
- exports.suspend = suspend;
773
- const void_ = exports.void = /*#__PURE__*/succeed(void 0);
968
+ exports.raceAllFirst = raceAllFirst;
969
+ const race = exports.race = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => raceAll([self, that]));
774
970
  /**
775
- * Create a `Micro` effect from an asynchronous computation.
971
+ * Returns an effect that races two effects, yielding the value of the first
972
+ * effect to succeed *or* fail. Losers of the race will be interrupted immediately
776
973
  *
777
- * You can return a cleanup effect that will be run when the effect is aborted.
778
- * It is also passed an `AbortSignal` that is triggered when the effect is
779
- * aborted.
974
+ * @since 3.4.0
975
+ * @experimental
976
+ * @category sequencing
977
+ */
978
+ const raceFirst = exports.raceFirst = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => raceAllFirst([self, that]));
979
+ /**
980
+ * Map the success value of this `Micro` effect to another `Micro` effect, then
981
+ * flatten the result.
780
982
  *
781
983
  * @since 3.4.0
782
984
  * @experimental
783
- * @category constructors
985
+ * @category mapping & sequencing
784
986
  */
785
- const async = register => make(function (env, onExit) {
786
- let resumed = false;
787
- const controller = register.length > 1 ? new AbortController() : undefined;
788
- const signal = envGet(env, currentAbortSignal);
789
- let cleanup = undefined;
790
- function onAbort() {
791
- if (cleanup) {
792
- resume(uninterruptible(andThen(cleanup, fromExit(exitInterrupt))));
793
- } else {
794
- resume(fromExit(exitInterrupt));
795
- }
796
- if (controller !== undefined) {
797
- controller.abort();
798
- }
799
- }
800
- function resume(effect) {
801
- if (resumed) {
802
- return;
803
- }
804
- resumed = true;
805
- signal.removeEventListener("abort", onAbort);
806
- effect[runSymbol](env, onExit);
807
- }
808
- cleanup = controller === undefined ? register(resume) : register(resume, controller.signal);
809
- if (resumed) return;
810
- signal.addEventListener("abort", onAbort);
987
+ const flatMap = exports.flatMap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => {
988
+ const onSuccess = Object.create(OnSuccessProto);
989
+ onSuccess[args] = self;
990
+ onSuccess[successCont] = f;
991
+ return onSuccess;
811
992
  });
812
- exports.async = async;
813
- const try_ = options => make(function (_env, onExit) {
814
- try {
815
- onExit(exitSucceed(options.try()));
816
- } catch (err) {
817
- onExit(exitFail(options.catch(err)));
993
+ const OnSuccessProto = /*#__PURE__*/makePrimitiveProto({
994
+ op: "OnSuccess",
995
+ eval(fiber) {
996
+ fiber._stack.push(this);
997
+ return this[args];
818
998
  }
819
999
  });
820
- exports.try = try_;
1000
+ // ----------------------------------------------------------------------------
1001
+ // mapping & sequencing
1002
+ // ----------------------------------------------------------------------------
821
1003
  /**
822
- * Wrap a `Promise` into a `Micro` effect. Any errors will result in a
823
- * `CauseDie`.
1004
+ * Flattens any nested `Micro` effects, merging the error and requirement types.
824
1005
  *
825
1006
  * @since 3.4.0
826
1007
  * @experimental
827
- * @category constructors
1008
+ * @category mapping & sequencing
828
1009
  */
829
- const promise = evaluate => async(function (resume, signal) {
830
- evaluate(signal).then(a => resume(succeed(a)), e => resume(die(e)));
831
- });
1010
+ const flatten = self => flatMap(self, _Function.identity);
832
1011
  /**
833
- * Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
834
- * converted into a specific error type.
1012
+ * Transforms the success value of the `Micro` effect with the specified
1013
+ * function.
835
1014
  *
836
1015
  * @since 3.4.0
837
1016
  * @experimental
838
- * @category constructors
839
- * @example
840
- * ```ts
841
- * import { Micro } from "effect"
842
- *
843
- * Micro.tryPromise({
844
- * try: () => Promise.resolve("success"),
845
- * catch: (cause) => new Error("caught", { cause })
846
- * })
847
- * ```
1017
+ * @category mapping & sequencing
848
1018
  */
849
- exports.promise = promise;
850
- const tryPromise = options => async(function (resume, signal) {
851
- try {
852
- options.try(signal).then(a => resume(succeed(a)), e => resume(fail(options.catch(e))));
853
- } catch (err) {
854
- resume(fail(options.catch(err)));
855
- }
856
- });
1019
+ exports.flatten = flatten;
1020
+ const map = exports.map = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => flatMap(self, a => succeed(f(a))));
857
1021
  /**
858
- * Pause the execution of the current `Micro` effect, and resume it on the next
859
- * iteration of the event loop.
860
- *
861
- * You can specify a priority for the task, which will determine when it is
862
- * executed relative to other tasks.
863
- *
864
- * @since 3.4.0
1022
+ * @since 3.4.6
865
1023
  * @experimental
866
- * @category constructors
1024
+ * @category MicroExit
867
1025
  */
868
- exports.tryPromise = tryPromise;
869
- const yieldWithPriority = priority => make(function (env, onExit) {
870
- envGet(env, currentScheduler).scheduleTask(() => onExit(exitVoid), priority);
871
- });
1026
+ const isMicroExit = u => (0, _Predicate.hasProperty)(u, MicroExitTypeId);
872
1027
  /**
873
- * Pause the execution of the current `Micro` effect, and resume it on the next
874
- * iteration of the event loop.
875
- *
876
- * @since 3.4.0
1028
+ * @since 3.4.6
877
1029
  * @experimental
878
- * @category constructors
1030
+ * @category MicroExit
879
1031
  */
880
- exports.yieldWithPriority = yieldWithPriority;
881
- const yieldNow = exports.yieldNow = /*#__PURE__*/yieldWithPriority(0);
1032
+ exports.isMicroExit = isMicroExit;
1033
+ const exitSucceed = exports.exitSucceed = succeed;
882
1034
  /**
883
- * Flush any yielded effects that are waiting to be executed.
884
- *
885
- * @since 3.4.0
1035
+ * @since 3.4.6
886
1036
  * @experimental
887
- * @category constructors
1037
+ * @category MicroExit
888
1038
  */
889
- const yieldFlush = exports.yieldFlush = /*#__PURE__*/make(function (env, onExit) {
890
- envGet(env, currentScheduler).flush();
891
- onExit(exitVoid);
892
- });
1039
+ const exitFailCause = exports.exitFailCause = failCause;
893
1040
  /**
894
- * A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
895
- * the Javascript runtime from exiting.
896
- *
897
- * @since 3.4.0
1041
+ * @since 3.4.6
898
1042
  * @experimental
899
- * @category constructors
1043
+ * @category MicroExit
900
1044
  */
901
- const never = exports.never = /*#__PURE__*/async(function () {
902
- const interval = setInterval(_Function.constVoid, 2147483646);
903
- return sync(() => clearInterval(interval));
904
- });
1045
+ const exitInterrupt = exports.exitInterrupt = /*#__PURE__*/exitFailCause( /*#__PURE__*/causeInterrupt());
905
1046
  /**
906
- * @since 3.4.0
1047
+ * @since 3.4.6
907
1048
  * @experimental
908
- * @category constructors
1049
+ * @category MicroExit
909
1050
  */
910
- const gen = (...args) => make(function (env, onExit) {
911
- const iterator = args.length === 1 ? args[0]() : args[1].call(args[0]);
912
- let running = false;
913
- let value = undefined;
914
- function run() {
915
- running = true;
916
- try {
917
- let shouldContinue = true;
918
- while (shouldContinue) {
919
- const result = iterator.next(value);
920
- if (result.done) {
921
- return onExit(exitSucceed(result.value));
922
- }
923
- shouldContinue = false;
924
- (0, _Utils.yieldWrapGet)(result.value)[runSymbol](env, function (exit) {
925
- if (exit._tag === "Left") {
926
- onExit(exit);
927
- } else {
928
- shouldContinue = true;
929
- value = exit.right;
930
- if (!running) run();
931
- }
932
- });
933
- }
934
- } catch (err) {
935
- onExit(exitDie(err));
936
- }
937
- running = false;
938
- }
939
- run();
940
- });
941
- // ----------------------------------------------------------------------------
942
- // mapping & sequencing
943
- // ----------------------------------------------------------------------------
1051
+ const exitFail = e => exitFailCause(causeFail(e));
944
1052
  /**
945
- * Flattens any nested `Micro` effects, merging the error and requirement types.
946
- *
947
- * @since 3.4.0
1053
+ * @since 3.4.6
948
1054
  * @experimental
949
- * @category mapping & sequencing
1055
+ * @category MicroExit
950
1056
  */
951
- exports.gen = gen;
952
- const flatten = self => make(function (env, onExit) {
953
- self[runSymbol](env, exit => exit._tag === "Left" ? onExit(exit) : exit.right[runSymbol](env, onExit));
954
- });
1057
+ exports.exitFail = exitFail;
1058
+ const exitDie = defect => exitFailCause(causeDie(defect));
955
1059
  /**
956
- * Transforms the success value of the `Micro` effect with the specified
957
- * function.
958
- *
959
- * @since 3.4.0
1060
+ * @since 3.4.6
960
1061
  * @experimental
961
- * @category mapping & sequencing
1062
+ * @category MicroExit
962
1063
  */
963
- exports.flatten = flatten;
964
- const map = exports.map = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make(function (env, onExit) {
965
- self[runSymbol](env, function (exit) {
966
- onExit(exit._tag === "Left" ? exit : exitSucceed(f(exit.right)));
967
- });
968
- }));
1064
+ exports.exitDie = exitDie;
1065
+ const exitIsSuccess = self => self._tag === "Success";
969
1066
  /**
970
- * Create a `Micro` effect that will replace the success value of the given
971
- * effect.
972
- *
973
- * @since 3.4.0
1067
+ * @since 3.4.6
974
1068
  * @experimental
975
- * @category mapping & sequencing
1069
+ * @category MicroExit
976
1070
  */
977
- const as = exports.as = /*#__PURE__*/(0, _Function.dual)(2, (self, value) => map(self, _ => value));
1071
+ exports.exitIsSuccess = exitIsSuccess;
1072
+ const exitIsFailure = self => self._tag === "Failure";
978
1073
  /**
979
- * Wrap the success value of this `Micro` effect in an `Option.Some`.
980
- *
981
- * @since 3.4.0
1074
+ * @since 3.4.6
982
1075
  * @experimental
983
- * @category mapping & sequencing
1076
+ * @category MicroExit
984
1077
  */
985
- const asSome = self => map(self, Option.some);
1078
+ exports.exitIsFailure = exitIsFailure;
1079
+ const exitIsInterrupt = self => exitIsFailure(self) && self.cause._tag === "Interrupt";
986
1080
  /**
987
- * Map the success value of this `Micro` effect to another `Micro` effect, then
988
- * flatten the result.
989
- *
990
- * @since 3.4.0
1081
+ * @since 3.4.6
991
1082
  * @experimental
992
- * @category mapping & sequencing
1083
+ * @category MicroExit
993
1084
  */
994
- exports.asSome = asSome;
995
- const flatMap = exports.flatMap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make(function (env, onExit) {
996
- self[runSymbol](env, function (exit) {
997
- if (exit._tag === "Left") {
998
- return onExit(exit);
1085
+ exports.exitIsInterrupt = exitIsInterrupt;
1086
+ const exitIsFail = self => exitIsFailure(self) && self.cause._tag === "Fail";
1087
+ /**
1088
+ * @since 3.4.6
1089
+ * @experimental
1090
+ * @category MicroExit
1091
+ */
1092
+ exports.exitIsFail = exitIsFail;
1093
+ const exitIsDie = self => exitIsFailure(self) && self.cause._tag === "Die";
1094
+ /**
1095
+ * @since 3.4.6
1096
+ * @experimental
1097
+ * @category MicroExit
1098
+ */
1099
+ exports.exitIsDie = exitIsDie;
1100
+ const exitVoid = exports.exitVoid = /*#__PURE__*/exitSucceed(void 0);
1101
+ /**
1102
+ * @since 3.11.0
1103
+ * @experimental
1104
+ * @category MicroExit
1105
+ */
1106
+ const exitVoidAll = exits => {
1107
+ for (const exit of exits) {
1108
+ if (exit._tag === "Failure") {
1109
+ return exit;
999
1110
  }
1000
- f(exit.right)[runSymbol](env, onExit);
1001
- });
1002
- }));
1111
+ }
1112
+ return exitVoid;
1113
+ };
1114
+ exports.exitVoidAll = exitVoidAll;
1115
+ const setImmediate = "setImmediate" in globalThis ? globalThis.setImmediate : f => setTimeout(f, 0);
1003
1116
  /**
1004
- * Swap the error and success types of the `Micro` effect.
1117
+ * @since 3.5.9
1118
+ * @experimental
1119
+ * @category scheduler
1120
+ */
1121
+ class MicroSchedulerDefault {
1122
+ tasks = [];
1123
+ running = false;
1124
+ /**
1125
+ * @since 3.5.9
1126
+ */
1127
+ scheduleTask(task, _priority) {
1128
+ this.tasks.push(task);
1129
+ if (!this.running) {
1130
+ this.running = true;
1131
+ setImmediate(this.afterScheduled);
1132
+ }
1133
+ }
1134
+ /**
1135
+ * @since 3.5.9
1136
+ */
1137
+ afterScheduled = () => {
1138
+ this.running = false;
1139
+ this.runTasks();
1140
+ };
1141
+ /**
1142
+ * @since 3.5.9
1143
+ */
1144
+ runTasks() {
1145
+ const tasks = this.tasks;
1146
+ this.tasks = [];
1147
+ for (let i = 0, len = tasks.length; i < len; i++) {
1148
+ tasks[i]();
1149
+ }
1150
+ }
1151
+ /**
1152
+ * @since 3.5.9
1153
+ */
1154
+ shouldYield(fiber) {
1155
+ return fiber.currentOpCount >= fiber.getRef(MaxOpsBeforeYield);
1156
+ }
1157
+ /**
1158
+ * @since 3.5.9
1159
+ */
1160
+ flush() {
1161
+ while (this.tasks.length > 0) {
1162
+ this.runTasks();
1163
+ }
1164
+ }
1165
+ }
1166
+ /**
1167
+ * Access the given `Context.Tag` from the environment.
1005
1168
  *
1006
1169
  * @since 3.4.0
1007
1170
  * @experimental
1008
- * @category mapping & sequencing
1171
+ * @category environment
1009
1172
  */
1010
- const flip = self => matchEffect(self, {
1011
- onFailure: succeed,
1012
- onSuccess: fail
1013
- });
1173
+ exports.MicroSchedulerDefault = MicroSchedulerDefault;
1174
+ const service = tag => withFiber(fiber => succeed(Context.unsafeGet(fiber.context, tag)));
1014
1175
  /**
1015
- * A more flexible version of `flatMap`, that combines `map` and `flatMap` into
1016
- * a single api.
1176
+ * Access the given `Context.Tag` from the environment, without tracking the
1177
+ * dependency at the type level.
1017
1178
  *
1018
- * It also allows you to pass in a `Micro` effect directly, which will be
1019
- * executed after the current effect.
1179
+ * It will return an `Option` of the service, depending on whether it is
1180
+ * available in the environment or not.
1020
1181
  *
1021
1182
  * @since 3.4.0
1022
1183
  * @experimental
1023
- * @category mapping & sequencing
1184
+ * @category environment
1024
1185
  */
1025
- exports.flip = flip;
1026
- const andThen = exports.andThen = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make(function (env, onExit) {
1027
- self[runSymbol](env, function (exit) {
1028
- if (exit._tag === "Left") {
1029
- return onExit(exit);
1030
- } else if (envGet(env, currentAbortSignal).aborted) {
1031
- return onExit(exitInterrupt);
1032
- }
1033
- const value = isMicro(f) ? f : typeof f === "function" ? f(exit.right) : f;
1034
- if (isMicro(value)) {
1035
- value[runSymbol](env, onExit);
1036
- } else {
1037
- onExit(exitSucceed(value));
1038
- }
1186
+ exports.service = service;
1187
+ const serviceOption = tag => withFiber(fiber => succeed(Context.getOption(fiber.context, tag)));
1188
+ /**
1189
+ * Update the Context with the given mapping function.
1190
+ *
1191
+ * @since 3.11.0
1192
+ * @experimental
1193
+ * @category environment
1194
+ */
1195
+ exports.serviceOption = serviceOption;
1196
+ const updateContext = exports.updateContext = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => withFiber(fiber => {
1197
+ const prev = fiber.context;
1198
+ fiber.context = f(prev);
1199
+ return onExit(self, () => {
1200
+ fiber.context = prev;
1201
+ return void_;
1039
1202
  });
1040
1203
  }));
1041
1204
  /**
1042
- * Execute a side effect from the success value of the `Micro` effect.
1205
+ * Update the service for the given `Context.Tag` in the environment.
1043
1206
  *
1044
- * It is similar to the `andThen` api, but the success value is ignored.
1045
- *
1046
- * @since 3.4.0
1207
+ * @since 3.11.0
1047
1208
  * @experimental
1048
- * @category mapping & sequencing
1209
+ * @category environment
1049
1210
  */
1050
- const tap = exports.tap = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => make(function (env, onExit) {
1051
- self[runSymbol](env, function (selfExit) {
1052
- if (selfExit._tag === "Left") {
1053
- return onExit(selfExit);
1054
- } else if (envGet(env, currentAbortSignal).aborted) {
1055
- return onExit(exitInterrupt);
1056
- }
1057
- const value = isMicro(f) ? f : typeof f === "function" ? f(selfExit.right) : f;
1058
- if (isMicro(value)) {
1059
- value[runSymbol](env, function (tapExit) {
1060
- if (tapExit._tag === "Left") {
1061
- return onExit(tapExit);
1062
- }
1063
- onExit(selfExit);
1064
- });
1065
- } else {
1066
- onExit(selfExit);
1067
- }
1211
+ const updateService = exports.updateService = /*#__PURE__*/(0, _Function.dual)(3, (self, tag, f) => withFiber(fiber => {
1212
+ const prev = Context.unsafeGet(fiber.context, tag);
1213
+ fiber.context = Context.add(fiber.context, tag, f(prev));
1214
+ return onExit(self, () => {
1215
+ fiber.context = Context.add(fiber.context, tag, prev);
1216
+ return void_;
1068
1217
  });
1069
1218
  }));
1070
1219
  /**
1071
- * Replace the success value of the `Micro` effect with `void`.
1220
+ * Access the current `Context` from the environment.
1072
1221
  *
1073
1222
  * @since 3.4.0
1074
1223
  * @experimental
1075
- * @category mapping & sequencing
1224
+ * @category environment
1076
1225
  */
1077
- const asVoid = self => map(self, _ => void 0);
1226
+ const context = () => getContext;
1227
+ exports.context = context;
1228
+ const getContext = /*#__PURE__*/withFiber(fiber => succeed(fiber.context));
1078
1229
  /**
1079
- * Access the `MicroExit` of the given `Micro` effect.
1230
+ * Merge the given `Context` with the current context.
1080
1231
  *
1081
- * @since 3.4.6
1232
+ * @since 3.4.0
1082
1233
  * @experimental
1083
- * @category mapping & sequencing
1234
+ * @category environment
1084
1235
  */
1085
- exports.asVoid = asVoid;
1086
- const exit = self => make(function (env, onExit) {
1087
- self[runSymbol](env, function (exit) {
1088
- onExit(exitSucceed(exit));
1089
- });
1090
- });
1236
+ const provideContext = exports.provideContext = /*#__PURE__*/(0, _Function.dual)(2, (self, provided) => updateContext(self, Context.merge(provided)));
1091
1237
  /**
1092
- * Replace the error type of the given `Micro` with the full `MicroCause` object.
1238
+ * Add the provided service to the current context.
1093
1239
  *
1094
1240
  * @since 3.4.0
1095
1241
  * @experimental
1096
- * @category mapping & sequencing
1242
+ * @category environment
1097
1243
  */
1098
- exports.exit = exit;
1099
- const sandbox = self => catchAllCause(self, cause => fail(cause));
1100
- exports.sandbox = sandbox;
1101
- function forkSignal(env) {
1102
- const controller = new AbortController();
1103
- const parentSignal = envGet(env, currentAbortSignal);
1104
- function onAbort() {
1105
- controller.abort();
1106
- parentSignal.removeEventListener("abort", onAbort);
1107
- }
1108
- parentSignal.addEventListener("abort", onAbort);
1109
- const envWithSignal = envMutate(env, function (refs) {
1110
- refs[currentAbortController.key] = controller;
1111
- refs[currentAbortSignal.key] = controller.signal;
1112
- return refs;
1113
- });
1114
- return [envWithSignal, onAbort];
1115
- }
1244
+ const provideService = exports.provideService = /*#__PURE__*/(0, _Function.dual)(3, (self, tag, service) => updateContext(self, Context.add(tag, service)));
1116
1245
  /**
1117
- * Returns an effect that races all the specified effects,
1118
- * yielding the value of the first effect to succeed with a value. Losers of
1119
- * the race will be interrupted immediately
1246
+ * Create a service using the provided `Micro` effect, and add it to the
1247
+ * current context.
1120
1248
  *
1121
- * @since 3.4.0
1249
+ * @since 3.4.6
1122
1250
  * @experimental
1123
- * @category sequencing
1251
+ * @category environment
1124
1252
  */
1125
- const raceAll = all => make(function (env, onExit) {
1126
- const [envWithSignal, onAbort] = forkSignal(env);
1127
- const effects = Array.from(all);
1128
- let len = effects.length;
1129
- let index = 0;
1130
- let done = 0;
1131
- let exit = undefined;
1132
- const causes = [];
1133
- function onDone(exit_) {
1134
- done++;
1135
- if (exit_._tag === "Right" && exit === undefined) {
1136
- len = index;
1137
- exit = exit_;
1138
- onAbort();
1139
- } else if (exit_._tag === "Left") {
1140
- causes.push(exit_.left);
1141
- }
1142
- if (done >= len) {
1143
- onExit(exit ?? Either.left(causes[0]));
1144
- }
1145
- }
1146
- for (; index < len; index++) {
1147
- effects[index][runSymbol](envWithSignal, onDone);
1148
- }
1149
- });
1253
+ const provideServiceEffect = exports.provideServiceEffect = /*#__PURE__*/(0, _Function.dual)(3, (self, tag, acquire) => flatMap(acquire, service => provideService(self, tag, service)));
1254
+ // ========================================================================
1255
+ // References
1256
+ // ========================================================================
1150
1257
  /**
1151
- * Returns an effect that races all the specified effects,
1152
- * yielding the value of the first effect to succeed or fail. Losers of
1153
- * the race will be interrupted immediately
1154
- *
1155
- * @since 3.4.0
1258
+ * @since 3.11.0
1156
1259
  * @experimental
1157
- * @category sequencing
1260
+ * @category references
1158
1261
  */
1159
- exports.raceAll = raceAll;
1160
- const raceAllFirst = all => make(function (env, onExit) {
1161
- const [envWithSignal, onAbort] = forkSignal(env);
1162
- const effects = Array.from(all);
1163
- let len = effects.length;
1164
- let index = 0;
1165
- let done = 0;
1166
- let exit = undefined;
1167
- const causes = [];
1168
- function onDone(exit_) {
1169
- done++;
1170
- if (exit === undefined) {
1171
- len = index;
1172
- exit = exit_;
1173
- onAbort();
1174
- }
1175
- if (done >= len) {
1176
- onExit(exit ?? Either.left(causes[0]));
1177
- }
1178
- }
1179
- for (; index < len; index++) {
1180
- effects[index][runSymbol](envWithSignal, onDone);
1181
- }
1182
- });
1262
+ class MaxOpsBeforeYield extends /*#__PURE__*/Context.Reference()("effect/Micro/currentMaxOpsBeforeYield", {
1263
+ defaultValue: () => 2048
1264
+ }) {}
1183
1265
  /**
1184
- * Returns an effect that races two effects, yielding the value of the first
1185
- * effect to succeed. Losers of the race will be interrupted immediately
1186
- *
1187
- * @since 3.4.0
1266
+ * @since 3.11.0
1188
1267
  * @experimental
1189
- * @category sequencing
1268
+ * @category environment refs
1190
1269
  */
1191
- exports.raceAllFirst = raceAllFirst;
1192
- const race = exports.race = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => raceAll([self, that]));
1270
+ exports.MaxOpsBeforeYield = MaxOpsBeforeYield;
1271
+ class CurrentConcurrency extends /*#__PURE__*/Context.Reference()("effect/Micro/currentConcurrency", {
1272
+ defaultValue: () => "unbounded"
1273
+ }) {}
1193
1274
  /**
1194
- * Returns an effect that races two effects, yielding the value of the first
1195
- * effect to succeed *or* fail. Losers of the race will be interrupted immediately
1275
+ * @since 3.11.0
1276
+ * @experimental
1277
+ * @category environment refs
1278
+ */
1279
+ exports.CurrentConcurrency = CurrentConcurrency;
1280
+ class CurrentScheduler extends /*#__PURE__*/Context.Reference()("effect/Micro/currentScheduler", {
1281
+ defaultValue: () => new MicroSchedulerDefault()
1282
+ }) {}
1283
+ /**
1284
+ * If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
1285
+ * api to control the concurrency of that `Micro` when it is run.
1196
1286
  *
1197
1287
  * @since 3.4.0
1198
1288
  * @experimental
1199
- * @category sequencing
1289
+ * @category environment refs
1290
+ * @example
1291
+ * import * as Micro from "effect/Micro"
1292
+ *
1293
+ * Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
1294
+ * concurrency: "inherit"
1295
+ * }).pipe(
1296
+ * Micro.withConcurrency(2) // use a concurrency of 2
1297
+ * )
1200
1298
  */
1201
- const raceFirst = exports.raceFirst = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => raceAllFirst([self, that]));
1299
+ exports.CurrentScheduler = CurrentScheduler;
1300
+ const withConcurrency = exports.withConcurrency = /*#__PURE__*/(0, _Function.dual)(2, (self, concurrency) => provideService(self, CurrentConcurrency, concurrency));
1202
1301
  // ----------------------------------------------------------------------------
1203
1302
  // zipping
1204
1303
  // ----------------------------------------------------------------------------
@@ -1220,15 +1319,11 @@ const zip = exports.zip = /*#__PURE__*/(0, _Function.dual)(args => isMicro(args[
1220
1319
  * @experimental
1221
1320
  * @category zipping
1222
1321
  */
1223
- const zipWith = exports.zipWith = /*#__PURE__*/(0, _Function.dual)(args => isMicro(args[1]), (self, that, f, options) => {
1224
- if (options?.concurrent) {
1225
- // Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
1226
- return map(all([self, that], {
1227
- concurrency: "unbounded"
1228
- }), ([a, a2]) => f(a, a2));
1229
- }
1230
- return flatMap(self, a => map(that, a2 => f(a, a2)));
1231
- });
1322
+ const zipWith = exports.zipWith = /*#__PURE__*/(0, _Function.dual)(args => isMicro(args[1]), (self, that, f, options) => options?.concurrent
1323
+ // Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
1324
+ ? map(all([self, that], {
1325
+ concurrency: 2
1326
+ }), ([a, a2]) => f(a, a2)) : flatMap(self, a => map(that, a2 => f(a, a2))));
1232
1327
  // ----------------------------------------------------------------------------
1233
1328
  // filtering & conditionals
1234
1329
  // ----------------------------------------------------------------------------
@@ -1263,7 +1358,7 @@ const filterOrFail = exports.filterOrFail = /*#__PURE__*/(0, _Function.dual)(arg
1263
1358
  * @experimental
1264
1359
  * @category filtering & conditionals
1265
1360
  */
1266
- const when = exports.when = /*#__PURE__*/(0, _Function.dual)(2, (self, condition) => flatMap(isMicro(condition) ? condition : sync(condition), pass => pass ? asSome(self) : succeed(Option.none())));
1361
+ const when = exports.when = /*#__PURE__*/(0, _Function.dual)(2, (self, condition) => flatMap(isMicro(condition) ? condition : sync(condition), pass => pass ? asSome(self) : succeedNone));
1267
1362
  // ----------------------------------------------------------------------------
1268
1363
  // repetition
1269
1364
  // ----------------------------------------------------------------------------
@@ -1277,14 +1372,14 @@ const when = exports.when = /*#__PURE__*/(0, _Function.dual)(2, (self, condition
1277
1372
  * @experimental
1278
1373
  * @category repetition
1279
1374
  */
1280
- const repeatExit = exports.repeatExit = /*#__PURE__*/(0, _Function.dual)(2, (self, options) => make(function (env, onExit) {
1375
+ const repeatExit = exports.repeatExit = /*#__PURE__*/(0, _Function.dual)(2, (self, options) => suspend(() => {
1281
1376
  const startedAt = options.schedule ? Date.now() : 0;
1282
1377
  let attempt = 0;
1283
- self[runSymbol](env, function loop(exit) {
1378
+ const loop = flatMap(exit(self), exit => {
1284
1379
  if (options.while !== undefined && !options.while(exit)) {
1285
- return onExit(exit);
1380
+ return exit;
1286
1381
  } else if (options.times !== undefined && attempt >= options.times) {
1287
- return onExit(exit);
1382
+ return exit;
1288
1383
  }
1289
1384
  attempt++;
1290
1385
  let delayEffect = yieldNow;
@@ -1292,17 +1387,13 @@ const repeatExit = exports.repeatExit = /*#__PURE__*/(0, _Function.dual)(2, (sel
1292
1387
  const elapsed = Date.now() - startedAt;
1293
1388
  const duration = options.schedule(attempt, elapsed);
1294
1389
  if (Option.isNone(duration)) {
1295
- return onExit(exit);
1390
+ return exit;
1296
1391
  }
1297
1392
  delayEffect = sleep(duration.value);
1298
1393
  }
1299
- delayEffect[runSymbol](env, function (exit) {
1300
- if (exit._tag === "Left") {
1301
- return onExit(exit);
1302
- }
1303
- self[runSymbol](env, loop);
1304
- });
1394
+ return flatMap(delayEffect, () => loop);
1305
1395
  });
1396
+ return loop;
1306
1397
  }));
1307
1398
  /**
1308
1399
  * Repeat the given `Micro` effect using the provided options. Only successful
@@ -1314,8 +1405,26 @@ const repeatExit = exports.repeatExit = /*#__PURE__*/(0, _Function.dual)(2, (sel
1314
1405
  */
1315
1406
  const repeat = exports.repeat = /*#__PURE__*/(0, _Function.dual)(args => isMicro(args[0]), (self, options) => repeatExit(self, {
1316
1407
  ...options,
1317
- while: exit => exit._tag === "Right" && (options?.while === undefined || options.while(exit.right))
1408
+ while: exit => exit._tag === "Success" && (options?.while === undefined || options.while(exit.value))
1318
1409
  }));
1410
+ /**
1411
+ * Replicates the given effect `n` times.
1412
+ *
1413
+ * @since 3.11.0
1414
+ * @experimental
1415
+ * @category repetition
1416
+ */
1417
+ const replicate = exports.replicate = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => Array.from({
1418
+ length: n
1419
+ }, () => self));
1420
+ /**
1421
+ * Performs this effect the specified number of times and collects the
1422
+ * results.
1423
+ *
1424
+ * @since 3.11.0
1425
+ * @category repetition
1426
+ */
1427
+ const replicateEffect = exports.replicateEffect = /*#__PURE__*/(0, _Function.dual)(args => isMicro(args[0]), (self, n, options) => all(replicate(self, n), options));
1319
1428
  /**
1320
1429
  * Repeat the given `Micro` effect forever, only stopping if the effect fails.
1321
1430
  *
@@ -1409,7 +1518,19 @@ const scheduleIntersect = exports.scheduleIntersect = /*#__PURE__*/(0, _Function
1409
1518
  * @experimental
1410
1519
  * @category error handling
1411
1520
  */
1412
- const catchAllCause = exports.catchAllCause = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => catchCauseIf(self, _Function.constTrue, f));
1521
+ const catchAllCause = exports.catchAllCause = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => {
1522
+ const onFailure = Object.create(OnFailureProto);
1523
+ onFailure[args] = self;
1524
+ onFailure[failureCont] = f;
1525
+ return onFailure;
1526
+ });
1527
+ const OnFailureProto = /*#__PURE__*/makePrimitiveProto({
1528
+ op: "OnFailure",
1529
+ eval(fiber) {
1530
+ fiber._stack.push(this);
1531
+ return this[args];
1532
+ }
1533
+ });
1413
1534
  /**
1414
1535
  * Selectively catch a `MicroCause` object of the given `Micro` effect,
1415
1536
  * using the provided predicate to determine if the failure should be caught.
@@ -1418,15 +1539,7 @@ const catchAllCause = exports.catchAllCause = /*#__PURE__*/(0, _Function.dual)(2
1418
1539
  * @experimental
1419
1540
  * @category error handling
1420
1541
  */
1421
- const catchCauseIf = exports.catchCauseIf = /*#__PURE__*/(0, _Function.dual)(3, (self, predicate, f) => make(function (env, onExit) {
1422
- self[runSymbol](env, function (exit) {
1423
- if (exit._tag === "Right" || !predicate(exit.left)) {
1424
- onExit(exit);
1425
- } else {
1426
- f(exit.left)[runSymbol](env, onExit);
1427
- }
1428
- });
1429
- }));
1542
+ const catchCauseIf = exports.catchCauseIf = /*#__PURE__*/(0, _Function.dual)(3, (self, predicate, f) => catchAllCause(self, cause => predicate(cause) ? f(cause) : failCause(cause)));
1430
1543
  /**
1431
1544
  * Catch the error of the given `Micro` effect, allowing you to recover from it.
1432
1545
  *
@@ -1436,7 +1549,7 @@ const catchCauseIf = exports.catchCauseIf = /*#__PURE__*/(0, _Function.dual)(3,
1436
1549
  * @experimental
1437
1550
  * @category error handling
1438
1551
  */
1439
- const catchAll = exports.catchAll = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => catchAllCause(self, cause => causeIsFail(cause) ? f(cause.error) : failCause(cause)));
1552
+ const catchAll = exports.catchAll = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => catchCauseIf(self, causeIsFail, cause => f(cause.error)));
1440
1553
  /**
1441
1554
  * Catch any unexpected errors of the given `Micro` effect, allowing you to recover from them.
1442
1555
  *
@@ -1563,7 +1676,7 @@ const ignoreLogged = self => matchEffect(self, {
1563
1676
  */
1564
1677
  exports.ignoreLogged = ignoreLogged;
1565
1678
  const option = self => match(self, {
1566
- onFailure: _ => Option.none(),
1679
+ onFailure: Option.none,
1567
1680
  onSuccess: Option.some
1568
1681
  });
1569
1682
  /**
@@ -1590,7 +1703,7 @@ const either = self => match(self, {
1590
1703
  exports.either = either;
1591
1704
  const retry = exports.retry = /*#__PURE__*/(0, _Function.dual)(args => isMicro(args[0]), (self, options) => repeatExit(self, {
1592
1705
  ...options,
1593
- while: exit => exit._tag === "Left" && exit.left._tag === "Fail" && (options?.while === undefined || options.while(exit.left.error))
1706
+ while: exit => exit._tag === "Failure" && exit.cause._tag === "Fail" && (options?.while === undefined || options.while(exit.cause.error))
1594
1707
  }));
1595
1708
  /**
1596
1709
  * Add a stack trace to any failures that occur in the effect. The trace will be
@@ -1617,11 +1730,7 @@ const withTrace = function () {
1617
1730
  const lineMatch = line.match(/\((.*)\)$/);
1618
1731
  return causeWithTrace(cause, `at ${name} (${lineMatch ? lineMatch[1] : line})`);
1619
1732
  }
1620
- const f = name => self => unsafeMakeOptions(function (env, onExit) {
1621
- self[runSymbol](env, function (exit) {
1622
- onExit(exit._tag === "Left" ? Either.left(generate(name, exit.left)) : exit);
1623
- });
1624
- }, false);
1733
+ const f = name => self => onError(self, cause => failCause(generate(name, cause)));
1625
1734
  if (arguments.length === 2) {
1626
1735
  return f(arguments[1])(arguments[0]);
1627
1736
  }
@@ -1636,16 +1745,20 @@ const withTrace = function () {
1636
1745
  * @category pattern matching
1637
1746
  */
1638
1747
  exports.withTrace = withTrace;
1639
- const matchCauseEffect = exports.matchCauseEffect = /*#__PURE__*/(0, _Function.dual)(2, (self, options) => make(function (env, onExit) {
1640
- self[runSymbol](env, function (exit) {
1641
- try {
1642
- const next = exit._tag === "Left" ? options.onFailure(exit.left) : options.onSuccess(exit.right);
1643
- next[runSymbol](env, onExit);
1644
- } catch (err) {
1645
- onExit(exitDie(err));
1646
- }
1647
- });
1648
- }));
1748
+ const matchCauseEffect = exports.matchCauseEffect = /*#__PURE__*/(0, _Function.dual)(2, (self, options) => {
1749
+ const primitive = Object.create(OnSuccessAndFailureProto);
1750
+ primitive[args] = self;
1751
+ primitive[successCont] = options.onSuccess;
1752
+ primitive[failureCont] = options.onFailure;
1753
+ return primitive;
1754
+ });
1755
+ const OnSuccessAndFailureProto = /*#__PURE__*/makePrimitiveProto({
1756
+ op: "OnSuccessAndFailure",
1757
+ eval(fiber) {
1758
+ fiber._stack.push(this);
1759
+ return this[args];
1760
+ }
1761
+ });
1649
1762
  /**
1650
1763
  * @since 3.4.6
1651
1764
  * @experimental
@@ -1683,12 +1796,12 @@ const match = exports.match = /*#__PURE__*/(0, _Function.dual)(2, (self, options
1683
1796
  * @experimental
1684
1797
  * @category delays & timeouts
1685
1798
  */
1686
- const sleep = millis => async(function (resume) {
1687
- const timeout = setTimeout(function () {
1799
+ const sleep = millis => async(resume => {
1800
+ const timeout = setTimeout(() => {
1688
1801
  resume(void_);
1689
1802
  }, millis);
1690
1803
  return sync(() => {
1691
- return clearTimeout(timeout);
1804
+ clearTimeout(timeout);
1692
1805
  });
1693
1806
  });
1694
1807
  /**
@@ -1790,7 +1903,7 @@ class MicroScopeImpl {
1790
1903
  _tag: "Closed",
1791
1904
  exit: microExit
1792
1905
  };
1793
- return flatMap(forEach(finalizers, finalizer => exit(finalizer(microExit))), exits => asVoid(fromExit(Either.all(exits))));
1906
+ return flatMap(forEach(finalizers, finalizer => exit(finalizer(microExit))), exitVoidAll);
1794
1907
  }
1795
1908
  return void_;
1796
1909
  });
@@ -1848,7 +1961,7 @@ const provideScope = exports.provideScope = /*#__PURE__*/(0, _Function.dual)(2,
1848
1961
  * @experimental
1849
1962
  * @category resources & finalization
1850
1963
  */
1851
- const scoped = self => suspend(function () {
1964
+ const scoped = self => suspend(() => {
1852
1965
  const scope = new MicroScopeImpl();
1853
1966
  return onExit(provideService(self, MicroScope, scope), exit => scope.close(exit));
1854
1967
  });
@@ -1880,36 +1993,27 @@ const addFinalizer = finalizer => flatMap(scope, scope => scope.addFinalizer(fin
1880
1993
  * @category resources & finalization
1881
1994
  */
1882
1995
  exports.addFinalizer = addFinalizer;
1883
- const onExit = exports.onExit = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => onExitIf(self, _Function.constTrue, f));
1996
+ const onExit = exports.onExit = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => uninterruptibleMask(restore => matchCauseEffect(restore(self), {
1997
+ onFailure: cause => flatMap(f(exitFailCause(cause)), () => failCause(cause)),
1998
+ onSuccess: a => flatMap(f(exitSucceed(a)), () => succeed(a))
1999
+ })));
1884
2000
  /**
1885
- * When the `Micro` effect is completed, run the given finalizer effect if it
1886
- * matches the specified predicate.
2001
+ * Regardless of the result of the this `Micro` effect, run the finalizer effect.
1887
2002
  *
1888
- * @since 3.4.6
2003
+ * @since 3.4.0
1889
2004
  * @experimental
1890
2005
  * @category resources & finalization
1891
2006
  */
1892
- const onExitIf = exports.onExitIf = /*#__PURE__*/(0, _Function.dual)(3, (self, refinement, f) => uninterruptibleMask(restore => make(function (env, onExit) {
1893
- restore(self)[runSymbol](env, function (exit) {
1894
- if (!refinement(exit)) {
1895
- return onExit(exit);
1896
- }
1897
- f(exit)[runSymbol](env, function (finalizerExit) {
1898
- if (finalizerExit._tag === "Left") {
1899
- return onExit(finalizerExit);
1900
- }
1901
- onExit(exit);
1902
- });
1903
- });
1904
- })));
2007
+ const ensuring = exports.ensuring = /*#__PURE__*/(0, _Function.dual)(2, (self, finalizer) => onExit(self, _ => finalizer));
1905
2008
  /**
1906
- * Regardless of the result of the this `Micro` effect, run the finalizer effect.
2009
+ * When the `Micro` effect is completed, run the given finalizer effect if it
2010
+ * matches the specified predicate.
1907
2011
  *
1908
- * @since 3.4.0
2012
+ * @since 3.4.6
1909
2013
  * @experimental
1910
2014
  * @category resources & finalization
1911
2015
  */
1912
- const ensuring = exports.ensuring = /*#__PURE__*/(0, _Function.dual)(2, (self, finalizer) => onExit(self, _ => finalizer));
2016
+ const onExitIf = exports.onExitIf = /*#__PURE__*/(0, _Function.dual)(3, (self, refinement, f) => onExit(self, exit => refinement(exit) ? f(exit) : exitVoid));
1913
2017
  /**
1914
2018
  * When the `Micro` effect fails, run the given finalizer effect with the
1915
2019
  * `MicroCause` of the executed effect.
@@ -1918,7 +2022,7 @@ const ensuring = exports.ensuring = /*#__PURE__*/(0, _Function.dual)(2, (self, f
1918
2022
  * @experimental
1919
2023
  * @category resources & finalization
1920
2024
  */
1921
- const onError = exports.onError = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => onExitIf(self, exitIsFailure, exit => f(exit.left)));
2025
+ const onError = exports.onError = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => onExitIf(self, exitIsFailure, exit => f(exit.cause)));
1922
2026
  /**
1923
2027
  * If this `Micro` effect is aborted, run the finalizer effect.
1924
2028
  *
@@ -1935,7 +2039,7 @@ const onInterrupt = exports.onInterrupt = /*#__PURE__*/(0, _Function.dual)(2, (s
1935
2039
  * @experimental
1936
2040
  * @category resources & finalization
1937
2041
  */
1938
- const acquireUseRelease = (acquire, use, release) => uninterruptibleMask(restore => flatMap(acquire, a => flatMap(exit(restore(use(a))), exit => andThen(release(a, exit), fromExit(exit)))));
2042
+ const acquireUseRelease = (acquire, use, release) => uninterruptibleMask(restore => flatMap(acquire, a => flatMap(exit(restore(use(a))), exit => andThen(release(a, exit), exit))));
1939
2043
  // ----------------------------------------------------------------------------
1940
2044
  // interruption
1941
2045
  // ----------------------------------------------------------------------------
@@ -1947,27 +2051,46 @@ const acquireUseRelease = (acquire, use, release) => uninterruptibleMask(restore
1947
2051
  * @category interruption
1948
2052
  */
1949
2053
  exports.acquireUseRelease = acquireUseRelease;
1950
- const interrupt = exports.interrupt = /*#__PURE__*/make(function (env, onExit) {
1951
- const controller = envGet(env, currentAbortController);
1952
- controller.abort();
1953
- onExit(exitInterrupt);
2054
+ const interrupt = exports.interrupt = /*#__PURE__*/failCause( /*#__PURE__*/causeInterrupt());
2055
+ /**
2056
+ * Flag the effect as uninterruptible, which means that when the effect is
2057
+ * interrupted, it will be allowed to continue running until completion.
2058
+ *
2059
+ * @since 3.4.0
2060
+ * @experimental
2061
+ * @category flags
2062
+ */
2063
+ const uninterruptible = self => withFiber(fiber => {
2064
+ if (!fiber.interruptible) return self;
2065
+ fiber.interruptible = false;
2066
+ fiber._stack.push(setInterruptible(true));
2067
+ return self;
2068
+ });
2069
+ exports.uninterruptible = uninterruptible;
2070
+ const setInterruptible = /*#__PURE__*/makePrimitive({
2071
+ op: "SetInterruptible",
2072
+ ensure(fiber) {
2073
+ fiber.interruptible = this[args];
2074
+ if (fiber._interrupted && fiber.interruptible) {
2075
+ return () => exitInterrupt;
2076
+ }
2077
+ }
1954
2078
  });
1955
2079
  /**
1956
- * Wrap the given `Micro` effect in an uninterruptible region, preventing the
1957
- * effect from being aborted.
2080
+ * Flag the effect as interruptible, which means that when the effect is
2081
+ * interrupted, it will be interrupted immediately.
1958
2082
  *
1959
2083
  * @since 3.4.0
1960
2084
  * @experimental
1961
- * @category interruption
2085
+ * @category flags
1962
2086
  */
1963
- const uninterruptible = self => unsafeMakeOptions(function (env, onExit) {
1964
- const nextEnv = envMutate(env, function (env) {
1965
- env[currentInterruptible.key] = false;
1966
- env[currentAbortSignal.key] = new AbortController().signal;
1967
- return env;
1968
- });
1969
- self[runSymbol](nextEnv, onExit);
1970
- }, false);
2087
+ const interruptible = self => withFiber(fiber => {
2088
+ if (fiber.interruptible) return self;
2089
+ fiber.interruptible = true;
2090
+ fiber._stack.push(setInterruptible(false));
2091
+ if (fiber._interrupted) return exitInterrupt;
2092
+ return self;
2093
+ });
1971
2094
  /**
1972
2095
  * Wrap the given `Micro` effect in an uninterruptible region, preventing the
1973
2096
  * effect from being aborted.
@@ -1989,38 +2112,12 @@ const uninterruptible = self => unsafeMakeOptions(function (env, onExit) {
1989
2112
  * )
1990
2113
  * ```
1991
2114
  */
1992
- exports.uninterruptible = uninterruptible;
1993
- const uninterruptibleMask = f => unsafeMakeOptions((env, onExit) => {
1994
- const isInterruptible = envGet(env, currentInterruptible);
1995
- const effect = isInterruptible ? f(interruptible) : f(_Function.identity);
1996
- const nextEnv = isInterruptible ? envMutate(env, function (env) {
1997
- env[currentInterruptible.key] = false;
1998
- env[currentAbortSignal.key] = new AbortController().signal;
1999
- return env;
2000
- }) : env;
2001
- effect[runSymbol](nextEnv, onExit);
2002
- }, false);
2003
- /**
2004
- * Wrap the given `Micro` effect in an interruptible region, allowing the effect
2005
- * to be aborted.
2006
- *
2007
- * @since 3.4.0
2008
- * @experimental
2009
- * @category interruption
2010
- */
2011
- exports.uninterruptibleMask = uninterruptibleMask;
2012
- const interruptible = self => make((env, onExit) => {
2013
- const isInterruptible = envGet(env, currentInterruptible);
2014
- let newEnv = env;
2015
- if (!isInterruptible) {
2016
- const controller = envGet(env, currentAbortController);
2017
- newEnv = envMutate(env, function (env) {
2018
- env[currentInterruptible.key] = true;
2019
- env[currentAbortSignal.key] = controller.signal;
2020
- return env;
2021
- });
2022
- }
2023
- self[runSymbol](newEnv, onExit);
2115
+ exports.interruptible = interruptible;
2116
+ const uninterruptibleMask = f => withFiber(fiber => {
2117
+ if (!fiber.interruptible) return f(_Function.identity);
2118
+ fiber.interruptible = false;
2119
+ fiber._stack.push(setInterruptible(true));
2120
+ return f(interruptible);
2024
2121
  });
2025
2122
  /**
2026
2123
  * Runs all the provided effects in sequence respecting the structure provided in input.
@@ -2031,7 +2128,7 @@ const interruptible = self => make((env, onExit) => {
2031
2128
  * @experimental
2032
2129
  * @category collecting & elements
2033
2130
  */
2034
- exports.interruptible = interruptible;
2131
+ exports.uninterruptibleMask = uninterruptibleMask;
2035
2132
  const all = (arg, options) => {
2036
2133
  if (Array.isArray(arg) || (0, _Predicate.isIterable)(arg)) {
2037
2134
  return forEach(arg, _Function.identity, options);
@@ -2048,6 +2145,30 @@ const all = (arg, options) => {
2048
2145
  }), out);
2049
2146
  });
2050
2147
  };
2148
+ /**
2149
+ * @since 3.11.0
2150
+ * @experimental
2151
+ * @category collecting & elements
2152
+ */
2153
+ exports.all = all;
2154
+ const whileLoop = exports.whileLoop = /*#__PURE__*/makePrimitive({
2155
+ op: "While",
2156
+ contA(value, fiber) {
2157
+ this[args].step(value);
2158
+ if (this[args].while()) {
2159
+ fiber._stack.push(this);
2160
+ return this[args].body();
2161
+ }
2162
+ return exitVoid;
2163
+ },
2164
+ eval(fiber) {
2165
+ if (this[args].while()) {
2166
+ fiber._stack.push(this);
2167
+ return this[args].body();
2168
+ }
2169
+ return exitVoid;
2170
+ }
2171
+ });
2051
2172
  /**
2052
2173
  * For each element of the provided iterable, run the effect and collect the results.
2053
2174
  *
@@ -2061,59 +2182,76 @@ const all = (arg, options) => {
2061
2182
  * @experimental
2062
2183
  * @category collecting & elements
2063
2184
  */
2064
- exports.all = all;
2065
- const forEach = (iterable, f, options) => make(function (env, onExit) {
2066
- const concurrencyOption = options?.concurrency === "inherit" ? envGet(env, currentConcurrency) : options?.concurrency ?? 1;
2185
+ const forEach = (iterable, f, options) => withFiber(parent => {
2186
+ const concurrencyOption = options?.concurrency === "inherit" ? parent.getRef(CurrentConcurrency) : options?.concurrency ?? 1;
2067
2187
  const concurrency = concurrencyOption === "unbounded" ? Number.POSITIVE_INFINITY : Math.max(1, concurrencyOption);
2068
- // abort
2069
- const [envWithSignal, onAbort] = forkSignal(env);
2070
- // iterate
2071
- let result = undefined;
2072
- const items = Array.from(iterable);
2188
+ const items = Arr.fromIterable(iterable);
2073
2189
  let length = items.length;
2074
2190
  if (length === 0) {
2075
- return onExit(Either.right(options?.discard ? undefined : []));
2191
+ return options?.discard ? void_ : succeed([]);
2076
2192
  }
2077
2193
  const out = options?.discard ? undefined : new Array(length);
2078
2194
  let index = 0;
2079
- let inProgress = 0;
2080
- let doneCount = 0;
2081
- let pumping = false;
2082
- function pump() {
2083
- pumping = true;
2084
- while (inProgress < concurrency && index < length) {
2085
- const currentIndex = index;
2086
- const item = items[currentIndex];
2087
- index++;
2088
- inProgress++;
2089
- try {
2090
- f(item, currentIndex)[runSymbol](envWithSignal, function (exit) {
2091
- if (exit._tag === "Left") {
2092
- if (result === undefined) {
2093
- result = exit;
2094
- length = index;
2095
- onAbort();
2195
+ if (concurrency === 1) {
2196
+ return as(whileLoop({
2197
+ while: () => index < items.length,
2198
+ body: () => f(items[index], index),
2199
+ step: out ? b => out[index++] = b : _ => index++
2200
+ }), out);
2201
+ }
2202
+ return async(resume => {
2203
+ const fibers = new Set();
2204
+ let result = undefined;
2205
+ let inProgress = 0;
2206
+ let doneCount = 0;
2207
+ let pumping = false;
2208
+ let interrupted = false;
2209
+ function pump() {
2210
+ pumping = true;
2211
+ while (inProgress < concurrency && index < length) {
2212
+ const currentIndex = index;
2213
+ const item = items[currentIndex];
2214
+ index++;
2215
+ inProgress++;
2216
+ try {
2217
+ const child = unsafeFork(parent, f(item, currentIndex), true, true);
2218
+ fibers.add(child);
2219
+ child.addObserver(exit => {
2220
+ fibers.delete(child);
2221
+ if (interrupted) {
2222
+ return;
2223
+ } else if (exit._tag === "Failure") {
2224
+ if (result === undefined) {
2225
+ result = exit;
2226
+ length = index;
2227
+ fibers.forEach(fiber => fiber.unsafeInterrupt());
2228
+ }
2229
+ } else if (out !== undefined) {
2230
+ out[currentIndex] = exit.value;
2096
2231
  }
2097
- } else if (out !== undefined) {
2098
- out[currentIndex] = exit.right;
2099
- }
2100
- doneCount++;
2101
- inProgress--;
2102
- if (doneCount === length) {
2103
- onExit(result ?? Either.right(out));
2104
- } else if (!pumping && inProgress < concurrency) {
2105
- pump();
2106
- }
2107
- });
2108
- } catch (err) {
2109
- result = exitDie(err);
2110
- length = index;
2111
- onAbort();
2232
+ doneCount++;
2233
+ inProgress--;
2234
+ if (doneCount === length) {
2235
+ resume(result ?? succeed(out));
2236
+ } else if (!pumping && inProgress < concurrency) {
2237
+ pump();
2238
+ }
2239
+ });
2240
+ } catch (err) {
2241
+ result = exitDie(err);
2242
+ length = index;
2243
+ fibers.forEach(fiber => fiber.unsafeInterrupt());
2244
+ }
2112
2245
  }
2246
+ pumping = false;
2113
2247
  }
2114
- pumping = false;
2115
- }
2116
- pump();
2248
+ pump();
2249
+ return suspend(() => {
2250
+ interrupted = true;
2251
+ index = length;
2252
+ return fiberInterruptAll(fibers);
2253
+ });
2254
+ });
2117
2255
  });
2118
2256
  /**
2119
2257
  * Effectfully filter the elements of the provided iterable.
@@ -2180,93 +2318,8 @@ const bindTo = exports.bindTo = /*#__PURE__*/doNotation.bindTo(map);
2180
2318
  const bind = exports.bind = /*#__PURE__*/doNotation.bind(map, flatMap);
2181
2319
  const let_ = exports.let = /*#__PURE__*/doNotation.let_(map);
2182
2320
  // ----------------------------------------------------------------------------
2183
- // handle & forking
2321
+ // fibers & forking
2184
2322
  // ----------------------------------------------------------------------------
2185
- /**
2186
- * @since 3.4.0
2187
- * @experimental
2188
- * @category handle & forking
2189
- */
2190
- const HandleTypeId = exports.HandleTypeId = /*#__PURE__*/Symbol.for("effect/Micro/Handle");
2191
- /**
2192
- * @since 3.4.0
2193
- * @experimental
2194
- * @category handle & forking
2195
- */
2196
- const isHandle = u => typeof u === "object" && u !== null && HandleTypeId in u;
2197
- exports.isHandle = isHandle;
2198
- class HandleImpl extends Class {
2199
- parentSignal;
2200
- [HandleTypeId];
2201
- observers = /*#__PURE__*/new Set();
2202
- _exit = undefined;
2203
- _controller;
2204
- isRoot;
2205
- constructor(parentSignal, controller) {
2206
- super();
2207
- this.parentSignal = parentSignal;
2208
- this[HandleTypeId] = HandleTypeId;
2209
- this.isRoot = controller !== undefined;
2210
- this._controller = controller ?? new AbortController();
2211
- if (!this.isRoot) {
2212
- parentSignal.addEventListener("abort", this.unsafeInterrupt);
2213
- }
2214
- }
2215
- unsafePoll() {
2216
- return this._exit ?? null;
2217
- }
2218
- unsafeInterrupt = () => {
2219
- this._controller.abort();
2220
- };
2221
- emit(exit) {
2222
- if (this._exit) {
2223
- return;
2224
- }
2225
- this._exit = exit;
2226
- if (!this.isRoot) {
2227
- this.parentSignal.removeEventListener("abort", this.unsafeInterrupt);
2228
- }
2229
- this.observers.forEach(observer => observer(exit));
2230
- this.observers.clear();
2231
- }
2232
- addObserver(observer) {
2233
- if (this._exit) {
2234
- return observer(this._exit);
2235
- }
2236
- this.observers.add(observer);
2237
- }
2238
- removeObserver(observer) {
2239
- this.observers.delete(observer);
2240
- }
2241
- get await() {
2242
- return suspend(() => {
2243
- if (this._exit) {
2244
- return succeed(this._exit);
2245
- }
2246
- return async(resume => {
2247
- function observer(exit) {
2248
- resume(succeed(exit));
2249
- }
2250
- this.addObserver(observer);
2251
- return sync(() => {
2252
- this.removeObserver(observer);
2253
- });
2254
- });
2255
- });
2256
- }
2257
- get join() {
2258
- return flatMap(this.await, fromExit);
2259
- }
2260
- get interrupt() {
2261
- return suspend(() => {
2262
- this.unsafeInterrupt();
2263
- return this.await;
2264
- });
2265
- }
2266
- asMicro() {
2267
- return this.join;
2268
- }
2269
- }
2270
2323
  /**
2271
2324
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2272
2325
  * aborted.
@@ -2277,21 +2330,24 @@ class HandleImpl extends Class {
2277
2330
  * @experimental
2278
2331
  * @category handle & forking
2279
2332
  */
2280
- const fork = self => make(function (env, onExit) {
2281
- const signal = envGet(env, currentAbortSignal);
2282
- const handle = new HandleImpl(signal);
2283
- const nextEnv = envMutate(env, map => {
2284
- map[currentAbortController.key] = handle._controller;
2285
- map[currentAbortSignal.key] = handle._controller.signal;
2286
- return map;
2287
- });
2288
- envGet(env, currentScheduler).scheduleTask(() => {
2289
- self[runSymbol](nextEnv, exit => {
2290
- handle.emit(exit);
2291
- });
2292
- }, 0);
2293
- onExit(Either.right(handle));
2333
+ const fork = self => withFiber(fiber => {
2334
+ fiberMiddleware.interruptChildren ??= fiberInterruptChildren;
2335
+ return succeed(unsafeFork(fiber, self));
2294
2336
  });
2337
+ exports.fork = fork;
2338
+ const unsafeFork = (parent, effect, immediate = false, daemon = false) => {
2339
+ const child = new FiberImpl(parent.context, parent.interruptible);
2340
+ if (!daemon) {
2341
+ parent.children().add(child);
2342
+ child.addObserver(() => parent.children().delete(child));
2343
+ }
2344
+ if (immediate) {
2345
+ child.evaluate(effect);
2346
+ } else {
2347
+ parent.getRef(CurrentScheduler).scheduleTask(() => child.evaluate(effect), 0);
2348
+ }
2349
+ return child;
2350
+ };
2295
2351
  /**
2296
2352
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2297
2353
  * aborted.
@@ -2302,22 +2358,7 @@ const fork = self => make(function (env, onExit) {
2302
2358
  * @experimental
2303
2359
  * @category handle & forking
2304
2360
  */
2305
- exports.fork = fork;
2306
- const forkDaemon = self => make(function (env, onExit) {
2307
- const controller = new AbortController();
2308
- const handle = new HandleImpl(controller.signal, controller);
2309
- const nextEnv = envMutate(env, map => {
2310
- map[currentAbortController.key] = controller;
2311
- map[currentAbortSignal.key] = controller.signal;
2312
- return map;
2313
- });
2314
- envGet(env, currentScheduler).scheduleTask(() => {
2315
- self[runSymbol](nextEnv, exit => {
2316
- handle.emit(exit);
2317
- });
2318
- }, 0);
2319
- onExit(Either.right(handle));
2320
- });
2361
+ const forkDaemon = self => withFiber(fiber => succeed(unsafeFork(fiber, self, false, true)));
2321
2362
  /**
2322
2363
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2323
2364
  * aborted.
@@ -2329,7 +2370,7 @@ const forkDaemon = self => make(function (env, onExit) {
2329
2370
  * @category handle & forking
2330
2371
  */
2331
2372
  exports.forkDaemon = forkDaemon;
2332
- const forkIn = exports.forkIn = /*#__PURE__*/(0, _Function.dual)(2, (self, scope) => uninterruptibleMask(restore => flatMap(scope.fork, scope => tap(restore(forkDaemon(onExit(self, exit => scope.close(exit)))), fiber => scope.addFinalizer(_ => asVoid(fiber.interrupt))))));
2373
+ const forkIn = exports.forkIn = /*#__PURE__*/(0, _Function.dual)(2, (self, scope) => uninterruptibleMask(restore => flatMap(scope.fork, scope => tap(restore(forkDaemon(onExit(self, exit => scope.close(exit)))), fiber => scope.addFinalizer(_ => fiberInterrupt(fiber))))));
2333
2374
  /**
2334
2375
  * Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
2335
2376
  * aborted.
@@ -2370,29 +2411,20 @@ const forkScoped = self => flatMap(scope, scope => forkIn(self, scope));
2370
2411
  */
2371
2412
  exports.forkScoped = forkScoped;
2372
2413
  const runFork = (effect, options) => {
2373
- const controller = new AbortController();
2374
- const refs = Object.create(null);
2375
- refs[currentAbortController.key] = controller;
2376
- refs[currentAbortSignal.key] = controller.signal;
2377
- refs[currentScheduler.key] = options?.scheduler ?? new MicroSchedulerDefault();
2378
- const env = envMake(refs);
2379
- const handle = new HandleImpl(controller.signal, controller);
2380
- effect[runSymbol](envSet(env, currentAbortSignal, handle._controller.signal), exit => {
2381
- handle.emit(exit);
2382
- if (options?.signal) {
2383
- options.signal.removeEventListener("abort", handle.unsafeInterrupt);
2384
- }
2385
- });
2414
+ const fiber = new FiberImpl(CurrentScheduler.context(options?.scheduler ?? new MicroSchedulerDefault()));
2415
+ fiber.evaluate(effect);
2386
2416
  if (options?.signal) {
2387
2417
  if (options.signal.aborted) {
2388
- handle.unsafeInterrupt();
2418
+ fiber.unsafeInterrupt();
2389
2419
  } else {
2390
- options.signal.addEventListener("abort", handle.unsafeInterrupt, {
2420
+ const abort = () => fiber.unsafeInterrupt();
2421
+ options.signal.addEventListener("abort", abort, {
2391
2422
  once: true
2392
2423
  });
2424
+ fiber.addObserver(() => options.signal.removeEventListener("abort", abort));
2393
2425
  }
2394
2426
  }
2395
- return handle;
2427
+ return fiber;
2396
2428
  };
2397
2429
  /**
2398
2430
  * Execute the `Micro` effect and return a `Promise` that resolves with the
@@ -2417,10 +2449,10 @@ const runPromiseExit = (effect, options) => new Promise((resolve, _reject) => {
2417
2449
  */
2418
2450
  exports.runPromiseExit = runPromiseExit;
2419
2451
  const runPromise = (effect, options) => runPromiseExit(effect, options).then(exit => {
2420
- if (exit._tag === "Left") {
2421
- throw exit.left;
2452
+ if (exit._tag === "Failure") {
2453
+ throw exit.cause;
2422
2454
  }
2423
- return exit.right;
2455
+ return exit.value;
2424
2456
  });
2425
2457
  /**
2426
2458
  * Attempt to execute the `Micro` effect synchronously and return the `MicroExit`.
@@ -2435,15 +2467,11 @@ const runPromise = (effect, options) => runPromiseExit(effect, options).then(exi
2435
2467
  exports.runPromise = runPromise;
2436
2468
  const runSyncExit = effect => {
2437
2469
  const scheduler = new MicroSchedulerDefault();
2438
- const handle = runFork(effect, {
2470
+ const fiber = runFork(effect, {
2439
2471
  scheduler
2440
2472
  });
2441
2473
  scheduler.flush();
2442
- const exit = handle.unsafePoll();
2443
- if (exit === null) {
2444
- return exitDie(handle);
2445
- }
2446
- return exit;
2474
+ return fiber._exit ?? exitDie(fiber);
2447
2475
  };
2448
2476
  /**
2449
2477
  * Attempt to execute the `Micro` effect synchronously and return the success
@@ -2456,25 +2484,25 @@ const runSyncExit = effect => {
2456
2484
  exports.runSyncExit = runSyncExit;
2457
2485
  const runSync = effect => {
2458
2486
  const exit = runSyncExit(effect);
2459
- if (exit._tag === "Left") {
2460
- throw exit.left;
2461
- }
2462
- return exit.right;
2487
+ if (exit._tag === "Failure") throw exit.cause;
2488
+ return exit.value;
2463
2489
  };
2464
2490
  exports.runSync = runSync;
2465
2491
  const YieldableError = /*#__PURE__*/function () {
2466
- class YieldableError extends globalThis.Error {
2467
- [runSymbol](_env, onExit) {
2468
- onExit(exitFail(this));
2469
- }
2492
+ class YieldableError extends globalThis.Error {}
2493
+ Object.assign(YieldableError.prototype, MicroProto, _effectable.StructuralPrototype, {
2494
+ [identifier]: "Failure",
2495
+ [evaluate]() {
2496
+ return fail(this);
2497
+ },
2470
2498
  toString() {
2471
2499
  return this.message ? `${this.name}: ${this.message}` : this.name;
2472
- }
2500
+ },
2473
2501
  toJSON() {
2474
2502
  return {
2475
2503
  ...this
2476
2504
  };
2477
- }
2505
+ },
2478
2506
  [_Inspectable.NodeInspectSymbol]() {
2479
2507
  const stack = this.stack;
2480
2508
  if (stack) {
@@ -2482,8 +2510,7 @@ const YieldableError = /*#__PURE__*/function () {
2482
2510
  }
2483
2511
  return this.toString();
2484
2512
  }
2485
- }
2486
- Object.assign(YieldableError.prototype, MicroProto, _effectable.StructuralPrototype);
2513
+ });
2487
2514
  return YieldableError;
2488
2515
  }();
2489
2516
  /**