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.
- package/dist/cjs/BigDecimal.js +125 -24
- package/dist/cjs/BigDecimal.js.map +1 -1
- package/dist/cjs/Channel.js +44 -4
- package/dist/cjs/Channel.js.map +1 -1
- package/dist/cjs/Config.js +8 -1
- package/dist/cjs/Config.js.map +1 -1
- package/dist/cjs/Context.js +26 -1
- package/dist/cjs/Context.js.map +1 -1
- package/dist/cjs/Cron.js +75 -67
- package/dist/cjs/Cron.js.map +1 -1
- package/dist/cjs/DateTime.js +114 -664
- package/dist/cjs/DateTime.js.map +1 -1
- package/dist/cjs/Effect.js +82 -4
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Inspectable.js +8 -4
- package/dist/cjs/Inspectable.js.map +1 -1
- package/dist/cjs/JSONSchema.js.map +1 -1
- package/dist/cjs/Micro.js +1099 -1072
- package/dist/cjs/Micro.js.map +1 -1
- package/dist/cjs/STM.js.map +1 -1
- package/dist/cjs/Schema.js +57 -8
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/Sink.js +9 -1
- package/dist/cjs/Sink.js.map +1 -1
- package/dist/cjs/Stream.js +25 -7
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/Utils.js +7 -1
- package/dist/cjs/Utils.js.map +1 -1
- package/dist/cjs/internal/channel/channelExecutor.js +5 -9
- package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
- package/dist/cjs/internal/channel.js +156 -130
- package/dist/cjs/internal/channel.js.map +1 -1
- package/dist/cjs/internal/config.js +13 -4
- package/dist/cjs/internal/config.js.map +1 -1
- package/dist/cjs/internal/context.js +46 -3
- package/dist/cjs/internal/context.js.map +1 -1
- package/dist/cjs/internal/dateTime.js +747 -0
- package/dist/cjs/internal/dateTime.js.map +1 -0
- package/dist/cjs/internal/fiberRuntime.js +34 -11
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/groupBy.js +9 -3
- package/dist/cjs/internal/groupBy.js.map +1 -1
- package/dist/cjs/internal/layer.js +1 -1
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/mailbox.js +1 -1
- package/dist/cjs/internal/mailbox.js.map +1 -1
- package/dist/cjs/internal/sink.js +25 -21
- package/dist/cjs/internal/sink.js.map +1 -1
- package/dist/cjs/internal/stream.js +70 -71
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/BigDecimal.d.ts +56 -1
- package/dist/dts/BigDecimal.d.ts.map +1 -1
- package/dist/dts/Channel.d.ts +66 -5
- package/dist/dts/Channel.d.ts.map +1 -1
- package/dist/dts/Config.d.ts +23 -1
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Context.d.ts +111 -0
- package/dist/dts/Context.d.ts.map +1 -1
- package/dist/dts/Cron.d.ts +15 -6
- package/dist/dts/Cron.d.ts.map +1 -1
- package/dist/dts/DateTime.d.ts +40 -49
- package/dist/dts/DateTime.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +88 -1
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Inspectable.d.ts.map +1 -1
- package/dist/dts/JSONSchema.d.ts +1 -0
- package/dist/dts/JSONSchema.d.ts.map +1 -1
- package/dist/dts/Micro.d.ts +875 -872
- package/dist/dts/Micro.d.ts.map +1 -1
- package/dist/dts/STM.d.ts +2 -0
- package/dist/dts/STM.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts +32 -0
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/dts/Sink.d.ts +8 -0
- package/dist/dts/Sink.d.ts.map +1 -1
- package/dist/dts/Stream.d.ts +50 -32
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/Utils.d.ts +4 -0
- package/dist/dts/Utils.d.ts.map +1 -1
- package/dist/dts/internal/context.d.ts +1 -1
- package/dist/dts/internal/context.d.ts.map +1 -1
- package/dist/dts/internal/dateTime.d.ts +2 -0
- package/dist/dts/internal/dateTime.d.ts.map +1 -0
- package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/BigDecimal.js +119 -20
- package/dist/esm/BigDecimal.js.map +1 -1
- package/dist/esm/Channel.js +42 -2
- package/dist/esm/Channel.js.map +1 -1
- package/dist/esm/Config.js +7 -0
- package/dist/esm/Config.js.map +1 -1
- package/dist/esm/Context.js +25 -0
- package/dist/esm/Context.js.map +1 -1
- package/dist/esm/Cron.js +75 -67
- package/dist/esm/Cron.js.map +1 -1
- package/dist/esm/DateTime.js +112 -627
- package/dist/esm/DateTime.js.map +1 -1
- package/dist/esm/Effect.js +77 -0
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Inspectable.js +8 -4
- package/dist/esm/Inspectable.js.map +1 -1
- package/dist/esm/JSONSchema.js.map +1 -1
- package/dist/esm/Micro.js +1077 -1047
- package/dist/esm/Micro.js.map +1 -1
- package/dist/esm/STM.js.map +1 -1
- package/dist/esm/Schema.js +54 -0
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/Sink.js +8 -0
- package/dist/esm/Sink.js.map +1 -1
- package/dist/esm/Stream.js +23 -5
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/Utils.js +5 -0
- package/dist/esm/Utils.js.map +1 -1
- package/dist/esm/internal/channel/channelExecutor.js +5 -7
- package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
- package/dist/esm/internal/channel.js +152 -129
- package/dist/esm/internal/channel.js.map +1 -1
- package/dist/esm/internal/config.js +11 -3
- package/dist/esm/internal/config.js.map +1 -1
- package/dist/esm/internal/context.js +42 -2
- package/dist/esm/internal/context.js.map +1 -1
- package/dist/esm/internal/dateTime.js +704 -0
- package/dist/esm/internal/dateTime.js.map +1 -0
- package/dist/esm/internal/fiberRuntime.js +31 -9
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/groupBy.js +9 -3
- package/dist/esm/internal/groupBy.js.map +1 -1
- package/dist/esm/internal/layer.js +1 -1
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/mailbox.js +1 -1
- package/dist/esm/internal/mailbox.js.map +1 -1
- package/dist/esm/internal/sink.js +23 -20
- package/dist/esm/internal/sink.js.map +1 -1
- package/dist/esm/internal/stream.js +66 -69
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +1 -1
- package/src/BigDecimal.ts +131 -21
- package/src/Channel.ts +81 -5
- package/src/Config.ts +24 -1
- package/src/Context.ts +119 -0
- package/src/Cron.ts +85 -68
- package/src/DateTime.ts +155 -757
- package/src/Effect.ts +340 -1
- package/src/Inspectable.ts +11 -7
- package/src/JSONSchema.ts +1 -0
- package/src/Micro.ts +2005 -1757
- package/src/STM.ts +2 -0
- package/src/Schema.ts +60 -0
- package/src/Sink.ts +11 -0
- package/src/Stream.ts +55 -44
- package/src/Utils.ts +8 -0
- package/src/internal/channel/channelExecutor.ts +37 -33
- package/src/internal/channel.ts +504 -467
- package/src/internal/config.ts +18 -6
- package/src/internal/context.ts +56 -4
- package/src/internal/dateTime.ts +1126 -0
- package/src/internal/fiberRuntime.ts +35 -16
- package/src/internal/groupBy.ts +13 -22
- package/src/internal/layer.ts +5 -8
- package/src/internal/mailbox.ts +6 -4
- package/src/internal/sink.ts +55 -35
- package/src/internal/stream.ts +299 -299
- package/src/internal/version.ts +1 -1
package/src/Micro.ts
CHANGED
|
@@ -4,28 +4,33 @@
|
|
|
4
4
|
* @since 3.4.0
|
|
5
5
|
* @experimental
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
7
|
+
import * as Arr from "effect/Array"
|
|
8
|
+
import type { Channel } from "./Channel.js"
|
|
8
9
|
import * as Context from "./Context.js"
|
|
9
|
-
import type { Effect,
|
|
10
|
+
import type { Effect, EffectUnify, EffectUnifyIgnore } from "./Effect.js"
|
|
10
11
|
import * as Effectable from "./Effectable.js"
|
|
11
12
|
import * as Either from "./Either.js"
|
|
12
|
-
import
|
|
13
|
+
import * as Equal from "./Equal.js"
|
|
14
|
+
import type { LazyArg } from "./Function.js"
|
|
15
|
+
import { constTrue, constVoid, dual, identity } from "./Function.js"
|
|
13
16
|
import { globalValue } from "./GlobalValue.js"
|
|
17
|
+
import * as Hash from "./Hash.js"
|
|
14
18
|
import type { TypeLambda } from "./HKT.js"
|
|
15
19
|
import type { Inspectable } from "./Inspectable.js"
|
|
16
|
-
import { NodeInspectSymbol, toStringUnknown } from "./Inspectable.js"
|
|
20
|
+
import { format, NodeInspectSymbol, toStringUnknown } from "./Inspectable.js"
|
|
21
|
+
import * as InternalContext from "./internal/context.js"
|
|
17
22
|
import * as doNotation from "./internal/doNotation.js"
|
|
18
23
|
import { StructuralPrototype } from "./internal/effectable.js"
|
|
19
|
-
import { SingleShotGen } from "./internal/singleShotGen.js"
|
|
20
24
|
import * as Option from "./Option.js"
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import type {
|
|
24
|
-
import
|
|
25
|
-
import type {
|
|
26
|
-
import type {
|
|
25
|
+
import type { Pipeable } from "./Pipeable.js"
|
|
26
|
+
import { pipeArguments } from "./Pipeable.js"
|
|
27
|
+
import type { Predicate, Refinement } from "./Predicate.js"
|
|
28
|
+
import { hasProperty, isIterable, isTagged } from "./Predicate.js"
|
|
29
|
+
import type { Sink } from "./Sink.js"
|
|
30
|
+
import type { Stream } from "./Stream.js"
|
|
31
|
+
import type { Concurrency, Covariant, Equals, NotFunction, Simplify } from "./Types.js"
|
|
27
32
|
import type * as Unify from "./Unify.js"
|
|
28
|
-
import { YieldWrap, yieldWrapGet } from "./Utils.js"
|
|
33
|
+
import { SingleShotGen, YieldWrap, yieldWrapGet } from "./Utils.js"
|
|
29
34
|
|
|
30
35
|
/**
|
|
31
36
|
* @since 3.4.0
|
|
@@ -44,16 +49,18 @@ export type TypeId = typeof TypeId
|
|
|
44
49
|
/**
|
|
45
50
|
* @since 3.4.0
|
|
46
51
|
* @experimental
|
|
47
|
-
* @category
|
|
52
|
+
* @category MicroExit
|
|
48
53
|
*/
|
|
49
|
-
export const
|
|
54
|
+
export const MicroExitTypeId: unique symbol = Symbol.for(
|
|
55
|
+
"effect/Micro/MicroExit"
|
|
56
|
+
)
|
|
50
57
|
|
|
51
58
|
/**
|
|
52
59
|
* @since 3.4.0
|
|
53
60
|
* @experimental
|
|
54
|
-
* @category
|
|
61
|
+
* @category MicroExit
|
|
55
62
|
*/
|
|
56
|
-
export type
|
|
63
|
+
export type MicroExitTypeId = typeof TypeId
|
|
57
64
|
|
|
58
65
|
/**
|
|
59
66
|
* A lightweight alternative to the `Effect` data type, with a subset of the functionality.
|
|
@@ -64,7 +71,6 @@ export type runSymbol = typeof runSymbol
|
|
|
64
71
|
*/
|
|
65
72
|
export interface Micro<out A, out E = never, out R = never> extends Effect<A, E, R> {
|
|
66
73
|
readonly [TypeId]: Micro.Variance<A, E, R>
|
|
67
|
-
[runSymbol](env: Env<any>, onExit: (exit: MicroExit<A, E>) => void): void
|
|
68
74
|
[Symbol.iterator](): MicroIterator<Micro<A, E, R>>
|
|
69
75
|
[Unify.typeSymbol]?: unknown
|
|
70
76
|
[Unify.unifySymbol]?: MicroUnify<this>
|
|
@@ -144,58 +150,6 @@ export interface MicroIterator<T extends Micro<any, any, any>> {
|
|
|
144
150
|
next(...args: ReadonlyArray<any>): IteratorResult<YieldWrap<T>, Micro.Success<T>>
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
/**
|
|
148
|
-
* @since 3.8.4
|
|
149
|
-
* @experimental
|
|
150
|
-
* @category models
|
|
151
|
-
*/
|
|
152
|
-
export interface MicroClass {
|
|
153
|
-
new<A, E = never, R = never>(): Micro<A, E, R>
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ----------------------------------------------------------------------------
|
|
157
|
-
// Microable
|
|
158
|
-
// ----------------------------------------------------------------------------
|
|
159
|
-
|
|
160
|
-
const MicroProto = {
|
|
161
|
-
...Effectable.EffectPrototype,
|
|
162
|
-
_op: "Micro",
|
|
163
|
-
[TypeId]: {
|
|
164
|
-
_A: identity,
|
|
165
|
-
_E: identity,
|
|
166
|
-
_R: identity
|
|
167
|
-
},
|
|
168
|
-
[Symbol.iterator]() {
|
|
169
|
-
return new SingleShotGen(new YieldWrap(this)) as any
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const MicroBase: MicroClass = (function() {
|
|
174
|
-
function Base() {}
|
|
175
|
-
Base.prototype = MicroProto
|
|
176
|
-
return Base as any
|
|
177
|
-
})()
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* @since 3.8.4
|
|
181
|
-
* @experimental
|
|
182
|
-
* @category constructors
|
|
183
|
-
*/
|
|
184
|
-
export abstract class Class<out A, out E = never, out R = never> extends MicroBase<A, E, R> {
|
|
185
|
-
/**
|
|
186
|
-
* @since 3.8.4
|
|
187
|
-
* @experimental
|
|
188
|
-
*/
|
|
189
|
-
abstract asMicro(): Micro<A, E, R>
|
|
190
|
-
/**
|
|
191
|
-
* @since 3.8.4
|
|
192
|
-
* @experimental
|
|
193
|
-
*/
|
|
194
|
-
[runSymbol](env: Env<any>, onExit: (exit: MicroExit<A, E>) => void): void {
|
|
195
|
-
this.asMicro()[runSymbol](env, onExit)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
153
|
// ----------------------------------------------------------------------------
|
|
200
154
|
// MicroCause
|
|
201
155
|
// ----------------------------------------------------------------------------
|
|
@@ -221,7 +175,10 @@ export type MicroCauseTypeId = typeof MicroCauseTypeId
|
|
|
221
175
|
* @experimental
|
|
222
176
|
* @category MicroCause
|
|
223
177
|
*/
|
|
224
|
-
export type MicroCause<E> =
|
|
178
|
+
export type MicroCause<E> =
|
|
179
|
+
| MicroCause.Die
|
|
180
|
+
| MicroCause.Fail<E>
|
|
181
|
+
| MicroCause.Interrupt
|
|
225
182
|
|
|
226
183
|
/**
|
|
227
184
|
* @since 3.6.6
|
|
@@ -302,7 +259,12 @@ abstract class MicroCauseImpl<Tag extends string, E> extends globalThis.Error im
|
|
|
302
259
|
message = originalError.message as string
|
|
303
260
|
const messageLines = message.split("\n").length
|
|
304
261
|
stack = originalError.stack
|
|
305
|
-
? `(${causeName}) ${
|
|
262
|
+
? `(${causeName}) ${
|
|
263
|
+
originalError.stack
|
|
264
|
+
.split("\n")
|
|
265
|
+
.slice(0, messageLines + 3)
|
|
266
|
+
.join("\n")
|
|
267
|
+
}`
|
|
306
268
|
: `${name}: ${message}`
|
|
307
269
|
} else {
|
|
308
270
|
name = causeName
|
|
@@ -329,7 +291,10 @@ abstract class MicroCauseImpl<Tag extends string, E> extends globalThis.Error im
|
|
|
329
291
|
}
|
|
330
292
|
|
|
331
293
|
class FailImpl<E> extends MicroCauseImpl<"Fail", E> implements MicroCause.Fail<E> {
|
|
332
|
-
constructor(
|
|
294
|
+
constructor(
|
|
295
|
+
readonly error: E,
|
|
296
|
+
traces: ReadonlyArray<string> = []
|
|
297
|
+
) {
|
|
333
298
|
super("Fail", error, traces)
|
|
334
299
|
}
|
|
335
300
|
}
|
|
@@ -339,10 +304,16 @@ class FailImpl<E> extends MicroCauseImpl<"Fail", E> implements MicroCause.Fail<E
|
|
|
339
304
|
* @experimental
|
|
340
305
|
* @category MicroCause
|
|
341
306
|
*/
|
|
342
|
-
export const causeFail = <E>(
|
|
307
|
+
export const causeFail = <E>(
|
|
308
|
+
error: E,
|
|
309
|
+
traces: ReadonlyArray<string> = []
|
|
310
|
+
): MicroCause<E> => new FailImpl(error, traces)
|
|
343
311
|
|
|
344
312
|
class DieImpl extends MicroCauseImpl<"Die", never> implements MicroCause.Die {
|
|
345
|
-
constructor(
|
|
313
|
+
constructor(
|
|
314
|
+
readonly defect: unknown,
|
|
315
|
+
traces: ReadonlyArray<string> = []
|
|
316
|
+
) {
|
|
346
317
|
super("Die", defect, traces)
|
|
347
318
|
}
|
|
348
319
|
}
|
|
@@ -352,8 +323,10 @@ class DieImpl extends MicroCauseImpl<"Die", never> implements MicroCause.Die {
|
|
|
352
323
|
* @experimental
|
|
353
324
|
* @category MicroCause
|
|
354
325
|
*/
|
|
355
|
-
export const causeDie = (
|
|
356
|
-
|
|
326
|
+
export const causeDie = (
|
|
327
|
+
defect: unknown,
|
|
328
|
+
traces: ReadonlyArray<string> = []
|
|
329
|
+
): MicroCause<never> => new DieImpl(defect, traces)
|
|
357
330
|
|
|
358
331
|
class InterruptImpl extends MicroCauseImpl<"Interrupt", never> implements MicroCause.Interrupt {
|
|
359
332
|
constructor(traces: ReadonlyArray<string> = []) {
|
|
@@ -366,14 +339,18 @@ class InterruptImpl extends MicroCauseImpl<"Interrupt", never> implements MicroC
|
|
|
366
339
|
* @experimental
|
|
367
340
|
* @category MicroCause
|
|
368
341
|
*/
|
|
369
|
-
export const causeInterrupt = (
|
|
342
|
+
export const causeInterrupt = (
|
|
343
|
+
traces: ReadonlyArray<string> = []
|
|
344
|
+
): MicroCause<never> => new InterruptImpl(traces)
|
|
370
345
|
|
|
371
346
|
/**
|
|
372
347
|
* @since 3.4.6
|
|
373
348
|
* @experimental
|
|
374
349
|
* @category MicroCause
|
|
375
350
|
*/
|
|
376
|
-
export const causeIsFail = <E>(
|
|
351
|
+
export const causeIsFail = <E>(
|
|
352
|
+
self: MicroCause<E>
|
|
353
|
+
): self is MicroCause.Fail<E> => self._tag === "Fail"
|
|
377
354
|
|
|
378
355
|
/**
|
|
379
356
|
* @since 3.4.6
|
|
@@ -387,7 +364,9 @@ export const causeIsDie = <E>(self: MicroCause<E>): self is MicroCause.Die => se
|
|
|
387
364
|
* @experimental
|
|
388
365
|
* @category MicroCause
|
|
389
366
|
*/
|
|
390
|
-
export const causeIsInterrupt = <E>(
|
|
367
|
+
export const causeIsInterrupt = <E>(
|
|
368
|
+
self: MicroCause<E>
|
|
369
|
+
): self is MicroCause.Interrupt => self._tag === "Interrupt"
|
|
391
370
|
|
|
392
371
|
/**
|
|
393
372
|
* @since 3.4.6
|
|
@@ -428,1690 +407,1963 @@ export const causeWithTrace: {
|
|
|
428
407
|
})
|
|
429
408
|
|
|
430
409
|
// ----------------------------------------------------------------------------
|
|
431
|
-
//
|
|
410
|
+
// Fiber
|
|
432
411
|
// ----------------------------------------------------------------------------
|
|
433
412
|
|
|
434
413
|
/**
|
|
435
|
-
* @since 3.
|
|
414
|
+
* @since 3.11.0
|
|
436
415
|
* @experimental
|
|
437
|
-
* @category
|
|
416
|
+
* @category Fiber
|
|
438
417
|
*/
|
|
439
|
-
export
|
|
440
|
-
/**
|
|
441
|
-
* @since 3.4.6
|
|
442
|
-
* @experimental
|
|
443
|
-
* @category MicroExit
|
|
444
|
-
*/
|
|
445
|
-
export type Success<A, E = never> = Either.Right<MicroCause<E>, A>
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* @since 3.4.6
|
|
449
|
-
* @experimental
|
|
450
|
-
* @category MicroExit
|
|
451
|
-
*/
|
|
452
|
-
export type Failure<A, E = never> = Either.Left<MicroCause<E>, A>
|
|
453
|
-
}
|
|
418
|
+
export const FiberTypeId = Symbol.for("effect/Micro/Fiber")
|
|
454
419
|
|
|
455
420
|
/**
|
|
456
|
-
*
|
|
457
|
-
* computation.
|
|
458
|
-
*
|
|
459
|
-
* It uses the `Either` data type to represent the success and failure cases.
|
|
460
|
-
*
|
|
461
|
-
* @since 3.4.6
|
|
421
|
+
* @since 3.11.0
|
|
462
422
|
* @experimental
|
|
463
|
-
* @category
|
|
423
|
+
* @category Fiber
|
|
464
424
|
*/
|
|
465
|
-
export type
|
|
425
|
+
export type FiberTypeId = typeof FiberTypeId
|
|
466
426
|
|
|
467
427
|
/**
|
|
468
|
-
* @since 3.
|
|
428
|
+
* @since 3.11.0
|
|
469
429
|
* @experimental
|
|
470
|
-
* @category
|
|
430
|
+
* @category Fiber
|
|
471
431
|
*/
|
|
472
|
-
export
|
|
432
|
+
export interface Fiber<out A, out E = never> {
|
|
433
|
+
readonly [FiberTypeId]: Fiber.Variance<A, E>
|
|
473
434
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
435
|
+
readonly currentOpCount: number
|
|
436
|
+
readonly getRef: <I, A>(ref: Context.Reference<I, A>) => A
|
|
437
|
+
readonly context: Context.Context<never>
|
|
438
|
+
readonly addObserver: (cb: (exit: MicroExit<A, E>) => void) => () => void
|
|
439
|
+
readonly unsafeInterrupt: () => void
|
|
440
|
+
readonly unsafePoll: () => MicroExit<A, E> | undefined
|
|
441
|
+
}
|
|
480
442
|
|
|
481
443
|
/**
|
|
482
|
-
* @since 3.
|
|
444
|
+
* @since 3.11.0
|
|
483
445
|
* @experimental
|
|
484
|
-
* @category
|
|
446
|
+
* @category Fiber
|
|
485
447
|
*/
|
|
486
|
-
export
|
|
448
|
+
export declare namespace Fiber {
|
|
449
|
+
/**
|
|
450
|
+
* @since 3.11.0
|
|
451
|
+
* @experimental
|
|
452
|
+
* @category Fiber
|
|
453
|
+
*/
|
|
454
|
+
export interface Variance<out A, out E = never> {
|
|
455
|
+
readonly _A: Covariant<A>
|
|
456
|
+
readonly _E: Covariant<E>
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const fiberVariance = {
|
|
461
|
+
_A: identity,
|
|
462
|
+
_E: identity
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
class FiberImpl<in out A = any, in out E = any> implements Fiber<A, E> {
|
|
466
|
+
readonly [FiberTypeId]: Fiber.Variance<A, E>
|
|
467
|
+
|
|
468
|
+
readonly _stack: Array<Primitive> = []
|
|
469
|
+
readonly _observers: Array<(exit: MicroExit<A, E>) => void> = []
|
|
470
|
+
_exit: MicroExit<A, E> | undefined
|
|
471
|
+
public _children: Set<FiberImpl<any, any>> | undefined
|
|
472
|
+
|
|
473
|
+
public currentOpCount = 0
|
|
474
|
+
|
|
475
|
+
constructor(
|
|
476
|
+
public context: Context.Context<never>,
|
|
477
|
+
public interruptible = true
|
|
478
|
+
) {
|
|
479
|
+
this[FiberTypeId] = fiberVariance
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
getRef<I, A>(ref: Context.Reference<I, A>): A {
|
|
483
|
+
return InternalContext.unsafeGetReference(this.context, ref)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
addObserver(cb: (exit: MicroExit<A, E>) => void): () => void {
|
|
487
|
+
if (this._exit) {
|
|
488
|
+
cb(this._exit)
|
|
489
|
+
return constVoid
|
|
490
|
+
}
|
|
491
|
+
this._observers.push(cb)
|
|
492
|
+
return () => {
|
|
493
|
+
const index = this._observers.indexOf(cb)
|
|
494
|
+
if (index >= 0) {
|
|
495
|
+
this._observers.splice(index, 1)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
_interrupted = false
|
|
501
|
+
unsafeInterrupt(): void {
|
|
502
|
+
if (this._exit) {
|
|
503
|
+
return
|
|
504
|
+
}
|
|
505
|
+
this._interrupted = true
|
|
506
|
+
if (this.interruptible) {
|
|
507
|
+
this.evaluate(exitInterrupt as any)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
unsafePoll(): MicroExit<A, E> | undefined {
|
|
512
|
+
return this._exit
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
evaluate(effect: Primitive): void {
|
|
516
|
+
if (this._exit) {
|
|
517
|
+
return
|
|
518
|
+
} else if (this._yielded !== undefined) {
|
|
519
|
+
const yielded = this._yielded as () => void
|
|
520
|
+
this._yielded = undefined
|
|
521
|
+
yielded()
|
|
522
|
+
}
|
|
523
|
+
const exit = this.runLoop(effect)
|
|
524
|
+
if (exit === Yield) {
|
|
525
|
+
return
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// the interruptChildren middlware is added in Micro.fork, so it can be
|
|
529
|
+
// tree-shaken if not used
|
|
530
|
+
const interruptChildren = fiberMiddleware.interruptChildren && fiberMiddleware.interruptChildren(this)
|
|
531
|
+
if (interruptChildren !== undefined) {
|
|
532
|
+
return this.evaluate(flatMap(interruptChildren, () => exit) as any)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
this._exit = exit
|
|
536
|
+
for (let i = 0; i < this._observers.length; i++) {
|
|
537
|
+
this._observers[i](exit)
|
|
538
|
+
}
|
|
539
|
+
this._observers.length = 0
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
runLoop(effect: Primitive): MicroExit<A, E> | Yield {
|
|
543
|
+
let yielding = false
|
|
544
|
+
let current: Primitive | Yield = effect
|
|
545
|
+
this.currentOpCount = 0
|
|
546
|
+
try {
|
|
547
|
+
while (true) {
|
|
548
|
+
this.currentOpCount++
|
|
549
|
+
if (!yielding && this.getRef(CurrentScheduler).shouldYield(this as any)) {
|
|
550
|
+
yielding = true
|
|
551
|
+
const prev = current
|
|
552
|
+
current = flatMap(yieldNow, () => prev as any) as any
|
|
553
|
+
}
|
|
554
|
+
current = (current as any)[evaluate](this)
|
|
555
|
+
if (current === Yield) {
|
|
556
|
+
const yielded = this._yielded!
|
|
557
|
+
if (MicroExitTypeId in yielded) {
|
|
558
|
+
this._yielded = undefined
|
|
559
|
+
return yielded
|
|
560
|
+
}
|
|
561
|
+
return Yield
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
} catch (error) {
|
|
565
|
+
if (!hasProperty(current, evaluate)) {
|
|
566
|
+
return exitDie(`Micro/Fiber.runLoop: Not a valid effect: ${String(current)}`)
|
|
567
|
+
}
|
|
568
|
+
return exitDie(error)
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
getCont<S extends successCont | failureCont>(
|
|
573
|
+
symbol: S
|
|
574
|
+
): Primitive & Record<S, (value: any, fiber: FiberImpl) => Primitive> | undefined {
|
|
575
|
+
while (true) {
|
|
576
|
+
const op = this._stack.pop()
|
|
577
|
+
if (!op) return undefined
|
|
578
|
+
const cont = op[ensureCont] && op[ensureCont](this)
|
|
579
|
+
if (cont) return { [symbol]: cont } as any
|
|
580
|
+
if (op[symbol]) return op as any
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// cancel the yielded operation, or for the yielded exit value
|
|
585
|
+
_yielded: MicroExit<any, any> | (() => void) | undefined = undefined
|
|
586
|
+
yieldWith(value: MicroExit<any, any> | (() => void)): Yield {
|
|
587
|
+
this._yielded = value
|
|
588
|
+
return Yield
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
children(): Set<Fiber<any, any>> {
|
|
592
|
+
return this._children ??= new Set()
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const fiberMiddleware = globalValue("effect/Micro/fiberMiddleware", () => ({
|
|
597
|
+
interruptChildren: undefined as ((fiber: FiberImpl) => Micro<void> | undefined) | undefined
|
|
598
|
+
}))
|
|
599
|
+
|
|
600
|
+
const fiberInterruptChildren = (fiber: FiberImpl) => {
|
|
601
|
+
if (fiber._children === undefined || fiber._children.size === 0) {
|
|
602
|
+
return undefined
|
|
603
|
+
}
|
|
604
|
+
return fiberInterruptAll(fiber._children)
|
|
605
|
+
}
|
|
487
606
|
|
|
488
607
|
/**
|
|
489
|
-
* @since 3.
|
|
608
|
+
* @since 3.11.0
|
|
490
609
|
* @experimental
|
|
491
|
-
* @category
|
|
610
|
+
* @category Fiber
|
|
492
611
|
*/
|
|
493
|
-
export const
|
|
612
|
+
export const fiberAwait = <A, E>(self: Fiber<A, E>): Micro<MicroExit<A, E>> =>
|
|
613
|
+
async((resume) => sync(self.addObserver((exit) => resume(succeed(exit)))))
|
|
494
614
|
|
|
495
615
|
/**
|
|
496
|
-
* @since 3.
|
|
616
|
+
* @since 3.11.0
|
|
497
617
|
* @experimental
|
|
498
|
-
* @category
|
|
618
|
+
* @category Fiber
|
|
499
619
|
*/
|
|
500
|
-
export const
|
|
620
|
+
export const fiberInterrupt = <A, E>(self: Fiber<A, E>): Micro<void> =>
|
|
621
|
+
suspend(() => {
|
|
622
|
+
self.unsafeInterrupt()
|
|
623
|
+
return asVoid(fiberAwait(self))
|
|
624
|
+
})
|
|
501
625
|
|
|
502
626
|
/**
|
|
503
|
-
* @since 3.
|
|
627
|
+
* @since 3.11.0
|
|
504
628
|
* @experimental
|
|
505
|
-
* @category
|
|
629
|
+
* @category Fiber
|
|
506
630
|
*/
|
|
507
|
-
export const
|
|
631
|
+
export const fiberInterruptAll = <A extends Iterable<Fiber<any, any>>>(fibers: A): Micro<void> =>
|
|
632
|
+
suspend(() => {
|
|
633
|
+
for (const fiber of fibers) fiber.unsafeInterrupt()
|
|
634
|
+
const iter = fibers[Symbol.iterator]()
|
|
635
|
+
const wait: Micro<void> = suspend(() => {
|
|
636
|
+
let result = iter.next()
|
|
637
|
+
while (!result.done) {
|
|
638
|
+
if (result.value.unsafePoll()) {
|
|
639
|
+
result = iter.next()
|
|
640
|
+
continue
|
|
641
|
+
}
|
|
642
|
+
const fiber = result.value
|
|
643
|
+
return async((resume) => {
|
|
644
|
+
fiber.addObserver((_) => {
|
|
645
|
+
resume(wait)
|
|
646
|
+
})
|
|
647
|
+
})
|
|
648
|
+
}
|
|
649
|
+
return exitVoid
|
|
650
|
+
})
|
|
651
|
+
return wait
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
const identifier = Symbol.for("effect/Micro/identifier")
|
|
655
|
+
type identifier = typeof identifier
|
|
656
|
+
|
|
657
|
+
const args = Symbol.for("effect/Micro/args")
|
|
658
|
+
type args = typeof args
|
|
659
|
+
|
|
660
|
+
const evaluate = Symbol.for("effect/Micro/evaluate")
|
|
661
|
+
type evaluate = typeof evaluate
|
|
662
|
+
|
|
663
|
+
const successCont = Symbol.for("effect/Micro/successCont")
|
|
664
|
+
type successCont = typeof successCont
|
|
665
|
+
|
|
666
|
+
const failureCont = Symbol.for("effect/Micro/failureCont")
|
|
667
|
+
type failureCont = typeof failureCont
|
|
668
|
+
|
|
669
|
+
const ensureCont = Symbol.for("effect/Micro/ensureCont")
|
|
670
|
+
type ensureCont = typeof ensureCont
|
|
671
|
+
|
|
672
|
+
const Yield = Symbol.for("effect/Micro/Yield")
|
|
673
|
+
type Yield = typeof Yield
|
|
674
|
+
|
|
675
|
+
interface Primitive {
|
|
676
|
+
readonly [identifier]: string
|
|
677
|
+
readonly [successCont]: ((value: unknown, fiber: FiberImpl) => Primitive | Yield) | undefined
|
|
678
|
+
readonly [failureCont]:
|
|
679
|
+
| ((cause: MicroCause<unknown>, fiber: FiberImpl) => Primitive | Yield)
|
|
680
|
+
| undefined
|
|
681
|
+
readonly [ensureCont]:
|
|
682
|
+
| ((fiber: FiberImpl) =>
|
|
683
|
+
| ((value: unknown, fiber: FiberImpl) => Primitive | Yield)
|
|
684
|
+
| undefined)
|
|
685
|
+
| undefined
|
|
686
|
+
[evaluate](fiber: FiberImpl): Primitive | Yield
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const microVariance = {
|
|
690
|
+
_A: identity,
|
|
691
|
+
_E: identity,
|
|
692
|
+
_R: identity
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const MicroProto = {
|
|
696
|
+
...Effectable.EffectPrototype,
|
|
697
|
+
_op: "Micro",
|
|
698
|
+
[TypeId]: microVariance,
|
|
699
|
+
pipe() {
|
|
700
|
+
return pipeArguments(this, arguments)
|
|
701
|
+
},
|
|
702
|
+
[Symbol.iterator]() {
|
|
703
|
+
return new SingleShotGen(new YieldWrap(this)) as any
|
|
704
|
+
},
|
|
705
|
+
toJSON(this: Primitive) {
|
|
706
|
+
return {
|
|
707
|
+
_id: "effect/Micro",
|
|
708
|
+
op: this[identifier],
|
|
709
|
+
...(args in this ? { args: this[args] } : undefined)
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
toString() {
|
|
713
|
+
return format(this)
|
|
714
|
+
},
|
|
715
|
+
[NodeInspectSymbol]() {
|
|
716
|
+
return format(this)
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
function defaultEvaluate(_fiber: FiberImpl): Primitive | Yield {
|
|
721
|
+
return exitDie(`Micro.evaluate: Not implemented`) as any
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const makePrimitiveProto = <Op extends string>(options: {
|
|
725
|
+
readonly op: Op
|
|
726
|
+
readonly eval?: (fiber: FiberImpl) => Primitive | Micro<any, any, any> | Yield
|
|
727
|
+
readonly contA?: (this: Primitive, value: any, fiber: FiberImpl) => Primitive | Micro<any, any, any> | Yield
|
|
728
|
+
readonly contE?: (
|
|
729
|
+
this: Primitive,
|
|
730
|
+
cause: MicroCause<any>,
|
|
731
|
+
fiber: FiberImpl
|
|
732
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
733
|
+
readonly ensure?: (this: Primitive, fiber: FiberImpl) => void | ((value: any, fiber: FiberImpl) => void)
|
|
734
|
+
}): Primitive => ({
|
|
735
|
+
...MicroProto,
|
|
736
|
+
[identifier]: options.op,
|
|
737
|
+
[evaluate]: options.eval ?? defaultEvaluate,
|
|
738
|
+
[successCont]: options.contA,
|
|
739
|
+
[failureCont]: options.contE,
|
|
740
|
+
[ensureCont]: options.ensure
|
|
741
|
+
} as any)
|
|
742
|
+
|
|
743
|
+
const makePrimitive = <Fn extends (...args: Array<any>) => any, Single extends boolean = true>(options: {
|
|
744
|
+
readonly op: string
|
|
745
|
+
readonly single?: Single
|
|
746
|
+
readonly eval?: (
|
|
747
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
748
|
+
fiber: FiberImpl
|
|
749
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
750
|
+
readonly contA?: (
|
|
751
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
752
|
+
value: any,
|
|
753
|
+
fiber: FiberImpl
|
|
754
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
755
|
+
readonly contE?: (
|
|
756
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
757
|
+
cause: MicroCause<any>,
|
|
758
|
+
fiber: FiberImpl
|
|
759
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
760
|
+
readonly ensure?: (
|
|
761
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
762
|
+
fiber: FiberImpl
|
|
763
|
+
) => void | ((value: any, fiber: FiberImpl) => void)
|
|
764
|
+
}): Fn => {
|
|
765
|
+
const Proto = makePrimitiveProto(options as any)
|
|
766
|
+
return function() {
|
|
767
|
+
const self = Object.create(Proto)
|
|
768
|
+
self[args] = options.single === false ? arguments : arguments[0]
|
|
769
|
+
return self
|
|
770
|
+
} as Fn
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
const makeExit = <Fn extends (...args: Array<any>) => any, Prop extends string>(options: {
|
|
774
|
+
readonly op: "Success" | "Failure"
|
|
775
|
+
readonly prop: Prop
|
|
776
|
+
readonly eval: (
|
|
777
|
+
this:
|
|
778
|
+
& MicroExit<unknown, unknown>
|
|
779
|
+
& { [args]: Parameters<Fn>[0] },
|
|
780
|
+
fiber: FiberImpl<unknown, unknown>
|
|
781
|
+
) => Primitive | Yield
|
|
782
|
+
}): Fn => {
|
|
783
|
+
const Proto = {
|
|
784
|
+
...makePrimitiveProto(options),
|
|
785
|
+
[MicroExitTypeId]: MicroExitTypeId,
|
|
786
|
+
_tag: options.op,
|
|
787
|
+
get [options.prop](): any {
|
|
788
|
+
return (this as any)[args]
|
|
789
|
+
},
|
|
790
|
+
toJSON(this: any) {
|
|
791
|
+
return {
|
|
792
|
+
_id: "effect/Micro/Exit",
|
|
793
|
+
_tag: options.op,
|
|
794
|
+
[options.prop]: this[args]
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
[Equal.symbol](this: any, that: any): boolean {
|
|
798
|
+
return isMicroExit(that) && that._tag === options.op &&
|
|
799
|
+
Equal.equals(this[args], (that as any)[args])
|
|
800
|
+
},
|
|
801
|
+
[Hash.symbol](this: any): number {
|
|
802
|
+
return Hash.cached(this, Hash.combine(Hash.string(options.op))(Hash.hash(this[args])))
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return function(value: unknown) {
|
|
806
|
+
const self = Object.create(Proto)
|
|
807
|
+
self[args] = value
|
|
808
|
+
self[successCont] = undefined
|
|
809
|
+
self[failureCont] = undefined
|
|
810
|
+
self[ensureCont] = undefined
|
|
811
|
+
return self
|
|
812
|
+
} as Fn
|
|
813
|
+
}
|
|
508
814
|
|
|
509
815
|
/**
|
|
510
|
-
*
|
|
816
|
+
* Creates a `Micro` effect that will succeed with the specified constant value.
|
|
817
|
+
*
|
|
818
|
+
* @since 3.4.0
|
|
511
819
|
* @experimental
|
|
512
|
-
* @category
|
|
820
|
+
* @category constructors
|
|
513
821
|
*/
|
|
514
|
-
export const
|
|
822
|
+
export const succeed: <A>(value: A) => Micro<A> = makeExit({
|
|
823
|
+
op: "Success",
|
|
824
|
+
prop: "value",
|
|
825
|
+
eval(fiber) {
|
|
826
|
+
const cont = fiber.getCont(successCont)
|
|
827
|
+
return cont ? cont[successCont](this[args], fiber) : fiber.yieldWith(this)
|
|
828
|
+
}
|
|
829
|
+
})
|
|
515
830
|
|
|
516
831
|
/**
|
|
832
|
+
* Creates a `Micro` effect that will fail with the specified `MicroCause`.
|
|
833
|
+
*
|
|
517
834
|
* @since 3.4.6
|
|
518
835
|
* @experimental
|
|
519
|
-
* @category
|
|
836
|
+
* @category constructors
|
|
520
837
|
*/
|
|
521
|
-
export const
|
|
522
|
-
|
|
838
|
+
export const failCause: <E>(cause: MicroCause<E>) => Micro<never, E> = makeExit({
|
|
839
|
+
op: "Failure",
|
|
840
|
+
prop: "cause",
|
|
841
|
+
eval(fiber) {
|
|
842
|
+
let cont = fiber.getCont(failureCont)
|
|
843
|
+
while (causeIsInterrupt(this[args]) && cont && fiber.interruptible) {
|
|
844
|
+
cont = fiber.getCont(failureCont)
|
|
845
|
+
}
|
|
846
|
+
return cont ? cont[failureCont](this[args], fiber) : fiber.yieldWith(this)
|
|
847
|
+
}
|
|
848
|
+
})
|
|
523
849
|
|
|
524
850
|
/**
|
|
525
|
-
*
|
|
851
|
+
* Creates a `Micro` effect that will fail with the specified error.
|
|
852
|
+
*
|
|
853
|
+
* This will result in a `CauseFail`, where the error is tracked at the
|
|
854
|
+
* type level.
|
|
855
|
+
*
|
|
856
|
+
* @since 3.4.0
|
|
526
857
|
* @experimental
|
|
527
|
-
* @category
|
|
858
|
+
* @category constructors
|
|
528
859
|
*/
|
|
529
|
-
export const
|
|
530
|
-
exitIsFailure(self) && self.left._tag === "Fail"
|
|
860
|
+
export const fail = <E>(error: E): Micro<never, E> => failCause(causeFail(error))
|
|
531
861
|
|
|
532
862
|
/**
|
|
533
|
-
*
|
|
863
|
+
* Creates a `Micro` effect that will succeed with the lazily evaluated value.
|
|
864
|
+
*
|
|
865
|
+
* If the evaluation of the value throws an error, the effect will fail with
|
|
866
|
+
* `CauseDie`.
|
|
867
|
+
*
|
|
868
|
+
* @since 3.4.0
|
|
534
869
|
* @experimental
|
|
535
|
-
* @category
|
|
870
|
+
* @category constructors
|
|
536
871
|
*/
|
|
537
|
-
export const
|
|
538
|
-
|
|
872
|
+
export const sync: <A>(evaluate: LazyArg<A>) => Micro<A> = makePrimitive({
|
|
873
|
+
op: "Sync",
|
|
874
|
+
eval(fiber): Primitive | Yield {
|
|
875
|
+
const value = this[args]()
|
|
876
|
+
const cont = fiber.getCont(successCont)
|
|
877
|
+
return cont ? cont[successCont](value, fiber) : fiber.yieldWith(exitSucceed(value))
|
|
878
|
+
}
|
|
879
|
+
})
|
|
539
880
|
|
|
540
881
|
/**
|
|
541
|
-
*
|
|
882
|
+
* Lazily creates a `Micro` effect from the given side-effect.
|
|
883
|
+
*
|
|
884
|
+
* @since 3.4.0
|
|
542
885
|
* @experimental
|
|
543
|
-
* @category
|
|
886
|
+
* @category constructors
|
|
544
887
|
*/
|
|
545
|
-
export const
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
888
|
+
export const suspend: <A, E, R>(evaluate: LazyArg<Micro<A, E, R>>) => Micro<A, E, R> = makePrimitive({
|
|
889
|
+
op: "Suspend",
|
|
890
|
+
eval(_fiber) {
|
|
891
|
+
return this[args]()
|
|
892
|
+
}
|
|
893
|
+
})
|
|
550
894
|
|
|
551
895
|
/**
|
|
896
|
+
* Pause the execution of the current `Micro` effect, and resume it on the next
|
|
897
|
+
* scheduler tick.
|
|
898
|
+
*
|
|
552
899
|
* @since 3.4.0
|
|
553
900
|
* @experimental
|
|
554
|
-
* @category
|
|
901
|
+
* @category constructors
|
|
555
902
|
*/
|
|
556
|
-
export const
|
|
903
|
+
export const yieldNowWith: (priority?: number) => Micro<void> = makePrimitive({
|
|
904
|
+
op: "Yield",
|
|
905
|
+
eval(fiber) {
|
|
906
|
+
let resumed = false
|
|
907
|
+
fiber.getRef(CurrentScheduler).scheduleTask(() => {
|
|
908
|
+
if (resumed) return
|
|
909
|
+
fiber.evaluate(exitVoid as any)
|
|
910
|
+
}, this[args] ?? 0)
|
|
911
|
+
return fiber.yieldWith(() => {
|
|
912
|
+
resumed = true
|
|
913
|
+
})
|
|
914
|
+
}
|
|
915
|
+
})
|
|
557
916
|
|
|
558
917
|
/**
|
|
918
|
+
* Pause the execution of the current `Micro` effect, and resume it on the next
|
|
919
|
+
* scheduler tick.
|
|
920
|
+
*
|
|
559
921
|
* @since 3.4.0
|
|
560
922
|
* @experimental
|
|
561
|
-
* @category
|
|
923
|
+
* @category constructors
|
|
562
924
|
*/
|
|
563
|
-
export
|
|
925
|
+
export const yieldNow: Micro<void> = yieldNowWith(0)
|
|
564
926
|
|
|
565
927
|
/**
|
|
566
|
-
*
|
|
928
|
+
* Creates a `Micro` effect that will succeed with `Option.Some` of the value.
|
|
929
|
+
*
|
|
930
|
+
* @since 3.4.0
|
|
567
931
|
* @experimental
|
|
568
|
-
* @category
|
|
932
|
+
* @category constructors
|
|
569
933
|
*/
|
|
570
|
-
export
|
|
571
|
-
readonly [EnvTypeId]: {
|
|
572
|
-
_R: Covariant<R>
|
|
573
|
-
}
|
|
574
|
-
readonly refs: ReadonlyRecord<string, unknown>
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const EnvProto = {
|
|
578
|
-
[EnvTypeId]: {
|
|
579
|
-
_R: identity
|
|
580
|
-
},
|
|
581
|
-
pipe() {
|
|
582
|
-
return pipeArguments(this, arguments)
|
|
583
|
-
}
|
|
584
|
-
}
|
|
934
|
+
export const succeedSome = <A>(a: A): Micro<Option.Option<A>> => succeed(Option.some(a))
|
|
585
935
|
|
|
586
936
|
/**
|
|
937
|
+
* Creates a `Micro` effect that will succeed with `Option.None`.
|
|
938
|
+
*
|
|
587
939
|
* @since 3.4.0
|
|
588
940
|
* @experimental
|
|
589
|
-
* @category
|
|
941
|
+
* @category constructors
|
|
590
942
|
*/
|
|
591
|
-
export const
|
|
592
|
-
refs: Record<string, unknown>
|
|
593
|
-
): Env<R> => {
|
|
594
|
-
const self = Object.create(EnvProto)
|
|
595
|
-
self.refs = refs
|
|
596
|
-
return self
|
|
597
|
-
}
|
|
943
|
+
export const succeedNone: Micro<Option.Option<never>> = succeed(Option.none())
|
|
598
944
|
|
|
599
945
|
/**
|
|
946
|
+
* Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
|
|
947
|
+
*
|
|
600
948
|
* @since 3.4.0
|
|
601
949
|
* @experimental
|
|
602
|
-
* @category
|
|
950
|
+
* @category constructors
|
|
603
951
|
*/
|
|
604
|
-
export const
|
|
605
|
-
|
|
606
|
-
const refs = Object.create(null)
|
|
607
|
-
refs[currentAbortController.key] = controller
|
|
608
|
-
refs[currentAbortSignal.key] = controller.signal
|
|
609
|
-
refs[currentScheduler.key] = new MicroSchedulerDefault()
|
|
610
|
-
return envMake(refs)
|
|
611
|
-
}
|
|
952
|
+
export const failCauseSync = <E>(evaluate: LazyArg<MicroCause<E>>): Micro<never, E> =>
|
|
953
|
+
suspend(() => failCause(evaluate()))
|
|
612
954
|
|
|
613
955
|
/**
|
|
956
|
+
* Creates a `Micro` effect that will die with the specified error.
|
|
957
|
+
*
|
|
958
|
+
* This will result in a `CauseDie`, where the error is not tracked at
|
|
959
|
+
* the type level.
|
|
960
|
+
*
|
|
614
961
|
* @since 3.4.0
|
|
615
962
|
* @experimental
|
|
616
|
-
* @category
|
|
963
|
+
* @category constructors
|
|
617
964
|
*/
|
|
618
|
-
export const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
} = dual(2, <R, A>(self: Env<R>, ref: EnvRef<A>): A => ref.key in self.refs ? (self.refs[ref.key] as A) : ref.initial)
|
|
965
|
+
export const die = (defect: unknown): Micro<never> => exitDie(defect)
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Creates a `Micro` effect that will fail with the lazily evaluated error.
|
|
969
|
+
*
|
|
970
|
+
* This will result in a `CauseFail`, where the error is tracked at the
|
|
971
|
+
* type level.
|
|
972
|
+
*
|
|
973
|
+
* @since 3.4.6
|
|
974
|
+
* @experimental
|
|
975
|
+
* @category constructors
|
|
976
|
+
*/
|
|
977
|
+
export const failSync = <E>(error: LazyArg<E>): Micro<never, E> => suspend(() => fail(error()))
|
|
632
978
|
|
|
633
979
|
/**
|
|
980
|
+
* Converts an `Option` into a `Micro` effect, that will fail with
|
|
981
|
+
* `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
|
|
982
|
+
* value of the option.
|
|
983
|
+
*
|
|
634
984
|
* @since 3.4.0
|
|
635
985
|
* @experimental
|
|
636
|
-
* @category
|
|
986
|
+
* @category constructors
|
|
637
987
|
*/
|
|
638
|
-
export const
|
|
639
|
-
|
|
640
|
-
* @since 3.4.0
|
|
641
|
-
* @experimental
|
|
642
|
-
* @category environment
|
|
643
|
-
*/
|
|
644
|
-
<A>(ref: EnvRef<A>, value: A): <R>(self: Env<R>) => Env<R>
|
|
645
|
-
/**
|
|
646
|
-
* @since 3.4.0
|
|
647
|
-
* @experimental
|
|
648
|
-
* @category environment
|
|
649
|
-
*/
|
|
650
|
-
<A, R>(self: Env<R>, ref: EnvRef<A>, value: A): Env<R>
|
|
651
|
-
} = dual(3, <R, A>(self: Env<R>, ref: EnvRef<A>, value: A): Env<R> => {
|
|
652
|
-
const refs = Object.assign(Object.create(null), self.refs)
|
|
653
|
-
refs[ref.key] = value
|
|
654
|
-
return envMake(refs)
|
|
655
|
-
})
|
|
988
|
+
export const fromOption = <A>(option: Option.Option<A>): Micro<A, NoSuchElementException> =>
|
|
989
|
+
option._tag === "Some" ? succeed(option.value) : fail(new NoSuchElementException({}))
|
|
656
990
|
|
|
657
991
|
/**
|
|
992
|
+
* Converts an `Either` into a `Micro` effect, that will fail with the left side
|
|
993
|
+
* of the either if it is a `Left`. Otherwise, it will succeed with the right
|
|
994
|
+
* side of the either.
|
|
995
|
+
*
|
|
658
996
|
* @since 3.4.0
|
|
659
997
|
* @experimental
|
|
660
|
-
* @category
|
|
998
|
+
* @category constructors
|
|
661
999
|
*/
|
|
662
|
-
export const
|
|
1000
|
+
export const fromEither = <R, L>(either: Either.Either<R, L>): Micro<R, L> =>
|
|
1001
|
+
either._tag === "Right" ? succeed(either.right) : fail(either.left)
|
|
1002
|
+
|
|
1003
|
+
const void_: Micro<void> = succeed(void 0)
|
|
1004
|
+
export {
|
|
663
1005
|
/**
|
|
1006
|
+
* A `Micro` effect that will succeed with `void` (`undefined`).
|
|
1007
|
+
*
|
|
664
1008
|
* @since 3.4.0
|
|
665
1009
|
* @experimental
|
|
666
|
-
* @category
|
|
1010
|
+
* @category constructors
|
|
667
1011
|
*/
|
|
668
|
-
|
|
1012
|
+
void_ as void
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
const try_ = <A, E>(options: {
|
|
1016
|
+
try: LazyArg<A>
|
|
1017
|
+
catch: (error: unknown) => E
|
|
1018
|
+
}): Micro<A, E> =>
|
|
1019
|
+
suspend(() => {
|
|
1020
|
+
try {
|
|
1021
|
+
return succeed(options.try())
|
|
1022
|
+
} catch (err) {
|
|
1023
|
+
return fail(options.catch(err))
|
|
1024
|
+
}
|
|
1025
|
+
})
|
|
1026
|
+
export {
|
|
669
1027
|
/**
|
|
1028
|
+
* The `Micro` equivalent of a try / catch block, which allows you to map
|
|
1029
|
+
* thrown errors to a specific error type.
|
|
1030
|
+
*
|
|
670
1031
|
* @since 3.4.0
|
|
671
1032
|
* @experimental
|
|
672
|
-
* @category
|
|
1033
|
+
* @category constructors
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```ts
|
|
1036
|
+
* import { Micro } from "effect"
|
|
1037
|
+
*
|
|
1038
|
+
* Micro.try({
|
|
1039
|
+
* try: () => throw new Error("boom"),
|
|
1040
|
+
* catch: (cause) => new Error("caught", { cause })
|
|
1041
|
+
* })
|
|
1042
|
+
* ```
|
|
673
1043
|
*/
|
|
674
|
-
|
|
675
|
-
}
|
|
676
|
-
2,
|
|
677
|
-
<R>(self: Env<R>, f: (map: Record<string, unknown>) => ReadonlyRecord<string, unknown>): Env<R> =>
|
|
678
|
-
envMake(f(Object.assign(Object.create(null), self.refs)))
|
|
679
|
-
)
|
|
1044
|
+
try_ as try
|
|
1045
|
+
}
|
|
680
1046
|
|
|
681
1047
|
/**
|
|
682
|
-
*
|
|
1048
|
+
* Wrap a `Promise` into a `Micro` effect. Any errors will result in a
|
|
1049
|
+
* `CauseDie`.
|
|
683
1050
|
*
|
|
684
1051
|
* @since 3.4.0
|
|
685
1052
|
* @experimental
|
|
686
|
-
* @category
|
|
1053
|
+
* @category constructors
|
|
687
1054
|
*/
|
|
688
|
-
export const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
1055
|
+
export const promise = <A>(evaluate: (signal: AbortSignal) => PromiseLike<A>): Micro<A> =>
|
|
1056
|
+
asyncOptions<A>(function(resume, signal) {
|
|
1057
|
+
evaluate(signal!).then(
|
|
1058
|
+
(a) => resume(succeed(a)),
|
|
1059
|
+
(e) => resume(die(e))
|
|
1060
|
+
)
|
|
1061
|
+
}, evaluate.length !== 0)
|
|
692
1062
|
|
|
693
1063
|
/**
|
|
694
|
-
*
|
|
695
|
-
*
|
|
1064
|
+
* Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
|
|
1065
|
+
* converted into a specific error type.
|
|
696
1066
|
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
1067
|
+
* @since 3.4.0
|
|
1068
|
+
* @experimental
|
|
1069
|
+
* @category constructors
|
|
1070
|
+
* @example
|
|
1071
|
+
* ```ts
|
|
1072
|
+
* import { Micro } from "effect"
|
|
1073
|
+
*
|
|
1074
|
+
* Micro.tryPromise({
|
|
1075
|
+
* try: () => Promise.resolve("success"),
|
|
1076
|
+
* catch: (cause) => new Error("caught", { cause })
|
|
1077
|
+
* })
|
|
1078
|
+
* ```
|
|
1079
|
+
*/
|
|
1080
|
+
export const tryPromise = <A, E>(options: {
|
|
1081
|
+
readonly try: (signal: AbortSignal) => PromiseLike<A>
|
|
1082
|
+
readonly catch: (error: unknown) => E
|
|
1083
|
+
}): Micro<A, E> =>
|
|
1084
|
+
asyncOptions<A, E>(function(resume, signal) {
|
|
1085
|
+
try {
|
|
1086
|
+
options.try(signal!).then(
|
|
1087
|
+
(a) => resume(succeed(a)),
|
|
1088
|
+
(e) => resume(fail(options.catch(e)))
|
|
1089
|
+
)
|
|
1090
|
+
} catch (err) {
|
|
1091
|
+
resume(fail(options.catch(err)))
|
|
1092
|
+
}
|
|
1093
|
+
}, options.try.length !== 0)
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Create a `Micro` effect using the current `Fiber`.
|
|
699
1097
|
*
|
|
700
1098
|
* @since 3.4.0
|
|
701
1099
|
* @experimental
|
|
702
|
-
* @category
|
|
1100
|
+
* @category constructors
|
|
703
1101
|
*/
|
|
704
|
-
export const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1102
|
+
export const withFiber: <A, E = never, R = never>(
|
|
1103
|
+
evaluate: (fiber: FiberImpl<A, E>) => Micro<A, E, R>
|
|
1104
|
+
) => Micro<A, E, R> = makePrimitive({
|
|
1105
|
+
op: "WithFiber",
|
|
1106
|
+
eval(fiber) {
|
|
1107
|
+
return this[args](fiber)
|
|
1108
|
+
}
|
|
1109
|
+
})
|
|
708
1110
|
|
|
709
1111
|
/**
|
|
710
|
-
*
|
|
1112
|
+
* Flush any yielded effects that are waiting to be executed.
|
|
711
1113
|
*
|
|
712
1114
|
* @since 3.4.0
|
|
713
1115
|
* @experimental
|
|
714
|
-
* @category
|
|
1116
|
+
* @category constructors
|
|
715
1117
|
*/
|
|
716
|
-
export const
|
|
717
|
-
|
|
1118
|
+
export const yieldFlush: Micro<void> = withFiber((fiber) => {
|
|
1119
|
+
fiber.getRef(CurrentScheduler).flush()
|
|
1120
|
+
return exitVoid
|
|
1121
|
+
})
|
|
1122
|
+
|
|
1123
|
+
const asyncOptions: <A, E = never, R = never>(
|
|
1124
|
+
register: (
|
|
1125
|
+
resume: (effect: Micro<A, E, R>) => void,
|
|
1126
|
+
signal?: AbortSignal
|
|
1127
|
+
) => void | Micro<void, never, R>,
|
|
1128
|
+
withSignal: boolean
|
|
1129
|
+
) => Micro<A, E, R> = makePrimitive({
|
|
1130
|
+
op: "Async",
|
|
1131
|
+
single: false,
|
|
1132
|
+
eval(fiber) {
|
|
1133
|
+
const register = this[args][0]
|
|
1134
|
+
let resumed = false
|
|
1135
|
+
let yielded: boolean | Primitive = false
|
|
1136
|
+
const controller = this[args][1] ? new AbortController() : undefined
|
|
1137
|
+
const onCancel = register((effect) => {
|
|
1138
|
+
if (resumed) return
|
|
1139
|
+
resumed = true
|
|
1140
|
+
if (yielded) {
|
|
1141
|
+
fiber.evaluate(effect as any)
|
|
1142
|
+
} else {
|
|
1143
|
+
yielded = effect as any
|
|
1144
|
+
}
|
|
1145
|
+
}, controller?.signal)
|
|
1146
|
+
if (yielded !== false) return yielded
|
|
1147
|
+
yielded = true
|
|
1148
|
+
fiber._yielded = () => {
|
|
1149
|
+
resumed = true
|
|
1150
|
+
}
|
|
1151
|
+
if (controller === undefined && onCancel === undefined) {
|
|
1152
|
+
return Yield
|
|
1153
|
+
}
|
|
1154
|
+
fiber._stack.push(asyncFinalizer(() => {
|
|
1155
|
+
resumed = true
|
|
1156
|
+
controller?.abort()
|
|
1157
|
+
return onCancel ?? exitVoid
|
|
1158
|
+
}))
|
|
1159
|
+
return Yield
|
|
1160
|
+
}
|
|
1161
|
+
})
|
|
1162
|
+
const asyncFinalizer: (onInterrupt: () => Micro<void, any, any>) => Primitive = makePrimitive({
|
|
1163
|
+
op: "AsyncFinalizer",
|
|
1164
|
+
ensure(fiber) {
|
|
1165
|
+
if (fiber.interruptible) {
|
|
1166
|
+
fiber.interruptible = false
|
|
1167
|
+
fiber._stack.push(setInterruptible(true))
|
|
1168
|
+
}
|
|
1169
|
+
},
|
|
1170
|
+
contE(cause, _fiber) {
|
|
1171
|
+
return causeIsInterrupt(cause)
|
|
1172
|
+
? flatMap(this[args](), () => failCause(cause))
|
|
1173
|
+
: failCause(cause)
|
|
1174
|
+
}
|
|
1175
|
+
})
|
|
718
1176
|
|
|
719
1177
|
/**
|
|
720
|
-
*
|
|
1178
|
+
* Create a `Micro` effect from an asynchronous computation.
|
|
1179
|
+
*
|
|
1180
|
+
* You can return a cleanup effect that will be run when the effect is aborted.
|
|
1181
|
+
* It is also passed an `AbortSignal` that is triggered when the effect is
|
|
1182
|
+
* aborted.
|
|
721
1183
|
*
|
|
722
1184
|
* @since 3.4.0
|
|
723
1185
|
* @experimental
|
|
724
|
-
* @category
|
|
1186
|
+
* @category constructors
|
|
725
1187
|
*/
|
|
726
|
-
export const
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
* @category environment
|
|
733
|
-
*/
|
|
734
|
-
<A>(fiberRef: EnvRef<A>, value: A): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R>
|
|
735
|
-
/**
|
|
736
|
-
* Set the value of the given `EnvRef` for the duration of the effect.
|
|
737
|
-
*
|
|
738
|
-
* @since 3.4.0
|
|
739
|
-
* @experimental
|
|
740
|
-
* @category environment
|
|
741
|
-
*/
|
|
742
|
-
<XA, E, R, A>(self: Micro<XA, E, R>, fiberRef: EnvRef<A>, value: A): Micro<XA, E, R>
|
|
743
|
-
} = dual(
|
|
744
|
-
3,
|
|
745
|
-
<XA, E, R, A>(self: Micro<XA, E, R>, fiberRef: EnvRef<A>, value: A): Micro<XA, E, R> =>
|
|
746
|
-
make((env, onExit) => self[runSymbol](envSet(env, fiberRef, value), onExit))
|
|
747
|
-
)
|
|
1188
|
+
export const async = <A, E = never, R = never>(
|
|
1189
|
+
register: (
|
|
1190
|
+
resume: (effect: Micro<A, E, R>) => void,
|
|
1191
|
+
signal: AbortSignal
|
|
1192
|
+
) => void | Micro<void, never, R>
|
|
1193
|
+
): Micro<A, E, R> => asyncOptions(register as any, register.length >= 2)
|
|
748
1194
|
|
|
749
1195
|
/**
|
|
750
|
-
*
|
|
1196
|
+
* A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
|
|
1197
|
+
* the Javascript runtime from exiting.
|
|
751
1198
|
*
|
|
752
1199
|
* @since 3.4.0
|
|
753
1200
|
* @experimental
|
|
754
|
-
* @category
|
|
1201
|
+
* @category constructors
|
|
755
1202
|
*/
|
|
756
|
-
export const
|
|
1203
|
+
export const never: Micro<never> = async<never>(function() {
|
|
1204
|
+
const interval = setInterval(constVoid, 2147483646)
|
|
1205
|
+
return sync(() => clearInterval(interval))
|
|
1206
|
+
})
|
|
757
1207
|
|
|
758
1208
|
/**
|
|
759
|
-
*
|
|
1209
|
+
* @since 3.4.0
|
|
1210
|
+
* @experimental
|
|
1211
|
+
* @category constructors
|
|
1212
|
+
*/
|
|
1213
|
+
export const gen = <Self, Eff extends YieldWrap<Micro<any, any, any>>, AEff>(
|
|
1214
|
+
...args:
|
|
1215
|
+
| [self: Self, body: (this: Self) => Generator<Eff, AEff, never>]
|
|
1216
|
+
| [body: () => Generator<Eff, AEff, never>]
|
|
1217
|
+
): Micro<
|
|
1218
|
+
AEff,
|
|
1219
|
+
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer E, infer _R>>] ? E : never,
|
|
1220
|
+
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer _E, infer R>>] ? R : never
|
|
1221
|
+
> => suspend(() => fromIterator(args.length === 1 ? args[0]() : args[1].call(args[0]) as any))
|
|
1222
|
+
|
|
1223
|
+
const fromIterator: (
|
|
1224
|
+
iterator: Iterator<any, YieldWrap<Micro<any, any, any>>>
|
|
1225
|
+
) => Micro<any, any, any> = makePrimitive({
|
|
1226
|
+
op: "Iterator",
|
|
1227
|
+
contA(value, fiber) {
|
|
1228
|
+
const state = this[args].next(value)
|
|
1229
|
+
if (state.done) return succeed(state.value)
|
|
1230
|
+
fiber._stack.push(this)
|
|
1231
|
+
return yieldWrapGet(state.value)
|
|
1232
|
+
},
|
|
1233
|
+
eval(this: any, fiber: FiberImpl) {
|
|
1234
|
+
return this[successCont](undefined, fiber)
|
|
1235
|
+
}
|
|
1236
|
+
})
|
|
1237
|
+
|
|
1238
|
+
// ----------------------------------------------------------------------------
|
|
1239
|
+
// mapping & sequencing
|
|
1240
|
+
// ----------------------------------------------------------------------------
|
|
1241
|
+
|
|
1242
|
+
/**
|
|
1243
|
+
* Create a `Micro` effect that will replace the success value of the given
|
|
1244
|
+
* effect.
|
|
760
1245
|
*
|
|
761
1246
|
* @since 3.4.0
|
|
762
1247
|
* @experimental
|
|
763
|
-
* @category
|
|
1248
|
+
* @category mapping & sequencing
|
|
764
1249
|
*/
|
|
765
|
-
export const
|
|
1250
|
+
export const as: {
|
|
1251
|
+
// ----------------------------------------------------------------------------
|
|
1252
|
+
// mapping & sequencing
|
|
1253
|
+
// ----------------------------------------------------------------------------
|
|
1254
|
+
|
|
766
1255
|
/**
|
|
767
|
-
*
|
|
1256
|
+
* Create a `Micro` effect that will replace the success value of the given
|
|
1257
|
+
* effect.
|
|
768
1258
|
*
|
|
769
1259
|
* @since 3.4.0
|
|
770
1260
|
* @experimental
|
|
771
|
-
* @category
|
|
1261
|
+
* @category mapping & sequencing
|
|
772
1262
|
*/
|
|
773
|
-
<
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
1263
|
+
<A, B>(value: B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>
|
|
1264
|
+
// ----------------------------------------------------------------------------
|
|
1265
|
+
// mapping & sequencing
|
|
1266
|
+
// ----------------------------------------------------------------------------
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* Create a `Micro` effect that will replace the success value of the given
|
|
1270
|
+
* effect.
|
|
1271
|
+
*
|
|
777
1272
|
* @since 3.4.0
|
|
778
1273
|
* @experimental
|
|
779
|
-
* @category
|
|
1274
|
+
* @category mapping & sequencing
|
|
780
1275
|
*/
|
|
781
|
-
<A, E, R,
|
|
782
|
-
} = dual(
|
|
783
|
-
2,
|
|
784
|
-
<A, E, R, XR>(self: Micro<A, E, R>, provided: Context.Context<XR>): Micro<A, E, Exclude<R, XR>> =>
|
|
785
|
-
make(function(env, onExit) {
|
|
786
|
-
const context = envGet(env, currentContext)
|
|
787
|
-
const nextEnv = envSet(env, currentContext, Context.merge(context, provided))
|
|
788
|
-
self[runSymbol](nextEnv, onExit)
|
|
789
|
-
})
|
|
790
|
-
)
|
|
1276
|
+
<A, E, R, B>(self: Micro<A, E, R>, value: B): Micro<B, E, R>
|
|
1277
|
+
} = dual(2, <A, E, R, B>(self: Micro<A, E, R>, value: B): Micro<B, E, R> => map(self, (_) => value))
|
|
791
1278
|
|
|
792
1279
|
/**
|
|
793
|
-
*
|
|
1280
|
+
* Wrap the success value of this `Micro` effect in an `Option.Some`.
|
|
794
1281
|
*
|
|
795
1282
|
* @since 3.4.0
|
|
796
1283
|
* @experimental
|
|
797
|
-
* @category
|
|
1284
|
+
* @category mapping & sequencing
|
|
798
1285
|
*/
|
|
799
|
-
export const
|
|
1286
|
+
export const asSome = <A, E, R>(self: Micro<A, E, R>): Micro<Option.Option<A>, E, R> => map(self, Option.some)
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Swap the error and success types of the `Micro` effect.
|
|
1290
|
+
*
|
|
1291
|
+
* @since 3.4.0
|
|
1292
|
+
* @experimental
|
|
1293
|
+
* @category mapping & sequencing
|
|
1294
|
+
*/
|
|
1295
|
+
export const flip = <A, E, R>(self: Micro<A, E, R>): Micro<E, A, R> =>
|
|
1296
|
+
matchEffect(self, {
|
|
1297
|
+
onFailure: succeed,
|
|
1298
|
+
onSuccess: fail
|
|
1299
|
+
})
|
|
1300
|
+
|
|
1301
|
+
/**
|
|
1302
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1303
|
+
* a single api.
|
|
1304
|
+
*
|
|
1305
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1306
|
+
* executed after the current effect.
|
|
1307
|
+
*
|
|
1308
|
+
* @since 3.4.0
|
|
1309
|
+
* @experimental
|
|
1310
|
+
* @category mapping & sequencing
|
|
1311
|
+
*/
|
|
1312
|
+
export const andThen: {
|
|
800
1313
|
/**
|
|
801
|
-
*
|
|
1314
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1315
|
+
* a single api.
|
|
1316
|
+
*
|
|
1317
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1318
|
+
* executed after the current effect.
|
|
802
1319
|
*
|
|
803
1320
|
* @since 3.4.0
|
|
804
1321
|
* @experimental
|
|
805
|
-
* @category
|
|
1322
|
+
* @category mapping & sequencing
|
|
806
1323
|
*/
|
|
807
|
-
<
|
|
1324
|
+
<A, X>(f: (a: A) => X): <E, R>(
|
|
1325
|
+
self: Micro<A, E, R>
|
|
1326
|
+
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1327
|
+
: Micro<X, E, R>
|
|
808
1328
|
/**
|
|
809
|
-
*
|
|
1329
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1330
|
+
* a single api.
|
|
1331
|
+
*
|
|
1332
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1333
|
+
* executed after the current effect.
|
|
810
1334
|
*
|
|
811
1335
|
* @since 3.4.0
|
|
812
1336
|
* @experimental
|
|
813
|
-
* @category
|
|
1337
|
+
* @category mapping & sequencing
|
|
814
1338
|
*/
|
|
815
|
-
<
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
make(function(env, onExit) {
|
|
820
|
-
const context = envGet(env, currentContext)
|
|
821
|
-
const nextEnv = envSet(env, currentContext, Context.add(context, tag, service))
|
|
822
|
-
self[runSymbol](nextEnv, onExit)
|
|
823
|
-
})
|
|
824
|
-
)
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* Create a service using the provided `Micro` effect, and add it to the
|
|
828
|
-
* current context.
|
|
829
|
-
*
|
|
830
|
-
* @since 3.4.6
|
|
831
|
-
* @experimental
|
|
832
|
-
* @category environment
|
|
833
|
-
*/
|
|
834
|
-
export const provideServiceEffect: {
|
|
1339
|
+
<X>(f: NotFunction<X>): <A, E, R>(
|
|
1340
|
+
self: Micro<A, E, R>
|
|
1341
|
+
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1342
|
+
: Micro<X, E, R>
|
|
835
1343
|
/**
|
|
836
|
-
*
|
|
837
|
-
*
|
|
1344
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1345
|
+
* a single api.
|
|
838
1346
|
*
|
|
839
|
-
*
|
|
1347
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1348
|
+
* executed after the current effect.
|
|
1349
|
+
*
|
|
1350
|
+
* @since 3.4.0
|
|
840
1351
|
* @experimental
|
|
841
|
-
* @category
|
|
1352
|
+
* @category mapping & sequencing
|
|
842
1353
|
*/
|
|
843
|
-
<
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
):
|
|
1354
|
+
<A, E, R, X>(
|
|
1355
|
+
self: Micro<A, E, R>,
|
|
1356
|
+
f: (a: A) => X
|
|
1357
|
+
): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1358
|
+
: Micro<X, E, R>
|
|
847
1359
|
/**
|
|
848
|
-
*
|
|
849
|
-
*
|
|
1360
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1361
|
+
* a single api.
|
|
850
1362
|
*
|
|
851
|
-
*
|
|
1363
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1364
|
+
* executed after the current effect.
|
|
1365
|
+
*
|
|
1366
|
+
* @since 3.4.0
|
|
852
1367
|
* @experimental
|
|
853
|
-
* @category
|
|
1368
|
+
* @category mapping & sequencing
|
|
854
1369
|
*/
|
|
855
|
-
<A, E, R,
|
|
1370
|
+
<A, E, R, X>(
|
|
856
1371
|
self: Micro<A, E, R>,
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1372
|
+
f: NotFunction<X>
|
|
1373
|
+
): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1374
|
+
: Micro<X, E, R>
|
|
860
1375
|
} = dual(
|
|
861
|
-
|
|
862
|
-
<A, E, R,
|
|
863
|
-
self
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1376
|
+
2,
|
|
1377
|
+
<A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: any): Micro<B, E | E2, R | R2> =>
|
|
1378
|
+
flatMap(self, (a) => {
|
|
1379
|
+
const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f
|
|
1380
|
+
return isMicro(value) ? value : succeed(value)
|
|
1381
|
+
})
|
|
867
1382
|
)
|
|
868
1383
|
|
|
869
|
-
// ----------------------------------------------------------------------------
|
|
870
|
-
// scheduler
|
|
871
|
-
// ----------------------------------------------------------------------------
|
|
872
|
-
|
|
873
1384
|
/**
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
readonly scheduleTask: (task: () => void, priority: number) => void
|
|
880
|
-
readonly shouldYield: (env: Env<unknown>) => boolean
|
|
881
|
-
readonly flush: () => void
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
const setImmediate = "setImmediate" in globalThis ? globalThis.setImmediate : (f: () => void) => setTimeout(f, 0)
|
|
885
|
-
|
|
886
|
-
/**
|
|
887
|
-
* @since 3.5.9
|
|
1385
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1386
|
+
*
|
|
1387
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1388
|
+
*
|
|
1389
|
+
* @since 3.4.0
|
|
888
1390
|
* @experimental
|
|
889
|
-
* @category
|
|
1391
|
+
* @category mapping & sequencing
|
|
890
1392
|
*/
|
|
891
|
-
export
|
|
892
|
-
private tasks: Array<() => void> = []
|
|
893
|
-
private running = false
|
|
894
|
-
|
|
895
|
-
/**
|
|
896
|
-
* @since 3.5.9
|
|
897
|
-
*/
|
|
898
|
-
scheduleTask(task: () => void, _priority: number) {
|
|
899
|
-
this.tasks.push(task)
|
|
900
|
-
if (!this.running) {
|
|
901
|
-
this.running = true
|
|
902
|
-
setImmediate(this.afterScheduled)
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* @since 3.5.9
|
|
908
|
-
*/
|
|
909
|
-
afterScheduled = () => {
|
|
910
|
-
this.running = false
|
|
911
|
-
this.runTasks()
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
/**
|
|
915
|
-
* @since 3.5.9
|
|
916
|
-
*/
|
|
917
|
-
runTasks() {
|
|
918
|
-
const tasks = this.tasks
|
|
919
|
-
this.tasks = []
|
|
920
|
-
for (let i = 0, len = tasks.length; i < len; i++) {
|
|
921
|
-
tasks[i]()
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
|
|
1393
|
+
export const tap: {
|
|
925
1394
|
/**
|
|
926
|
-
*
|
|
1395
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1396
|
+
*
|
|
1397
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1398
|
+
*
|
|
1399
|
+
* @since 3.4.0
|
|
1400
|
+
* @experimental
|
|
1401
|
+
* @category mapping & sequencing
|
|
927
1402
|
*/
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1403
|
+
<A, X>(f: (a: NoInfer<A>) => X): <E, R>(
|
|
1404
|
+
self: Micro<A, E, R>
|
|
1405
|
+
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1406
|
+
: Micro<A, E, R>
|
|
932
1407
|
/**
|
|
933
|
-
*
|
|
1408
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1409
|
+
*
|
|
1410
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1411
|
+
*
|
|
1412
|
+
* @since 3.4.0
|
|
1413
|
+
* @experimental
|
|
1414
|
+
* @category mapping & sequencing
|
|
934
1415
|
*/
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
// ========================================================================
|
|
943
|
-
// Env refs
|
|
944
|
-
// ========================================================================
|
|
945
|
-
|
|
946
|
-
/**
|
|
947
|
-
* @since 3.4.0
|
|
948
|
-
* @experimental
|
|
949
|
-
* @category environment
|
|
950
|
-
*/
|
|
951
|
-
export const EnvRefTypeId: unique symbol = Symbol.for("effect/Micro/EnvRef")
|
|
952
|
-
|
|
953
|
-
/**
|
|
954
|
-
* @since 3.4.0
|
|
955
|
-
* @experimental
|
|
956
|
-
* @category environment
|
|
957
|
-
*/
|
|
958
|
-
export type EnvRefTypeId = typeof EnvRefTypeId
|
|
959
|
-
|
|
960
|
-
/**
|
|
961
|
-
* @since 3.4.0
|
|
962
|
-
* @experimental
|
|
963
|
-
* @category environment
|
|
964
|
-
*/
|
|
965
|
-
export interface EnvRef<A> extends Micro<A> {
|
|
966
|
-
readonly [EnvRefTypeId]: EnvRefTypeId
|
|
967
|
-
readonly key: string
|
|
968
|
-
readonly initial: A
|
|
969
|
-
|
|
970
|
-
[Unify.typeSymbol]?: unknown
|
|
971
|
-
[Unify.unifySymbol]?: EnvRefUnify<this>
|
|
972
|
-
[Unify.ignoreSymbol]?: EnvRefUnifyIgnore
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* @category models
|
|
977
|
-
* @since 3.8.4
|
|
978
|
-
* @experimental
|
|
979
|
-
*/
|
|
980
|
-
export interface EnvRefUnify<A extends { [Unify.typeSymbol]?: any }> extends MicroUnify<A> {
|
|
981
|
-
EnvRef?: () => A[Unify.typeSymbol] extends EnvRef<infer A0> | infer _ ? EnvRef<A0> : never
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
/**
|
|
985
|
-
* @category models
|
|
986
|
-
* @since 3.8.4
|
|
987
|
-
* @experimental
|
|
988
|
-
*/
|
|
989
|
-
export interface EnvRefUnifyIgnore extends MicroUnifyIgnore {
|
|
990
|
-
Micro?: true
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
const EnvRefProto: ThisType<EnvRef<any>> = {
|
|
994
|
-
...MicroProto,
|
|
995
|
-
[EnvRefTypeId]: EnvRefTypeId,
|
|
996
|
-
[runSymbol](env: Env<any>, onExit: (exit: MicroExit<any, any>) => void) {
|
|
997
|
-
getEnvRef(this)[runSymbol](env, onExit)
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
/**
|
|
1002
|
-
* @since 3.4.0
|
|
1003
|
-
* @experimental
|
|
1004
|
-
* @category environment refs
|
|
1005
|
-
*/
|
|
1006
|
-
export const envRefMake = <A>(key: string, initial: LazyArg<A>): EnvRef<A> =>
|
|
1007
|
-
globalValue(key, () => {
|
|
1008
|
-
const self = Object.create(EnvRefProto)
|
|
1009
|
-
self.key = key
|
|
1010
|
-
self.initial = initial()
|
|
1011
|
-
return self
|
|
1012
|
-
})
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* @since 3.4.0
|
|
1016
|
-
* @experimental
|
|
1017
|
-
* @category environment refs
|
|
1018
|
-
*/
|
|
1019
|
-
export const currentAbortController: EnvRef<AbortController> = envRefMake(
|
|
1020
|
-
"effect/Micro/currentAbortController",
|
|
1021
|
-
() => undefined as any
|
|
1022
|
-
)
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* @since 3.4.0
|
|
1026
|
-
* @experimental
|
|
1027
|
-
* @category environment refs
|
|
1028
|
-
*/
|
|
1029
|
-
export const currentAbortSignal: EnvRef<AbortSignal> = envRefMake(
|
|
1030
|
-
"effect/Micro/currentAbortSignal",
|
|
1031
|
-
() => undefined as any
|
|
1032
|
-
)
|
|
1033
|
-
|
|
1034
|
-
/**
|
|
1035
|
-
* @since 3.4.0
|
|
1036
|
-
* @experimental
|
|
1037
|
-
* @category environment refs
|
|
1038
|
-
*/
|
|
1039
|
-
export const currentContext: EnvRef<Context.Context<never>> = envRefMake(
|
|
1040
|
-
"effect/Micro/currentContext",
|
|
1041
|
-
() => Context.empty()
|
|
1042
|
-
)
|
|
1043
|
-
|
|
1044
|
-
/**
|
|
1045
|
-
* @since 3.4.0
|
|
1046
|
-
* @experimental
|
|
1047
|
-
* @category environment refs
|
|
1048
|
-
*/
|
|
1049
|
-
export const currentConcurrency: EnvRef<"unbounded" | number> = envRefMake(
|
|
1050
|
-
"effect/Micro/currentConcurrency",
|
|
1051
|
-
() => "unbounded"
|
|
1052
|
-
)
|
|
1053
|
-
|
|
1054
|
-
/**
|
|
1055
|
-
* @since 3.4.0
|
|
1056
|
-
* @experimental
|
|
1057
|
-
* @category environment refs
|
|
1058
|
-
*/
|
|
1059
|
-
export const currentMaxDepthBeforeYield: EnvRef<number> = envRefMake(
|
|
1060
|
-
"effect/Micro/currentMaxDepthBeforeYield",
|
|
1061
|
-
() => 2048
|
|
1062
|
-
)
|
|
1063
|
-
|
|
1064
|
-
const currentInterruptible: EnvRef<boolean> = envRefMake(
|
|
1065
|
-
"effect/Micro/currentInterruptible",
|
|
1066
|
-
() => true
|
|
1067
|
-
)
|
|
1068
|
-
|
|
1069
|
-
/**
|
|
1070
|
-
* @since 3.4.0
|
|
1071
|
-
* @experimental
|
|
1072
|
-
* @category environment refs
|
|
1073
|
-
*/
|
|
1074
|
-
export const currentScheduler: EnvRef<MicroScheduler> = envRefMake(
|
|
1075
|
-
"effect/Micro/currentScheduler",
|
|
1076
|
-
() => new MicroSchedulerDefault()
|
|
1077
|
-
)
|
|
1078
|
-
|
|
1079
|
-
/**
|
|
1080
|
-
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
1081
|
-
* api to control the concurrency of that `Micro` when it is run.
|
|
1082
|
-
*
|
|
1083
|
-
* @since 3.4.0
|
|
1084
|
-
* @experimental
|
|
1085
|
-
* @category environment refs
|
|
1086
|
-
* @example
|
|
1087
|
-
* ```ts
|
|
1088
|
-
* import * as Micro from "effect/Micro"
|
|
1089
|
-
*
|
|
1090
|
-
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
1091
|
-
* concurrency: "inherit"
|
|
1092
|
-
* }).pipe(
|
|
1093
|
-
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
1094
|
-
* )
|
|
1095
|
-
* ```
|
|
1096
|
-
*/
|
|
1097
|
-
export const withConcurrency: {
|
|
1416
|
+
<X>(f: NotFunction<X>): <A, E, R>(
|
|
1417
|
+
self: Micro<A, E, R>
|
|
1418
|
+
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1419
|
+
: Micro<A, E, R>
|
|
1098
1420
|
/**
|
|
1099
|
-
*
|
|
1100
|
-
*
|
|
1421
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1422
|
+
*
|
|
1423
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1101
1424
|
*
|
|
1102
1425
|
* @since 3.4.0
|
|
1103
1426
|
* @experimental
|
|
1104
|
-
* @category
|
|
1105
|
-
* @example
|
|
1106
|
-
* ```ts
|
|
1107
|
-
* import * as Micro from "effect/Micro"
|
|
1108
|
-
*
|
|
1109
|
-
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
1110
|
-
* concurrency: "inherit"
|
|
1111
|
-
* }).pipe(
|
|
1112
|
-
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
1113
|
-
* )
|
|
1114
|
-
* ```
|
|
1427
|
+
* @category mapping & sequencing
|
|
1115
1428
|
*/
|
|
1116
|
-
|
|
1429
|
+
<A, E, R, X>(
|
|
1430
|
+
self: Micro<A, E, R>,
|
|
1431
|
+
f: (a: NoInfer<A>) => X
|
|
1432
|
+
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1433
|
+
: Micro<A, E, R>
|
|
1117
1434
|
/**
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1435
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1436
|
+
*
|
|
1437
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1120
1438
|
*
|
|
1121
1439
|
* @since 3.4.0
|
|
1122
1440
|
* @experimental
|
|
1123
|
-
* @category
|
|
1124
|
-
* @example
|
|
1125
|
-
* ```ts
|
|
1126
|
-
* import * as Micro from "effect/Micro"
|
|
1127
|
-
*
|
|
1128
|
-
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
1129
|
-
* concurrency: "inherit"
|
|
1130
|
-
* }).pipe(
|
|
1131
|
-
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
1132
|
-
* )
|
|
1133
|
-
* ```
|
|
1441
|
+
* @category mapping & sequencing
|
|
1134
1442
|
*/
|
|
1135
|
-
<A, E, R
|
|
1443
|
+
<A, E, R, X>(
|
|
1444
|
+
self: Micro<A, E, R>,
|
|
1445
|
+
f: NotFunction<X>
|
|
1446
|
+
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1447
|
+
: Micro<A, E, R>
|
|
1136
1448
|
} = dual(
|
|
1137
1449
|
2,
|
|
1138
|
-
<A, E, R>(self: Micro<A, E, R>,
|
|
1139
|
-
|
|
1450
|
+
<A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (a: A) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2> =>
|
|
1451
|
+
flatMap(self, (a) => {
|
|
1452
|
+
const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f
|
|
1453
|
+
return isMicro(value) ? as(value, a) : succeed(a)
|
|
1454
|
+
})
|
|
1140
1455
|
)
|
|
1141
1456
|
|
|
1142
|
-
// ----------------------------------------------------------------------------
|
|
1143
|
-
// constructors
|
|
1144
|
-
// ----------------------------------------------------------------------------
|
|
1145
|
-
|
|
1146
|
-
const microDepthState = globalValue("effect/Micro/microDepthState", () => ({
|
|
1147
|
-
depth: 0,
|
|
1148
|
-
maxDepthBeforeYield: currentMaxDepthBeforeYield.initial
|
|
1149
|
-
}))
|
|
1150
|
-
|
|
1151
|
-
const unsafeMake = <R, A, E>(
|
|
1152
|
-
run: (env: Env<R>, onExit: (exit: MicroExit<A, E>) => void) => void
|
|
1153
|
-
): Micro<A, E, R> => {
|
|
1154
|
-
const self = Object.create(MicroProto)
|
|
1155
|
-
self[runSymbol] = run
|
|
1156
|
-
return self
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
const unsafeMakeOptions = <R, A, E>(
|
|
1160
|
-
run: (env: Env<R>, onExit: (exit: MicroExit<A, E>) => void) => void,
|
|
1161
|
-
checkAbort: boolean
|
|
1162
|
-
): Micro<A, E, R> =>
|
|
1163
|
-
unsafeMake(function execute(env, onExit) {
|
|
1164
|
-
if (
|
|
1165
|
-
checkAbort && env.refs[currentInterruptible.key] !== false &&
|
|
1166
|
-
(env.refs[currentAbortSignal.key] as AbortSignal).aborted
|
|
1167
|
-
) {
|
|
1168
|
-
return onExit(exitInterrupt)
|
|
1169
|
-
}
|
|
1170
|
-
microDepthState.depth++
|
|
1171
|
-
if (microDepthState.depth === 1) {
|
|
1172
|
-
microDepthState.maxDepthBeforeYield = envGet(env, currentMaxDepthBeforeYield)
|
|
1173
|
-
}
|
|
1174
|
-
const scheduler = env.refs[currentScheduler.key] as MicroScheduler
|
|
1175
|
-
if (microDepthState.depth >= microDepthState.maxDepthBeforeYield || scheduler.shouldYield(env)) {
|
|
1176
|
-
scheduler.scheduleTask(() => execute(env, onExit), 0)
|
|
1177
|
-
} else {
|
|
1178
|
-
try {
|
|
1179
|
-
run(env, onExit)
|
|
1180
|
-
} catch (err) {
|
|
1181
|
-
onExit(exitDie(err))
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
microDepthState.depth--
|
|
1185
|
-
})
|
|
1186
|
-
|
|
1187
1457
|
/**
|
|
1188
|
-
*
|
|
1189
|
-
* that receives an environment and a callback which should be called with the
|
|
1190
|
-
* result of the effect.
|
|
1458
|
+
* Replace the success value of the `Micro` effect with `void`.
|
|
1191
1459
|
*
|
|
1192
1460
|
* @since 3.4.0
|
|
1193
1461
|
* @experimental
|
|
1194
|
-
* @category
|
|
1462
|
+
* @category mapping & sequencing
|
|
1195
1463
|
*/
|
|
1196
|
-
export const
|
|
1197
|
-
run: (env: Env<R>, onExit: (exit: MicroExit<A, E>) => void) => void
|
|
1198
|
-
): Micro<A, E, R> => unsafeMakeOptions(run, true)
|
|
1464
|
+
export const asVoid = <A, E, R>(self: Micro<A, E, R>): Micro<void, E, R> => flatMap(self, (_) => exitVoid)
|
|
1199
1465
|
|
|
1200
1466
|
/**
|
|
1201
|
-
*
|
|
1467
|
+
* Access the `MicroExit` of the given `Micro` effect.
|
|
1202
1468
|
*
|
|
1203
1469
|
* @since 3.4.6
|
|
1204
1470
|
* @experimental
|
|
1205
|
-
* @category
|
|
1471
|
+
* @category mapping & sequencing
|
|
1206
1472
|
*/
|
|
1207
|
-
export const
|
|
1208
|
-
|
|
1209
|
-
|
|
1473
|
+
export const exit = <A, E, R>(self: Micro<A, E, R>): Micro<MicroExit<A, E>, never, R> =>
|
|
1474
|
+
matchCause(self, {
|
|
1475
|
+
onFailure: exitFailCause,
|
|
1476
|
+
onSuccess: exitSucceed
|
|
1210
1477
|
})
|
|
1211
1478
|
|
|
1212
1479
|
/**
|
|
1213
|
-
*
|
|
1480
|
+
* Replace the error type of the given `Micro` with the full `MicroCause` object.
|
|
1214
1481
|
*
|
|
1215
|
-
* @since 3.4.
|
|
1482
|
+
* @since 3.4.0
|
|
1216
1483
|
* @experimental
|
|
1217
|
-
* @category
|
|
1484
|
+
* @category mapping & sequencing
|
|
1218
1485
|
*/
|
|
1219
|
-
export const
|
|
1220
|
-
make(function(_env, onExit) {
|
|
1221
|
-
onExit(self())
|
|
1222
|
-
})
|
|
1486
|
+
export const sandbox = <A, E, R>(self: Micro<A, E, R>): Micro<A, MicroCause<E>, R> => catchAllCause(self, fail)
|
|
1223
1487
|
|
|
1224
1488
|
/**
|
|
1225
|
-
*
|
|
1489
|
+
* Returns an effect that races all the specified effects,
|
|
1490
|
+
* yielding the value of the first effect to succeed with a value. Losers of
|
|
1491
|
+
* the race will be interrupted immediately
|
|
1226
1492
|
*
|
|
1227
1493
|
* @since 3.4.0
|
|
1228
1494
|
* @experimental
|
|
1229
|
-
* @category
|
|
1495
|
+
* @category sequencing
|
|
1230
1496
|
*/
|
|
1231
|
-
export const
|
|
1497
|
+
export const raceAll = <Eff extends Micro<any, any, any>>(
|
|
1498
|
+
all: Iterable<Eff>
|
|
1499
|
+
): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
|
|
1500
|
+
withFiber((parent) =>
|
|
1501
|
+
async((resume) => {
|
|
1502
|
+
const effects = Arr.fromIterable(all)
|
|
1503
|
+
const len = effects.length
|
|
1504
|
+
let doneCount = 0
|
|
1505
|
+
let done = false
|
|
1506
|
+
const fibers = new Set<Fiber<any, any>>()
|
|
1507
|
+
const causes: Array<MicroCause<any>> = []
|
|
1508
|
+
const onExit = (exit: MicroExit<any, any>) => {
|
|
1509
|
+
doneCount++
|
|
1510
|
+
if (exit._tag === "Failure") {
|
|
1511
|
+
causes.push(exit.cause)
|
|
1512
|
+
if (doneCount >= len) {
|
|
1513
|
+
resume(failCause(causes[0]))
|
|
1514
|
+
}
|
|
1515
|
+
return
|
|
1516
|
+
}
|
|
1517
|
+
done = true
|
|
1518
|
+
resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit))
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
for (let i = 0; i < len; i++) {
|
|
1522
|
+
if (done) break
|
|
1523
|
+
const fiber = unsafeFork(parent, interruptible(effects[i]), true, true)
|
|
1524
|
+
fibers.add(fiber)
|
|
1525
|
+
fiber.addObserver((exit) => {
|
|
1526
|
+
fibers.delete(fiber)
|
|
1527
|
+
onExit(exit)
|
|
1528
|
+
})
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
return fiberInterruptAll(fibers)
|
|
1532
|
+
})
|
|
1533
|
+
)
|
|
1232
1534
|
|
|
1233
1535
|
/**
|
|
1234
|
-
*
|
|
1536
|
+
* Returns an effect that races all the specified effects,
|
|
1537
|
+
* yielding the value of the first effect to succeed or fail. Losers of
|
|
1538
|
+
* the race will be interrupted immediately
|
|
1235
1539
|
*
|
|
1236
1540
|
* @since 3.4.0
|
|
1237
1541
|
* @experimental
|
|
1238
|
-
* @category
|
|
1542
|
+
* @category sequencing
|
|
1239
1543
|
*/
|
|
1240
|
-
export const
|
|
1544
|
+
export const raceAllFirst = <Eff extends Micro<any, any, any>>(
|
|
1545
|
+
all: Iterable<Eff>
|
|
1546
|
+
): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
|
|
1547
|
+
withFiber((parent) =>
|
|
1548
|
+
async((resume) => {
|
|
1549
|
+
let done = false
|
|
1550
|
+
const fibers = new Set<Fiber<any, any>>()
|
|
1551
|
+
const onExit = (exit: MicroExit<any, any>) => {
|
|
1552
|
+
done = true
|
|
1553
|
+
resume(fibers.size === 0 ? exit : flatMap(fiberInterruptAll(fibers), () => exit))
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
for (const effect of all) {
|
|
1557
|
+
if (done) break
|
|
1558
|
+
const fiber = unsafeFork(parent, interruptible(effect), true, true)
|
|
1559
|
+
fibers.add(fiber)
|
|
1560
|
+
fiber.addObserver((exit) => {
|
|
1561
|
+
fibers.delete(fiber)
|
|
1562
|
+
onExit(exit)
|
|
1563
|
+
})
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
return fiberInterruptAll(fibers)
|
|
1567
|
+
})
|
|
1568
|
+
)
|
|
1241
1569
|
|
|
1242
1570
|
/**
|
|
1243
|
-
*
|
|
1571
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1572
|
+
* effect to succeed. Losers of the race will be interrupted immediately
|
|
1244
1573
|
*
|
|
1245
1574
|
* @since 3.4.0
|
|
1246
1575
|
* @experimental
|
|
1247
|
-
* @category
|
|
1576
|
+
* @category sequencing
|
|
1248
1577
|
*/
|
|
1249
|
-
export const
|
|
1578
|
+
export const race: {
|
|
1579
|
+
/**
|
|
1580
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1581
|
+
* effect to succeed. Losers of the race will be interrupted immediately
|
|
1582
|
+
*
|
|
1583
|
+
* @since 3.4.0
|
|
1584
|
+
* @experimental
|
|
1585
|
+
* @category sequencing
|
|
1586
|
+
*/
|
|
1587
|
+
<A2, E2, R2>(that: Micro<A2, E2, R2>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
|
|
1588
|
+
/**
|
|
1589
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1590
|
+
* effect to succeed. Losers of the race will be interrupted immediately
|
|
1591
|
+
*
|
|
1592
|
+
* @since 3.4.0
|
|
1593
|
+
* @experimental
|
|
1594
|
+
* @category sequencing
|
|
1595
|
+
*/
|
|
1596
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2>
|
|
1597
|
+
} = dual(
|
|
1598
|
+
2,
|
|
1599
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2> =>
|
|
1600
|
+
raceAll([self, that])
|
|
1601
|
+
)
|
|
1250
1602
|
|
|
1251
1603
|
/**
|
|
1252
|
-
*
|
|
1604
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1605
|
+
* effect to succeed *or* fail. Losers of the race will be interrupted immediately
|
|
1253
1606
|
*
|
|
1254
|
-
*
|
|
1255
|
-
*
|
|
1607
|
+
* @since 3.4.0
|
|
1608
|
+
* @experimental
|
|
1609
|
+
* @category sequencing
|
|
1610
|
+
*/
|
|
1611
|
+
export const raceFirst: {
|
|
1612
|
+
/**
|
|
1613
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1614
|
+
* effect to succeed *or* fail. Losers of the race will be interrupted immediately
|
|
1615
|
+
*
|
|
1616
|
+
* @since 3.4.0
|
|
1617
|
+
* @experimental
|
|
1618
|
+
* @category sequencing
|
|
1619
|
+
*/
|
|
1620
|
+
<A2, E2, R2>(that: Micro<A2, E2, R2>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
|
|
1621
|
+
/**
|
|
1622
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1623
|
+
* effect to succeed *or* fail. Losers of the race will be interrupted immediately
|
|
1624
|
+
*
|
|
1625
|
+
* @since 3.4.0
|
|
1626
|
+
* @experimental
|
|
1627
|
+
* @category sequencing
|
|
1628
|
+
*/
|
|
1629
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2>
|
|
1630
|
+
} = dual(
|
|
1631
|
+
2,
|
|
1632
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2> =>
|
|
1633
|
+
raceAllFirst([self, that])
|
|
1634
|
+
)
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* Map the success value of this `Micro` effect to another `Micro` effect, then
|
|
1638
|
+
* flatten the result.
|
|
1256
1639
|
*
|
|
1257
1640
|
* @since 3.4.0
|
|
1258
1641
|
* @experimental
|
|
1259
|
-
* @category
|
|
1642
|
+
* @category mapping & sequencing
|
|
1260
1643
|
*/
|
|
1261
|
-
export const
|
|
1644
|
+
export const flatMap: {
|
|
1645
|
+
/**
|
|
1646
|
+
* Map the success value of this `Micro` effect to another `Micro` effect, then
|
|
1647
|
+
* flatten the result.
|
|
1648
|
+
*
|
|
1649
|
+
* @since 3.4.0
|
|
1650
|
+
* @experimental
|
|
1651
|
+
* @category mapping & sequencing
|
|
1652
|
+
*/
|
|
1653
|
+
<A, B, E2, R2>(f: (a: A) => Micro<B, E2, R2>): <E, R>(self: Micro<A, E, R>) => Micro<B, E | E2, R | R2>
|
|
1654
|
+
/**
|
|
1655
|
+
* Map the success value of this `Micro` effect to another `Micro` effect, then
|
|
1656
|
+
* flatten the result.
|
|
1657
|
+
*
|
|
1658
|
+
* @since 3.4.0
|
|
1659
|
+
* @experimental
|
|
1660
|
+
* @category mapping & sequencing
|
|
1661
|
+
*/
|
|
1662
|
+
<A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (a: A) => Micro<B, E2, R2>): Micro<B, E | E2, R | R2>
|
|
1663
|
+
} = dual(
|
|
1664
|
+
2,
|
|
1665
|
+
<A, E, R, B, E2, R2>(
|
|
1666
|
+
self: Micro<A, E, R>,
|
|
1667
|
+
f: (a: A) => Micro<B, E2, R2>
|
|
1668
|
+
): Micro<B, E | E2, R | R2> => {
|
|
1669
|
+
const onSuccess = Object.create(OnSuccessProto)
|
|
1670
|
+
onSuccess[args] = self
|
|
1671
|
+
onSuccess[successCont] = f
|
|
1672
|
+
return onSuccess
|
|
1673
|
+
}
|
|
1674
|
+
)
|
|
1675
|
+
const OnSuccessProto = makePrimitiveProto({
|
|
1676
|
+
op: "OnSuccess",
|
|
1677
|
+
eval(this: any, fiber: FiberImpl): Primitive {
|
|
1678
|
+
fiber._stack.push(this)
|
|
1679
|
+
return this[args]
|
|
1680
|
+
}
|
|
1681
|
+
})
|
|
1682
|
+
|
|
1683
|
+
// ----------------------------------------------------------------------------
|
|
1684
|
+
// mapping & sequencing
|
|
1685
|
+
// ----------------------------------------------------------------------------
|
|
1262
1686
|
|
|
1263
1687
|
/**
|
|
1264
|
-
*
|
|
1688
|
+
* Flattens any nested `Micro` effects, merging the error and requirement types.
|
|
1265
1689
|
*
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1690
|
+
* @since 3.4.0
|
|
1691
|
+
* @experimental
|
|
1692
|
+
* @category mapping & sequencing
|
|
1693
|
+
*/
|
|
1694
|
+
export const flatten = <A, E, R, E2, R2>(
|
|
1695
|
+
self: Micro<Micro<A, E, R>, E2, R2>
|
|
1696
|
+
): Micro<A, E | E2, R | R2> => flatMap(self, identity)
|
|
1697
|
+
|
|
1698
|
+
/**
|
|
1699
|
+
* Transforms the success value of the `Micro` effect with the specified
|
|
1700
|
+
* function.
|
|
1268
1701
|
*
|
|
1269
1702
|
* @since 3.4.0
|
|
1270
1703
|
* @experimental
|
|
1271
|
-
* @category
|
|
1704
|
+
* @category mapping & sequencing
|
|
1272
1705
|
*/
|
|
1273
|
-
export const
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1706
|
+
export const map: {
|
|
1707
|
+
/**
|
|
1708
|
+
* Transforms the success value of the `Micro` effect with the specified
|
|
1709
|
+
* function.
|
|
1710
|
+
*
|
|
1711
|
+
* @since 3.4.0
|
|
1712
|
+
* @experimental
|
|
1713
|
+
* @category mapping & sequencing
|
|
1714
|
+
*/
|
|
1715
|
+
<A, B>(f: (a: A) => B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>
|
|
1716
|
+
/**
|
|
1717
|
+
* Transforms the success value of the `Micro` effect with the specified
|
|
1718
|
+
* function.
|
|
1719
|
+
*
|
|
1720
|
+
* @since 3.4.0
|
|
1721
|
+
* @experimental
|
|
1722
|
+
* @category mapping & sequencing
|
|
1723
|
+
*/
|
|
1724
|
+
<A, E, R, B>(self: Micro<A, E, R>, f: (a: A) => B): Micro<B, E, R>
|
|
1725
|
+
} = dual(
|
|
1726
|
+
2,
|
|
1727
|
+
<A, E, R, B>(self: Micro<A, E, R>, f: (a: A) => B): Micro<B, E, R> => flatMap(self, (a) => succeed(f(a)))
|
|
1728
|
+
)
|
|
1729
|
+
|
|
1730
|
+
// ----------------------------------------------------------------------------
|
|
1731
|
+
// MicroExit
|
|
1732
|
+
// ----------------------------------------------------------------------------
|
|
1277
1733
|
|
|
1278
1734
|
/**
|
|
1279
|
-
*
|
|
1735
|
+
* The MicroExit type is a data type that represents the result of a Micro
|
|
1736
|
+
* computation.
|
|
1280
1737
|
*
|
|
1281
|
-
*
|
|
1282
|
-
* the type level.
|
|
1738
|
+
* It uses the `Either` data type to represent the success and failure cases.
|
|
1283
1739
|
*
|
|
1284
|
-
* @since 3.4.
|
|
1740
|
+
* @since 3.4.6
|
|
1285
1741
|
* @experimental
|
|
1286
|
-
* @category
|
|
1742
|
+
* @category MicroExit
|
|
1743
|
+
*/
|
|
1744
|
+
export type MicroExit<A, E = never> =
|
|
1745
|
+
| MicroExit.Success<A, E>
|
|
1746
|
+
| MicroExit.Failure<A, E>
|
|
1747
|
+
|
|
1748
|
+
/**
|
|
1749
|
+
* @since 3.4.6
|
|
1750
|
+
* @experimental
|
|
1751
|
+
* @category MicroExit
|
|
1287
1752
|
*/
|
|
1288
|
-
export
|
|
1753
|
+
export declare namespace MicroExit {
|
|
1754
|
+
/**
|
|
1755
|
+
* @since 3.4.6
|
|
1756
|
+
* @experimental
|
|
1757
|
+
* @category MicroExit
|
|
1758
|
+
*/
|
|
1759
|
+
export interface Proto<out A, out E = never> extends Micro<A, E> {
|
|
1760
|
+
readonly [MicroExitTypeId]: MicroExitTypeId
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
/**
|
|
1764
|
+
* @since 3.4.6
|
|
1765
|
+
* @experimental
|
|
1766
|
+
* @category MicroExit
|
|
1767
|
+
*/
|
|
1768
|
+
export interface Success<out A, out E> extends Proto<A, E> {
|
|
1769
|
+
readonly _tag: "Success"
|
|
1770
|
+
readonly value: A
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
/**
|
|
1774
|
+
* @since 3.4.6
|
|
1775
|
+
* @experimental
|
|
1776
|
+
* @category MicroExit
|
|
1777
|
+
*/
|
|
1778
|
+
export interface Failure<out A, out E> extends Proto<A, E> {
|
|
1779
|
+
readonly _tag: "Failure"
|
|
1780
|
+
readonly cause: MicroCause<E>
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1289
1783
|
|
|
1290
1784
|
/**
|
|
1291
|
-
* Creates a `Micro` effect that will fail with the specified `MicroCause`.
|
|
1292
|
-
*
|
|
1293
1785
|
* @since 3.4.6
|
|
1294
1786
|
* @experimental
|
|
1295
|
-
* @category
|
|
1787
|
+
* @category MicroExit
|
|
1296
1788
|
*/
|
|
1297
|
-
export const
|
|
1789
|
+
export const isMicroExit = (u: unknown): u is MicroExit<unknown, unknown> => hasProperty(u, MicroExitTypeId)
|
|
1298
1790
|
|
|
1299
1791
|
/**
|
|
1300
|
-
* Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
|
|
1301
|
-
*
|
|
1302
1792
|
* @since 3.4.6
|
|
1303
1793
|
* @experimental
|
|
1304
|
-
* @category
|
|
1305
|
-
*/
|
|
1306
|
-
export const failCauseSync = <E>(cause: LazyArg<MicroCause<E>>): Micro<never, E> =>
|
|
1307
|
-
fromExitSync(() => exitFailCause(cause()))
|
|
1308
|
-
|
|
1309
|
-
/**
|
|
1310
|
-
* Creates a `Micro` effect that will succeed with the lazily evaluated value.
|
|
1311
|
-
*
|
|
1312
|
-
* If the evaluation of the value throws an error, the effect will fail with
|
|
1313
|
-
* `CauseDie`.
|
|
1314
|
-
*
|
|
1315
|
-
* @since 3.4.0
|
|
1316
|
-
* @experimental
|
|
1317
|
-
* @category constructors
|
|
1794
|
+
* @category MicroExit
|
|
1318
1795
|
*/
|
|
1319
|
-
export const
|
|
1320
|
-
make(function(_env, onExit) {
|
|
1321
|
-
onExit(exitSucceed(evaluate()))
|
|
1322
|
-
})
|
|
1796
|
+
export const exitSucceed: <A>(a: A) => MicroExit<A, never> = succeed as any
|
|
1323
1797
|
|
|
1324
1798
|
/**
|
|
1325
|
-
*
|
|
1326
|
-
* `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
|
|
1327
|
-
* value of the option.
|
|
1328
|
-
*
|
|
1329
|
-
* @since 3.4.0
|
|
1799
|
+
* @since 3.4.6
|
|
1330
1800
|
* @experimental
|
|
1331
|
-
* @category
|
|
1801
|
+
* @category MicroExit
|
|
1332
1802
|
*/
|
|
1333
|
-
export const
|
|
1334
|
-
make(function(_env, onExit) {
|
|
1335
|
-
onExit(option._tag === "Some" ? exitSucceed(option.value) : exitFail(new NoSuchElementException({})))
|
|
1336
|
-
})
|
|
1803
|
+
export const exitFailCause: <E>(cause: MicroCause<E>) => MicroExit<never, E> = failCause as any
|
|
1337
1804
|
|
|
1338
1805
|
/**
|
|
1339
|
-
*
|
|
1340
|
-
* of the either if it is a `Left`. Otherwise, it will succeed with the right
|
|
1341
|
-
* side of the either.
|
|
1342
|
-
*
|
|
1343
|
-
* @since 3.4.0
|
|
1806
|
+
* @since 3.4.6
|
|
1344
1807
|
* @experimental
|
|
1345
|
-
* @category
|
|
1808
|
+
* @category MicroExit
|
|
1346
1809
|
*/
|
|
1347
|
-
export const
|
|
1348
|
-
make(function(_env, onExit) {
|
|
1349
|
-
onExit(either._tag === "Right" ? either as MicroExit<R, never> : exitFail(either.left))
|
|
1350
|
-
})
|
|
1810
|
+
export const exitInterrupt: MicroExit<never> = exitFailCause(causeInterrupt())
|
|
1351
1811
|
|
|
1352
1812
|
/**
|
|
1353
|
-
*
|
|
1354
|
-
*
|
|
1355
|
-
* @since 3.4.0
|
|
1813
|
+
* @since 3.4.6
|
|
1356
1814
|
* @experimental
|
|
1357
|
-
* @category
|
|
1815
|
+
* @category MicroExit
|
|
1358
1816
|
*/
|
|
1359
|
-
export const
|
|
1360
|
-
make(function(env, onExit) {
|
|
1361
|
-
evaluate()[runSymbol](env, onExit)
|
|
1362
|
-
})
|
|
1363
|
-
|
|
1364
|
-
const void_: Micro<void> = succeed(void 0)
|
|
1365
|
-
export {
|
|
1366
|
-
/**
|
|
1367
|
-
* A `Micro` effect that will succeed with `void` (`undefined`).
|
|
1368
|
-
*
|
|
1369
|
-
* @since 3.4.0
|
|
1370
|
-
* @experimental
|
|
1371
|
-
* @category constructors
|
|
1372
|
-
*/
|
|
1373
|
-
void_ as void
|
|
1374
|
-
}
|
|
1817
|
+
export const exitFail = <E>(e: E): MicroExit<never, E> => exitFailCause(causeFail(e))
|
|
1375
1818
|
|
|
1376
1819
|
/**
|
|
1377
|
-
*
|
|
1378
|
-
*
|
|
1379
|
-
* You can return a cleanup effect that will be run when the effect is aborted.
|
|
1380
|
-
* It is also passed an `AbortSignal` that is triggered when the effect is
|
|
1381
|
-
* aborted.
|
|
1382
|
-
*
|
|
1383
|
-
* @since 3.4.0
|
|
1820
|
+
* @since 3.4.6
|
|
1384
1821
|
* @experimental
|
|
1385
|
-
* @category
|
|
1822
|
+
* @category MicroExit
|
|
1386
1823
|
*/
|
|
1387
|
-
export const
|
|
1388
|
-
register: (resume: (effect: Micro<A, E, R>) => void, signal: AbortSignal) => void | Micro<void, never, R>
|
|
1389
|
-
): Micro<A, E, R> =>
|
|
1390
|
-
make(function(env, onExit) {
|
|
1391
|
-
let resumed = false
|
|
1392
|
-
const controller = register.length > 1 ? new AbortController() : undefined
|
|
1393
|
-
const signal = envGet(env, currentAbortSignal)
|
|
1394
|
-
let cleanup: Micro<void, never, R> | void = undefined
|
|
1395
|
-
function onAbort() {
|
|
1396
|
-
if (cleanup) {
|
|
1397
|
-
resume(uninterruptible(andThen(cleanup, fromExit(exitInterrupt))))
|
|
1398
|
-
} else {
|
|
1399
|
-
resume(fromExit(exitInterrupt))
|
|
1400
|
-
}
|
|
1401
|
-
if (controller !== undefined) {
|
|
1402
|
-
controller.abort()
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
function resume(effect: Micro<A, E, R>) {
|
|
1406
|
-
if (resumed) {
|
|
1407
|
-
return
|
|
1408
|
-
}
|
|
1409
|
-
resumed = true
|
|
1410
|
-
signal.removeEventListener("abort", onAbort)
|
|
1411
|
-
effect[runSymbol](env, onExit)
|
|
1412
|
-
}
|
|
1413
|
-
cleanup = controller === undefined
|
|
1414
|
-
? (register as any)(resume)
|
|
1415
|
-
: register(resume, controller.signal)
|
|
1416
|
-
if (resumed) return
|
|
1417
|
-
signal.addEventListener("abort", onAbort)
|
|
1418
|
-
})
|
|
1419
|
-
|
|
1420
|
-
const try_ = <A, E>(options: {
|
|
1421
|
-
try: LazyArg<A>
|
|
1422
|
-
catch: (error: unknown) => E
|
|
1423
|
-
}): Micro<A, E> =>
|
|
1424
|
-
make(function(_env, onExit) {
|
|
1425
|
-
try {
|
|
1426
|
-
onExit(exitSucceed(options.try()))
|
|
1427
|
-
} catch (err) {
|
|
1428
|
-
onExit(exitFail(options.catch(err)))
|
|
1429
|
-
}
|
|
1430
|
-
})
|
|
1431
|
-
export {
|
|
1432
|
-
/**
|
|
1433
|
-
* The `Micro` equivalent of a try / catch block, which allows you to map
|
|
1434
|
-
* thrown errors to a specific error type.
|
|
1435
|
-
*
|
|
1436
|
-
* @since 3.4.0
|
|
1437
|
-
* @experimental
|
|
1438
|
-
* @category constructors
|
|
1439
|
-
* @example
|
|
1440
|
-
* ```ts
|
|
1441
|
-
* import { Micro } from "effect"
|
|
1442
|
-
*
|
|
1443
|
-
* Micro.try({
|
|
1444
|
-
* try: () => throw new Error("boom"),
|
|
1445
|
-
* catch: (cause) => new Error("caught", { cause })
|
|
1446
|
-
* })
|
|
1447
|
-
* ```
|
|
1448
|
-
*/
|
|
1449
|
-
try_ as try
|
|
1450
|
-
}
|
|
1824
|
+
export const exitDie = (defect: unknown): MicroExit<never> => exitFailCause(causeDie(defect))
|
|
1451
1825
|
|
|
1452
1826
|
/**
|
|
1453
|
-
*
|
|
1454
|
-
* `CauseDie`.
|
|
1455
|
-
*
|
|
1456
|
-
* @since 3.4.0
|
|
1827
|
+
* @since 3.4.6
|
|
1457
1828
|
* @experimental
|
|
1458
|
-
* @category
|
|
1829
|
+
* @category MicroExit
|
|
1459
1830
|
*/
|
|
1460
|
-
export const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
(a) => resume(succeed(a)),
|
|
1464
|
-
(e) => resume(die(e))
|
|
1465
|
-
)
|
|
1466
|
-
})
|
|
1831
|
+
export const exitIsSuccess = <A, E>(
|
|
1832
|
+
self: MicroExit<A, E>
|
|
1833
|
+
): self is MicroExit.Success<A, E> => self._tag === "Success"
|
|
1467
1834
|
|
|
1468
1835
|
/**
|
|
1469
|
-
*
|
|
1470
|
-
* converted into a specific error type.
|
|
1471
|
-
*
|
|
1472
|
-
* @since 3.4.0
|
|
1836
|
+
* @since 3.4.6
|
|
1473
1837
|
* @experimental
|
|
1474
|
-
* @category
|
|
1475
|
-
* @example
|
|
1476
|
-
* ```ts
|
|
1477
|
-
* import { Micro } from "effect"
|
|
1478
|
-
*
|
|
1479
|
-
* Micro.tryPromise({
|
|
1480
|
-
* try: () => Promise.resolve("success"),
|
|
1481
|
-
* catch: (cause) => new Error("caught", { cause })
|
|
1482
|
-
* })
|
|
1483
|
-
* ```
|
|
1838
|
+
* @category MicroExit
|
|
1484
1839
|
*/
|
|
1485
|
-
export const
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
}): Micro<A, E> =>
|
|
1489
|
-
async<A, E>(function(resume, signal) {
|
|
1490
|
-
try {
|
|
1491
|
-
options.try(signal).then(
|
|
1492
|
-
(a) => resume(succeed(a)),
|
|
1493
|
-
(e) => resume(fail(options.catch(e)))
|
|
1494
|
-
)
|
|
1495
|
-
} catch (err) {
|
|
1496
|
-
resume(fail(options.catch(err)))
|
|
1497
|
-
}
|
|
1498
|
-
})
|
|
1840
|
+
export const exitIsFailure = <A, E>(
|
|
1841
|
+
self: MicroExit<A, E>
|
|
1842
|
+
): self is MicroExit.Failure<A, E> => self._tag === "Failure"
|
|
1499
1843
|
|
|
1500
1844
|
/**
|
|
1501
|
-
*
|
|
1502
|
-
* iteration of the event loop.
|
|
1503
|
-
*
|
|
1504
|
-
* You can specify a priority for the task, which will determine when it is
|
|
1505
|
-
* executed relative to other tasks.
|
|
1506
|
-
*
|
|
1507
|
-
* @since 3.4.0
|
|
1845
|
+
* @since 3.4.6
|
|
1508
1846
|
* @experimental
|
|
1509
|
-
* @category
|
|
1847
|
+
* @category MicroExit
|
|
1510
1848
|
*/
|
|
1511
|
-
export const
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1849
|
+
export const exitIsInterrupt = <A, E>(
|
|
1850
|
+
self: MicroExit<A, E>
|
|
1851
|
+
): self is MicroExit.Failure<A, E> & {
|
|
1852
|
+
readonly cause: MicroCause.Interrupt
|
|
1853
|
+
} => exitIsFailure(self) && self.cause._tag === "Interrupt"
|
|
1515
1854
|
|
|
1516
1855
|
/**
|
|
1517
|
-
*
|
|
1518
|
-
* iteration of the event loop.
|
|
1519
|
-
*
|
|
1520
|
-
* @since 3.4.0
|
|
1856
|
+
* @since 3.4.6
|
|
1521
1857
|
* @experimental
|
|
1522
|
-
* @category
|
|
1858
|
+
* @category MicroExit
|
|
1523
1859
|
*/
|
|
1524
|
-
export const
|
|
1860
|
+
export const exitIsFail = <A, E>(
|
|
1861
|
+
self: MicroExit<A, E>
|
|
1862
|
+
): self is MicroExit.Failure<A, E> & {
|
|
1863
|
+
readonly cause: MicroCause.Fail<E>
|
|
1864
|
+
} => exitIsFailure(self) && self.cause._tag === "Fail"
|
|
1525
1865
|
|
|
1526
1866
|
/**
|
|
1527
|
-
*
|
|
1528
|
-
*
|
|
1529
|
-
* @since 3.4.0
|
|
1867
|
+
* @since 3.4.6
|
|
1530
1868
|
* @experimental
|
|
1531
|
-
* @category
|
|
1869
|
+
* @category MicroExit
|
|
1532
1870
|
*/
|
|
1533
|
-
export const
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1871
|
+
export const exitIsDie = <A, E>(
|
|
1872
|
+
self: MicroExit<A, E>
|
|
1873
|
+
): self is MicroExit.Failure<A, E> & {
|
|
1874
|
+
readonly cause: MicroCause.Die
|
|
1875
|
+
} => exitIsFailure(self) && self.cause._tag === "Die"
|
|
1537
1876
|
|
|
1538
1877
|
/**
|
|
1539
|
-
*
|
|
1540
|
-
* the Javascript runtime from exiting.
|
|
1541
|
-
*
|
|
1542
|
-
* @since 3.4.0
|
|
1878
|
+
* @since 3.4.6
|
|
1543
1879
|
* @experimental
|
|
1544
|
-
* @category
|
|
1880
|
+
* @category MicroExit
|
|
1545
1881
|
*/
|
|
1546
|
-
export const
|
|
1547
|
-
const interval = setInterval(constVoid, 2147483646)
|
|
1548
|
-
return sync(() => clearInterval(interval))
|
|
1549
|
-
})
|
|
1882
|
+
export const exitVoid: MicroExit<void> = exitSucceed(void 0)
|
|
1550
1883
|
|
|
1551
1884
|
/**
|
|
1552
|
-
* @since 3.
|
|
1885
|
+
* @since 3.11.0
|
|
1553
1886
|
* @experimental
|
|
1554
|
-
* @category
|
|
1887
|
+
* @category MicroExit
|
|
1555
1888
|
*/
|
|
1556
|
-
export const
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
)
|
|
1561
|
-
|
|
1562
|
-
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer E, infer _R>>] ? E : never,
|
|
1563
|
-
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer _E, infer R>>] ? R : never
|
|
1564
|
-
> =>
|
|
1565
|
-
make(function(env, onExit) {
|
|
1566
|
-
const iterator: Generator<Eff, AEff, any> = args.length === 1 ? args[0]() : args[1].call(args[0])
|
|
1567
|
-
let running = false
|
|
1568
|
-
let value: any = undefined
|
|
1569
|
-
function run() {
|
|
1570
|
-
running = true
|
|
1571
|
-
try {
|
|
1572
|
-
let shouldContinue = true
|
|
1573
|
-
while (shouldContinue) {
|
|
1574
|
-
const result = iterator.next(value)
|
|
1575
|
-
if (result.done) {
|
|
1576
|
-
return onExit(exitSucceed(result.value))
|
|
1577
|
-
}
|
|
1578
|
-
shouldContinue = false
|
|
1579
|
-
yieldWrapGet(result.value)[runSymbol](env, function(exit) {
|
|
1580
|
-
if (exit._tag === "Left") {
|
|
1581
|
-
onExit(exit)
|
|
1582
|
-
} else {
|
|
1583
|
-
shouldContinue = true
|
|
1584
|
-
value = exit.right
|
|
1585
|
-
if (!running) run()
|
|
1586
|
-
}
|
|
1587
|
-
})
|
|
1588
|
-
}
|
|
1589
|
-
} catch (err) {
|
|
1590
|
-
onExit(exitDie(err))
|
|
1591
|
-
}
|
|
1592
|
-
running = false
|
|
1889
|
+
export const exitVoidAll = <I extends Iterable<MicroExit<any, any>>>(
|
|
1890
|
+
exits: I
|
|
1891
|
+
): MicroExit<void, I extends Iterable<MicroExit<infer _A, infer _E>> ? _E : never> => {
|
|
1892
|
+
for (const exit of exits) {
|
|
1893
|
+
if (exit._tag === "Failure") {
|
|
1894
|
+
return exit
|
|
1593
1895
|
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1896
|
+
}
|
|
1897
|
+
return exitVoid
|
|
1898
|
+
}
|
|
1596
1899
|
|
|
1597
1900
|
// ----------------------------------------------------------------------------
|
|
1598
|
-
//
|
|
1901
|
+
// scheduler
|
|
1599
1902
|
// ----------------------------------------------------------------------------
|
|
1600
1903
|
|
|
1601
1904
|
/**
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
* @since 3.4.0
|
|
1905
|
+
* @since 3.5.9
|
|
1605
1906
|
* @experimental
|
|
1606
|
-
* @category
|
|
1907
|
+
* @category scheduler
|
|
1607
1908
|
*/
|
|
1608
|
-
export
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1909
|
+
export interface MicroScheduler {
|
|
1910
|
+
readonly scheduleTask: (task: () => void, priority: number) => void
|
|
1911
|
+
readonly shouldYield: (fiber: Fiber<unknown, unknown>) => boolean
|
|
1912
|
+
readonly flush: () => void
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
const setImmediate = "setImmediate" in globalThis
|
|
1916
|
+
? globalThis.setImmediate
|
|
1917
|
+
: (f: () => void) => setTimeout(f, 0)
|
|
1615
1918
|
|
|
1616
1919
|
/**
|
|
1617
|
-
*
|
|
1618
|
-
* function.
|
|
1619
|
-
*
|
|
1620
|
-
* @since 3.4.0
|
|
1920
|
+
* @since 3.5.9
|
|
1621
1921
|
* @experimental
|
|
1622
|
-
* @category
|
|
1922
|
+
* @category scheduler
|
|
1623
1923
|
*/
|
|
1624
|
-
export
|
|
1924
|
+
export class MicroSchedulerDefault implements MicroScheduler {
|
|
1925
|
+
private tasks: Array<() => void> = []
|
|
1926
|
+
private running = false
|
|
1927
|
+
|
|
1625
1928
|
/**
|
|
1626
|
-
*
|
|
1627
|
-
* function.
|
|
1628
|
-
*
|
|
1629
|
-
* @since 3.4.0
|
|
1630
|
-
* @experimental
|
|
1631
|
-
* @category mapping & sequencing
|
|
1929
|
+
* @since 3.5.9
|
|
1632
1930
|
*/
|
|
1633
|
-
|
|
1931
|
+
scheduleTask(task: () => void, _priority: number) {
|
|
1932
|
+
this.tasks.push(task)
|
|
1933
|
+
if (!this.running) {
|
|
1934
|
+
this.running = true
|
|
1935
|
+
setImmediate(this.afterScheduled)
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1634
1939
|
/**
|
|
1635
|
-
*
|
|
1636
|
-
* function.
|
|
1637
|
-
*
|
|
1638
|
-
* @since 3.4.0
|
|
1639
|
-
* @experimental
|
|
1640
|
-
* @category mapping & sequencing
|
|
1940
|
+
* @since 3.5.9
|
|
1641
1941
|
*/
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
onExit(exit._tag === "Left" ? exit as MicroExit<never, E> : exitSucceed(f(exit.right)))
|
|
1647
|
-
})
|
|
1648
|
-
}))
|
|
1942
|
+
afterScheduled = () => {
|
|
1943
|
+
this.running = false
|
|
1944
|
+
this.runTasks()
|
|
1945
|
+
}
|
|
1649
1946
|
|
|
1650
|
-
/**
|
|
1651
|
-
* Create a `Micro` effect that will replace the success value of the given
|
|
1652
|
-
* effect.
|
|
1653
|
-
*
|
|
1654
|
-
* @since 3.4.0
|
|
1655
|
-
* @experimental
|
|
1656
|
-
* @category mapping & sequencing
|
|
1657
|
-
*/
|
|
1658
|
-
export const as: {
|
|
1659
1947
|
/**
|
|
1660
|
-
*
|
|
1661
|
-
* effect.
|
|
1662
|
-
*
|
|
1663
|
-
* @since 3.4.0
|
|
1664
|
-
* @experimental
|
|
1665
|
-
* @category mapping & sequencing
|
|
1948
|
+
* @since 3.5.9
|
|
1666
1949
|
*/
|
|
1667
|
-
|
|
1950
|
+
runTasks() {
|
|
1951
|
+
const tasks = this.tasks
|
|
1952
|
+
this.tasks = []
|
|
1953
|
+
for (let i = 0, len = tasks.length; i < len; i++) {
|
|
1954
|
+
tasks[i]()
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1668
1958
|
/**
|
|
1669
|
-
*
|
|
1670
|
-
* effect.
|
|
1671
|
-
*
|
|
1672
|
-
* @since 3.4.0
|
|
1673
|
-
* @experimental
|
|
1674
|
-
* @category mapping & sequencing
|
|
1959
|
+
* @since 3.5.9
|
|
1675
1960
|
*/
|
|
1676
|
-
|
|
1677
|
-
|
|
1961
|
+
shouldYield(fiber: Fiber<unknown, unknown>) {
|
|
1962
|
+
return fiber.currentOpCount >= fiber.getRef(MaxOpsBeforeYield)
|
|
1963
|
+
}
|
|
1678
1964
|
|
|
1679
|
-
/**
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1965
|
+
/**
|
|
1966
|
+
* @since 3.5.9
|
|
1967
|
+
*/
|
|
1968
|
+
flush() {
|
|
1969
|
+
while (this.tasks.length > 0) {
|
|
1970
|
+
this.runTasks()
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1687
1974
|
|
|
1688
1975
|
/**
|
|
1689
|
-
*
|
|
1690
|
-
* flatten the result.
|
|
1976
|
+
* Access the given `Context.Tag` from the environment.
|
|
1691
1977
|
*
|
|
1692
1978
|
* @since 3.4.0
|
|
1693
1979
|
* @experimental
|
|
1694
|
-
* @category
|
|
1980
|
+
* @category environment
|
|
1695
1981
|
*/
|
|
1696
|
-
export const
|
|
1982
|
+
export const service: {
|
|
1697
1983
|
/**
|
|
1698
|
-
*
|
|
1699
|
-
* flatten the result.
|
|
1984
|
+
* Access the given `Context.Tag` from the environment.
|
|
1700
1985
|
*
|
|
1701
1986
|
* @since 3.4.0
|
|
1702
1987
|
* @experimental
|
|
1703
|
-
* @category
|
|
1988
|
+
* @category environment
|
|
1704
1989
|
*/
|
|
1705
|
-
<
|
|
1990
|
+
<I, S>(tag: Context.Reference<I, S>): Micro<S>
|
|
1706
1991
|
/**
|
|
1707
|
-
*
|
|
1708
|
-
* flatten the result.
|
|
1992
|
+
* Access the given `Context.Tag` from the environment.
|
|
1709
1993
|
*
|
|
1710
1994
|
* @since 3.4.0
|
|
1711
1995
|
* @experimental
|
|
1712
|
-
* @category
|
|
1996
|
+
* @category environment
|
|
1713
1997
|
*/
|
|
1714
|
-
<
|
|
1715
|
-
} =
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
make(function(env, onExit) {
|
|
1719
|
-
self[runSymbol](env, function(exit) {
|
|
1720
|
-
if (exit._tag === "Left") {
|
|
1721
|
-
return onExit(exit as MicroExit<never, E>)
|
|
1722
|
-
}
|
|
1723
|
-
f(exit.right)[runSymbol](env, onExit)
|
|
1724
|
-
})
|
|
1725
|
-
})
|
|
1726
|
-
)
|
|
1998
|
+
<I, S>(tag: Context.Tag<I, S>): Micro<S, never, I>
|
|
1999
|
+
} =
|
|
2000
|
+
(<I, S>(tag: Context.Tag<I, S>): Micro<S, never, I> =>
|
|
2001
|
+
withFiber((fiber) => succeed(Context.unsafeGet(fiber.context, tag)))) as any
|
|
1727
2002
|
|
|
1728
2003
|
/**
|
|
1729
|
-
*
|
|
2004
|
+
* Access the given `Context.Tag` from the environment, without tracking the
|
|
2005
|
+
* dependency at the type level.
|
|
2006
|
+
*
|
|
2007
|
+
* It will return an `Option` of the service, depending on whether it is
|
|
2008
|
+
* available in the environment or not.
|
|
1730
2009
|
*
|
|
1731
2010
|
* @since 3.4.0
|
|
1732
2011
|
* @experimental
|
|
1733
|
-
* @category
|
|
2012
|
+
* @category environment
|
|
1734
2013
|
*/
|
|
1735
|
-
export const
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
onSuccess: fail
|
|
1739
|
-
})
|
|
2014
|
+
export const serviceOption = <I, S>(
|
|
2015
|
+
tag: Context.Tag<I, S>
|
|
2016
|
+
): Micro<Option.Option<S>> => withFiber((fiber) => succeed(Context.getOption(fiber.context, tag)))
|
|
1740
2017
|
|
|
1741
2018
|
/**
|
|
1742
|
-
*
|
|
1743
|
-
* a single api.
|
|
1744
|
-
*
|
|
1745
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1746
|
-
* executed after the current effect.
|
|
2019
|
+
* Update the Context with the given mapping function.
|
|
1747
2020
|
*
|
|
1748
|
-
* @since 3.
|
|
2021
|
+
* @since 3.11.0
|
|
1749
2022
|
* @experimental
|
|
1750
|
-
* @category
|
|
2023
|
+
* @category environment
|
|
1751
2024
|
*/
|
|
1752
|
-
export const
|
|
1753
|
-
/**
|
|
1754
|
-
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1755
|
-
* a single api.
|
|
1756
|
-
*
|
|
1757
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1758
|
-
* executed after the current effect.
|
|
1759
|
-
*
|
|
1760
|
-
* @since 3.4.0
|
|
1761
|
-
* @experimental
|
|
1762
|
-
* @category mapping & sequencing
|
|
1763
|
-
*/
|
|
1764
|
-
<A, X>(f: (a: A) => X): <E, R>(
|
|
1765
|
-
self: Micro<A, E, R>
|
|
1766
|
-
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1767
|
-
: Micro<X, E, R>
|
|
1768
|
-
/**
|
|
1769
|
-
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1770
|
-
* a single api.
|
|
1771
|
-
*
|
|
1772
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1773
|
-
* executed after the current effect.
|
|
1774
|
-
*
|
|
1775
|
-
* @since 3.4.0
|
|
1776
|
-
* @experimental
|
|
1777
|
-
* @category mapping & sequencing
|
|
1778
|
-
*/
|
|
1779
|
-
<X>(f: NotFunction<X>): <A, E, R>(
|
|
1780
|
-
self: Micro<A, E, R>
|
|
1781
|
-
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1782
|
-
: Micro<X, E, R>
|
|
2025
|
+
export const updateContext: {
|
|
1783
2026
|
/**
|
|
1784
|
-
*
|
|
1785
|
-
* a single api.
|
|
2027
|
+
* Update the Context with the given mapping function.
|
|
1786
2028
|
*
|
|
1787
|
-
*
|
|
1788
|
-
* executed after the current effect.
|
|
1789
|
-
*
|
|
1790
|
-
* @since 3.4.0
|
|
2029
|
+
* @since 3.11.0
|
|
1791
2030
|
* @experimental
|
|
1792
|
-
* @category
|
|
2031
|
+
* @category environment
|
|
1793
2032
|
*/
|
|
1794
|
-
<
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1798
|
-
: Micro<X, E, R>
|
|
2033
|
+
<R2, R>(
|
|
2034
|
+
f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
|
|
2035
|
+
): <A, E>(self: Micro<A, E, R>) => Micro<A, E, R2>
|
|
1799
2036
|
/**
|
|
1800
|
-
*
|
|
1801
|
-
* a single api.
|
|
1802
|
-
*
|
|
1803
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1804
|
-
* executed after the current effect.
|
|
2037
|
+
* Update the Context with the given mapping function.
|
|
1805
2038
|
*
|
|
1806
|
-
* @since 3.
|
|
2039
|
+
* @since 3.11.0
|
|
1807
2040
|
* @experimental
|
|
1808
|
-
* @category
|
|
2041
|
+
* @category environment
|
|
1809
2042
|
*/
|
|
1810
|
-
<A, E, R,
|
|
2043
|
+
<A, E, R, R2>(
|
|
1811
2044
|
self: Micro<A, E, R>,
|
|
1812
|
-
f:
|
|
1813
|
-
):
|
|
1814
|
-
: Micro<X, E, R>
|
|
2045
|
+
f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
|
|
2046
|
+
): Micro<A, E, R2>
|
|
1815
2047
|
} = dual(
|
|
1816
2048
|
2,
|
|
1817
|
-
<A, E, R,
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
2049
|
+
<A, E, R, R2>(
|
|
2050
|
+
self: Micro<A, E, R>,
|
|
2051
|
+
f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
|
|
2052
|
+
): Micro<A, E, R2> =>
|
|
2053
|
+
withFiber<
|
|
2054
|
+
/**
|
|
2055
|
+
* Update the Context with the given mapping function.
|
|
2056
|
+
*
|
|
2057
|
+
* @since 3.11.0
|
|
2058
|
+
* @experimental
|
|
2059
|
+
* @category environment
|
|
2060
|
+
*/
|
|
2061
|
+
A, /**
|
|
2062
|
+
* Update the Context with the given mapping function.
|
|
2063
|
+
*
|
|
2064
|
+
* @since 3.11.0
|
|
2065
|
+
* @experimental
|
|
2066
|
+
* @category environment
|
|
2067
|
+
*/
|
|
2068
|
+
E, /**
|
|
2069
|
+
* Update the Context with the given mapping function.
|
|
2070
|
+
*
|
|
2071
|
+
* @since 3.11.0
|
|
2072
|
+
* @experimental
|
|
2073
|
+
* @category environment
|
|
2074
|
+
*/
|
|
2075
|
+
R2
|
|
2076
|
+
>((fiber) => {
|
|
2077
|
+
const prev = fiber.context as Context.Context<R2>
|
|
2078
|
+
fiber.context = f(prev)
|
|
2079
|
+
return onExit(
|
|
2080
|
+
self as any,
|
|
2081
|
+
() => {
|
|
2082
|
+
fiber.context = prev
|
|
2083
|
+
return void_
|
|
1830
2084
|
}
|
|
1831
|
-
|
|
2085
|
+
)
|
|
1832
2086
|
})
|
|
1833
2087
|
)
|
|
1834
2088
|
|
|
1835
2089
|
/**
|
|
1836
|
-
*
|
|
1837
|
-
*
|
|
1838
|
-
* It is similar to the `andThen` api, but the success value is ignored.
|
|
2090
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1839
2091
|
*
|
|
1840
|
-
* @since 3.
|
|
2092
|
+
* @since 3.11.0
|
|
1841
2093
|
* @experimental
|
|
1842
|
-
* @category
|
|
2094
|
+
* @category environment
|
|
1843
2095
|
*/
|
|
1844
|
-
export const
|
|
2096
|
+
export const updateService: {
|
|
1845
2097
|
/**
|
|
1846
|
-
*
|
|
2098
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1847
2099
|
*
|
|
1848
|
-
*
|
|
1849
|
-
*
|
|
1850
|
-
* @since 3.4.0
|
|
2100
|
+
* @since 3.11.0
|
|
1851
2101
|
* @experimental
|
|
1852
|
-
* @category
|
|
2102
|
+
* @category environment
|
|
1853
2103
|
*/
|
|
1854
|
-
<
|
|
1855
|
-
self: Micro<A, E, R>
|
|
1856
|
-
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1857
|
-
: Micro<A, E, R>
|
|
2104
|
+
<I, A>(tag: Context.Reference<I, A>, f: (value: A) => A): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R>
|
|
1858
2105
|
/**
|
|
1859
|
-
*
|
|
1860
|
-
*
|
|
1861
|
-
* It is similar to the `andThen` api, but the success value is ignored.
|
|
2106
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1862
2107
|
*
|
|
1863
|
-
* @since 3.
|
|
2108
|
+
* @since 3.11.0
|
|
1864
2109
|
* @experimental
|
|
1865
|
-
* @category
|
|
2110
|
+
* @category environment
|
|
1866
2111
|
*/
|
|
1867
|
-
<
|
|
1868
|
-
self: Micro<A, E, R>
|
|
1869
|
-
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1870
|
-
: Micro<A, E, R>
|
|
2112
|
+
<I, A>(tag: Context.Tag<I, A>, f: (value: A) => A): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R | I>
|
|
1871
2113
|
/**
|
|
1872
|
-
*
|
|
2114
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1873
2115
|
*
|
|
1874
|
-
*
|
|
1875
|
-
*
|
|
1876
|
-
* @since 3.4.0
|
|
2116
|
+
* @since 3.11.0
|
|
1877
2117
|
* @experimental
|
|
1878
|
-
* @category
|
|
2118
|
+
* @category environment
|
|
1879
2119
|
*/
|
|
1880
|
-
<A, E, R,
|
|
1881
|
-
self: Micro<A, E, R>,
|
|
1882
|
-
f: (a: NoInfer<A>) => X
|
|
1883
|
-
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1884
|
-
: Micro<A, E, R>
|
|
2120
|
+
<XA, E, R, I, A>(self: Micro<XA, E, R>, tag: Context.Reference<I, A>, f: (value: A) => A): Micro<XA, E, R>
|
|
1885
2121
|
/**
|
|
1886
|
-
*
|
|
1887
|
-
*
|
|
1888
|
-
* It is similar to the `andThen` api, but the success value is ignored.
|
|
2122
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1889
2123
|
*
|
|
1890
|
-
* @since 3.
|
|
2124
|
+
* @since 3.11.0
|
|
1891
2125
|
* @experimental
|
|
1892
|
-
* @category
|
|
2126
|
+
* @category environment
|
|
1893
2127
|
*/
|
|
1894
|
-
<A, E, R,
|
|
1895
|
-
self: Micro<A, E, R>,
|
|
1896
|
-
f: NotFunction<X>
|
|
1897
|
-
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1898
|
-
: Micro<A, E, R>
|
|
2128
|
+
<XA, E, R, I, A>(self: Micro<XA, E, R>, tag: Context.Tag<I, A>, f: (value: A) => A): Micro<XA, E, R | I>
|
|
1899
2129
|
} = dual(
|
|
1900
|
-
|
|
1901
|
-
<
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
}
|
|
1915
|
-
onExit(selfExit)
|
|
1916
|
-
})
|
|
1917
|
-
} else {
|
|
1918
|
-
onExit(selfExit)
|
|
2130
|
+
3,
|
|
2131
|
+
<XA, E, R, I, A>(
|
|
2132
|
+
self: Micro<XA, E, R>,
|
|
2133
|
+
tag: Context.Reference<I, A>,
|
|
2134
|
+
f: (value: A) => A
|
|
2135
|
+
): Micro<XA, E, R> =>
|
|
2136
|
+
withFiber((fiber) => {
|
|
2137
|
+
const prev = Context.unsafeGet(fiber.context, tag)
|
|
2138
|
+
fiber.context = Context.add(fiber.context, tag, f(prev))
|
|
2139
|
+
return onExit(
|
|
2140
|
+
self,
|
|
2141
|
+
() => {
|
|
2142
|
+
fiber.context = Context.add(fiber.context, tag, prev)
|
|
2143
|
+
return void_
|
|
1919
2144
|
}
|
|
1920
|
-
|
|
2145
|
+
)
|
|
1921
2146
|
})
|
|
1922
2147
|
)
|
|
1923
|
-
|
|
1924
|
-
/**
|
|
1925
|
-
*
|
|
1926
|
-
*
|
|
1927
|
-
* @since 3.4.0
|
|
1928
|
-
* @experimental
|
|
1929
|
-
* @category mapping & sequencing
|
|
1930
|
-
*/
|
|
1931
|
-
export const asVoid = <A, E, R>(self: Micro<A, E, R>): Micro<void, E, R> => map(self, (_) => void 0)
|
|
1932
|
-
|
|
1933
|
-
/**
|
|
1934
|
-
* Access the `MicroExit` of the given `Micro` effect.
|
|
1935
|
-
*
|
|
1936
|
-
* @since 3.4.6
|
|
1937
|
-
* @experimental
|
|
1938
|
-
* @category mapping & sequencing
|
|
1939
|
-
*/
|
|
1940
|
-
export const exit = <A, E, R>(self: Micro<A, E, R>): Micro<MicroExit<A, E>, never, R> =>
|
|
1941
|
-
make(function(env, onExit) {
|
|
1942
|
-
self[runSymbol](env, function(exit) {
|
|
1943
|
-
onExit(exitSucceed(exit))
|
|
1944
|
-
})
|
|
1945
|
-
})
|
|
1946
|
-
|
|
1947
|
-
/**
|
|
1948
|
-
* Replace the error type of the given `Micro` with the full `MicroCause` object.
|
|
1949
|
-
*
|
|
1950
|
-
* @since 3.4.0
|
|
1951
|
-
* @experimental
|
|
1952
|
-
* @category mapping & sequencing
|
|
1953
|
-
*/
|
|
1954
|
-
export const sandbox = <A, E, R>(self: Micro<A, E, R>): Micro<A, MicroCause<E>, R> =>
|
|
1955
|
-
catchAllCause(self, (cause) => fail(cause))
|
|
1956
|
-
|
|
1957
|
-
function forkSignal(env: Env<any>) {
|
|
1958
|
-
const controller = new AbortController()
|
|
1959
|
-
const parentSignal = envGet(env, currentAbortSignal)
|
|
1960
|
-
function onAbort() {
|
|
1961
|
-
controller.abort()
|
|
1962
|
-
parentSignal.removeEventListener("abort", onAbort)
|
|
1963
|
-
}
|
|
1964
|
-
parentSignal.addEventListener("abort", onAbort)
|
|
1965
|
-
const envWithSignal = envMutate(env, function(refs) {
|
|
1966
|
-
refs[currentAbortController.key] = controller
|
|
1967
|
-
refs[currentAbortSignal.key] = controller.signal
|
|
1968
|
-
return refs
|
|
1969
|
-
})
|
|
1970
|
-
return [envWithSignal, onAbort] as const
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
/**
|
|
1974
|
-
* Returns an effect that races all the specified effects,
|
|
1975
|
-
* yielding the value of the first effect to succeed with a value. Losers of
|
|
1976
|
-
* the race will be interrupted immediately
|
|
2148
|
+
|
|
2149
|
+
/**
|
|
2150
|
+
* Access the current `Context` from the environment.
|
|
1977
2151
|
*
|
|
1978
2152
|
* @since 3.4.0
|
|
1979
2153
|
* @experimental
|
|
1980
|
-
* @category
|
|
2154
|
+
* @category environment
|
|
1981
2155
|
*/
|
|
1982
|
-
export const
|
|
1983
|
-
|
|
1984
|
-
): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
|
|
1985
|
-
make(function(env, onExit) {
|
|
1986
|
-
const [envWithSignal, onAbort] = forkSignal(env)
|
|
1987
|
-
|
|
1988
|
-
const effects = Array.from(all)
|
|
1989
|
-
let len = effects.length
|
|
1990
|
-
let index = 0
|
|
1991
|
-
let done = 0
|
|
1992
|
-
let exit: MicroExit<any, any> | undefined = undefined
|
|
1993
|
-
const causes: Array<MicroCause<any>> = []
|
|
1994
|
-
function onDone(exit_: MicroExit<any, any>) {
|
|
1995
|
-
done++
|
|
1996
|
-
if (exit_._tag === "Right" && exit === undefined) {
|
|
1997
|
-
len = index
|
|
1998
|
-
exit = exit_
|
|
1999
|
-
onAbort()
|
|
2000
|
-
} else if (exit_._tag === "Left") {
|
|
2001
|
-
causes.push(exit_.left)
|
|
2002
|
-
}
|
|
2003
|
-
if (done >= len) {
|
|
2004
|
-
onExit(exit ?? Either.left(causes[0]))
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
for (; index < len; index++) {
|
|
2009
|
-
effects[index][runSymbol](envWithSignal, onDone)
|
|
2010
|
-
}
|
|
2011
|
-
})
|
|
2156
|
+
export const context = <R>(): Micro<Context.Context<R>> => getContext as any
|
|
2157
|
+
const getContext = withFiber((fiber) => succeed(fiber.context))
|
|
2012
2158
|
|
|
2013
2159
|
/**
|
|
2014
|
-
*
|
|
2015
|
-
* yielding the value of the first effect to succeed or fail. Losers of
|
|
2016
|
-
* the race will be interrupted immediately
|
|
2160
|
+
* Merge the given `Context` with the current context.
|
|
2017
2161
|
*
|
|
2018
2162
|
* @since 3.4.0
|
|
2019
2163
|
* @experimental
|
|
2020
|
-
* @category
|
|
2164
|
+
* @category environment
|
|
2021
2165
|
*/
|
|
2022
|
-
export const
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
for (; index < len; index++) {
|
|
2047
|
-
effects[index][runSymbol](envWithSignal, onDone)
|
|
2048
|
-
}
|
|
2049
|
-
})
|
|
2166
|
+
export const provideContext: {
|
|
2167
|
+
/**
|
|
2168
|
+
* Merge the given `Context` with the current context.
|
|
2169
|
+
*
|
|
2170
|
+
* @since 3.4.0
|
|
2171
|
+
* @experimental
|
|
2172
|
+
* @category environment
|
|
2173
|
+
*/
|
|
2174
|
+
<XR>(context: Context.Context<XR>): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, XR>>
|
|
2175
|
+
/**
|
|
2176
|
+
* Merge the given `Context` with the current context.
|
|
2177
|
+
*
|
|
2178
|
+
* @since 3.4.0
|
|
2179
|
+
* @experimental
|
|
2180
|
+
* @category environment
|
|
2181
|
+
*/
|
|
2182
|
+
<A, E, R, XR>(self: Micro<A, E, R>, context: Context.Context<XR>): Micro<A, E, Exclude<R, XR>>
|
|
2183
|
+
} = dual(
|
|
2184
|
+
2,
|
|
2185
|
+
<A, E, R, XR>(
|
|
2186
|
+
self: Micro<A, E, R>,
|
|
2187
|
+
provided: Context.Context<XR>
|
|
2188
|
+
): Micro<A, E, Exclude<R, XR>> => updateContext(self, Context.merge(provided)) as any
|
|
2189
|
+
)
|
|
2050
2190
|
|
|
2051
2191
|
/**
|
|
2052
|
-
*
|
|
2053
|
-
* effect to succeed. Losers of the race will be interrupted immediately
|
|
2192
|
+
* Add the provided service to the current context.
|
|
2054
2193
|
*
|
|
2055
2194
|
* @since 3.4.0
|
|
2056
2195
|
* @experimental
|
|
2057
|
-
* @category
|
|
2196
|
+
* @category environment
|
|
2058
2197
|
*/
|
|
2059
|
-
export const
|
|
2198
|
+
export const provideService: {
|
|
2060
2199
|
/**
|
|
2061
|
-
*
|
|
2062
|
-
* effect to succeed. Losers of the race will be interrupted immediately
|
|
2200
|
+
* Add the provided service to the current context.
|
|
2063
2201
|
*
|
|
2064
2202
|
* @since 3.4.0
|
|
2065
2203
|
* @experimental
|
|
2066
|
-
* @category
|
|
2204
|
+
* @category environment
|
|
2067
2205
|
*/
|
|
2068
|
-
<
|
|
2206
|
+
<I, S>(tag: Context.Tag<I, S>, service: S): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, I>>
|
|
2069
2207
|
/**
|
|
2070
|
-
*
|
|
2071
|
-
* effect to succeed. Losers of the race will be interrupted immediately
|
|
2208
|
+
* Add the provided service to the current context.
|
|
2072
2209
|
*
|
|
2073
2210
|
* @since 3.4.0
|
|
2074
2211
|
* @experimental
|
|
2075
|
-
* @category
|
|
2212
|
+
* @category environment
|
|
2076
2213
|
*/
|
|
2077
|
-
<A, E, R,
|
|
2214
|
+
<A, E, R, I, S>(self: Micro<A, E, R>, tag: Context.Tag<I, S>, service: S): Micro<A, E, Exclude<R, I>>
|
|
2078
2215
|
} = dual(
|
|
2079
|
-
|
|
2080
|
-
<A, E, R,
|
|
2081
|
-
|
|
2216
|
+
3,
|
|
2217
|
+
<A, E, R, I, S>(
|
|
2218
|
+
self: Micro<A, E, R>,
|
|
2219
|
+
tag: Context.Tag<I, S>,
|
|
2220
|
+
service: S
|
|
2221
|
+
): Micro<A, E, Exclude<R, I>> => updateContext(self, Context.add(tag, service)) as any
|
|
2082
2222
|
)
|
|
2083
2223
|
|
|
2084
2224
|
/**
|
|
2085
|
-
*
|
|
2086
|
-
*
|
|
2225
|
+
* Create a service using the provided `Micro` effect, and add it to the
|
|
2226
|
+
* current context.
|
|
2227
|
+
*
|
|
2228
|
+
* @since 3.4.6
|
|
2229
|
+
* @experimental
|
|
2230
|
+
* @category environment
|
|
2231
|
+
*/
|
|
2232
|
+
export const provideServiceEffect: {
|
|
2233
|
+
/**
|
|
2234
|
+
* Create a service using the provided `Micro` effect, and add it to the
|
|
2235
|
+
* current context.
|
|
2236
|
+
*
|
|
2237
|
+
* @since 3.4.6
|
|
2238
|
+
* @experimental
|
|
2239
|
+
* @category environment
|
|
2240
|
+
*/
|
|
2241
|
+
<I, S, E2, R2>(
|
|
2242
|
+
tag: Context.Tag<I, S>,
|
|
2243
|
+
acquire: Micro<S, E2, R2>
|
|
2244
|
+
): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | E2, Exclude<R, I> | R2>
|
|
2245
|
+
/**
|
|
2246
|
+
* Create a service using the provided `Micro` effect, and add it to the
|
|
2247
|
+
* current context.
|
|
2248
|
+
*
|
|
2249
|
+
* @since 3.4.6
|
|
2250
|
+
* @experimental
|
|
2251
|
+
* @category environment
|
|
2252
|
+
*/
|
|
2253
|
+
<A, E, R, I, S, E2, R2>(
|
|
2254
|
+
self: Micro<A, E, R>,
|
|
2255
|
+
tag: Context.Tag<I, S>,
|
|
2256
|
+
acquire: Micro<S, E2, R2>
|
|
2257
|
+
): Micro<A, E | E2, Exclude<R, I> | R2>
|
|
2258
|
+
} = dual(
|
|
2259
|
+
3,
|
|
2260
|
+
<A, E, R, I, S, E2, R2>(
|
|
2261
|
+
self: Micro<A, E, R>,
|
|
2262
|
+
tag: Context.Tag<I, S>,
|
|
2263
|
+
acquire: Micro<S, E2, R2>
|
|
2264
|
+
): Micro<A, E | E2, Exclude<R, I> | R2> => flatMap(acquire, (service) => provideService(self, tag, service))
|
|
2265
|
+
)
|
|
2266
|
+
|
|
2267
|
+
// ========================================================================
|
|
2268
|
+
// References
|
|
2269
|
+
// ========================================================================
|
|
2270
|
+
|
|
2271
|
+
/**
|
|
2272
|
+
* @since 3.11.0
|
|
2273
|
+
* @experimental
|
|
2274
|
+
* @category references
|
|
2275
|
+
*/
|
|
2276
|
+
export class MaxOpsBeforeYield extends Context.Reference<MaxOpsBeforeYield>()<
|
|
2277
|
+
"effect/Micro/currentMaxOpsBeforeYield",
|
|
2278
|
+
number
|
|
2279
|
+
>(
|
|
2280
|
+
"effect/Micro/currentMaxOpsBeforeYield",
|
|
2281
|
+
{ defaultValue: () => 2048 }
|
|
2282
|
+
) {}
|
|
2283
|
+
|
|
2284
|
+
/**
|
|
2285
|
+
* @since 3.11.0
|
|
2286
|
+
* @experimental
|
|
2287
|
+
* @category environment refs
|
|
2288
|
+
*/
|
|
2289
|
+
export class CurrentConcurrency extends Context.Reference<CurrentConcurrency>()<
|
|
2290
|
+
"effect/Micro/currentConcurrency",
|
|
2291
|
+
"unbounded" | number
|
|
2292
|
+
>(
|
|
2293
|
+
"effect/Micro/currentConcurrency",
|
|
2294
|
+
{ defaultValue: () => "unbounded" }
|
|
2295
|
+
) {}
|
|
2296
|
+
|
|
2297
|
+
/**
|
|
2298
|
+
* @since 3.11.0
|
|
2299
|
+
* @experimental
|
|
2300
|
+
* @category environment refs
|
|
2301
|
+
*/
|
|
2302
|
+
export class CurrentScheduler extends Context.Reference<CurrentScheduler>()<
|
|
2303
|
+
"effect/Micro/currentScheduler",
|
|
2304
|
+
MicroScheduler
|
|
2305
|
+
>(
|
|
2306
|
+
"effect/Micro/currentScheduler",
|
|
2307
|
+
{ defaultValue: () => new MicroSchedulerDefault() }
|
|
2308
|
+
) {}
|
|
2309
|
+
|
|
2310
|
+
/**
|
|
2311
|
+
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
2312
|
+
* api to control the concurrency of that `Micro` when it is run.
|
|
2087
2313
|
*
|
|
2088
2314
|
* @since 3.4.0
|
|
2089
2315
|
* @experimental
|
|
2090
|
-
* @category
|
|
2316
|
+
* @category environment refs
|
|
2317
|
+
* @example
|
|
2318
|
+
* import * as Micro from "effect/Micro"
|
|
2319
|
+
*
|
|
2320
|
+
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
2321
|
+
* concurrency: "inherit"
|
|
2322
|
+
* }).pipe(
|
|
2323
|
+
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
2324
|
+
* )
|
|
2091
2325
|
*/
|
|
2092
|
-
export const
|
|
2326
|
+
export const withConcurrency: {
|
|
2093
2327
|
/**
|
|
2094
|
-
*
|
|
2095
|
-
*
|
|
2328
|
+
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
2329
|
+
* api to control the concurrency of that `Micro` when it is run.
|
|
2096
2330
|
*
|
|
2097
2331
|
* @since 3.4.0
|
|
2098
2332
|
* @experimental
|
|
2099
|
-
* @category
|
|
2333
|
+
* @category environment refs
|
|
2334
|
+
* @example
|
|
2335
|
+
* import * as Micro from "effect/Micro"
|
|
2336
|
+
*
|
|
2337
|
+
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
2338
|
+
* concurrency: "inherit"
|
|
2339
|
+
* }).pipe(
|
|
2340
|
+
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
2341
|
+
* )
|
|
2100
2342
|
*/
|
|
2101
|
-
|
|
2343
|
+
(concurrency: "unbounded" | number): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, R>
|
|
2102
2344
|
/**
|
|
2103
|
-
*
|
|
2104
|
-
*
|
|
2345
|
+
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
2346
|
+
* api to control the concurrency of that `Micro` when it is run.
|
|
2105
2347
|
*
|
|
2106
2348
|
* @since 3.4.0
|
|
2107
2349
|
* @experimental
|
|
2108
|
-
* @category
|
|
2350
|
+
* @category environment refs
|
|
2351
|
+
* @example
|
|
2352
|
+
* import * as Micro from "effect/Micro"
|
|
2353
|
+
*
|
|
2354
|
+
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
2355
|
+
* concurrency: "inherit"
|
|
2356
|
+
* }).pipe(
|
|
2357
|
+
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
2358
|
+
* )
|
|
2109
2359
|
*/
|
|
2110
|
-
<A, E, R
|
|
2360
|
+
<A, E, R>(self: Micro<A, E, R>, concurrency: "unbounded" | number): Micro<A, E, R>
|
|
2111
2361
|
} = dual(
|
|
2112
2362
|
2,
|
|
2113
|
-
<A, E, R
|
|
2114
|
-
|
|
2363
|
+
<A, E, R>(
|
|
2364
|
+
self: Micro<A, E, R>,
|
|
2365
|
+
concurrency: "unbounded" | number
|
|
2366
|
+
): Micro<A, E, R> => provideService(self, CurrentConcurrency, concurrency)
|
|
2115
2367
|
)
|
|
2116
2368
|
|
|
2117
2369
|
// ----------------------------------------------------------------------------
|
|
@@ -2212,13 +2464,11 @@ export const zipWith: {
|
|
|
2212
2464
|
that: Micro<A2, E2, R2>,
|
|
2213
2465
|
f: (a: A, b: A2) => B,
|
|
2214
2466
|
options?: { readonly concurrent?: boolean | undefined }
|
|
2215
|
-
): Micro<B, E2 | E, R2 | R> =>
|
|
2216
|
-
|
|
2467
|
+
): Micro<B, E2 | E, R2 | R> =>
|
|
2468
|
+
options?.concurrent
|
|
2217
2469
|
// Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
return flatMap(self, (a) => map(that, (a2) => f(a, a2)))
|
|
2221
|
-
})
|
|
2470
|
+
? map(all([self, that], { concurrency: 2 }), ([a, a2]) => f(a, a2))
|
|
2471
|
+
: flatMap(self, (a) => map(that, (a2) => f(a, a2))))
|
|
2222
2472
|
|
|
2223
2473
|
// ----------------------------------------------------------------------------
|
|
2224
2474
|
// filtering & conditionals
|
|
@@ -2431,7 +2681,7 @@ export const when: {
|
|
|
2431
2681
|
self: Micro<A, E, R>,
|
|
2432
2682
|
condition: LazyArg<boolean> | Micro<boolean, E2, R2>
|
|
2433
2683
|
): Micro<Option.Option<A>, E | E2, R | R2> =>
|
|
2434
|
-
flatMap(isMicro(condition) ? condition : sync(condition), (pass) => pass ? asSome(self) :
|
|
2684
|
+
flatMap(isMicro(condition) ? condition : sync(condition), (pass) => pass ? asSome(self) : succeedNone)
|
|
2435
2685
|
)
|
|
2436
2686
|
|
|
2437
2687
|
// ----------------------------------------------------------------------------
|
|
@@ -2497,14 +2747,15 @@ export const repeatExit: {
|
|
|
2497
2747
|
times?: number | undefined
|
|
2498
2748
|
schedule?: MicroSchedule | undefined
|
|
2499
2749
|
}): Micro<A, E, R> =>
|
|
2500
|
-
|
|
2750
|
+
suspend(() => {
|
|
2501
2751
|
const startedAt = options.schedule ? Date.now() : 0
|
|
2502
2752
|
let attempt = 0
|
|
2503
|
-
|
|
2753
|
+
|
|
2754
|
+
const loop: Micro<A, E, R> = flatMap(exit(self), (exit) => {
|
|
2504
2755
|
if (options.while !== undefined && !options.while(exit)) {
|
|
2505
|
-
return
|
|
2756
|
+
return exit
|
|
2506
2757
|
} else if (options.times !== undefined && attempt >= options.times) {
|
|
2507
|
-
return
|
|
2758
|
+
return exit
|
|
2508
2759
|
}
|
|
2509
2760
|
attempt++
|
|
2510
2761
|
let delayEffect = yieldNow
|
|
@@ -2512,17 +2763,14 @@ export const repeatExit: {
|
|
|
2512
2763
|
const elapsed = Date.now() - startedAt
|
|
2513
2764
|
const duration = options.schedule(attempt, elapsed)
|
|
2514
2765
|
if (Option.isNone(duration)) {
|
|
2515
|
-
return
|
|
2766
|
+
return exit
|
|
2516
2767
|
}
|
|
2517
2768
|
delayEffect = sleep(duration.value)
|
|
2518
2769
|
}
|
|
2519
|
-
delayEffect
|
|
2520
|
-
if (exit._tag === "Left") {
|
|
2521
|
-
return onExit(exit as MicroExit<never, never>)
|
|
2522
|
-
}
|
|
2523
|
-
self[runSymbol](env, loop)
|
|
2524
|
-
})
|
|
2770
|
+
return flatMap(delayEffect, () => loop)
|
|
2525
2771
|
})
|
|
2772
|
+
|
|
2773
|
+
return loop
|
|
2526
2774
|
}))
|
|
2527
2775
|
|
|
2528
2776
|
/**
|
|
@@ -2575,9 +2823,116 @@ export const repeat: {
|
|
|
2575
2823
|
): Micro<A, E, R> =>
|
|
2576
2824
|
repeatExit(self, {
|
|
2577
2825
|
...options,
|
|
2578
|
-
while: (exit) => exit._tag === "
|
|
2826
|
+
while: (exit) => exit._tag === "Success" && (options?.while === undefined || options.while(exit.value))
|
|
2579
2827
|
}))
|
|
2580
2828
|
|
|
2829
|
+
/**
|
|
2830
|
+
* Replicates the given effect `n` times.
|
|
2831
|
+
*
|
|
2832
|
+
* @since 3.11.0
|
|
2833
|
+
* @experimental
|
|
2834
|
+
* @category repetition
|
|
2835
|
+
*/
|
|
2836
|
+
export const replicate: {
|
|
2837
|
+
/**
|
|
2838
|
+
* Replicates the given effect `n` times.
|
|
2839
|
+
*
|
|
2840
|
+
* @since 3.11.0
|
|
2841
|
+
* @experimental
|
|
2842
|
+
* @category repetition
|
|
2843
|
+
*/
|
|
2844
|
+
(n: number): <A, E, R>(self: Micro<A, E, R>) => Array<Micro<A, E, R>>
|
|
2845
|
+
/**
|
|
2846
|
+
* Replicates the given effect `n` times.
|
|
2847
|
+
*
|
|
2848
|
+
* @since 3.11.0
|
|
2849
|
+
* @experimental
|
|
2850
|
+
* @category repetition
|
|
2851
|
+
*/
|
|
2852
|
+
<A, E, R>(self: Micro<A, E, R>, n: number): Array<Micro<A, E, R>>
|
|
2853
|
+
} = dual(
|
|
2854
|
+
2,
|
|
2855
|
+
<A, E, R>(self: Micro<A, E, R>, n: number): Array<Micro<A, E, R>> => Array.from({ length: n }, () => self)
|
|
2856
|
+
)
|
|
2857
|
+
|
|
2858
|
+
/**
|
|
2859
|
+
* Performs this effect the specified number of times and collects the
|
|
2860
|
+
* results.
|
|
2861
|
+
*
|
|
2862
|
+
* @since 3.11.0
|
|
2863
|
+
* @category repetition
|
|
2864
|
+
*/
|
|
2865
|
+
export const replicateEffect: {
|
|
2866
|
+
/**
|
|
2867
|
+
* Performs this effect the specified number of times and collects the
|
|
2868
|
+
* results.
|
|
2869
|
+
*
|
|
2870
|
+
* @since 3.11.0
|
|
2871
|
+
* @category repetition
|
|
2872
|
+
*/
|
|
2873
|
+
(
|
|
2874
|
+
n: number,
|
|
2875
|
+
options?: {
|
|
2876
|
+
readonly concurrency?: Concurrency | undefined
|
|
2877
|
+
readonly discard?: false | undefined
|
|
2878
|
+
}
|
|
2879
|
+
): <A, E, R>(self: Micro<A, E, R>) => Micro<Array<A>, E, R>
|
|
2880
|
+
/**
|
|
2881
|
+
* Performs this effect the specified number of times and collects the
|
|
2882
|
+
* results.
|
|
2883
|
+
*
|
|
2884
|
+
* @since 3.11.0
|
|
2885
|
+
* @category repetition
|
|
2886
|
+
*/
|
|
2887
|
+
(
|
|
2888
|
+
n: number,
|
|
2889
|
+
options: {
|
|
2890
|
+
readonly concurrency?: Concurrency | undefined
|
|
2891
|
+
readonly discard: true
|
|
2892
|
+
}
|
|
2893
|
+
): <A, E, R>(self: Micro<A, E, R>) => Micro<void, E, R>
|
|
2894
|
+
/**
|
|
2895
|
+
* Performs this effect the specified number of times and collects the
|
|
2896
|
+
* results.
|
|
2897
|
+
*
|
|
2898
|
+
* @since 3.11.0
|
|
2899
|
+
* @category repetition
|
|
2900
|
+
*/
|
|
2901
|
+
<A, E, R>(
|
|
2902
|
+
self: Micro<A, E, R>,
|
|
2903
|
+
n: number,
|
|
2904
|
+
options?: {
|
|
2905
|
+
readonly concurrency?: Concurrency | undefined
|
|
2906
|
+
readonly discard?: false | undefined
|
|
2907
|
+
}
|
|
2908
|
+
): Micro<Array<A>, E, R>
|
|
2909
|
+
/**
|
|
2910
|
+
* Performs this effect the specified number of times and collects the
|
|
2911
|
+
* results.
|
|
2912
|
+
*
|
|
2913
|
+
* @since 3.11.0
|
|
2914
|
+
* @category repetition
|
|
2915
|
+
*/
|
|
2916
|
+
<A, E, R>(
|
|
2917
|
+
self: Micro<A, E, R>,
|
|
2918
|
+
n: number,
|
|
2919
|
+
options: {
|
|
2920
|
+
readonly concurrency?: Concurrency | undefined
|
|
2921
|
+
readonly discard: true
|
|
2922
|
+
}
|
|
2923
|
+
): Micro<void, E, R>
|
|
2924
|
+
} = dual(
|
|
2925
|
+
(args) => isMicro(args[0]),
|
|
2926
|
+
<A, E, R>(
|
|
2927
|
+
self: Micro<A, E, R>,
|
|
2928
|
+
n: number,
|
|
2929
|
+
options: {
|
|
2930
|
+
readonly concurrency?: Concurrency | undefined
|
|
2931
|
+
readonly discard: true
|
|
2932
|
+
}
|
|
2933
|
+
): Micro<void, E, R> => all(replicate(self, n), options)
|
|
2934
|
+
)
|
|
2935
|
+
|
|
2581
2936
|
/**
|
|
2582
2937
|
* Repeat the given `Micro` effect forever, only stopping if the effect fails.
|
|
2583
2938
|
*
|
|
@@ -2848,8 +3203,20 @@ export const catchAllCause: {
|
|
|
2848
3203
|
<A, E, R, B, E2, R2>(
|
|
2849
3204
|
self: Micro<A, E, R>,
|
|
2850
3205
|
f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
|
|
2851
|
-
): Micro<A | B, E2, R | R2> =>
|
|
3206
|
+
): Micro<A | B, E2, R | R2> => {
|
|
3207
|
+
const onFailure = Object.create(OnFailureProto)
|
|
3208
|
+
onFailure[args] = self
|
|
3209
|
+
onFailure[failureCont] = f
|
|
3210
|
+
return onFailure
|
|
3211
|
+
}
|
|
2852
3212
|
)
|
|
3213
|
+
const OnFailureProto = makePrimitiveProto({
|
|
3214
|
+
op: "OnFailure",
|
|
3215
|
+
eval(this: any, fiber: FiberImpl): Primitive {
|
|
3216
|
+
fiber._stack.push(this as any)
|
|
3217
|
+
return this[args]
|
|
3218
|
+
}
|
|
3219
|
+
})
|
|
2853
3220
|
|
|
2854
3221
|
/**
|
|
2855
3222
|
* Selectively catch a `MicroCause` object of the given `Micro` effect,
|
|
@@ -2871,7 +3238,9 @@ export const catchCauseIf: {
|
|
|
2871
3238
|
<E, B, E2, R2, EB extends MicroCause<E>>(
|
|
2872
3239
|
refinement: Refinement<MicroCause<E>, EB>,
|
|
2873
3240
|
f: (cause: EB) => Micro<B, E2, R2>
|
|
2874
|
-
): <A, R>(
|
|
3241
|
+
): <A, R>(
|
|
3242
|
+
self: Micro<A, E, R>
|
|
3243
|
+
) => Micro<A | B, Exclude<E, MicroCause.Error<EB>> | E2, R | R2>
|
|
2875
3244
|
/**
|
|
2876
3245
|
* Selectively catch a `MicroCause` object of the given `Micro` effect,
|
|
2877
3246
|
* using the provided predicate to determine if the failure should be caught.
|
|
@@ -2910,20 +3279,15 @@ export const catchCauseIf: {
|
|
|
2910
3279
|
predicate: Predicate<MicroCause<NoInfer<E>>>,
|
|
2911
3280
|
f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
|
|
2912
3281
|
): Micro<A | B, E | E2, R | R2>
|
|
2913
|
-
} = dual(
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
} else {
|
|
2923
|
-
f(exit.left)[runSymbol](env, onExit)
|
|
2924
|
-
}
|
|
2925
|
-
})
|
|
2926
|
-
}))
|
|
3282
|
+
} = dual(
|
|
3283
|
+
3,
|
|
3284
|
+
<A, E, R, B, E2, R2>(
|
|
3285
|
+
self: Micro<A, E, R>,
|
|
3286
|
+
predicate: Predicate<MicroCause<E>>,
|
|
3287
|
+
f: (cause: MicroCause<E>) => Micro<B, E2, R2>
|
|
3288
|
+
): Micro<A | B, E | E2, R | R2> =>
|
|
3289
|
+
catchAllCause(self, (cause) => predicate(cause) ? f(cause) : failCause(cause) as any)
|
|
3290
|
+
)
|
|
2927
3291
|
|
|
2928
3292
|
/**
|
|
2929
3293
|
* Catch the error of the given `Micro` effect, allowing you to recover from it.
|
|
@@ -2960,7 +3324,7 @@ export const catchAll: {
|
|
|
2960
3324
|
<A, E, R, B, E2, R2>(
|
|
2961
3325
|
self: Micro<A, E, R>,
|
|
2962
3326
|
f: (a: NoInfer<E>) => Micro<B, E2, R2>
|
|
2963
|
-
): Micro<A | B, E2, R | R2> =>
|
|
3327
|
+
): Micro<A | B, E2, R | R2> => catchCauseIf(self, causeIsFail, (cause) => f(cause.error))
|
|
2964
3328
|
)
|
|
2965
3329
|
|
|
2966
3330
|
/**
|
|
@@ -3396,7 +3760,7 @@ export const ignoreLogged = <A, E, R>(self: Micro<A, E, R>): Micro<void, never,
|
|
|
3396
3760
|
* @category error handling
|
|
3397
3761
|
*/
|
|
3398
3762
|
export const option = <A, E, R>(self: Micro<A, E, R>): Micro<Option.Option<A>, never, R> =>
|
|
3399
|
-
match(self, { onFailure:
|
|
3763
|
+
match(self, { onFailure: Option.none, onSuccess: Option.some })
|
|
3400
3764
|
|
|
3401
3765
|
/**
|
|
3402
3766
|
* Replace the success value of the given `Micro` effect with an `Either`,
|
|
@@ -3458,8 +3822,8 @@ export const retry: {
|
|
|
3458
3822
|
repeatExit(self, {
|
|
3459
3823
|
...options,
|
|
3460
3824
|
while: (exit) =>
|
|
3461
|
-
exit._tag === "
|
|
3462
|
-
(options?.while === undefined || options.while(exit.
|
|
3825
|
+
exit._tag === "Failure" && exit.cause._tag === "Fail" &&
|
|
3826
|
+
(options?.while === undefined || options.while(exit.cause.error))
|
|
3463
3827
|
}))
|
|
3464
3828
|
|
|
3465
3829
|
/**
|
|
@@ -3506,12 +3870,7 @@ export const withTrace: {
|
|
|
3506
3870
|
const lineMatch = line.match(/\((.*)\)$/)
|
|
3507
3871
|
return causeWithTrace(cause, `at ${name} (${lineMatch ? lineMatch[1] : line})`)
|
|
3508
3872
|
}
|
|
3509
|
-
const f = (name: string) => (self: Micro<any, any, any>) =>
|
|
3510
|
-
unsafeMakeOptions(function(env, onExit) {
|
|
3511
|
-
self[runSymbol](env, function(exit) {
|
|
3512
|
-
onExit(exit._tag === "Left" ? Either.left(generate(name, exit.left)) : exit)
|
|
3513
|
-
})
|
|
3514
|
-
}, false)
|
|
3873
|
+
const f = (name: string) => (self: Micro<any, any, any>) => onError(self, (cause) => failCause(generate(name, cause)))
|
|
3515
3874
|
if (arguments.length === 2) {
|
|
3516
3875
|
return f(arguments[1])(arguments[0])
|
|
3517
3876
|
}
|
|
@@ -3567,18 +3926,21 @@ export const matchCauseEffect: {
|
|
|
3567
3926
|
readonly onFailure: (cause: MicroCause<E>) => Micro<A2, E2, R2>
|
|
3568
3927
|
readonly onSuccess: (a: A) => Micro<A3, E3, R3>
|
|
3569
3928
|
}
|
|
3570
|
-
): Micro<A2 | A3, E2 | E3, R2 | R3 | R> =>
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
onExit(exitDie(err))
|
|
3578
|
-
}
|
|
3579
|
-
})
|
|
3580
|
-
})
|
|
3929
|
+
): Micro<A2 | A3, E2 | E3, R2 | R3 | R> => {
|
|
3930
|
+
const primitive = Object.create(OnSuccessAndFailureProto)
|
|
3931
|
+
primitive[args] = self
|
|
3932
|
+
primitive[successCont] = options.onSuccess
|
|
3933
|
+
primitive[failureCont] = options.onFailure
|
|
3934
|
+
return primitive
|
|
3935
|
+
}
|
|
3581
3936
|
)
|
|
3937
|
+
const OnSuccessAndFailureProto = makePrimitiveProto({
|
|
3938
|
+
op: "OnSuccessAndFailure",
|
|
3939
|
+
eval(this: any, fiber: FiberImpl): Primitive {
|
|
3940
|
+
fiber._stack.push(this)
|
|
3941
|
+
return this[args]
|
|
3942
|
+
}
|
|
3943
|
+
})
|
|
3582
3944
|
|
|
3583
3945
|
/**
|
|
3584
3946
|
* @since 3.4.6
|
|
@@ -3724,12 +4086,12 @@ export const match: {
|
|
|
3724
4086
|
* @category delays & timeouts
|
|
3725
4087
|
*/
|
|
3726
4088
|
export const sleep = (millis: number): Micro<void> =>
|
|
3727
|
-
async(
|
|
3728
|
-
const timeout = setTimeout(
|
|
4089
|
+
async((resume) => {
|
|
4090
|
+
const timeout = setTimeout(() => {
|
|
3729
4091
|
resume(void_)
|
|
3730
4092
|
}, millis)
|
|
3731
4093
|
return sync(() => {
|
|
3732
|
-
|
|
4094
|
+
clearTimeout(timeout)
|
|
3733
4095
|
})
|
|
3734
4096
|
})
|
|
3735
4097
|
|
|
@@ -3997,7 +4359,7 @@ class MicroScopeImpl implements MicroScope.Closeable {
|
|
|
3997
4359
|
this.state = { _tag: "Closed", exit: microExit }
|
|
3998
4360
|
return flatMap(
|
|
3999
4361
|
forEach(finalizers, (finalizer) => exit(finalizer(microExit))),
|
|
4000
|
-
|
|
4362
|
+
exitVoidAll
|
|
4001
4363
|
)
|
|
4002
4364
|
}
|
|
4003
4365
|
return void_
|
|
@@ -4082,7 +4444,7 @@ export const provideScope: {
|
|
|
4082
4444
|
* @category resources & finalization
|
|
4083
4445
|
*/
|
|
4084
4446
|
export const scoped = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, Exclude<R, MicroScope>> =>
|
|
4085
|
-
suspend(
|
|
4447
|
+
suspend(() => {
|
|
4086
4448
|
const scope = new MicroScopeImpl()
|
|
4087
4449
|
return onExit(provideService(self, MicroScope, scope), (exit) => scope.close(exit))
|
|
4088
4450
|
})
|
|
@@ -4149,7 +4511,45 @@ export const onExit: {
|
|
|
4149
4511
|
<A, E, R, XE, XR>(
|
|
4150
4512
|
self: Micro<A, E, R>,
|
|
4151
4513
|
f: (exit: MicroExit<A, E>) => Micro<void, XE, XR>
|
|
4152
|
-
): Micro<A, E | XE, R | XR> =>
|
|
4514
|
+
): Micro<A, E | XE, R | XR> =>
|
|
4515
|
+
uninterruptibleMask((restore) =>
|
|
4516
|
+
matchCauseEffect(restore(self), {
|
|
4517
|
+
onFailure: (cause) => flatMap(f(exitFailCause(cause)), () => failCause(cause)),
|
|
4518
|
+
onSuccess: (a) => flatMap(f(exitSucceed(a)), () => succeed(a))
|
|
4519
|
+
})
|
|
4520
|
+
)
|
|
4521
|
+
)
|
|
4522
|
+
|
|
4523
|
+
/**
|
|
4524
|
+
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4525
|
+
*
|
|
4526
|
+
* @since 3.4.0
|
|
4527
|
+
* @experimental
|
|
4528
|
+
* @category resources & finalization
|
|
4529
|
+
*/
|
|
4530
|
+
export const ensuring: {
|
|
4531
|
+
/**
|
|
4532
|
+
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4533
|
+
*
|
|
4534
|
+
* @since 3.4.0
|
|
4535
|
+
* @experimental
|
|
4536
|
+
* @category resources & finalization
|
|
4537
|
+
*/
|
|
4538
|
+
<XE, XR>(finalizer: Micro<void, XE, XR>): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
|
|
4539
|
+
/**
|
|
4540
|
+
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4541
|
+
*
|
|
4542
|
+
* @since 3.4.0
|
|
4543
|
+
* @experimental
|
|
4544
|
+
* @category resources & finalization
|
|
4545
|
+
*/
|
|
4546
|
+
<A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR>
|
|
4547
|
+
} = dual(
|
|
4548
|
+
2,
|
|
4549
|
+
<A, E, R, XE, XR>(
|
|
4550
|
+
self: Micro<A, E, R>,
|
|
4551
|
+
finalizer: Micro<void, XE, XR>
|
|
4552
|
+
): Micro<A, E | XE, R | XR> => onExit(self, (_) => finalizer)
|
|
4153
4553
|
)
|
|
4154
4554
|
|
|
4155
4555
|
/**
|
|
@@ -4217,52 +4617,7 @@ export const onExitIf: {
|
|
|
4217
4617
|
self: Micro<A, E, R>,
|
|
4218
4618
|
refinement: Refinement<MicroExit<A, E>, B>,
|
|
4219
4619
|
f: (exit: B) => Micro<void, XE, XR>
|
|
4220
|
-
): Micro<A, E | XE, R | XR> =>
|
|
4221
|
-
uninterruptibleMask((restore) =>
|
|
4222
|
-
make(function(env, onExit) {
|
|
4223
|
-
restore(self)[runSymbol](env, function(exit) {
|
|
4224
|
-
if (!refinement(exit)) {
|
|
4225
|
-
return onExit(exit)
|
|
4226
|
-
}
|
|
4227
|
-
f(exit)[runSymbol](env, function(finalizerExit) {
|
|
4228
|
-
if (finalizerExit._tag === "Left") {
|
|
4229
|
-
return onExit(finalizerExit as MicroExit<never, XE>)
|
|
4230
|
-
}
|
|
4231
|
-
onExit(exit)
|
|
4232
|
-
})
|
|
4233
|
-
})
|
|
4234
|
-
})
|
|
4235
|
-
)
|
|
4236
|
-
)
|
|
4237
|
-
|
|
4238
|
-
/**
|
|
4239
|
-
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4240
|
-
*
|
|
4241
|
-
* @since 3.4.0
|
|
4242
|
-
* @experimental
|
|
4243
|
-
* @category resources & finalization
|
|
4244
|
-
*/
|
|
4245
|
-
export const ensuring: {
|
|
4246
|
-
/**
|
|
4247
|
-
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4248
|
-
*
|
|
4249
|
-
* @since 3.4.0
|
|
4250
|
-
* @experimental
|
|
4251
|
-
* @category resources & finalization
|
|
4252
|
-
*/
|
|
4253
|
-
<XE, XR>(finalizer: Micro<void, XE, XR>): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
|
|
4254
|
-
/**
|
|
4255
|
-
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4256
|
-
*
|
|
4257
|
-
* @since 3.4.0
|
|
4258
|
-
* @experimental
|
|
4259
|
-
* @category resources & finalization
|
|
4260
|
-
*/
|
|
4261
|
-
<A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR>
|
|
4262
|
-
} = dual(
|
|
4263
|
-
2,
|
|
4264
|
-
<A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR> =>
|
|
4265
|
-
onExit(self, (_) => finalizer)
|
|
4620
|
+
): Micro<A, E | XE, R | XR> => onExit(self, (exit) => (refinement(exit) ? f(exit) : exitVoid))
|
|
4266
4621
|
)
|
|
4267
4622
|
|
|
4268
4623
|
/**
|
|
@@ -4302,7 +4657,7 @@ export const onError: {
|
|
|
4302
4657
|
<A, E, R, XE, XR>(
|
|
4303
4658
|
self: Micro<A, E, R>,
|
|
4304
4659
|
f: (cause: MicroCause<NoInfer<E>>) => Micro<void, XE, XR>
|
|
4305
|
-
): Micro<A, E | XE, R | XR> => onExitIf(self, exitIsFailure, (exit) => f(exit.
|
|
4660
|
+
): Micro<A, E | XE, R | XR> => onExitIf(self, exitIsFailure, (exit) => f(exit.cause))
|
|
4306
4661
|
)
|
|
4307
4662
|
|
|
4308
4663
|
/**
|
|
@@ -4354,7 +4709,7 @@ export const acquireUseRelease = <Resource, E, R, A, E2, R2, E3, R3>(
|
|
|
4354
4709
|
(a) =>
|
|
4355
4710
|
flatMap(
|
|
4356
4711
|
exit(restore(use(a))),
|
|
4357
|
-
(exit) => andThen(release(a, exit),
|
|
4712
|
+
(exit) => andThen(release(a, exit), exit)
|
|
4358
4713
|
)
|
|
4359
4714
|
)
|
|
4360
4715
|
)
|
|
@@ -4370,29 +4725,54 @@ export const acquireUseRelease = <Resource, E, R, A, E2, R2, E3, R3>(
|
|
|
4370
4725
|
* @experimental
|
|
4371
4726
|
* @category interruption
|
|
4372
4727
|
*/
|
|
4373
|
-
export const interrupt: Micro<never> =
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4728
|
+
export const interrupt: Micro<never> = failCause(causeInterrupt())
|
|
4729
|
+
|
|
4730
|
+
/**
|
|
4731
|
+
* Flag the effect as uninterruptible, which means that when the effect is
|
|
4732
|
+
* interrupted, it will be allowed to continue running until completion.
|
|
4733
|
+
*
|
|
4734
|
+
* @since 3.4.0
|
|
4735
|
+
* @experimental
|
|
4736
|
+
* @category flags
|
|
4737
|
+
*/
|
|
4738
|
+
export const uninterruptible = <A, E, R>(
|
|
4739
|
+
self: Micro<A, E, R>
|
|
4740
|
+
): Micro<A, E, R> =>
|
|
4741
|
+
withFiber((fiber) => {
|
|
4742
|
+
if (!fiber.interruptible) return self
|
|
4743
|
+
fiber.interruptible = false
|
|
4744
|
+
fiber._stack.push(setInterruptible(true))
|
|
4745
|
+
return self
|
|
4746
|
+
})
|
|
4747
|
+
|
|
4748
|
+
const setInterruptible: (interruptible: boolean) => Primitive = makePrimitive({
|
|
4749
|
+
op: "SetInterruptible",
|
|
4750
|
+
ensure(fiber) {
|
|
4751
|
+
fiber.interruptible = this[args]
|
|
4752
|
+
if (fiber._interrupted && fiber.interruptible) {
|
|
4753
|
+
return () => exitInterrupt
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4377
4756
|
})
|
|
4378
4757
|
|
|
4379
4758
|
/**
|
|
4380
|
-
*
|
|
4381
|
-
*
|
|
4759
|
+
* Flag the effect as interruptible, which means that when the effect is
|
|
4760
|
+
* interrupted, it will be interrupted immediately.
|
|
4382
4761
|
*
|
|
4383
4762
|
* @since 3.4.0
|
|
4384
4763
|
* @experimental
|
|
4385
|
-
* @category
|
|
4764
|
+
* @category flags
|
|
4386
4765
|
*/
|
|
4387
|
-
export const
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4766
|
+
export const interruptible = <A, E, R>(
|
|
4767
|
+
self: Micro<A, E, R>
|
|
4768
|
+
): Micro<A, E, R> =>
|
|
4769
|
+
withFiber((fiber) => {
|
|
4770
|
+
if (fiber.interruptible) return self
|
|
4771
|
+
fiber.interruptible = true
|
|
4772
|
+
fiber._stack.push(setInterruptible(false))
|
|
4773
|
+
if (fiber._interrupted) return exitInterrupt
|
|
4774
|
+
return self
|
|
4775
|
+
})
|
|
4396
4776
|
|
|
4397
4777
|
/**
|
|
4398
4778
|
* Wrap the given `Micro` effect in an uninterruptible region, preventing the
|
|
@@ -4416,42 +4796,15 @@ export const uninterruptible = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, R> =
|
|
|
4416
4796
|
* ```
|
|
4417
4797
|
*/
|
|
4418
4798
|
export const uninterruptibleMask = <A, E, R>(
|
|
4419
|
-
f: (
|
|
4799
|
+
f: (
|
|
4800
|
+
restore: <A, E, R>(effect: Micro<A, E, R>) => Micro<A, E, R>
|
|
4801
|
+
) => Micro<A, E, R>
|
|
4420
4802
|
): Micro<A, E, R> =>
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
env[currentInterruptible.key] = false
|
|
4427
|
-
env[currentAbortSignal.key] = new AbortController().signal
|
|
4428
|
-
return env
|
|
4429
|
-
}) :
|
|
4430
|
-
env
|
|
4431
|
-
effect[runSymbol](nextEnv, onExit)
|
|
4432
|
-
}, false)
|
|
4433
|
-
|
|
4434
|
-
/**
|
|
4435
|
-
* Wrap the given `Micro` effect in an interruptible region, allowing the effect
|
|
4436
|
-
* to be aborted.
|
|
4437
|
-
*
|
|
4438
|
-
* @since 3.4.0
|
|
4439
|
-
* @experimental
|
|
4440
|
-
* @category interruption
|
|
4441
|
-
*/
|
|
4442
|
-
export const interruptible = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, R> =>
|
|
4443
|
-
make((env, onExit) => {
|
|
4444
|
-
const isInterruptible = envGet(env, currentInterruptible)
|
|
4445
|
-
let newEnv = env
|
|
4446
|
-
if (!isInterruptible) {
|
|
4447
|
-
const controller = envGet(env, currentAbortController)
|
|
4448
|
-
newEnv = envMutate(env, function(env) {
|
|
4449
|
-
env[currentInterruptible.key] = true
|
|
4450
|
-
env[currentAbortSignal.key] = controller.signal
|
|
4451
|
-
return env
|
|
4452
|
-
})
|
|
4453
|
-
}
|
|
4454
|
-
self[runSymbol](newEnv, onExit)
|
|
4803
|
+
withFiber((fiber) => {
|
|
4804
|
+
if (!fiber.interruptible) return f(identity)
|
|
4805
|
+
fiber.interruptible = false
|
|
4806
|
+
fiber._stack.push(setInterruptible(true))
|
|
4807
|
+
return f(interruptible)
|
|
4455
4808
|
})
|
|
4456
4809
|
|
|
4457
4810
|
// ========================================================================
|
|
@@ -4571,6 +4924,34 @@ export const all = <
|
|
|
4571
4924
|
}) as any
|
|
4572
4925
|
}
|
|
4573
4926
|
|
|
4927
|
+
/**
|
|
4928
|
+
* @since 3.11.0
|
|
4929
|
+
* @experimental
|
|
4930
|
+
* @category collecting & elements
|
|
4931
|
+
*/
|
|
4932
|
+
export const whileLoop: <A, E, R>(options: {
|
|
4933
|
+
readonly while: LazyArg<boolean>
|
|
4934
|
+
readonly body: LazyArg<Micro<A, E, R>>
|
|
4935
|
+
readonly step: (a: A) => void
|
|
4936
|
+
}) => Micro<void, E, R> = makePrimitive({
|
|
4937
|
+
op: "While",
|
|
4938
|
+
contA(value, fiber) {
|
|
4939
|
+
this[args].step(value)
|
|
4940
|
+
if (this[args].while()) {
|
|
4941
|
+
fiber._stack.push(this)
|
|
4942
|
+
return this[args].body()
|
|
4943
|
+
}
|
|
4944
|
+
return exitVoid
|
|
4945
|
+
},
|
|
4946
|
+
eval(fiber) {
|
|
4947
|
+
if (this[args].while()) {
|
|
4948
|
+
fiber._stack.push(this)
|
|
4949
|
+
return this[args].body()
|
|
4950
|
+
}
|
|
4951
|
+
return exitVoid
|
|
4952
|
+
}
|
|
4953
|
+
})
|
|
4954
|
+
|
|
4574
4955
|
/**
|
|
4575
4956
|
* For each element of the provided iterable, run the effect and collect the results.
|
|
4576
4957
|
*
|
|
@@ -4636,64 +5017,89 @@ export const forEach: {
|
|
|
4636
5017
|
readonly concurrency?: Concurrency | undefined
|
|
4637
5018
|
readonly discard?: boolean | undefined
|
|
4638
5019
|
}): Micro<any, E, R> =>
|
|
4639
|
-
|
|
5020
|
+
withFiber((parent) => {
|
|
4640
5021
|
const concurrencyOption = options?.concurrency === "inherit"
|
|
4641
|
-
?
|
|
5022
|
+
? parent.getRef(CurrentConcurrency)
|
|
4642
5023
|
: options?.concurrency ?? 1
|
|
4643
5024
|
const concurrency = concurrencyOption === "unbounded"
|
|
4644
5025
|
? Number.POSITIVE_INFINITY
|
|
4645
5026
|
: Math.max(1, concurrencyOption)
|
|
4646
5027
|
|
|
4647
|
-
|
|
4648
|
-
const [envWithSignal, onAbort] = forkSignal(env)
|
|
4649
|
-
|
|
4650
|
-
// iterate
|
|
4651
|
-
let result: MicroExit<any, any> | undefined = undefined
|
|
4652
|
-
const items = Array.from(iterable)
|
|
5028
|
+
const items = Arr.fromIterable(iterable)
|
|
4653
5029
|
let length = items.length
|
|
4654
5030
|
if (length === 0) {
|
|
4655
|
-
return
|
|
5031
|
+
return options?.discard ? void_ : succeed([])
|
|
4656
5032
|
}
|
|
5033
|
+
|
|
4657
5034
|
const out: Array<B> | undefined = options?.discard ? undefined : new Array(length)
|
|
4658
5035
|
let index = 0
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
5036
|
+
|
|
5037
|
+
if (concurrency === 1) {
|
|
5038
|
+
return as(
|
|
5039
|
+
whileLoop({
|
|
5040
|
+
while: () => index < items.length,
|
|
5041
|
+
body: () => f(items[index], index),
|
|
5042
|
+
step: out ?
|
|
5043
|
+
(b) => out[index++] = b :
|
|
5044
|
+
(_) => index++
|
|
5045
|
+
}),
|
|
5046
|
+
out as any
|
|
5047
|
+
)
|
|
5048
|
+
}
|
|
5049
|
+
return async((resume) => {
|
|
5050
|
+
const fibers = new Set<Fiber<unknown, unknown>>()
|
|
5051
|
+
let result: MicroExit<any, any> | undefined = undefined
|
|
5052
|
+
let inProgress = 0
|
|
5053
|
+
let doneCount = 0
|
|
5054
|
+
let pumping = false
|
|
5055
|
+
let interrupted = false
|
|
5056
|
+
function pump() {
|
|
5057
|
+
pumping = true
|
|
5058
|
+
while (inProgress < concurrency && index < length) {
|
|
5059
|
+
const currentIndex = index
|
|
5060
|
+
const item = items[currentIndex]
|
|
5061
|
+
index++
|
|
5062
|
+
inProgress++
|
|
5063
|
+
try {
|
|
5064
|
+
const child = unsafeFork(parent, f(item, currentIndex), true, true)
|
|
5065
|
+
fibers.add(child)
|
|
5066
|
+
child.addObserver((exit) => {
|
|
5067
|
+
fibers.delete(child)
|
|
5068
|
+
if (interrupted) {
|
|
5069
|
+
return
|
|
5070
|
+
} else if (exit._tag === "Failure") {
|
|
5071
|
+
if (result === undefined) {
|
|
5072
|
+
result = exit
|
|
5073
|
+
length = index
|
|
5074
|
+
fibers.forEach((fiber) => fiber.unsafeInterrupt())
|
|
5075
|
+
}
|
|
5076
|
+
} else if (out !== undefined) {
|
|
5077
|
+
out[currentIndex] = exit.value
|
|
4676
5078
|
}
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
}
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
length = index
|
|
4691
|
-
onAbort()
|
|
5079
|
+
doneCount++
|
|
5080
|
+
inProgress--
|
|
5081
|
+
if (doneCount === length) {
|
|
5082
|
+
resume(result ?? succeed(out))
|
|
5083
|
+
} else if (!pumping && inProgress < concurrency) {
|
|
5084
|
+
pump()
|
|
5085
|
+
}
|
|
5086
|
+
})
|
|
5087
|
+
} catch (err) {
|
|
5088
|
+
result = exitDie(err)
|
|
5089
|
+
length = index
|
|
5090
|
+
fibers.forEach((fiber) => fiber.unsafeInterrupt())
|
|
5091
|
+
}
|
|
4692
5092
|
}
|
|
5093
|
+
pumping = false
|
|
4693
5094
|
}
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
5095
|
+
pump()
|
|
5096
|
+
|
|
5097
|
+
return suspend(() => {
|
|
5098
|
+
interrupted = true
|
|
5099
|
+
index = length
|
|
5100
|
+
return fiberInterruptAll(fibers)
|
|
5101
|
+
})
|
|
5102
|
+
})
|
|
4697
5103
|
})
|
|
4698
5104
|
|
|
4699
5105
|
/**
|
|
@@ -4843,151 +5249,9 @@ export {
|
|
|
4843
5249
|
}
|
|
4844
5250
|
|
|
4845
5251
|
// ----------------------------------------------------------------------------
|
|
4846
|
-
//
|
|
5252
|
+
// fibers & forking
|
|
4847
5253
|
// ----------------------------------------------------------------------------
|
|
4848
5254
|
|
|
4849
|
-
/**
|
|
4850
|
-
* @since 3.4.0
|
|
4851
|
-
* @experimental
|
|
4852
|
-
* @category handle & forking
|
|
4853
|
-
*/
|
|
4854
|
-
export const HandleTypeId: unique symbol = Symbol.for("effect/Micro/Handle")
|
|
4855
|
-
|
|
4856
|
-
/**
|
|
4857
|
-
* @since 3.4.0
|
|
4858
|
-
* @experimental
|
|
4859
|
-
* @category handle & forking
|
|
4860
|
-
*/
|
|
4861
|
-
export type HandleTypeId = typeof HandleTypeId
|
|
4862
|
-
|
|
4863
|
-
/**
|
|
4864
|
-
* @since 3.4.0
|
|
4865
|
-
* @experimental
|
|
4866
|
-
* @category handle & forking
|
|
4867
|
-
*/
|
|
4868
|
-
export interface Handle<A, E = never> extends Micro<A, E> {
|
|
4869
|
-
readonly [HandleTypeId]: HandleTypeId
|
|
4870
|
-
readonly await: Micro<MicroExit<A, E>>
|
|
4871
|
-
readonly join: Micro<A, E>
|
|
4872
|
-
readonly interrupt: Micro<MicroExit<A, E>>
|
|
4873
|
-
readonly unsafeInterrupt: () => void
|
|
4874
|
-
readonly addObserver: (observer: (exit: MicroExit<A, E>) => void) => void
|
|
4875
|
-
readonly removeObserver: (observer: (exit: MicroExit<A, E>) => void) => void
|
|
4876
|
-
readonly unsafePoll: () => MicroExit<A, E> | null
|
|
4877
|
-
|
|
4878
|
-
[Unify.typeSymbol]?: unknown
|
|
4879
|
-
[Unify.unifySymbol]?: HandleUnify<this>
|
|
4880
|
-
[Unify.ignoreSymbol]?: HandleUnifyIgnore
|
|
4881
|
-
}
|
|
4882
|
-
|
|
4883
|
-
/**
|
|
4884
|
-
* @category models
|
|
4885
|
-
* @since 3.8.4
|
|
4886
|
-
* @experimental
|
|
4887
|
-
*/
|
|
4888
|
-
export interface HandleUnify<A extends { [Unify.typeSymbol]?: any }> extends MicroUnify<A> {
|
|
4889
|
-
Handle?: () => A[Unify.typeSymbol] extends Handle<infer A0, infer E0> | infer _ ? Handle<A0, E0> : never
|
|
4890
|
-
}
|
|
4891
|
-
|
|
4892
|
-
/**
|
|
4893
|
-
* @category models
|
|
4894
|
-
* @since 3.8.4
|
|
4895
|
-
* @experimental
|
|
4896
|
-
*/
|
|
4897
|
-
export interface HandleUnifyIgnore extends MicroUnifyIgnore {
|
|
4898
|
-
Micro?: true
|
|
4899
|
-
}
|
|
4900
|
-
|
|
4901
|
-
/**
|
|
4902
|
-
* @since 3.4.0
|
|
4903
|
-
* @experimental
|
|
4904
|
-
* @category handle & forking
|
|
4905
|
-
*/
|
|
4906
|
-
export const isHandle = (u: unknown): u is Handle<unknown, unknown> =>
|
|
4907
|
-
typeof u === "object" && u !== null && HandleTypeId in u
|
|
4908
|
-
|
|
4909
|
-
class HandleImpl<A, E> extends Class<A, E> implements Handle<A, E> {
|
|
4910
|
-
readonly [HandleTypeId]: HandleTypeId
|
|
4911
|
-
|
|
4912
|
-
readonly observers: Set<(exit: MicroExit<A, E>) => void> = new Set()
|
|
4913
|
-
private _exit: MicroExit<A, E> | undefined = undefined
|
|
4914
|
-
_controller: AbortController
|
|
4915
|
-
readonly isRoot: boolean
|
|
4916
|
-
|
|
4917
|
-
constructor(readonly parentSignal: AbortSignal, controller?: AbortController) {
|
|
4918
|
-
super()
|
|
4919
|
-
this[HandleTypeId] = HandleTypeId
|
|
4920
|
-
this.isRoot = controller !== undefined
|
|
4921
|
-
this._controller = controller ?? new AbortController()
|
|
4922
|
-
if (!this.isRoot) {
|
|
4923
|
-
parentSignal.addEventListener("abort", this.unsafeInterrupt)
|
|
4924
|
-
}
|
|
4925
|
-
}
|
|
4926
|
-
|
|
4927
|
-
unsafePoll(): MicroExit<A, E> | null {
|
|
4928
|
-
return this._exit ?? null
|
|
4929
|
-
}
|
|
4930
|
-
|
|
4931
|
-
unsafeInterrupt = () => {
|
|
4932
|
-
this._controller.abort()
|
|
4933
|
-
}
|
|
4934
|
-
|
|
4935
|
-
emit(exit: MicroExit<A, E>): void {
|
|
4936
|
-
if (this._exit) {
|
|
4937
|
-
return
|
|
4938
|
-
}
|
|
4939
|
-
this._exit = exit
|
|
4940
|
-
if (!this.isRoot) {
|
|
4941
|
-
this.parentSignal.removeEventListener("abort", this.unsafeInterrupt)
|
|
4942
|
-
}
|
|
4943
|
-
this.observers.forEach((observer) => observer(exit))
|
|
4944
|
-
this.observers.clear()
|
|
4945
|
-
}
|
|
4946
|
-
|
|
4947
|
-
addObserver(observer: (exit: MicroExit<A, E>) => void): void {
|
|
4948
|
-
if (this._exit) {
|
|
4949
|
-
return observer(this._exit)
|
|
4950
|
-
}
|
|
4951
|
-
this.observers.add(observer)
|
|
4952
|
-
}
|
|
4953
|
-
|
|
4954
|
-
removeObserver(observer: (exit: MicroExit<A, E>) => void): void {
|
|
4955
|
-
this.observers.delete(observer)
|
|
4956
|
-
}
|
|
4957
|
-
|
|
4958
|
-
get await(): Micro<MicroExit<A, E>> {
|
|
4959
|
-
return suspend(() => {
|
|
4960
|
-
if (this._exit) {
|
|
4961
|
-
return succeed(this._exit)
|
|
4962
|
-
}
|
|
4963
|
-
return async((resume) => {
|
|
4964
|
-
function observer(exit: MicroExit<A, E>) {
|
|
4965
|
-
resume(succeed(exit))
|
|
4966
|
-
}
|
|
4967
|
-
this.addObserver(observer)
|
|
4968
|
-
return sync(() => {
|
|
4969
|
-
this.removeObserver(observer)
|
|
4970
|
-
})
|
|
4971
|
-
})
|
|
4972
|
-
})
|
|
4973
|
-
}
|
|
4974
|
-
|
|
4975
|
-
get join(): Micro<A, E> {
|
|
4976
|
-
return flatMap(this.await, fromExit)
|
|
4977
|
-
}
|
|
4978
|
-
|
|
4979
|
-
get interrupt(): Micro<MicroExit<A, E>> {
|
|
4980
|
-
return suspend(() => {
|
|
4981
|
-
this.unsafeInterrupt()
|
|
4982
|
-
return this.await
|
|
4983
|
-
})
|
|
4984
|
-
}
|
|
4985
|
-
|
|
4986
|
-
asMicro(): Micro<A, E> {
|
|
4987
|
-
return this.join
|
|
4988
|
-
}
|
|
4989
|
-
}
|
|
4990
|
-
|
|
4991
5255
|
/**
|
|
4992
5256
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
4993
5257
|
* aborted.
|
|
@@ -4998,23 +5262,33 @@ class HandleImpl<A, E> extends Class<A, E> implements Handle<A, E> {
|
|
|
4998
5262
|
* @experimental
|
|
4999
5263
|
* @category handle & forking
|
|
5000
5264
|
*/
|
|
5001
|
-
export const fork = <A, E, R>(
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
map[currentAbortSignal.key] = handle._controller.signal
|
|
5008
|
-
return map
|
|
5009
|
-
})
|
|
5010
|
-
envGet(env, currentScheduler).scheduleTask(() => {
|
|
5011
|
-
self[runSymbol](nextEnv, (exit) => {
|
|
5012
|
-
handle.emit(exit)
|
|
5013
|
-
})
|
|
5014
|
-
}, 0)
|
|
5015
|
-
onExit(Either.right(handle))
|
|
5265
|
+
export const fork = <A, E, R>(
|
|
5266
|
+
self: Micro<A, E, R>
|
|
5267
|
+
): Micro<Fiber<A, E>, never, R> =>
|
|
5268
|
+
withFiber((fiber) => {
|
|
5269
|
+
fiberMiddleware.interruptChildren ??= fiberInterruptChildren
|
|
5270
|
+
return succeed(unsafeFork(fiber, self))
|
|
5016
5271
|
})
|
|
5017
5272
|
|
|
5273
|
+
const unsafeFork = <FA, FE, A, E, R>(
|
|
5274
|
+
parent: FiberImpl<FA, FE>,
|
|
5275
|
+
effect: Micro<A, E, R>,
|
|
5276
|
+
immediate = false,
|
|
5277
|
+
daemon = false
|
|
5278
|
+
): Fiber<A, E> => {
|
|
5279
|
+
const child = new FiberImpl<A, E>(parent.context, parent.interruptible)
|
|
5280
|
+
if (!daemon) {
|
|
5281
|
+
parent.children().add(child)
|
|
5282
|
+
child.addObserver(() => parent.children().delete(child))
|
|
5283
|
+
}
|
|
5284
|
+
if (immediate) {
|
|
5285
|
+
child.evaluate(effect as any)
|
|
5286
|
+
} else {
|
|
5287
|
+
parent.getRef(CurrentScheduler).scheduleTask(() => child.evaluate(effect as any), 0)
|
|
5288
|
+
}
|
|
5289
|
+
return child
|
|
5290
|
+
}
|
|
5291
|
+
|
|
5018
5292
|
/**
|
|
5019
5293
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
5020
5294
|
* aborted.
|
|
@@ -5025,22 +5299,9 @@ export const fork = <A, E, R>(self: Micro<A, E, R>): Micro<Handle<A, E>, never,
|
|
|
5025
5299
|
* @experimental
|
|
5026
5300
|
* @category handle & forking
|
|
5027
5301
|
*/
|
|
5028
|
-
export const forkDaemon = <A, E, R>(
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
const handle = new HandleImpl<A, E>(controller.signal, controller)
|
|
5032
|
-
const nextEnv = envMutate(env, (map) => {
|
|
5033
|
-
map[currentAbortController.key] = controller
|
|
5034
|
-
map[currentAbortSignal.key] = controller.signal
|
|
5035
|
-
return map
|
|
5036
|
-
})
|
|
5037
|
-
envGet(env, currentScheduler).scheduleTask(() => {
|
|
5038
|
-
self[runSymbol](nextEnv, (exit) => {
|
|
5039
|
-
handle.emit(exit)
|
|
5040
|
-
})
|
|
5041
|
-
}, 0)
|
|
5042
|
-
onExit(Either.right(handle))
|
|
5043
|
-
})
|
|
5302
|
+
export const forkDaemon = <A, E, R>(
|
|
5303
|
+
self: Micro<A, E, R>
|
|
5304
|
+
): Micro<Fiber<A, E>, never, R> => withFiber((fiber) => succeed(unsafeFork(fiber, self, false, true)))
|
|
5044
5305
|
|
|
5045
5306
|
/**
|
|
5046
5307
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
@@ -5063,7 +5324,7 @@ export const forkIn: {
|
|
|
5063
5324
|
* @experimental
|
|
5064
5325
|
* @category handle & forking
|
|
5065
5326
|
*/
|
|
5066
|
-
(scope: MicroScope): <A, E, R>(self: Micro<A, E, R>) => Micro<
|
|
5327
|
+
(scope: MicroScope): <A, E, R>(self: Micro<A, E, R>) => Micro<Fiber<A, E>, never, R>
|
|
5067
5328
|
/**
|
|
5068
5329
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
5069
5330
|
* aborted.
|
|
@@ -5074,15 +5335,15 @@ export const forkIn: {
|
|
|
5074
5335
|
* @experimental
|
|
5075
5336
|
* @category handle & forking
|
|
5076
5337
|
*/
|
|
5077
|
-
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<
|
|
5338
|
+
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<Fiber<A, E>, never, R>
|
|
5078
5339
|
} = dual(
|
|
5079
5340
|
2,
|
|
5080
|
-
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<
|
|
5341
|
+
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<Fiber<A, E>, never, R> =>
|
|
5081
5342
|
uninterruptibleMask((restore) =>
|
|
5082
5343
|
flatMap(scope.fork, (scope) =>
|
|
5083
5344
|
tap(
|
|
5084
5345
|
restore(forkDaemon(onExit(self, (exit) => scope.close(exit)))),
|
|
5085
|
-
(fiber) => scope.addFinalizer((_) =>
|
|
5346
|
+
(fiber) => scope.addFinalizer((_) => fiberInterrupt(fiber))
|
|
5086
5347
|
))
|
|
5087
5348
|
)
|
|
5088
5349
|
)
|
|
@@ -5097,7 +5358,7 @@ export const forkIn: {
|
|
|
5097
5358
|
* @experimental
|
|
5098
5359
|
* @category handle & forking
|
|
5099
5360
|
*/
|
|
5100
|
-
export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<
|
|
5361
|
+
export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<Fiber<A, E>, never, R | MicroScope> =>
|
|
5101
5362
|
flatMap(scope, (scope) => forkIn(self, scope))
|
|
5102
5363
|
|
|
5103
5364
|
// ----------------------------------------------------------------------------
|
|
@@ -5134,28 +5395,21 @@ export const runFork = <A, E>(
|
|
|
5134
5395
|
readonly signal?: AbortSignal | undefined
|
|
5135
5396
|
readonly scheduler?: MicroScheduler | undefined
|
|
5136
5397
|
} | undefined
|
|
5137
|
-
):
|
|
5138
|
-
const
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
refs[currentScheduler.key] = options?.scheduler ?? new MicroSchedulerDefault()
|
|
5143
|
-
const env = envMake(refs)
|
|
5144
|
-
const handle = new HandleImpl<A, E>(controller.signal, controller)
|
|
5145
|
-
effect[runSymbol](envSet(env, currentAbortSignal, handle._controller.signal), (exit) => {
|
|
5146
|
-
handle.emit(exit)
|
|
5147
|
-
if (options?.signal) {
|
|
5148
|
-
options.signal.removeEventListener("abort", handle.unsafeInterrupt)
|
|
5149
|
-
}
|
|
5150
|
-
})
|
|
5398
|
+
): FiberImpl<A, E> => {
|
|
5399
|
+
const fiber = new FiberImpl<A, E>(CurrentScheduler.context(
|
|
5400
|
+
options?.scheduler ?? new MicroSchedulerDefault()
|
|
5401
|
+
))
|
|
5402
|
+
fiber.evaluate(effect as any)
|
|
5151
5403
|
if (options?.signal) {
|
|
5152
5404
|
if (options.signal.aborted) {
|
|
5153
|
-
|
|
5405
|
+
fiber.unsafeInterrupt()
|
|
5154
5406
|
} else {
|
|
5155
|
-
|
|
5407
|
+
const abort = () => fiber.unsafeInterrupt()
|
|
5408
|
+
options.signal.addEventListener("abort", abort, { once: true })
|
|
5409
|
+
fiber.addObserver(() => options.signal!.removeEventListener("abort", abort))
|
|
5156
5410
|
}
|
|
5157
5411
|
}
|
|
5158
|
-
return
|
|
5412
|
+
return fiber
|
|
5159
5413
|
}
|
|
5160
5414
|
|
|
5161
5415
|
/**
|
|
@@ -5194,10 +5448,10 @@ export const runPromise = <A, E>(
|
|
|
5194
5448
|
} | undefined
|
|
5195
5449
|
): Promise<A> =>
|
|
5196
5450
|
runPromiseExit(effect, options).then((exit) => {
|
|
5197
|
-
if (exit._tag === "
|
|
5198
|
-
throw exit.
|
|
5451
|
+
if (exit._tag === "Failure") {
|
|
5452
|
+
throw exit.cause
|
|
5199
5453
|
}
|
|
5200
|
-
return exit.
|
|
5454
|
+
return exit.value
|
|
5201
5455
|
})
|
|
5202
5456
|
|
|
5203
5457
|
/**
|
|
@@ -5212,13 +5466,9 @@ export const runPromise = <A, E>(
|
|
|
5212
5466
|
*/
|
|
5213
5467
|
export const runSyncExit = <A, E>(effect: Micro<A, E>): MicroExit<A, E> => {
|
|
5214
5468
|
const scheduler = new MicroSchedulerDefault()
|
|
5215
|
-
const
|
|
5469
|
+
const fiber = runFork(effect, { scheduler })
|
|
5216
5470
|
scheduler.flush()
|
|
5217
|
-
|
|
5218
|
-
if (exit === null) {
|
|
5219
|
-
return exitDie(handle)
|
|
5220
|
-
}
|
|
5221
|
-
return exit
|
|
5471
|
+
return fiber._exit ?? exitDie(fiber)
|
|
5222
5472
|
}
|
|
5223
5473
|
|
|
5224
5474
|
/**
|
|
@@ -5231,10 +5481,8 @@ export const runSyncExit = <A, E>(effect: Micro<A, E>): MicroExit<A, E> => {
|
|
|
5231
5481
|
*/
|
|
5232
5482
|
export const runSync = <A, E>(effect: Micro<A, E>): A => {
|
|
5233
5483
|
const exit = runSyncExit(effect)
|
|
5234
|
-
if (exit._tag === "
|
|
5235
|
-
|
|
5236
|
-
}
|
|
5237
|
-
return exit.right
|
|
5484
|
+
if (exit._tag === "Failure") throw exit.cause
|
|
5485
|
+
return exit.value
|
|
5238
5486
|
}
|
|
5239
5487
|
|
|
5240
5488
|
// ----------------------------------------------------------------------------
|
|
@@ -5247,35 +5495,35 @@ export const runSync = <A, E>(effect: Micro<A, E>): A => {
|
|
|
5247
5495
|
* @category errors
|
|
5248
5496
|
*/
|
|
5249
5497
|
export interface YieldableError extends Pipeable, Inspectable, Readonly<Error> {
|
|
5250
|
-
readonly [EffectTypeId]: Effect.VarianceStruct<never, this, never>
|
|
5251
|
-
readonly [StreamTypeId]: Stream.VarianceStruct<never, this, never>
|
|
5252
|
-
readonly [SinkTypeId]: Sink.VarianceStruct<never, unknown, never, this, never>
|
|
5253
|
-
readonly [ChannelTypeId]: Channel.VarianceStruct<never, unknown, this, unknown, never, unknown, never>
|
|
5498
|
+
readonly [Effectable.EffectTypeId]: Effect.VarianceStruct<never, this, never>
|
|
5499
|
+
readonly [Effectable.StreamTypeId]: Stream.VarianceStruct<never, this, never>
|
|
5500
|
+
readonly [Effectable.SinkTypeId]: Sink.VarianceStruct<never, unknown, never, this, never>
|
|
5501
|
+
readonly [Effectable.ChannelTypeId]: Channel.VarianceStruct<never, unknown, this, unknown, never, unknown, never>
|
|
5254
5502
|
readonly [TypeId]: Micro.Variance<never, this, never>
|
|
5255
|
-
readonly [runSymbol]: (env: Env<any>, onExit: (exit: MicroExit<never, this>) => void) => void
|
|
5256
5503
|
[Symbol.iterator](): MicroIterator<Micro<never, this, never>>
|
|
5257
5504
|
}
|
|
5258
5505
|
|
|
5259
5506
|
const YieldableError: new(message?: string) => YieldableError = (function() {
|
|
5260
|
-
class YieldableError extends globalThis.Error {
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5507
|
+
class YieldableError extends globalThis.Error {}
|
|
5508
|
+
Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype, {
|
|
5509
|
+
[identifier]: "Failure",
|
|
5510
|
+
[evaluate]() {
|
|
5511
|
+
return fail(this)
|
|
5512
|
+
},
|
|
5513
|
+
toString(this: Error) {
|
|
5265
5514
|
return this.message ? `${this.name}: ${this.message}` : this.name
|
|
5266
|
-
}
|
|
5515
|
+
},
|
|
5267
5516
|
toJSON() {
|
|
5268
5517
|
return { ...this }
|
|
5269
|
-
}
|
|
5270
|
-
[NodeInspectSymbol](): string {
|
|
5518
|
+
},
|
|
5519
|
+
[NodeInspectSymbol](this: Error): string {
|
|
5271
5520
|
const stack = this.stack
|
|
5272
5521
|
if (stack) {
|
|
5273
5522
|
return `${this.toString()}\n${stack.split("\n").slice(1).join("\n")}`
|
|
5274
5523
|
}
|
|
5275
5524
|
return this.toString()
|
|
5276
5525
|
}
|
|
5277
|
-
}
|
|
5278
|
-
Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype)
|
|
5526
|
+
})
|
|
5279
5527
|
return YieldableError as any
|
|
5280
5528
|
})()
|
|
5281
5529
|
|