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