@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SourceLocation/package.json +6 -0
- package/dist/cjs/Effect.js +2 -28
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/FiberRef.js +12 -1
- package/dist/cjs/FiberRef.js.map +1 -1
- package/dist/cjs/Layer.js +2 -24
- package/dist/cjs/Layer.js.map +1 -1
- package/dist/cjs/RuntimeFlags.js +1 -29
- package/dist/cjs/RuntimeFlags.js.map +1 -1
- package/dist/cjs/SourceLocation.js +60 -0
- package/dist/cjs/SourceLocation.js.map +1 -0
- package/dist/cjs/Tracer.js +1 -15
- package/dist/cjs/Tracer.js.map +1 -1
- package/dist/cjs/Utils.js +1 -1
- package/dist/cjs/Utils.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/clock.js +1 -1
- package/dist/cjs/internal/clock.js.map +1 -1
- package/dist/cjs/internal/core.js +17 -50
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +18 -30
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +16 -65
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/layer/circular.js +1 -5
- package/dist/cjs/internal/layer/circular.js.map +1 -1
- package/dist/cjs/internal/layer.js +1 -3
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/logger.js +25 -2
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/runtimeFlags.js +2 -11
- package/dist/cjs/internal/runtimeFlags.js.map +1 -1
- package/dist/cjs/internal/tracer.js +1 -114
- package/dist/cjs/internal/tracer.js.map +1 -1
- package/dist/dts/Config.d.ts +2 -2
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +8 -29
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/FiberRef.d.ts +12 -0
- package/dist/dts/FiberRef.d.ts.map +1 -1
- package/dist/dts/Layer.d.ts +0 -22
- package/dist/dts/Layer.d.ts.map +1 -1
- package/dist/dts/RuntimeFlags.d.ts +0 -28
- package/dist/dts/RuntimeFlags.d.ts.map +1 -1
- package/dist/dts/SourceLocation.d.ts +88 -0
- package/dist/dts/SourceLocation.d.ts.map +1 -0
- package/dist/dts/Tracer.d.ts +0 -15
- package/dist/dts/Tracer.d.ts.map +1 -1
- package/dist/dts/index.d.ts +6 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/core.d.ts.map +1 -1
- package/dist/dts/internal/layer.d.ts.map +1 -1
- package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
- package/dist/esm/Effect.js +0 -26
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/FiberRef.js +11 -0
- package/dist/esm/FiberRef.js.map +1 -1
- package/dist/esm/Layer.js +0 -22
- package/dist/esm/Layer.js.map +1 -1
- package/dist/esm/RuntimeFlags.js +0 -28
- package/dist/esm/RuntimeFlags.js.map +1 -1
- package/dist/esm/SourceLocation.js +51 -0
- package/dist/esm/SourceLocation.js.map +1 -0
- package/dist/esm/Tracer.js +0 -14
- package/dist/esm/Tracer.js.map +1 -1
- package/dist/esm/Utils.js +1 -1
- package/dist/esm/Utils.js.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/clock.js +1 -1
- package/dist/esm/internal/clock.js.map +1 -1
- package/dist/esm/internal/core.js +12 -45
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +18 -30
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +13 -60
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/layer/circular.js +0 -4
- package/dist/esm/internal/layer/circular.js.map +1 -1
- package/dist/esm/internal/layer.js +0 -2
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/logger.js +25 -2
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/runtimeFlags.js +1 -9
- package/dist/esm/internal/runtimeFlags.js.map +1 -1
- package/dist/esm/internal/tracer.js +0 -111
- package/dist/esm/internal/tracer.js.map +1 -1
- package/package.json +12 -1
- package/src/Arbitrary.ts +1101 -0
- package/src/Array.ts +3589 -0
- package/src/BigDecimal.ts +1349 -0
- package/src/BigInt.ts +643 -0
- package/src/Boolean.ts +287 -0
- package/src/Brand.ts +360 -0
- package/src/Cache.ts +281 -0
- package/src/Cause.ts +1555 -0
- package/src/Channel.ts +2355 -0
- package/src/ChildExecutorDecision.ts +146 -0
- package/src/Chunk.ts +1495 -0
- package/src/Clock.ts +111 -0
- package/src/Config.ts +542 -0
- package/src/ConfigError.ts +270 -0
- package/src/ConfigProvider.ts +333 -0
- package/src/ConfigProviderPathPatch.ts +100 -0
- package/src/Console.ts +226 -0
- package/src/Context.ts +585 -0
- package/src/Cron.ts +706 -0
- package/src/Data.ts +596 -0
- package/src/DateTime.ts +1686 -0
- package/src/DefaultServices.ts +34 -0
- package/src/Deferred.ts +301 -0
- package/src/Differ.ts +450 -0
- package/src/Duration.ts +1000 -0
- package/src/Effect.ts +14817 -0
- package/src/Effectable.ts +107 -0
- package/src/Either.ts +1040 -0
- package/src/Encoding.ts +195 -0
- package/src/Equal.ts +98 -0
- package/src/Equivalence.ts +235 -0
- package/src/ExecutionPlan.ts +308 -0
- package/src/ExecutionStrategy.ts +119 -0
- package/src/Exit.ts +467 -0
- package/src/FastCheck.ts +9 -0
- package/src/Fiber.ts +744 -0
- package/src/FiberHandle.ts +540 -0
- package/src/FiberId.ts +195 -0
- package/src/FiberMap.ts +656 -0
- package/src/FiberRef.ts +444 -0
- package/src/FiberRefs.ts +204 -0
- package/src/FiberRefsPatch.ts +105 -0
- package/src/FiberSet.ts +491 -0
- package/src/FiberStatus.ts +108 -0
- package/src/Function.ts +1222 -0
- package/src/GlobalValue.ts +53 -0
- package/src/Graph.ts +3732 -0
- package/src/GroupBy.ts +103 -0
- package/src/HKT.ts +45 -0
- package/src/Hash.ts +195 -0
- package/src/HashMap.ts +519 -0
- package/src/HashRing.ts +317 -0
- package/src/HashSet.ts +2346 -0
- package/src/Inspectable.ts +287 -0
- package/src/Iterable.ts +1119 -0
- package/src/JSONSchema.ts +1044 -0
- package/src/KeyedPool.ts +167 -0
- package/src/Layer.ts +1228 -0
- package/src/LayerMap.ts +436 -0
- package/src/List.ts +977 -0
- package/src/LogLevel.ts +285 -0
- package/src/LogSpan.ts +25 -0
- package/src/Logger.ts +702 -0
- package/src/Mailbox.ts +268 -0
- package/src/ManagedRuntime.ts +180 -0
- package/src/Match.ts +1477 -0
- package/src/MergeDecision.ts +95 -0
- package/src/MergeState.ts +172 -0
- package/src/MergeStrategy.ts +107 -0
- package/src/Metric.ts +780 -0
- package/src/MetricBoundaries.ts +69 -0
- package/src/MetricHook.ts +151 -0
- package/src/MetricKey.ts +224 -0
- package/src/MetricKeyType.ts +262 -0
- package/src/MetricLabel.ts +47 -0
- package/src/MetricPair.ts +71 -0
- package/src/MetricPolling.ts +148 -0
- package/src/MetricRegistry.ts +48 -0
- package/src/MetricState.ts +257 -0
- package/src/Micro.ts +4405 -0
- package/src/ModuleVersion.ts +18 -0
- package/src/MutableHashMap.ts +411 -0
- package/src/MutableHashSet.ts +706 -0
- package/src/MutableList.ts +297 -0
- package/src/MutableQueue.ts +227 -0
- package/src/MutableRef.ts +202 -0
- package/src/NonEmptyIterable.ts +32 -0
- package/src/Number.ts +1071 -0
- package/src/Option.ts +2170 -0
- package/src/Order.ts +373 -0
- package/src/Ordering.ts +111 -0
- package/src/ParseResult.ts +2031 -0
- package/src/PartitionedSemaphore.ts +200 -0
- package/src/Pipeable.ts +566 -0
- package/src/Pool.ts +204 -0
- package/src/Predicate.ts +1405 -0
- package/src/Pretty.ts +205 -0
- package/src/PrimaryKey.ts +23 -0
- package/src/PubSub.ts +182 -0
- package/src/Queue.ts +644 -0
- package/src/Random.ts +204 -0
- package/src/RateLimiter.ts +138 -0
- package/src/RcMap.ts +141 -0
- package/src/RcRef.ts +122 -0
- package/src/Readable.ts +93 -0
- package/src/Record.ts +1274 -0
- package/src/RedBlackTree.ts +421 -0
- package/src/Redacted.ts +144 -0
- package/src/Ref.ts +180 -0
- package/src/RegExp.ts +38 -0
- package/src/Reloadable.ts +127 -0
- package/src/Request.ts +347 -0
- package/src/RequestBlock.ts +118 -0
- package/src/RequestResolver.ts +366 -0
- package/src/Resource.ts +119 -0
- package/src/Runtime.ts +383 -0
- package/src/RuntimeFlags.ts +336 -0
- package/src/RuntimeFlagsPatch.ts +183 -0
- package/src/STM.ts +2045 -0
- package/src/Schedule.ts +2219 -0
- package/src/ScheduleDecision.ts +62 -0
- package/src/ScheduleInterval.ts +151 -0
- package/src/ScheduleIntervals.ts +122 -0
- package/src/Scheduler.ts +353 -0
- package/src/Schema.ts +10914 -0
- package/src/SchemaAST.ts +3043 -0
- package/src/Scope.ts +204 -0
- package/src/ScopedCache.ts +151 -0
- package/src/ScopedRef.ts +117 -0
- package/src/Secret.ts +88 -0
- package/src/SingleProducerAsyncInput.ts +67 -0
- package/src/Sink.ts +1461 -0
- package/src/SortedMap.ts +287 -0
- package/src/SortedSet.ts +390 -0
- package/src/SourceLocation.ts +108 -0
- package/src/Stream.ts +6468 -0
- package/src/StreamEmit.ts +136 -0
- package/src/StreamHaltStrategy.ts +123 -0
- package/src/Streamable.ts +45 -0
- package/src/String.ts +778 -0
- package/src/Struct.ts +243 -0
- package/src/Subscribable.ts +100 -0
- package/src/SubscriptionRef.ts +298 -0
- package/src/Supervisor.ts +240 -0
- package/src/Symbol.ts +29 -0
- package/src/SynchronizedRef.ts +270 -0
- package/src/TArray.ts +495 -0
- package/src/TDeferred.ts +100 -0
- package/src/TMap.ts +515 -0
- package/src/TPriorityQueue.ts +223 -0
- package/src/TPubSub.ts +200 -0
- package/src/TQueue.ts +432 -0
- package/src/TRandom.ts +129 -0
- package/src/TReentrantLock.ts +224 -0
- package/src/TRef.ts +178 -0
- package/src/TSemaphore.ts +129 -0
- package/src/TSet.ts +365 -0
- package/src/TSubscriptionRef.ts +192 -0
- package/src/Take.ts +258 -0
- package/src/TestAnnotation.ts +158 -0
- package/src/TestAnnotationMap.ts +119 -0
- package/src/TestAnnotations.ts +117 -0
- package/src/TestClock.ts +556 -0
- package/src/TestConfig.ts +47 -0
- package/src/TestContext.ts +36 -0
- package/src/TestLive.ts +53 -0
- package/src/TestServices.ts +390 -0
- package/src/TestSized.ts +55 -0
- package/src/Tracer.ts +182 -0
- package/src/Trie.ts +840 -0
- package/src/Tuple.ts +305 -0
- package/src/Types.ts +353 -0
- package/src/Unify.ts +113 -0
- package/src/UpstreamPullRequest.ts +117 -0
- package/src/UpstreamPullStrategy.ts +121 -0
- package/src/Utils.ts +809 -0
- package/src/index.ts +1568 -0
- package/src/internal/array.ts +8 -0
- package/src/internal/blockedRequests.ts +520 -0
- package/src/internal/cache.ts +733 -0
- package/src/internal/cause.ts +1050 -0
- package/src/internal/channel/channelExecutor.ts +1200 -0
- package/src/internal/channel/channelState.ts +134 -0
- package/src/internal/channel/childExecutorDecision.ts +96 -0
- package/src/internal/channel/continuation.ts +200 -0
- package/src/internal/channel/mergeDecision.ts +113 -0
- package/src/internal/channel/mergeState.ts +120 -0
- package/src/internal/channel/mergeStrategy.ts +72 -0
- package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
- package/src/internal/channel/subexecutor.ts +229 -0
- package/src/internal/channel/upstreamPullRequest.ts +84 -0
- package/src/internal/channel/upstreamPullStrategy.ts +87 -0
- package/src/internal/channel.ts +2603 -0
- package/src/internal/clock.ts +95 -0
- package/src/internal/completedRequestMap.ts +9 -0
- package/src/internal/concurrency.ts +54 -0
- package/src/internal/config.ts +716 -0
- package/src/internal/configError.ts +304 -0
- package/src/internal/configProvider/pathPatch.ts +97 -0
- package/src/internal/configProvider.ts +799 -0
- package/src/internal/console.ts +153 -0
- package/src/internal/context.ts +337 -0
- package/src/internal/core-effect.ts +2293 -0
- package/src/internal/core-stream.ts +998 -0
- package/src/internal/core.ts +3189 -0
- package/src/internal/data.ts +36 -0
- package/src/internal/dataSource.ts +327 -0
- package/src/internal/dateTime.ts +1277 -0
- package/src/internal/defaultServices/console.ts +100 -0
- package/src/internal/defaultServices.ts +163 -0
- package/src/internal/deferred.ts +46 -0
- package/src/internal/differ/chunkPatch.ts +211 -0
- package/src/internal/differ/contextPatch.ts +232 -0
- package/src/internal/differ/hashMapPatch.ts +220 -0
- package/src/internal/differ/hashSetPatch.ts +176 -0
- package/src/internal/differ/orPatch.ts +311 -0
- package/src/internal/differ/readonlyArrayPatch.ts +210 -0
- package/src/internal/differ.ts +200 -0
- package/src/internal/doNotation.ts +80 -0
- package/src/internal/effect/circular.ts +895 -0
- package/src/internal/effectable.ts +131 -0
- package/src/internal/either.ts +110 -0
- package/src/internal/encoding/base64.ts +286 -0
- package/src/internal/encoding/base64Url.ts +29 -0
- package/src/internal/encoding/common.ts +51 -0
- package/src/internal/encoding/hex.ts +315 -0
- package/src/internal/errors.ts +7 -0
- package/src/internal/executionPlan.ts +114 -0
- package/src/internal/executionStrategy.ts +74 -0
- package/src/internal/fiber.ts +388 -0
- package/src/internal/fiberId.ts +267 -0
- package/src/internal/fiberMessage.ts +82 -0
- package/src/internal/fiberRefs/patch.ts +144 -0
- package/src/internal/fiberRefs.ts +297 -0
- package/src/internal/fiberRuntime.ts +3842 -0
- package/src/internal/fiberScope.ts +71 -0
- package/src/internal/fiberStatus.ts +119 -0
- package/src/internal/groupBy.ts +530 -0
- package/src/internal/hashMap/array.ts +49 -0
- package/src/internal/hashMap/bitwise.ts +32 -0
- package/src/internal/hashMap/config.ts +14 -0
- package/src/internal/hashMap/keySet.ts +8 -0
- package/src/internal/hashMap/node.ts +391 -0
- package/src/internal/hashMap.ts +586 -0
- package/src/internal/hashSet.ts +323 -0
- package/src/internal/keyedPool.ts +244 -0
- package/src/internal/layer/circular.ts +214 -0
- package/src/internal/layer.ts +1483 -0
- package/src/internal/logSpan.ts +20 -0
- package/src/internal/logger-circular.ts +24 -0
- package/src/internal/logger.ts +522 -0
- package/src/internal/mailbox.ts +561 -0
- package/src/internal/managedRuntime/circular.ts +6 -0
- package/src/internal/managedRuntime.ts +134 -0
- package/src/internal/matcher.ts +652 -0
- package/src/internal/metric/boundaries.ts +75 -0
- package/src/internal/metric/hook.ts +483 -0
- package/src/internal/metric/key.ts +167 -0
- package/src/internal/metric/keyType.ts +238 -0
- package/src/internal/metric/label.ts +41 -0
- package/src/internal/metric/pair.ts +48 -0
- package/src/internal/metric/polling.ts +149 -0
- package/src/internal/metric/registry.ts +187 -0
- package/src/internal/metric/state.ts +290 -0
- package/src/internal/metric.ts +577 -0
- package/src/internal/opCodes/cause.ts +35 -0
- package/src/internal/opCodes/channel.ts +83 -0
- package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
- package/src/internal/opCodes/channelMergeDecision.ts +11 -0
- package/src/internal/opCodes/channelMergeState.ts +17 -0
- package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
- package/src/internal/opCodes/channelState.ts +23 -0
- package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
- package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
- package/src/internal/opCodes/config.ts +65 -0
- package/src/internal/opCodes/configError.ts +35 -0
- package/src/internal/opCodes/continuation.ts +11 -0
- package/src/internal/opCodes/deferred.ts +11 -0
- package/src/internal/opCodes/effect.ts +89 -0
- package/src/internal/opCodes/layer.ts +59 -0
- package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
- package/src/internal/option.ts +80 -0
- package/src/internal/pool.ts +432 -0
- package/src/internal/pubsub.ts +1762 -0
- package/src/internal/query.ts +204 -0
- package/src/internal/queue.ts +766 -0
- package/src/internal/random.ts +161 -0
- package/src/internal/rateLimiter.ts +93 -0
- package/src/internal/rcMap.ts +285 -0
- package/src/internal/rcRef.ts +192 -0
- package/src/internal/redBlackTree/iterator.ts +200 -0
- package/src/internal/redBlackTree/node.ts +68 -0
- package/src/internal/redBlackTree.ts +1245 -0
- package/src/internal/redacted.ts +73 -0
- package/src/internal/ref.ts +171 -0
- package/src/internal/reloadable.ts +140 -0
- package/src/internal/request.ts +177 -0
- package/src/internal/resource.ts +76 -0
- package/src/internal/ringBuffer.ts +68 -0
- package/src/internal/runtime.ts +558 -0
- package/src/internal/runtimeFlags.ts +178 -0
- package/src/internal/runtimeFlagsPatch.ts +103 -0
- package/src/internal/schedule/decision.ts +47 -0
- package/src/internal/schedule/interval.ts +101 -0
- package/src/internal/schedule/intervals.ts +180 -0
- package/src/internal/schedule.ts +2199 -0
- package/src/internal/schema/errors.ts +191 -0
- package/src/internal/schema/schemaId.ts +106 -0
- package/src/internal/schema/util.ts +50 -0
- package/src/internal/scopedCache.ts +644 -0
- package/src/internal/scopedRef.ts +118 -0
- package/src/internal/secret.ts +89 -0
- package/src/internal/singleShotGen.ts +35 -0
- package/src/internal/sink.ts +2120 -0
- package/src/internal/stack.ts +10 -0
- package/src/internal/stm/core.ts +817 -0
- package/src/internal/stm/entry.ts +59 -0
- package/src/internal/stm/journal.ts +123 -0
- package/src/internal/stm/opCodes/stm.ts +71 -0
- package/src/internal/stm/opCodes/stmState.ts +17 -0
- package/src/internal/stm/opCodes/strategy.ts +17 -0
- package/src/internal/stm/opCodes/tExit.ts +29 -0
- package/src/internal/stm/opCodes/tryCommit.ts +11 -0
- package/src/internal/stm/stm.ts +1453 -0
- package/src/internal/stm/stmState.ts +136 -0
- package/src/internal/stm/tArray.ts +550 -0
- package/src/internal/stm/tDeferred.ts +81 -0
- package/src/internal/stm/tExit.ts +190 -0
- package/src/internal/stm/tMap.ts +824 -0
- package/src/internal/stm/tPriorityQueue.ts +267 -0
- package/src/internal/stm/tPubSub.ts +551 -0
- package/src/internal/stm/tQueue.ts +393 -0
- package/src/internal/stm/tRandom.ts +140 -0
- package/src/internal/stm/tReentrantLock.ts +352 -0
- package/src/internal/stm/tRef.ts +195 -0
- package/src/internal/stm/tSemaphore.ts +113 -0
- package/src/internal/stm/tSet.ts +259 -0
- package/src/internal/stm/tSubscriptionRef.ts +286 -0
- package/src/internal/stm/tryCommit.ts +34 -0
- package/src/internal/stm/txnId.ts +14 -0
- package/src/internal/stm/versioned.ts +4 -0
- package/src/internal/stream/debounceState.ts +57 -0
- package/src/internal/stream/emit.ts +123 -0
- package/src/internal/stream/haltStrategy.ts +94 -0
- package/src/internal/stream/handoff.ts +187 -0
- package/src/internal/stream/handoffSignal.ts +59 -0
- package/src/internal/stream/pull.ts +34 -0
- package/src/internal/stream/sinkEndReason.ts +30 -0
- package/src/internal/stream/zipAllState.ts +88 -0
- package/src/internal/stream/zipChunksState.ts +56 -0
- package/src/internal/stream.ts +8801 -0
- package/src/internal/string-utils.ts +107 -0
- package/src/internal/subscriptionRef.ts +138 -0
- package/src/internal/supervisor/patch.ts +190 -0
- package/src/internal/supervisor.ts +303 -0
- package/src/internal/synchronizedRef.ts +114 -0
- package/src/internal/take.ts +199 -0
- package/src/internal/testing/sleep.ts +27 -0
- package/src/internal/testing/suspendedWarningData.ts +85 -0
- package/src/internal/testing/warningData.ts +94 -0
- package/src/internal/tracer.ts +150 -0
- package/src/internal/trie.ts +722 -0
- package/src/internal/version.ts +7 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import * as Effect from "../../Effect.js"
|
|
2
|
+
import * as Equal from "../../Equal.js"
|
|
3
|
+
import * as FiberId from "../../FiberId.js"
|
|
4
|
+
import { dual } from "../../Function.js"
|
|
5
|
+
import * as HashMap from "../../HashMap.js"
|
|
6
|
+
import * as Option from "../../Option.js"
|
|
7
|
+
import type * as Scope from "../../Scope.js"
|
|
8
|
+
import type * as STM from "../../STM.js"
|
|
9
|
+
import type * as TReentrantLock from "../../TReentrantLock.js"
|
|
10
|
+
import type * as TRef from "../../TRef.js"
|
|
11
|
+
import * as core from "./core.js"
|
|
12
|
+
import * as tRef from "./tRef.js"
|
|
13
|
+
|
|
14
|
+
const TReentrantLockSymbolKey = "effect/TReentrantLock"
|
|
15
|
+
|
|
16
|
+
/** @internal */
|
|
17
|
+
export const TReentrantLockTypeId: TReentrantLock.TReentrantLockTypeId = Symbol.for(
|
|
18
|
+
TReentrantLockSymbolKey
|
|
19
|
+
) as TReentrantLock.TReentrantLockTypeId
|
|
20
|
+
|
|
21
|
+
const WriteLockTypeId = Symbol.for("effect/TReentrantLock/WriteLock")
|
|
22
|
+
|
|
23
|
+
type WriteLockTypeId = typeof WriteLockTypeId
|
|
24
|
+
|
|
25
|
+
const ReadLockTypeId = Symbol.for("effect/TReentrantLock/ReadLock")
|
|
26
|
+
|
|
27
|
+
type ReadLockTypeId = typeof ReadLockTypeId
|
|
28
|
+
|
|
29
|
+
class TReentranLockImpl implements TReentrantLock.TReentrantLock {
|
|
30
|
+
readonly [TReentrantLockTypeId]: TReentrantLock.TReentrantLockTypeId = TReentrantLockTypeId
|
|
31
|
+
constructor(readonly state: TRef.TRef<LockState>) {}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** @internal */
|
|
35
|
+
export interface LockState {
|
|
36
|
+
/**
|
|
37
|
+
* Computes the total number of read locks acquired.
|
|
38
|
+
*/
|
|
39
|
+
readonly readLocks: number
|
|
40
|
+
/**
|
|
41
|
+
* Computes the total number of write locks acquired.
|
|
42
|
+
*/
|
|
43
|
+
readonly writeLocks: number
|
|
44
|
+
/**
|
|
45
|
+
* Computes the number of read locks held by the specified fiber id.
|
|
46
|
+
*/
|
|
47
|
+
readLocksHeld(fiberId: FiberId.FiberId): number
|
|
48
|
+
/**
|
|
49
|
+
* Computes the number of write locks held by the specified fiber id.
|
|
50
|
+
*/
|
|
51
|
+
writeLocksHeld(fiberId: FiberId.FiberId): number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* This data structure describes the state of the lock when multiple fibers
|
|
56
|
+
* have acquired read locks. The state is tracked as a map from fiber identity
|
|
57
|
+
* to number of read locks acquired by the fiber. This level of detail permits
|
|
58
|
+
* upgrading a read lock to a write lock.
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export class ReadLock implements LockState {
|
|
63
|
+
readonly [ReadLockTypeId]: ReadLockTypeId = ReadLockTypeId
|
|
64
|
+
constructor(readonly readers: HashMap.HashMap<FiberId.FiberId, number>) {}
|
|
65
|
+
get readLocks(): number {
|
|
66
|
+
return Array.from(this.readers).reduce((acc, curr) => acc + curr[1], 0)
|
|
67
|
+
}
|
|
68
|
+
get writeLocks(): number {
|
|
69
|
+
return 0
|
|
70
|
+
}
|
|
71
|
+
readLocksHeld(fiberId: FiberId.FiberId): number {
|
|
72
|
+
return Option.getOrElse(
|
|
73
|
+
HashMap.get(this.readers, fiberId),
|
|
74
|
+
() => 0
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
writeLocksHeld(_fiberId: FiberId.FiberId): number {
|
|
78
|
+
return 0
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* This data structure describes the state of the lock when a single fiber has
|
|
84
|
+
* a write lock. The fiber has an identity, and may also have acquired a
|
|
85
|
+
* certain number of read locks.
|
|
86
|
+
*
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
export class WriteLock implements LockState {
|
|
90
|
+
readonly [WriteLockTypeId]: WriteLockTypeId = WriteLockTypeId
|
|
91
|
+
constructor(
|
|
92
|
+
readonly readLocks: number,
|
|
93
|
+
readonly writeLocks: number,
|
|
94
|
+
readonly fiberId: FiberId.FiberId
|
|
95
|
+
) {}
|
|
96
|
+
readLocksHeld(fiberId: FiberId.FiberId): number {
|
|
97
|
+
return Equal.equals(fiberId)(this.fiberId) ? this.readLocks : 0
|
|
98
|
+
}
|
|
99
|
+
writeLocksHeld(fiberId: FiberId.FiberId): number {
|
|
100
|
+
return Equal.equals(fiberId)(this.fiberId) ? this.writeLocks : 0
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const isReadLock = (lock: LockState): lock is ReadLock => {
|
|
105
|
+
return ReadLockTypeId in lock
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const isWriteLock = (lock: LockState): lock is WriteLock => {
|
|
109
|
+
return WriteLockTypeId in lock
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* An empty read lock state, in which no fiber holds any read locks.
|
|
114
|
+
*/
|
|
115
|
+
const emptyReadLock = new ReadLock(HashMap.empty())
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Creates a new read lock where the specified fiber holds the specified
|
|
119
|
+
* number of read locks.
|
|
120
|
+
*/
|
|
121
|
+
const makeReadLock = (fiberId: FiberId.FiberId, count: number): ReadLock => {
|
|
122
|
+
if (count <= 0) {
|
|
123
|
+
return emptyReadLock
|
|
124
|
+
}
|
|
125
|
+
return new ReadLock(HashMap.make([fiberId, count]))
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Determines if there is no other holder of read locks aside from the
|
|
130
|
+
* specified fiber id. If there are no other holders of read locks aside
|
|
131
|
+
* from the specified fiber id, then it is safe to upgrade the read lock
|
|
132
|
+
* into a write lock.
|
|
133
|
+
*/
|
|
134
|
+
const noOtherHolder = (readLock: ReadLock, fiberId: FiberId.FiberId): boolean => {
|
|
135
|
+
return HashMap.isEmpty(readLock.readers) ||
|
|
136
|
+
(HashMap.size(readLock.readers) === 1 && HashMap.has(readLock.readers, fiberId))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Adjusts the number of read locks held by the specified fiber id.
|
|
141
|
+
*/
|
|
142
|
+
const adjustReadLock = (readLock: ReadLock, fiberId: FiberId.FiberId, adjustment: number): ReadLock => {
|
|
143
|
+
const total = readLock.readLocksHeld(fiberId)
|
|
144
|
+
const newTotal = total + adjustment
|
|
145
|
+
if (newTotal < 0) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
"BUG - TReentrantLock.ReadLock.adjust - please report an issue at https://github.com/Effect-TS/effect/issues"
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
if (newTotal === 0) {
|
|
151
|
+
return new ReadLock(HashMap.remove(readLock.readers, fiberId))
|
|
152
|
+
}
|
|
153
|
+
return new ReadLock(HashMap.set(readLock.readers, fiberId, newTotal))
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const adjustRead = (self: TReentrantLock.TReentrantLock, delta: number): STM.STM<number> =>
|
|
157
|
+
core.withSTMRuntime((runtime) => {
|
|
158
|
+
const lock = tRef.unsafeGet(self.state, runtime.journal)
|
|
159
|
+
if (isReadLock(lock)) {
|
|
160
|
+
const result = adjustReadLock(lock, runtime.fiberId, delta)
|
|
161
|
+
tRef.unsafeSet(self.state, result, runtime.journal)
|
|
162
|
+
return core.succeed(result.readLocksHeld(runtime.fiberId))
|
|
163
|
+
}
|
|
164
|
+
if (isWriteLock(lock) && Equal.equals(runtime.fiberId)(lock.fiberId)) {
|
|
165
|
+
const newTotal = lock.readLocks + delta
|
|
166
|
+
if (newTotal < 0) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Defect: Fiber ${
|
|
169
|
+
FiberId.threadName(runtime.fiberId)
|
|
170
|
+
} releasing read locks it does not hold, newTotal: ${newTotal}`
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
tRef.unsafeSet(
|
|
174
|
+
self.state,
|
|
175
|
+
new WriteLock(newTotal, lock.writeLocks, runtime.fiberId),
|
|
176
|
+
runtime.journal
|
|
177
|
+
)
|
|
178
|
+
return core.succeed(newTotal)
|
|
179
|
+
}
|
|
180
|
+
return core.retry
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
/** @internal */
|
|
184
|
+
export const acquireRead = (self: TReentrantLock.TReentrantLock): STM.STM<number> => adjustRead(self, 1)
|
|
185
|
+
|
|
186
|
+
/** @internal */
|
|
187
|
+
export const acquireWrite = (self: TReentrantLock.TReentrantLock): STM.STM<number> =>
|
|
188
|
+
core.withSTMRuntime((runtime) => {
|
|
189
|
+
const lock = tRef.unsafeGet(self.state, runtime.journal)
|
|
190
|
+
if (isReadLock(lock) && noOtherHolder(lock, runtime.fiberId)) {
|
|
191
|
+
tRef.unsafeSet(
|
|
192
|
+
self.state,
|
|
193
|
+
new WriteLock(lock.readLocksHeld(runtime.fiberId), 1, runtime.fiberId),
|
|
194
|
+
runtime.journal
|
|
195
|
+
)
|
|
196
|
+
return core.succeed(1)
|
|
197
|
+
}
|
|
198
|
+
if (isWriteLock(lock) && Equal.equals(runtime.fiberId)(lock.fiberId)) {
|
|
199
|
+
tRef.unsafeSet(
|
|
200
|
+
self.state,
|
|
201
|
+
new WriteLock(lock.readLocks, lock.writeLocks + 1, runtime.fiberId),
|
|
202
|
+
runtime.journal
|
|
203
|
+
)
|
|
204
|
+
return core.succeed(lock.writeLocks + 1)
|
|
205
|
+
}
|
|
206
|
+
return core.retry
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
/** @internal */
|
|
210
|
+
export const fiberReadLocks = (self: TReentrantLock.TReentrantLock): STM.STM<number> =>
|
|
211
|
+
core.effect<never, number>((journal, fiberId) =>
|
|
212
|
+
tRef.unsafeGet(
|
|
213
|
+
self.state,
|
|
214
|
+
journal
|
|
215
|
+
).readLocksHeld(fiberId)
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
/** @internal */
|
|
219
|
+
export const fiberWriteLocks = (self: TReentrantLock.TReentrantLock): STM.STM<number> =>
|
|
220
|
+
core.effect<never, number>((journal, fiberId) =>
|
|
221
|
+
tRef.unsafeGet(
|
|
222
|
+
self.state,
|
|
223
|
+
journal
|
|
224
|
+
).writeLocksHeld(fiberId)
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
/** @internal */
|
|
228
|
+
export const lock = (self: TReentrantLock.TReentrantLock): Effect.Effect<number, never, Scope.Scope> => writeLock(self)
|
|
229
|
+
|
|
230
|
+
/** @internal */
|
|
231
|
+
export const locked = (self: TReentrantLock.TReentrantLock): STM.STM<boolean> =>
|
|
232
|
+
core.zipWith(
|
|
233
|
+
readLocked(self),
|
|
234
|
+
writeLocked(self),
|
|
235
|
+
(x, y) => x || y
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
/** @internal */
|
|
239
|
+
export const make: STM.STM<TReentrantLock.TReentrantLock> = core.map(
|
|
240
|
+
tRef.make<LockState>(emptyReadLock),
|
|
241
|
+
(readLock) => new TReentranLockImpl(readLock)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
/** @internal */
|
|
245
|
+
export const readLock = (self: TReentrantLock.TReentrantLock): Effect.Effect<number, never, Scope.Scope> =>
|
|
246
|
+
Effect.acquireRelease(
|
|
247
|
+
core.commit(acquireRead(self)),
|
|
248
|
+
() => core.commit(releaseRead(self))
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
/** @internal */
|
|
252
|
+
export const readLocks = (self: TReentrantLock.TReentrantLock): STM.STM<number> =>
|
|
253
|
+
core.map(
|
|
254
|
+
tRef.get(self.state),
|
|
255
|
+
(state) => state.readLocks
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
/** @internal */
|
|
259
|
+
export const readLocked = (self: TReentrantLock.TReentrantLock): STM.STM<boolean> =>
|
|
260
|
+
core.map(
|
|
261
|
+
tRef.get(self.state),
|
|
262
|
+
(state) => state.readLocks > 0
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
/** @internal */
|
|
266
|
+
export const releaseRead = (self: TReentrantLock.TReentrantLock): STM.STM<number> => adjustRead(self, -1)
|
|
267
|
+
|
|
268
|
+
/** @internal */
|
|
269
|
+
export const releaseWrite = (self: TReentrantLock.TReentrantLock): STM.STM<number> =>
|
|
270
|
+
core.withSTMRuntime((runtime) => {
|
|
271
|
+
const lock = tRef.unsafeGet(self.state, runtime.journal)
|
|
272
|
+
if (isWriteLock(lock) && lock.writeLocks === 1 && Equal.equals(runtime.fiberId)(lock.fiberId)) {
|
|
273
|
+
const result = makeReadLock(lock.fiberId, lock.readLocks)
|
|
274
|
+
tRef.unsafeSet(self.state, result, runtime.journal)
|
|
275
|
+
return core.succeed(result.writeLocksHeld(runtime.fiberId))
|
|
276
|
+
}
|
|
277
|
+
if (isWriteLock(lock) && Equal.equals(runtime.fiberId)(lock.fiberId)) {
|
|
278
|
+
const result = new WriteLock(lock.readLocks, lock.writeLocks - 1, runtime.fiberId)
|
|
279
|
+
tRef.unsafeSet(self.state, result, runtime.journal)
|
|
280
|
+
return core.succeed(result.writeLocksHeld(runtime.fiberId))
|
|
281
|
+
}
|
|
282
|
+
throw new Error(
|
|
283
|
+
`Defect: Fiber ${FiberId.threadName(runtime.fiberId)} releasing write lock it does not hold`
|
|
284
|
+
)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
/** @internal */
|
|
288
|
+
export const withLock = dual<
|
|
289
|
+
(
|
|
290
|
+
self: TReentrantLock.TReentrantLock
|
|
291
|
+
) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
|
|
292
|
+
<A, E, R>(
|
|
293
|
+
effect: Effect.Effect<A, E, R>,
|
|
294
|
+
self: TReentrantLock.TReentrantLock
|
|
295
|
+
) => Effect.Effect<A, E, R>
|
|
296
|
+
>(2, (effect, self) => withWriteLock(effect, self))
|
|
297
|
+
|
|
298
|
+
/** @internal */
|
|
299
|
+
export const withReadLock = dual<
|
|
300
|
+
(self: TReentrantLock.TReentrantLock) => <A, E, R>(
|
|
301
|
+
effect: Effect.Effect<A, E, R>
|
|
302
|
+
) => Effect.Effect<A, E, R>,
|
|
303
|
+
<A, E, R>(
|
|
304
|
+
effect: Effect.Effect<A, E, R>,
|
|
305
|
+
self: TReentrantLock.TReentrantLock
|
|
306
|
+
) => Effect.Effect<A, E, R>
|
|
307
|
+
>(2, (effect, self) =>
|
|
308
|
+
Effect.uninterruptibleMask((restore) =>
|
|
309
|
+
Effect.zipRight(
|
|
310
|
+
restore(core.commit(acquireRead(self))),
|
|
311
|
+
Effect.ensuring(
|
|
312
|
+
effect,
|
|
313
|
+
core.commit(releaseRead(self))
|
|
314
|
+
)
|
|
315
|
+
)
|
|
316
|
+
))
|
|
317
|
+
|
|
318
|
+
/** @internal */
|
|
319
|
+
export const withWriteLock = dual<
|
|
320
|
+
(self: TReentrantLock.TReentrantLock) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
|
|
321
|
+
<A, E, R>(effect: Effect.Effect<A, E, R>, self: TReentrantLock.TReentrantLock) => Effect.Effect<A, E, R>
|
|
322
|
+
>(2, (effect, self) =>
|
|
323
|
+
Effect.uninterruptibleMask((restore) =>
|
|
324
|
+
Effect.zipRight(
|
|
325
|
+
restore(core.commit(acquireWrite(self))),
|
|
326
|
+
Effect.ensuring(
|
|
327
|
+
effect,
|
|
328
|
+
core.commit(releaseWrite(self))
|
|
329
|
+
)
|
|
330
|
+
)
|
|
331
|
+
))
|
|
332
|
+
|
|
333
|
+
/** @internal */
|
|
334
|
+
export const writeLock = (self: TReentrantLock.TReentrantLock): Effect.Effect<number, never, Scope.Scope> =>
|
|
335
|
+
Effect.acquireRelease(
|
|
336
|
+
core.commit(acquireWrite(self)),
|
|
337
|
+
() => core.commit(releaseWrite(self))
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
/** @internal */
|
|
341
|
+
export const writeLocked = (self: TReentrantLock.TReentrantLock): STM.STM<boolean> =>
|
|
342
|
+
core.map(
|
|
343
|
+
tRef.get(self.state),
|
|
344
|
+
(state) => state.writeLocks > 0
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
/** @internal */
|
|
348
|
+
export const writeLocks = (self: TReentrantLock.TReentrantLock): STM.STM<number> =>
|
|
349
|
+
core.map(
|
|
350
|
+
tRef.get(self.state),
|
|
351
|
+
(state) => state.writeLocks
|
|
352
|
+
)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { dual } from "../../Function.js"
|
|
2
|
+
import * as Option from "../../Option.js"
|
|
3
|
+
import type { Pipeable } from "../../Pipeable.js"
|
|
4
|
+
import { pipeArguments } from "../../Pipeable.js"
|
|
5
|
+
import type * as STM from "../../STM.js"
|
|
6
|
+
import type * as TRef from "../../TRef.js"
|
|
7
|
+
import * as core from "./core.js"
|
|
8
|
+
import * as Entry from "./entry.js"
|
|
9
|
+
import type * as Journal from "./journal.js"
|
|
10
|
+
import type * as TxnId from "./txnId.js"
|
|
11
|
+
import * as Versioned from "./versioned.js"
|
|
12
|
+
|
|
13
|
+
/** @internal */
|
|
14
|
+
const TRefSymbolKey = "effect/TRef"
|
|
15
|
+
|
|
16
|
+
/** @internal */
|
|
17
|
+
export const TRefTypeId: TRef.TRefTypeId = Symbol.for(
|
|
18
|
+
TRefSymbolKey
|
|
19
|
+
) as TRef.TRefTypeId
|
|
20
|
+
|
|
21
|
+
export const tRefVariance = {
|
|
22
|
+
/* c8 ignore next */
|
|
23
|
+
_A: (_: any) => _
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** @internal */
|
|
27
|
+
export class TRefImpl<in out A> implements TRef.TRef<A>, Pipeable {
|
|
28
|
+
readonly [TRefTypeId] = tRefVariance
|
|
29
|
+
/** @internal */
|
|
30
|
+
todos: Map<TxnId.TxnId, Journal.Todo>
|
|
31
|
+
/** @internal */
|
|
32
|
+
versioned: Versioned.Versioned<A>
|
|
33
|
+
constructor(value: A) {
|
|
34
|
+
this.versioned = new Versioned.Versioned(value)
|
|
35
|
+
this.todos = new Map()
|
|
36
|
+
}
|
|
37
|
+
modify<B>(f: (a: A) => readonly [B, A]): STM.STM<B> {
|
|
38
|
+
return core.effect<never, B>((journal) => {
|
|
39
|
+
const entry = getOrMakeEntry(this, journal)
|
|
40
|
+
const [retValue, newValue] = f(Entry.unsafeGet(entry) as A)
|
|
41
|
+
Entry.unsafeSet(entry, newValue)
|
|
42
|
+
return retValue
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
pipe() {
|
|
46
|
+
return pipeArguments(this, arguments)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @internal */
|
|
51
|
+
export const make = <A>(value: A): STM.STM<TRef.TRef<A>> =>
|
|
52
|
+
core.effect<never, TRef.TRef<A>>((journal) => {
|
|
53
|
+
const ref = new TRefImpl(value)
|
|
54
|
+
journal.set(ref, Entry.make(ref, true))
|
|
55
|
+
return ref
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
/** @internal */
|
|
59
|
+
export const get = <A>(self: TRef.TRef<A>) => self.modify((a) => [a, a])
|
|
60
|
+
|
|
61
|
+
/** @internal */
|
|
62
|
+
export const set = dual<
|
|
63
|
+
<A>(value: A) => (self: TRef.TRef<A>) => STM.STM<void>,
|
|
64
|
+
<A>(self: TRef.TRef<A>, value: A) => STM.STM<void>
|
|
65
|
+
>(
|
|
66
|
+
2,
|
|
67
|
+
<A>(self: TRef.TRef<A>, value: A): STM.STM<void> => self.modify((): [void, A] => [void 0, value])
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
/** @internal */
|
|
71
|
+
export const getAndSet = dual<
|
|
72
|
+
<A>(value: A) => (self: TRef.TRef<A>) => STM.STM<A>,
|
|
73
|
+
<A>(self: TRef.TRef<A>, value: A) => STM.STM<A>
|
|
74
|
+
>(2, (self, value) => self.modify((a) => [a, value]))
|
|
75
|
+
|
|
76
|
+
/** @internal */
|
|
77
|
+
export const getAndUpdate = dual<
|
|
78
|
+
<A>(f: (a: A) => A) => (self: TRef.TRef<A>) => STM.STM<A>,
|
|
79
|
+
<A>(self: TRef.TRef<A>, f: (a: A) => A) => STM.STM<A>
|
|
80
|
+
>(2, (self, f) => self.modify((a) => [a, f(a)]))
|
|
81
|
+
|
|
82
|
+
/** @internal */
|
|
83
|
+
export const getAndUpdateSome = dual<
|
|
84
|
+
<A>(f: (a: A) => Option.Option<A>) => (self: TRef.TRef<A>) => STM.STM<A>,
|
|
85
|
+
<A>(self: TRef.TRef<A>, f: (a: A) => Option.Option<A>) => STM.STM<A>
|
|
86
|
+
>(2, (self, f) =>
|
|
87
|
+
self.modify((a) =>
|
|
88
|
+
Option.match(f(a), {
|
|
89
|
+
onNone: () => [a, a],
|
|
90
|
+
onSome: (b) => [a, b]
|
|
91
|
+
})
|
|
92
|
+
))
|
|
93
|
+
|
|
94
|
+
/** @internal */
|
|
95
|
+
export const setAndGet = dual<
|
|
96
|
+
<A>(value: A) => (self: TRef.TRef<A>) => STM.STM<A>,
|
|
97
|
+
<A>(self: TRef.TRef<A>, value: A) => STM.STM<A>
|
|
98
|
+
>(2, (self, value) => self.modify(() => [value, value]))
|
|
99
|
+
|
|
100
|
+
/** @internal */
|
|
101
|
+
export const modify = dual<
|
|
102
|
+
<A, B>(f: (a: A) => readonly [B, A]) => (self: TRef.TRef<A>) => STM.STM<B>,
|
|
103
|
+
<A, B>(self: TRef.TRef<A>, f: (a: A) => readonly [B, A]) => STM.STM<B>
|
|
104
|
+
>(2, (self, f) => self.modify(f))
|
|
105
|
+
|
|
106
|
+
/** @internal */
|
|
107
|
+
export const modifySome = dual<
|
|
108
|
+
<A, B>(fallback: B, f: (a: A) => Option.Option<readonly [B, A]>) => (self: TRef.TRef<A>) => STM.STM<B>,
|
|
109
|
+
<A, B>(self: TRef.TRef<A>, fallback: B, f: (a: A) => Option.Option<readonly [B, A]>) => STM.STM<B>
|
|
110
|
+
>(3, (self, fallback, f) =>
|
|
111
|
+
self.modify((a) =>
|
|
112
|
+
Option.match(f(a), {
|
|
113
|
+
onNone: () => [fallback, a],
|
|
114
|
+
onSome: (b) => b
|
|
115
|
+
})
|
|
116
|
+
))
|
|
117
|
+
|
|
118
|
+
/** @internal */
|
|
119
|
+
export const update = dual<
|
|
120
|
+
<A>(f: (a: A) => A) => (self: TRef.TRef<A>) => STM.STM<void>,
|
|
121
|
+
<A>(self: TRef.TRef<A>, f: (a: A) => A) => STM.STM<void>
|
|
122
|
+
>(2, (self, f) => self.modify((a) => [void 0, f(a)]))
|
|
123
|
+
|
|
124
|
+
/** @internal */
|
|
125
|
+
export const updateAndGet = dual<
|
|
126
|
+
<A>(f: (a: A) => A) => (self: TRef.TRef<A>) => STM.STM<A>,
|
|
127
|
+
<A>(self: TRef.TRef<A>, f: (a: A) => A) => STM.STM<A>
|
|
128
|
+
>(2, (self, f) =>
|
|
129
|
+
self.modify((a) => {
|
|
130
|
+
const b = f(a)
|
|
131
|
+
return [b, b]
|
|
132
|
+
}))
|
|
133
|
+
|
|
134
|
+
/** @internal */
|
|
135
|
+
export const updateSome = dual<
|
|
136
|
+
<A>(f: (a: A) => Option.Option<A>) => (self: TRef.TRef<A>) => STM.STM<void>,
|
|
137
|
+
<A>(self: TRef.TRef<A>, f: (a: A) => Option.Option<A>) => STM.STM<void>
|
|
138
|
+
>(
|
|
139
|
+
2,
|
|
140
|
+
(self, f) =>
|
|
141
|
+
self.modify((a) => [
|
|
142
|
+
void 0,
|
|
143
|
+
Option.match(f(a), {
|
|
144
|
+
onNone: () => a,
|
|
145
|
+
onSome: (b) => b
|
|
146
|
+
})
|
|
147
|
+
])
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
/** @internal */
|
|
151
|
+
export const updateSomeAndGet = dual<
|
|
152
|
+
<A>(f: (a: A) => Option.Option<A>) => (self: TRef.TRef<A>) => STM.STM<A>,
|
|
153
|
+
<A>(self: TRef.TRef<A>, f: (a: A) => Option.Option<A>) => STM.STM<A>
|
|
154
|
+
>(
|
|
155
|
+
2,
|
|
156
|
+
(self, f) =>
|
|
157
|
+
self.modify((a) =>
|
|
158
|
+
Option.match(f(a), {
|
|
159
|
+
onNone: () => [a, a],
|
|
160
|
+
onSome: (b) => [b, b]
|
|
161
|
+
})
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
/** @internal */
|
|
166
|
+
const getOrMakeEntry = <A>(self: TRef.TRef<A>, journal: Journal.Journal): Entry.Entry => {
|
|
167
|
+
if (journal.has(self)) {
|
|
168
|
+
return journal.get(self)!
|
|
169
|
+
}
|
|
170
|
+
const entry = Entry.make(self, false)
|
|
171
|
+
journal.set(self, entry)
|
|
172
|
+
return entry
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** @internal */
|
|
176
|
+
export const unsafeGet: {
|
|
177
|
+
(journal: Journal.Journal): <A>(self: TRef.TRef<A>) => A
|
|
178
|
+
<A>(self: TRef.TRef<A>, journal: Journal.Journal): A
|
|
179
|
+
} = dual<
|
|
180
|
+
(journal: Journal.Journal) => <A>(self: TRef.TRef<A>) => A,
|
|
181
|
+
<A>(self: TRef.TRef<A>, journal: Journal.Journal) => A
|
|
182
|
+
>(2, <A>(self: TRef.TRef<A>, journal: Journal.Journal) => Entry.unsafeGet(getOrMakeEntry(self, journal)) as A)
|
|
183
|
+
|
|
184
|
+
/** @internal */
|
|
185
|
+
export const unsafeSet: {
|
|
186
|
+
<A>(value: A, journal: Journal.Journal): (self: TRef.TRef<A>) => void
|
|
187
|
+
<A>(self: TRef.TRef<A>, value: A, journal: Journal.Journal): void
|
|
188
|
+
} = dual<
|
|
189
|
+
<A>(value: A, journal: Journal.Journal) => (self: TRef.TRef<A>) => void,
|
|
190
|
+
<A>(self: TRef.TRef<A>, value: A, journal: Journal.Journal) => void
|
|
191
|
+
>(3, (self, value, journal) => {
|
|
192
|
+
const entry = getOrMakeEntry(self, journal)
|
|
193
|
+
Entry.unsafeSet(entry, value)
|
|
194
|
+
return undefined
|
|
195
|
+
})
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as Cause from "../../Cause.js"
|
|
2
|
+
import * as Effect from "../../Effect.js"
|
|
3
|
+
import { dual } from "../../Function.js"
|
|
4
|
+
import type * as Scope from "../../Scope.js"
|
|
5
|
+
import * as STM from "../../STM.js"
|
|
6
|
+
import type * as TRef from "../../TRef.js"
|
|
7
|
+
import type * as TSemaphore from "../../TSemaphore.js"
|
|
8
|
+
import * as core from "./core.js"
|
|
9
|
+
import * as tRef from "./tRef.js"
|
|
10
|
+
|
|
11
|
+
/** @internal */
|
|
12
|
+
const TSemaphoreSymbolKey = "effect/TSemaphore"
|
|
13
|
+
|
|
14
|
+
/** @internal */
|
|
15
|
+
export const TSemaphoreTypeId: TSemaphore.TSemaphoreTypeId = Symbol.for(
|
|
16
|
+
TSemaphoreSymbolKey
|
|
17
|
+
) as TSemaphore.TSemaphoreTypeId
|
|
18
|
+
|
|
19
|
+
/** @internal */
|
|
20
|
+
class TSemaphoreImpl implements TSemaphore.TSemaphore {
|
|
21
|
+
readonly [TSemaphoreTypeId]: TSemaphore.TSemaphoreTypeId = TSemaphoreTypeId
|
|
22
|
+
constructor(readonly permits: TRef.TRef<number>) {}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @internal */
|
|
26
|
+
export const make = (permits: number): STM.STM<TSemaphore.TSemaphore> =>
|
|
27
|
+
STM.map(tRef.make(permits), (permits) => new TSemaphoreImpl(permits))
|
|
28
|
+
|
|
29
|
+
/** @internal */
|
|
30
|
+
export const acquire = (self: TSemaphore.TSemaphore): STM.STM<void> => acquireN(self, 1)
|
|
31
|
+
|
|
32
|
+
/** @internal */
|
|
33
|
+
export const acquireN = dual<
|
|
34
|
+
(n: number) => (self: TSemaphore.TSemaphore) => STM.STM<void>,
|
|
35
|
+
(self: TSemaphore.TSemaphore, n: number) => STM.STM<void>
|
|
36
|
+
>(2, (self, n) =>
|
|
37
|
+
core.withSTMRuntime((driver) => {
|
|
38
|
+
if (n < 0) {
|
|
39
|
+
throw new Cause.IllegalArgumentException(`Unexpected negative value ${n} passed to Semaphore.acquireN`)
|
|
40
|
+
}
|
|
41
|
+
const value = tRef.unsafeGet(self.permits, driver.journal)
|
|
42
|
+
if (value < n) {
|
|
43
|
+
return STM.retry
|
|
44
|
+
} else {
|
|
45
|
+
return STM.succeed(tRef.unsafeSet(self.permits, value - n, driver.journal))
|
|
46
|
+
}
|
|
47
|
+
}))
|
|
48
|
+
|
|
49
|
+
/** @internal */
|
|
50
|
+
export const available = (self: TSemaphore.TSemaphore) => tRef.get(self.permits)
|
|
51
|
+
|
|
52
|
+
/** @internal */
|
|
53
|
+
export const release = (self: TSemaphore.TSemaphore): STM.STM<void> => releaseN(self, 1)
|
|
54
|
+
|
|
55
|
+
/** @internal */
|
|
56
|
+
export const releaseN = dual<
|
|
57
|
+
(n: number) => (self: TSemaphore.TSemaphore) => STM.STM<void>,
|
|
58
|
+
(self: TSemaphore.TSemaphore, n: number) => STM.STM<void>
|
|
59
|
+
>(2, (self, n) =>
|
|
60
|
+
core.withSTMRuntime((driver) => {
|
|
61
|
+
if (n < 0) {
|
|
62
|
+
throw new Cause.IllegalArgumentException(`Unexpected negative value ${n} passed to Semaphore.releaseN`)
|
|
63
|
+
}
|
|
64
|
+
const current = tRef.unsafeGet(self.permits, driver.journal)
|
|
65
|
+
return STM.succeed(tRef.unsafeSet(self.permits, current + n, driver.journal))
|
|
66
|
+
}))
|
|
67
|
+
|
|
68
|
+
/** @internal */
|
|
69
|
+
export const withPermit = dual<
|
|
70
|
+
(semaphore: TSemaphore.TSemaphore) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
|
|
71
|
+
<A, E, R>(self: Effect.Effect<A, E, R>, semaphore: TSemaphore.TSemaphore) => Effect.Effect<A, E, R>
|
|
72
|
+
>(2, (self, semaphore) => withPermits(self, semaphore, 1))
|
|
73
|
+
|
|
74
|
+
/** @internal */
|
|
75
|
+
export const withPermits = dual<
|
|
76
|
+
(
|
|
77
|
+
semaphore: TSemaphore.TSemaphore,
|
|
78
|
+
permits: number
|
|
79
|
+
) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
|
|
80
|
+
<A, E, R>(
|
|
81
|
+
self: Effect.Effect<A, E, R>,
|
|
82
|
+
semaphore: TSemaphore.TSemaphore,
|
|
83
|
+
permits: number
|
|
84
|
+
) => Effect.Effect<A, E, R>
|
|
85
|
+
>(3, (self, semaphore, permits) =>
|
|
86
|
+
Effect.uninterruptibleMask((restore) =>
|
|
87
|
+
Effect.zipRight(
|
|
88
|
+
restore(core.commit(acquireN(permits)(semaphore))),
|
|
89
|
+
Effect.ensuring(
|
|
90
|
+
self,
|
|
91
|
+
core.commit(releaseN(permits)(semaphore))
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
/** @internal */
|
|
97
|
+
export const withPermitScoped = (self: TSemaphore.TSemaphore): Effect.Effect<void, never, Scope.Scope> =>
|
|
98
|
+
withPermitsScoped(self, 1)
|
|
99
|
+
|
|
100
|
+
/** @internal */
|
|
101
|
+
export const withPermitsScoped = dual<
|
|
102
|
+
(permits: number) => (self: TSemaphore.TSemaphore) => Effect.Effect<void, never, Scope.Scope>,
|
|
103
|
+
(self: TSemaphore.TSemaphore, permits: number) => Effect.Effect<void, never, Scope.Scope>
|
|
104
|
+
>(2, (self, permits) =>
|
|
105
|
+
Effect.acquireReleaseInterruptible(
|
|
106
|
+
core.commit(acquireN(self, permits)),
|
|
107
|
+
() => core.commit(releaseN(self, permits))
|
|
108
|
+
))
|
|
109
|
+
|
|
110
|
+
/** @internal */
|
|
111
|
+
export const unsafeMakeSemaphore = (permits: number): TSemaphore.TSemaphore => {
|
|
112
|
+
return new TSemaphoreImpl(new tRef.TRefImpl(permits))
|
|
113
|
+
}
|