effect 4.0.0-beta.93 → 4.0.0-beta.97
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/Array.d.ts.map +1 -1
- package/dist/BigDecimal.d.ts.map +1 -1
- package/dist/BigDecimal.js.map +1 -1
- package/dist/BigInt.d.ts.map +1 -1
- package/dist/Boolean.d.ts.map +1 -1
- package/dist/Brand.d.ts.map +1 -1
- package/dist/Cache.d.ts.map +1 -1
- package/dist/Cause.d.ts.map +1 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/ChannelSchema.d.ts.map +1 -1
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Combiner.d.ts.map +1 -1
- package/dist/Config.d.ts +1 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/ConfigProvider.d.ts +44 -6
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +63 -24
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Console.d.ts.map +1 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Cron.d.ts +4 -1
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +98 -53
- package/dist/Cron.js.map +1 -1
- package/dist/Crypto.d.ts.map +1 -1
- package/dist/Data.d.ts.map +1 -1
- package/dist/DateTime.d.ts +12 -12
- package/dist/DateTime.d.ts.map +1 -1
- package/dist/Deferred.d.ts.map +1 -1
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Effect.d.ts +130 -0
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +43 -0
- package/dist/Effect.js.map +1 -1
- package/dist/Effectable.d.ts.map +1 -1
- package/dist/Encoding.d.ts.map +1 -1
- package/dist/Equal.d.ts.map +1 -1
- package/dist/Equivalence.d.ts.map +1 -1
- package/dist/ErrorReporter.d.ts.map +1 -1
- package/dist/ExecutionPlan.d.ts +2 -2
- package/dist/ExecutionPlan.d.ts.map +1 -1
- package/dist/Fiber.d.ts.map +1 -1
- package/dist/FiberHandle.d.ts +8 -8
- package/dist/FiberHandle.d.ts.map +1 -1
- package/dist/FiberMap.d.ts +8 -8
- package/dist/FiberMap.d.ts.map +1 -1
- package/dist/FiberSet.d.ts +4 -4
- package/dist/FiberSet.d.ts.map +1 -1
- package/dist/FileSystem.d.ts +7 -0
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +3 -0
- package/dist/FileSystem.js.map +1 -1
- package/dist/Filter.d.ts.map +1 -1
- package/dist/Function.d.ts.map +1 -1
- package/dist/Graph.d.ts.map +1 -1
- package/dist/Graph.js.map +1 -1
- package/dist/Hash.d.ts.map +1 -1
- package/dist/HashMap.d.ts.map +1 -1
- package/dist/HashRing.d.ts.map +1 -1
- package/dist/Inspectable.d.ts.map +1 -1
- package/dist/Inspectable.js.map +1 -1
- package/dist/Iterable.d.ts.map +1 -1
- package/dist/Latch.d.ts.map +1 -1
- package/dist/Layer.d.ts +1 -1
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +6 -3
- package/dist/Layer.js.map +1 -1
- package/dist/LayerMap.d.ts.map +1 -1
- package/dist/LayerMap.js +1 -1
- package/dist/LayerMap.js.map +1 -1
- package/dist/LayerRef.d.ts +252 -0
- package/dist/LayerRef.d.ts.map +1 -0
- package/dist/LayerRef.js +171 -0
- package/dist/LayerRef.js.map +1 -0
- package/dist/LogLevel.d.ts.map +1 -1
- package/dist/Logger.d.ts.map +1 -1
- package/dist/ManagedRuntime.d.ts.map +1 -1
- package/dist/Metric.d.ts.map +1 -1
- package/dist/MutableHashMap.d.ts.map +1 -1
- package/dist/MutableHashSet.d.ts.map +1 -1
- package/dist/MutableList.d.ts.map +1 -1
- package/dist/MutableRef.d.ts.map +1 -1
- package/dist/NonEmptyIterable.d.ts.map +1 -1
- package/dist/Number.d.ts.map +1 -1
- package/dist/Optic.d.ts.map +1 -1
- package/dist/Option.d.ts.map +1 -1
- package/dist/Order.d.ts.map +1 -1
- package/dist/Ordering.d.ts.map +1 -1
- package/dist/PartitionedSemaphore.d.ts.map +1 -1
- package/dist/Pipeable.d.ts.map +1 -1
- package/dist/PlatformError.d.ts.map +1 -1
- package/dist/Pool.d.ts.map +1 -1
- package/dist/PrimaryKey.d.ts.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/Pull.d.ts.map +1 -1
- package/dist/Queue.d.ts.map +1 -1
- package/dist/Random.d.ts.map +1 -1
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/Record.d.ts.map +1 -1
- package/dist/Redactable.d.ts.map +1 -1
- package/dist/Redacted.d.ts.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/RegExp.d.ts.map +1 -1
- package/dist/Request.d.ts +1 -1
- package/dist/Request.d.ts.map +1 -1
- package/dist/RequestResolver.d.ts.map +1 -1
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Result.d.ts.map +1 -1
- package/dist/Runtime.d.ts.map +1 -1
- package/dist/Schedule.d.ts +1206 -4013
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +244 -1348
- package/dist/Schedule.js.map +1 -1
- package/dist/Scheduler.d.ts.map +1 -1
- package/dist/Scheduler.js.map +1 -1
- package/dist/Schema.d.ts +123 -30
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +40 -0
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaIssue.d.ts.map +1 -1
- package/dist/SchemaIssue.js.map +1 -1
- package/dist/SchemaParser.d.ts +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +106 -106
- package/dist/SchemaTransformation.d.ts +38 -2
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +38 -2
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedRef.d.ts.map +1 -1
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Stdio.d.ts.map +1 -1
- package/dist/Stream.d.ts +2 -2
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +1 -1
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js.map +1 -1
- package/dist/Struct.d.ts.map +1 -1
- package/dist/SubscriptionRef.d.ts.map +1 -1
- package/dist/SynchronizedRef.d.ts.map +1 -1
- package/dist/Take.d.ts.map +1 -1
- package/dist/Terminal.d.ts.map +1 -1
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Trie.d.ts.map +1 -1
- package/dist/Tuple.d.ts.map +1 -1
- package/dist/TxChunk.d.ts.map +1 -1
- package/dist/TxDeferred.d.ts.map +1 -1
- package/dist/TxHashMap.d.ts.map +1 -1
- package/dist/TxHashSet.d.ts.map +1 -1
- package/dist/TxPriorityQueue.d.ts.map +1 -1
- package/dist/TxPubSub.d.ts.map +1 -1
- package/dist/TxQueue.d.ts.map +1 -1
- package/dist/TxReentrantLock.d.ts.map +1 -1
- package/dist/TxRef.d.ts.map +1 -1
- package/dist/TxSemaphore.d.ts.map +1 -1
- package/dist/TxSubscriptionRef.d.ts.map +1 -1
- package/dist/Types.d.ts +1 -1
- package/dist/Types.d.ts.map +1 -1
- package/dist/UndefinedOr.d.ts.map +1 -1
- package/dist/Utils.d.ts.map +1 -1
- package/dist/internal/effect.js +2 -0
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/schema/schema.d.ts.map +1 -1
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestConsole.d.ts.map +1 -1
- package/dist/testing/TestSchema.d.ts +2 -2
- package/dist/testing/TestSchema.d.ts.map +1 -1
- package/dist/testing/TestSchema.js.map +1 -1
- package/dist/unstable/ai/AiError.d.ts +1 -1
- package/dist/unstable/ai/AiError.d.ts.map +1 -1
- package/dist/unstable/ai/Chat.d.ts +2 -2
- package/dist/unstable/ai/Chat.d.ts.map +1 -1
- package/dist/unstable/ai/IdGenerator.d.ts.map +1 -1
- package/dist/unstable/ai/LanguageModel.d.ts +2 -2
- package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
- package/dist/unstable/ai/McpSchema.d.ts +221 -221
- package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
- package/dist/unstable/ai/McpServer.d.ts.map +1 -1
- package/dist/unstable/ai/Model.d.ts.map +1 -1
- package/dist/unstable/ai/Prompt.d.ts.map +1 -1
- package/dist/unstable/ai/Response.d.ts.map +1 -1
- package/dist/unstable/ai/Telemetry.d.ts.map +1 -1
- package/dist/unstable/ai/Tokenizer.d.ts.map +1 -1
- package/dist/unstable/ai/Tool.d.ts.map +1 -1
- package/dist/unstable/ai/Toolkit.d.ts.map +1 -1
- package/dist/unstable/cli/Argument.d.ts +2 -2
- package/dist/unstable/cli/Argument.d.ts.map +1 -1
- package/dist/unstable/cli/Argument.js.map +1 -1
- package/dist/unstable/cli/CliError.d.ts.map +1 -1
- package/dist/unstable/cli/CliOutput.d.ts.map +1 -1
- package/dist/unstable/cli/Command.d.ts.map +1 -1
- package/dist/unstable/cli/Completions.d.ts.map +1 -1
- package/dist/unstable/cli/Flag.d.ts +2 -2
- package/dist/unstable/cli/Flag.d.ts.map +1 -1
- package/dist/unstable/cli/Flag.js.map +1 -1
- package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/unstable/cli/Param.d.ts +2 -2
- package/dist/unstable/cli/Param.d.ts.map +1 -1
- package/dist/unstable/cli/Param.js.map +1 -1
- package/dist/unstable/cli/Primitive.d.ts.map +1 -1
- package/dist/unstable/cli/Primitive.js.map +1 -1
- package/dist/unstable/cli/Prompt.d.ts.map +1 -1
- package/dist/unstable/cli/Prompt.js.map +1 -1
- package/dist/unstable/cli/internal/ansi.d.ts.map +1 -1
- package/dist/unstable/cli/internal/ansi.js.map +1 -1
- package/dist/unstable/cli/internal/command.d.ts.map +1 -1
- package/dist/unstable/cli/internal/help.d.ts.map +1 -1
- package/dist/unstable/cli/internal/parser.js.map +1 -1
- package/dist/unstable/cluster/ClusterCron.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterCron.js +1 -1
- package/dist/unstable/cluster/ClusterCron.js.map +1 -1
- package/dist/unstable/cluster/ClusterError.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterSchema.d.ts +1 -1
- package/dist/unstable/cluster/ClusterSchema.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.js +2 -1
- package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/unstable/cluster/DeliverAt.d.ts.map +1 -1
- package/dist/unstable/cluster/Entity.d.ts.map +1 -1
- package/dist/unstable/cluster/Entity.js +5 -3
- package/dist/unstable/cluster/Entity.js.map +1 -1
- package/dist/unstable/cluster/EntityAddress.d.ts.map +1 -1
- package/dist/unstable/cluster/EntityId.d.ts.map +1 -1
- package/dist/unstable/cluster/EntityProxy.d.ts.map +1 -1
- package/dist/unstable/cluster/EntityProxyServer.d.ts.map +1 -1
- package/dist/unstable/cluster/EntityType.d.ts.map +1 -1
- package/dist/unstable/cluster/Envelope.d.ts.map +1 -1
- package/dist/unstable/cluster/HttpRunner.d.ts.map +1 -1
- package/dist/unstable/cluster/MachineId.d.ts.map +1 -1
- package/dist/unstable/cluster/Message.d.ts.map +1 -1
- package/dist/unstable/cluster/MessageStorage.d.ts +25 -29
- package/dist/unstable/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/unstable/cluster/Reply.d.ts.map +1 -1
- package/dist/unstable/cluster/Runner.d.ts.map +1 -1
- package/dist/unstable/cluster/RunnerAddress.d.ts.map +1 -1
- package/dist/unstable/cluster/RunnerHealth.d.ts.map +1 -1
- package/dist/unstable/cluster/RunnerServer.d.ts +1 -1
- package/dist/unstable/cluster/RunnerStorage.d.ts.map +1 -1
- package/dist/unstable/cluster/Runners.d.ts +8 -8
- package/dist/unstable/cluster/ShardId.d.ts.map +1 -1
- package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
- package/dist/unstable/cluster/Sharding.js +6 -5
- package/dist/unstable/cluster/Sharding.js.map +1 -1
- package/dist/unstable/cluster/ShardingConfig.d.ts.map +1 -1
- package/dist/unstable/cluster/ShardingRegistrationEvent.d.ts +6 -8
- package/dist/unstable/cluster/ShardingRegistrationEvent.d.ts.map +1 -1
- package/dist/unstable/cluster/SingleRunner.d.ts.map +1 -1
- package/dist/unstable/cluster/Singleton.d.ts.map +1 -1
- package/dist/unstable/cluster/SingletonAddress.d.ts.map +1 -1
- package/dist/unstable/cluster/Snowflake.d.ts +1 -1
- package/dist/unstable/cluster/Snowflake.d.ts.map +1 -1
- package/dist/unstable/cluster/Snowflake.js +1 -1
- package/dist/unstable/cluster/Snowflake.js.map +1 -1
- package/dist/unstable/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/unstable/cluster/SqlRunnerStorage.d.ts +1 -1
- package/dist/unstable/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/unstable/cluster/internal/entityManager.js +14 -14
- package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
- package/dist/unstable/cluster/internal/resourceMap.js +39 -14
- package/dist/unstable/cluster/internal/resourceMap.js.map +1 -1
- package/dist/unstable/devtools/DevTools.d.ts.map +1 -1
- package/dist/unstable/encoding/Msgpack.d.ts.map +1 -1
- package/dist/unstable/encoding/Ndjson.d.ts.map +1 -1
- package/dist/unstable/encoding/Sse.d.ts +2 -2
- package/dist/unstable/encoding/Sse.d.ts.map +1 -1
- package/dist/unstable/eventlog/Event.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventGroup.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventJournal.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventJournal.js.map +1 -1
- package/dist/unstable/eventlog/EventLog.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventLog.js +2 -2
- package/dist/unstable/eventlog/EventLog.js.map +1 -1
- package/dist/unstable/eventlog/EventLogEncryption.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventLogRemote.d.ts +21 -21
- package/dist/unstable/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventLogServerEncrypted.d.ts +1 -1
- package/dist/unstable/eventlog/EventLogServerUnencrypted.d.ts +3 -4
- package/dist/unstable/eventlog/EventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/unstable/eventlog/EventLogSessionAuth.d.ts.map +1 -1
- package/dist/unstable/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/unstable/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
- package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/unstable/http/Cookies.d.ts +1 -1
- package/dist/unstable/http/Cookies.d.ts.map +1 -1
- package/dist/unstable/http/Etag.d.ts.map +1 -1
- package/dist/unstable/http/Headers.d.ts.map +1 -1
- package/dist/unstable/http/HttpBody.d.ts.map +1 -1
- package/dist/unstable/http/HttpClient.d.ts.map +1 -1
- package/dist/unstable/http/HttpClientError.d.ts +1 -1
- package/dist/unstable/http/HttpClientError.d.ts.map +1 -1
- package/dist/unstable/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/unstable/http/HttpClientResponse.d.ts +1 -1
- package/dist/unstable/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/unstable/http/HttpClientResponse.js.map +1 -1
- package/dist/unstable/http/HttpEffect.d.ts.map +1 -1
- package/dist/unstable/http/HttpIncomingMessage.d.ts +2 -2
- package/dist/unstable/http/HttpIncomingMessage.d.ts.map +1 -1
- package/dist/unstable/http/HttpIncomingMessage.js.map +1 -1
- package/dist/unstable/http/HttpMethod.d.ts.map +1 -1
- package/dist/unstable/http/HttpMiddleware.d.ts +1 -1
- package/dist/unstable/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/unstable/http/HttpRouter.d.ts +4 -4
- package/dist/unstable/http/HttpRouter.d.ts.map +1 -1
- package/dist/unstable/http/HttpRouter.js.map +1 -1
- package/dist/unstable/http/HttpServer.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerError.d.ts +1 -1
- package/dist/unstable/http/HttpServerError.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerRequest.d.ts +8 -8
- package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerRequest.js.map +1 -1
- package/dist/unstable/http/HttpServerRespondable.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerResponse.d.ts +1 -1
- package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerResponse.js.map +1 -1
- package/dist/unstable/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/unstable/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/unstable/http/Multipart.d.ts +4 -3
- package/dist/unstable/http/Multipart.d.ts.map +1 -1
- package/dist/unstable/http/Multipart.js.map +1 -1
- package/dist/unstable/http/Url.d.ts.map +1 -1
- package/dist/unstable/http/UrlParams.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApi.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApi.js +2 -4
- package/dist/unstable/httpapi/HttpApi.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +26 -26
- package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiError.d.ts +1 -1
- package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiGroup.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiScalar.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiSchema.d.ts +1 -1
- package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiSecurity.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiSwagger.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiTest.d.ts +1 -1
- package/dist/unstable/observability/Otlp.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpExporter.js +3 -1
- package/dist/unstable/observability/OtlpExporter.js.map +1 -1
- package/dist/unstable/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpResource.d.ts.map +1 -1
- package/dist/unstable/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/unstable/observability/PrometheusMetrics.d.ts.map +1 -1
- package/dist/unstable/observability/internal/otlpEnv.d.ts.map +1 -1
- package/dist/unstable/persistence/KeyValueStore.d.ts.map +1 -1
- package/dist/unstable/persistence/KeyValueStore.js.map +1 -1
- package/dist/unstable/persistence/Persistable.d.ts.map +1 -1
- package/dist/unstable/persistence/PersistedQueue.d.ts +1 -1
- package/dist/unstable/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/unstable/persistence/Persistence.d.ts.map +1 -1
- package/dist/unstable/persistence/RateLimiter.d.ts.map +1 -1
- package/dist/unstable/persistence/Redis.d.ts.map +1 -1
- package/dist/unstable/process/ChildProcess.d.ts.map +1 -1
- package/dist/unstable/process/ChildProcess.js.map +1 -1
- package/dist/unstable/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/unstable/reactivity/AsyncResult.d.ts +2 -2
- package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/unstable/reactivity/Atom.d.ts +4 -4
- package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
- package/dist/unstable/reactivity/Atom.js.map +1 -1
- package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomRef.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomRegistry.d.ts +2 -2
- package/dist/unstable/reactivity/AtomRegistry.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomRegistry.js +28 -37
- package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
- package/dist/unstable/reactivity/AtomRpc.d.ts.map +1 -1
- package/dist/unstable/reactivity/Hydration.d.ts.map +1 -1
- package/dist/unstable/reactivity/Reactivity.d.ts.map +1 -1
- package/dist/unstable/rpc/Rpc.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcClient.d.ts +2 -1
- package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcClient.js +5 -5
- package/dist/unstable/rpc/RpcClient.js.map +1 -1
- package/dist/unstable/rpc/RpcGroup.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcMessage.d.ts +7 -7
- package/dist/unstable/rpc/RpcMessage.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcMessage.js +2 -2
- package/dist/unstable/rpc/RpcMessage.js.map +1 -1
- package/dist/unstable/rpc/RpcMiddleware.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcSchema.d.ts +1 -1
- package/dist/unstable/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcSerialization.js +8 -8
- package/dist/unstable/rpc/RpcSerialization.js.map +1 -1
- package/dist/unstable/rpc/RpcServer.d.ts +2 -2
- package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
- package/dist/unstable/rpc/RpcServer.js +5 -5
- package/dist/unstable/rpc/RpcServer.js.map +1 -1
- package/dist/unstable/rpc/RpcWorker.d.ts.map +1 -1
- package/dist/unstable/rpc/Utils.d.ts.map +1 -1
- package/dist/unstable/schema/Model.d.ts +24 -38
- package/dist/unstable/schema/Model.d.ts.map +1 -1
- package/dist/unstable/schema/VariantSchema.d.ts +1 -1
- package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
- package/dist/unstable/socket/Socket.d.ts +1 -1
- package/dist/unstable/socket/Socket.d.ts.map +1 -1
- package/dist/unstable/socket/SocketServer.d.ts.map +1 -1
- package/dist/unstable/sql/Migrator.d.ts.map +1 -1
- package/dist/unstable/sql/SqlClient.d.ts.map +1 -1
- package/dist/unstable/sql/SqlError.d.ts +2 -2
- package/dist/unstable/sql/SqlError.d.ts.map +1 -1
- package/dist/unstable/sql/SqlError.js.map +1 -1
- package/dist/unstable/sql/SqlModel.d.ts.map +1 -1
- package/dist/unstable/sql/SqlResolver.d.ts.map +1 -1
- package/dist/unstable/sql/SqlSchema.d.ts.map +1 -1
- package/dist/unstable/sql/SqlStream.d.ts.map +1 -1
- package/dist/unstable/sql/Statement.d.ts.map +1 -1
- package/dist/unstable/workers/Transferable.d.ts.map +1 -1
- package/dist/unstable/workers/Worker.d.ts.map +1 -1
- package/dist/unstable/workers/WorkerError.d.ts.map +1 -1
- package/dist/unstable/workflow/Activity.d.ts +1 -1
- package/dist/unstable/workflow/Activity.d.ts.map +1 -1
- package/dist/unstable/workflow/Activity.js +1 -1
- package/dist/unstable/workflow/Activity.js.map +1 -1
- package/dist/unstable/workflow/DurableClock.d.ts.map +1 -1
- package/dist/unstable/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/unstable/workflow/DurableQueue.d.ts.map +1 -1
- package/dist/unstable/workflow/DurableQueue.js +1 -1
- package/dist/unstable/workflow/DurableQueue.js.map +1 -1
- package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
- package/dist/unstable/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/unstable/workflow/WorkflowEngine.js +1 -1
- package/dist/unstable/workflow/WorkflowEngine.js.map +1 -1
- package/dist/unstable/workflow/WorkflowProxy.d.ts.map +1 -1
- package/dist/unstable/workflow/WorkflowProxyServer.d.ts.map +1 -1
- package/package.json +11 -12
- package/src/Config.ts +1 -1
- package/src/ConfigProvider.ts +79 -27
- package/src/Cron.ts +109 -57
- package/src/Effect.ts +131 -0
- package/src/FileSystem.ts +13 -0
- package/src/Layer.ts +6 -6
- package/src/LayerMap.ts +1 -1
- package/src/LayerRef.ts +379 -0
- package/src/Schedule.ts +1437 -4445
- package/src/Schema.ts +133 -33
- package/src/SchemaParser.ts +2 -2
- package/src/SchemaTransformation.ts +42 -2
- package/src/Stream.ts +1 -1
- package/src/internal/effect.ts +19 -0
- package/src/testing/TestSchema.ts +2 -2
- package/src/unstable/ai/Chat.ts +1 -1
- package/src/unstable/ai/LanguageModel.ts +3 -3
- package/src/unstable/cli/Argument.ts +14 -7
- package/src/unstable/cli/Flag.ts +6 -3
- package/src/unstable/cli/Param.ts +6 -3
- package/src/unstable/cli/Primitive.ts +2 -2
- package/src/unstable/cluster/ClusterCron.ts +4 -3
- package/src/unstable/cluster/ClusterWorkflowEngine.ts +5 -3
- package/src/unstable/cluster/Entity.ts +13 -14
- package/src/unstable/cluster/Sharding.ts +137 -134
- package/src/unstable/cluster/Snowflake.ts +2 -2
- package/src/unstable/cluster/internal/entityManager.ts +27 -25
- package/src/unstable/cluster/internal/resourceMap.ts +59 -25
- package/src/unstable/encoding/Sse.ts +3 -3
- package/src/unstable/eventlog/EventLog.ts +4 -3
- package/src/unstable/http/HttpClientResponse.ts +2 -3
- package/src/unstable/http/HttpIncomingMessage.ts +4 -5
- package/src/unstable/http/HttpRouter.ts +8 -10
- package/src/unstable/http/HttpServerRequest.ts +20 -19
- package/src/unstable/http/HttpServerResponse.ts +2 -2
- package/src/unstable/http/Multipart.ts +3 -3
- package/src/unstable/httpapi/HttpApi.ts +2 -4
- package/src/unstable/httpapi/HttpApiClient.ts +2 -2
- package/src/unstable/httpapi/HttpApiEndpoint.ts +7 -7
- package/src/unstable/httpapi/HttpApiSchema.ts +1 -1
- package/src/unstable/observability/OtlpExporter.ts +1 -1
- package/src/unstable/reactivity/Atom.ts +10 -7
- package/src/unstable/reactivity/AtomRegistry.ts +35 -44
- package/src/unstable/rpc/RpcClient.ts +10 -9
- package/src/unstable/rpc/RpcMessage.ts +8 -9
- package/src/unstable/rpc/RpcSerialization.ts +16 -16
- package/src/unstable/rpc/RpcServer.ts +5 -5
- package/src/unstable/workflow/Activity.ts +6 -5
- package/src/unstable/workflow/DurableQueue.ts +4 -3
- package/src/unstable/workflow/WorkflowEngine.ts +4 -3
package/dist/Schedule.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Describes policies for retrying, repeating, and pacing Effect programs.
|
|
3
|
-
*
|
|
4
|
-
* A `Schedule<Output, Input, Error, Env>` is stepped with an input value. Each
|
|
5
|
-
* step either stops or produces an output together with the delay before the
|
|
6
|
-
* next step. Schedules are used by retry, repeat, stream, and channel APIs to
|
|
7
|
-
* decide when work should continue, how long to wait, and when to stop.
|
|
8
|
-
*
|
|
9
|
-
* @since 2.0.0
|
|
10
|
-
*/
|
|
11
1
|
import * as Cause from "./Cause.js";
|
|
12
2
|
import * as Context from "./Context.js";
|
|
13
3
|
import * as Cron from "./Cron.js";
|
|
@@ -161,7 +151,7 @@ export const fromStepWithMetadata = step => fromStep(effect.map(step, f => {
|
|
|
161
151
|
* import { Effect, Schedule } from "effect"
|
|
162
152
|
*
|
|
163
153
|
* // Extract step function from an existing schedule
|
|
164
|
-
* const schedule = Schedule.exponential("100 millis").pipe(Schedule.
|
|
154
|
+
* const schedule = Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 3 }))
|
|
165
155
|
*
|
|
166
156
|
* const program = Effect.gen(function*() {
|
|
167
157
|
* const stepFn = yield* Schedule.toStep(schedule)
|
|
@@ -221,7 +211,7 @@ export const toStepWithMetadata = schedule => effect.clockWith(clock => effect.m
|
|
|
221
211
|
* import { Effect, Schedule } from "effect"
|
|
222
212
|
*
|
|
223
213
|
* // Convert schedule to step function with automatic sleeping
|
|
224
|
-
* const schedule = Schedule.spaced("1 second").pipe(Schedule.
|
|
214
|
+
* const schedule = Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 3 }))
|
|
225
215
|
*
|
|
226
216
|
* const program = Effect.gen(function*() {
|
|
227
217
|
* const stepWithSleep = yield* Schedule.toStepWithSleep(schedule)
|
|
@@ -254,10 +244,10 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
254
244
|
*
|
|
255
245
|
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
256
246
|
*
|
|
257
|
-
* // Add a deterministic extra delay based on the schedule
|
|
247
|
+
* // Add a deterministic extra delay based on the schedule metadata
|
|
258
248
|
* const delayedSchedule = Schedule.addDelay(
|
|
259
|
-
* Schedule.exponential("100 millis").pipe(Schedule.
|
|
260
|
-
* (output) =>
|
|
249
|
+
* Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 5 })),
|
|
250
|
+
* ({ output }) =>
|
|
261
251
|
* Effect.succeed(Duration.millis(Duration.toMillis(output) * 0.25))
|
|
262
252
|
* )
|
|
263
253
|
*
|
|
@@ -265,7 +255,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
265
255
|
* yield* Effect.repeat(
|
|
266
256
|
* Effect.succeed("delayed task"),
|
|
267
257
|
* delayedSchedule.pipe(
|
|
268
|
-
* Schedule.
|
|
258
|
+
* Schedule.tap(({ output: delay }) =>
|
|
269
259
|
* Console.log(`Base delay: ${delay}`)
|
|
270
260
|
* )
|
|
271
261
|
* )
|
|
@@ -275,7 +265,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
275
265
|
* // Add adaptive delay based on execution count
|
|
276
266
|
* const adaptiveSchedule = Schedule.addDelay(
|
|
277
267
|
* Schedule.recurs(6),
|
|
278
|
-
* (executionCount) =>
|
|
268
|
+
* ({ output: executionCount }) =>
|
|
279
269
|
* // Increase delay as execution count grows
|
|
280
270
|
* Effect.succeed(Duration.millis(executionCount * 200))
|
|
281
271
|
* )
|
|
@@ -287,7 +277,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
287
277
|
* return "adaptive"
|
|
288
278
|
* }),
|
|
289
279
|
* adaptiveSchedule.pipe(
|
|
290
|
-
* Schedule.
|
|
280
|
+
* Schedule.tap(({ output: count }) =>
|
|
291
281
|
* Console.log(`Execution ${count + 1} with adaptive delay`)
|
|
292
282
|
* )
|
|
293
283
|
* )
|
|
@@ -298,8 +288,8 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
298
288
|
* const loadByExecution = [1, 3, 2, 4] as const
|
|
299
289
|
*
|
|
300
290
|
* const dynamicSchedule = Schedule.addDelay(
|
|
301
|
-
* Schedule.spaced("1 second").pipe(Schedule.
|
|
302
|
-
* (executionNumber) => {
|
|
291
|
+
* Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 4 })),
|
|
292
|
+
* ({ output: executionNumber }) => {
|
|
303
293
|
* const load = loadByExecution[executionNumber] ?? 1
|
|
304
294
|
* return Effect.succeed(Duration.millis(load * 100))
|
|
305
295
|
* }
|
|
@@ -317,7 +307,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
317
307
|
*
|
|
318
308
|
* // Combine with retry for progressive backoff
|
|
319
309
|
* const progressiveRetrySchedule = Schedule.addDelay(
|
|
320
|
-
* Schedule.exponential("50 millis").pipe(Schedule.
|
|
310
|
+
* Schedule.exponential("50 millis").pipe(Schedule.upTo({ times: 4 })),
|
|
321
311
|
* () => Effect.succeed(Duration.millis(100)) // Fixed additional delay
|
|
322
312
|
* )
|
|
323
313
|
*
|
|
@@ -342,7 +332,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
|
|
|
342
332
|
* @category delays & timeouts
|
|
343
333
|
* @since 2.0.0
|
|
344
334
|
*/
|
|
345
|
-
export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self,
|
|
335
|
+
export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, metadata => effect.map(f(metadata), d => Duration.sum(Duration.fromInputUnsafe(d), metadata.duration))));
|
|
346
336
|
/**
|
|
347
337
|
* Returns a schedule that runs `self` to completion, then runs `other`, and
|
|
348
338
|
* merges their outputs.
|
|
@@ -356,10 +346,10 @@ export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, (out
|
|
|
356
346
|
*
|
|
357
347
|
* // First retry 3 times quickly, then switch to slower retries
|
|
358
348
|
* const quickRetries = Schedule.exponential("100 millis").pipe(
|
|
359
|
-
* Schedule.
|
|
349
|
+
* Schedule.upTo({ times: 3 })
|
|
360
350
|
* )
|
|
361
351
|
* const slowRetries = Schedule.exponential("1 second").pipe(
|
|
362
|
-
* Schedule.
|
|
352
|
+
* Schedule.upTo({ times: 2 })
|
|
363
353
|
* )
|
|
364
354
|
*
|
|
365
355
|
* const combinedRetries = Schedule.andThen(quickRetries, slowRetries)
|
|
@@ -383,7 +373,9 @@ export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, (out
|
|
|
383
373
|
* @category sequencing
|
|
384
374
|
* @since 2.0.0
|
|
385
375
|
*/
|
|
386
|
-
export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(self, other),
|
|
376
|
+
export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(self, other), ({
|
|
377
|
+
output
|
|
378
|
+
}) => effect.succeed(Result.merge(output))));
|
|
387
379
|
/**
|
|
388
380
|
* Returns a schedule that runs `self` to completion, then runs `other`, and
|
|
389
381
|
* preserves which schedule produced each output.
|
|
@@ -401,8 +393,8 @@ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(s
|
|
|
401
393
|
*
|
|
402
394
|
* // Track which phase of the schedule we're in
|
|
403
395
|
* const phaseTracker = Schedule.andThenResult(
|
|
404
|
-
* Schedule.exponential("100 millis").pipe(Schedule.
|
|
405
|
-
* Schedule.spaced("500 millis").pipe(Schedule.
|
|
396
|
+
* Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 2 })),
|
|
397
|
+
* Schedule.spaced("500 millis").pipe(Schedule.upTo({ times: 2 }))
|
|
406
398
|
* )
|
|
407
399
|
*
|
|
408
400
|
* const program = Effect.gen(function*() {
|
|
@@ -412,7 +404,7 @@ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(s
|
|
|
412
404
|
* return "task-result"
|
|
413
405
|
* }),
|
|
414
406
|
* phaseTracker.pipe(
|
|
415
|
-
* Schedule.
|
|
407
|
+
* Schedule.tap(({ output: result }) =>
|
|
416
408
|
* Result.match(result, {
|
|
417
409
|
* onFailure: (phase1Output) => Console.log(`Phase 1: ${phase1Output}`),
|
|
418
410
|
* onSuccess: (phase2Output) => Console.log(`Phase 2: ${phase2Output}`)
|
|
@@ -429,8 +421,12 @@ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(s
|
|
|
429
421
|
export const andThenResult = /*#__PURE__*/dual(2, (self, other) => fromStep(effect.sync(() => {
|
|
430
422
|
let currentSide = 0;
|
|
431
423
|
let currentStep;
|
|
432
|
-
const left = map(self,
|
|
433
|
-
|
|
424
|
+
const left = map(self, ({
|
|
425
|
+
output
|
|
426
|
+
}) => Result.fail(output));
|
|
427
|
+
const right = map(other, ({
|
|
428
|
+
output
|
|
429
|
+
}) => Result.succeed(output));
|
|
434
430
|
return function recur(now, input) {
|
|
435
431
|
if (currentStep) return currentStep(now, input);
|
|
436
432
|
return toStep(currentSide === 0 ? left : right).pipe(effect.flatMap(step => {
|
|
@@ -448,366 +444,70 @@ export const andThenResult = /*#__PURE__*/dual(2, (self, other) => fromStep(effe
|
|
|
448
444
|
};
|
|
449
445
|
})));
|
|
450
446
|
/**
|
|
451
|
-
* Combines
|
|
452
|
-
*
|
|
453
|
-
* outputting a tuple of the outputs of both schedules.
|
|
447
|
+
* Combines schedules by recurring while all schedules want to recur, using the
|
|
448
|
+
* maximum delay between recurrences and outputting that maximum delay.
|
|
454
449
|
*
|
|
455
450
|
* **When to use**
|
|
456
451
|
*
|
|
457
|
-
* Use when
|
|
452
|
+
* Use when a combined policy should continue only while every schedule still
|
|
453
|
+
* recurs, and should wait for the slowest schedule between recurrences.
|
|
458
454
|
*
|
|
459
|
-
* **Example** (Combining
|
|
455
|
+
* **Example** (Combining retry schedules by their maximum delay)
|
|
460
456
|
*
|
|
461
457
|
* ```ts
|
|
462
458
|
* import { Console, Data, Effect, Schedule } from "effect"
|
|
463
459
|
*
|
|
464
460
|
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
465
461
|
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
* const bothSchedule = Schedule.both(timeLimit, attemptLimit)
|
|
472
|
-
* // Outputs: [time_result, attempt_count] tuple
|
|
462
|
+
* const retrySchedule = Schedule.max([
|
|
463
|
+
* Schedule.fixed("5 seconds"),
|
|
464
|
+
* Schedule.exponential("5 seconds"),
|
|
465
|
+
* Schedule.spaced("10 seconds")
|
|
466
|
+
* ])
|
|
473
467
|
*
|
|
474
468
|
* const program = Effect.gen(function*() {
|
|
475
|
-
* const results = yield* Effect.repeat(
|
|
476
|
-
* Effect.gen(function*() {
|
|
477
|
-
* yield* Console.log("Task executed")
|
|
478
|
-
* return "task completed"
|
|
479
|
-
* }),
|
|
480
|
-
* bothSchedule.pipe(
|
|
481
|
-
* Schedule.tapOutput(([timeResult, attemptResult]) =>
|
|
482
|
-
* Console.log(`Time: ${timeResult}, Attempts: ${attemptResult}`)
|
|
483
|
-
* )
|
|
484
|
-
* )
|
|
485
|
-
* )
|
|
486
|
-
*
|
|
487
|
-
* yield* Console.log("Completed all executions")
|
|
488
|
-
* })
|
|
489
|
-
*
|
|
490
|
-
* // Both with different delay strategies - uses maximum delay
|
|
491
|
-
* const fastSchedule = Schedule.fixed("500 millis").pipe(Schedule.take(4))
|
|
492
|
-
* const slowSchedule = Schedule.spaced("2 seconds").pipe(Schedule.take(6))
|
|
493
|
-
*
|
|
494
|
-
* // Will use the slower (maximum) delay and stop when first schedule exhausts
|
|
495
|
-
* const conservativeSchedule = Schedule.both(fastSchedule, slowSchedule)
|
|
496
|
-
*
|
|
497
|
-
* const retryProgram = Effect.gen(function*() {
|
|
498
469
|
* let attempt = 0
|
|
499
470
|
*
|
|
500
|
-
*
|
|
471
|
+
* yield* Effect.retry(
|
|
501
472
|
* Effect.gen(function*() {
|
|
502
473
|
* attempt++
|
|
503
474
|
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
504
|
-
*
|
|
505
475
|
* if (attempt < 3) {
|
|
506
476
|
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
507
477
|
* }
|
|
508
|
-
*
|
|
509
|
-
* return `Success on attempt ${attempt}`
|
|
510
|
-
* }),
|
|
511
|
-
* conservativeSchedule
|
|
512
|
-
* )
|
|
513
|
-
*
|
|
514
|
-
* yield* Console.log(`Final result: ${result}`)
|
|
515
|
-
* })
|
|
516
|
-
*
|
|
517
|
-
* // Both provides intersection semantics (AND logic)
|
|
518
|
-
* // Compare with either which provides union semantics (OR logic)
|
|
519
|
-
* ```
|
|
520
|
-
*
|
|
521
|
-
* @see {@link either} for continuing while either schedule still recurs
|
|
522
|
-
*
|
|
523
|
-
* @category combining
|
|
524
|
-
* @since 2.0.0
|
|
525
|
-
*/
|
|
526
|
-
export const both = /*#__PURE__*/dual(2, (self, other) => bothWith(self, other, (left, right) => [left, right]));
|
|
527
|
-
/**
|
|
528
|
-
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
529
|
-
* to recur, using the maximum of the two durations between recurrences and
|
|
530
|
-
* outputting the result of the left schedule (i.e. `self`).
|
|
531
|
-
*
|
|
532
|
-
* **When to use**
|
|
533
|
-
*
|
|
534
|
-
* Use when two schedules must both allow recurrence and only the left schedule's
|
|
535
|
-
* output is needed.
|
|
536
|
-
*
|
|
537
|
-
* **Example** (Combining schedules and keeping the left output)
|
|
538
|
-
*
|
|
539
|
-
* ```ts
|
|
540
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
541
|
-
*
|
|
542
|
-
* // Combine two schedules, keeping left output
|
|
543
|
-
* const leftSchedule = Schedule.exponential("100 millis").pipe(
|
|
544
|
-
* Schedule.map(() => Effect.succeed("left-result"))
|
|
545
|
-
* )
|
|
546
|
-
* const rightSchedule = Schedule.spaced("50 millis")
|
|
547
|
-
*
|
|
548
|
-
* const combined = Schedule.bothLeft(leftSchedule, rightSchedule)
|
|
549
|
-
*
|
|
550
|
-
* const program = Effect.gen(function*() {
|
|
551
|
-
* yield* Effect.repeat(
|
|
552
|
-
* Effect.gen(function*() {
|
|
553
|
-
* yield* Console.log("Task executed")
|
|
554
|
-
* return "task-done"
|
|
555
|
-
* }),
|
|
556
|
-
* combined.pipe(Schedule.take(3))
|
|
557
|
-
* )
|
|
558
|
-
* })
|
|
559
|
-
* ```
|
|
560
|
-
*
|
|
561
|
-
* @category combining
|
|
562
|
-
* @since 2.0.0
|
|
563
|
-
*/
|
|
564
|
-
export const bothLeft = /*#__PURE__*/dual(2, (self, other) => bothWith(self, other, output => output));
|
|
565
|
-
/**
|
|
566
|
-
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
567
|
-
* to recur, using the maximum of the two durations between recurrences and
|
|
568
|
-
* outputting the result of the right schedule (i.e. `other`).
|
|
569
|
-
*
|
|
570
|
-
* **When to use**
|
|
571
|
-
*
|
|
572
|
-
* Use when two schedules must both allow recurrence and only the right
|
|
573
|
-
* schedule's output is needed.
|
|
574
|
-
*
|
|
575
|
-
* **Example** (Combining schedules and keeping the right output)
|
|
576
|
-
*
|
|
577
|
-
* ```ts
|
|
578
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
579
|
-
*
|
|
580
|
-
* // Combine two schedules, keeping right output
|
|
581
|
-
* const leftSchedule = Schedule.exponential("100 millis").pipe(
|
|
582
|
-
* Schedule.map(() => Effect.succeed("left-result"))
|
|
583
|
-
* )
|
|
584
|
-
* const rightSchedule = Schedule.spaced("50 millis").pipe(
|
|
585
|
-
* Schedule.map(() => Effect.succeed("right-result"))
|
|
586
|
-
* )
|
|
587
|
-
*
|
|
588
|
-
* const combined = Schedule.bothRight(leftSchedule, rightSchedule)
|
|
589
|
-
*
|
|
590
|
-
* const program = Effect.gen(function*() {
|
|
591
|
-
* yield* Effect.repeat(
|
|
592
|
-
* Effect.gen(function*() {
|
|
593
|
-
* yield* Console.log("Task executed")
|
|
594
|
-
* return "task-done"
|
|
595
|
-
* }),
|
|
596
|
-
* combined.pipe(Schedule.take(3))
|
|
597
|
-
* )
|
|
598
|
-
* })
|
|
599
|
-
* ```
|
|
600
|
-
*
|
|
601
|
-
* @category combining
|
|
602
|
-
* @since 2.0.0
|
|
603
|
-
*/
|
|
604
|
-
export const bothRight = /*#__PURE__*/dual(2, (self, other) => bothWith(self, other, (_, output) => output));
|
|
605
|
-
/**
|
|
606
|
-
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
607
|
-
* to recur, using the maximum of the two durations between recurrences and
|
|
608
|
-
* outputting the result of the combination of both schedule outputs using the
|
|
609
|
-
* specified `combine` function.
|
|
610
|
-
*
|
|
611
|
-
* **When to use**
|
|
612
|
-
*
|
|
613
|
-
* Use when two schedules must both allow recurrence and their outputs should be
|
|
614
|
-
* combined into a custom value.
|
|
615
|
-
*
|
|
616
|
-
* **Example** (Combining schedule outputs)
|
|
617
|
-
*
|
|
618
|
-
* ```ts
|
|
619
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
620
|
-
*
|
|
621
|
-
* // Combine two schedules with custom output combination
|
|
622
|
-
* const leftSchedule = Schedule.exponential("100 millis").pipe(
|
|
623
|
-
* Schedule.map(() => Effect.succeed("left"))
|
|
624
|
-
* )
|
|
625
|
-
* const rightSchedule = Schedule.spaced("50 millis").pipe(
|
|
626
|
-
* Schedule.map(() => Effect.succeed("right"))
|
|
627
|
-
* )
|
|
628
|
-
*
|
|
629
|
-
* const combined = Schedule.bothWith(
|
|
630
|
-
* leftSchedule,
|
|
631
|
-
* rightSchedule,
|
|
632
|
-
* (left, right) => `${left}-${right}`
|
|
633
|
-
* )
|
|
634
|
-
*
|
|
635
|
-
* const program = Effect.gen(function*() {
|
|
636
|
-
* yield* Effect.repeat(
|
|
637
|
-
* Effect.gen(function*() {
|
|
638
|
-
* yield* Console.log("Task executed")
|
|
639
|
-
* return "task-result"
|
|
478
|
+
* return "success"
|
|
640
479
|
* }),
|
|
641
|
-
*
|
|
480
|
+
* retrySchedule.pipe(
|
|
481
|
+
* Schedule.tap(({ output: duration }) =>
|
|
482
|
+
* Console.log(`Waiting for the slowest schedule: ${duration}`)
|
|
483
|
+
* )
|
|
484
|
+
* )
|
|
642
485
|
* )
|
|
643
486
|
* })
|
|
644
487
|
* ```
|
|
645
488
|
*
|
|
646
489
|
* @category combining
|
|
647
|
-
* @since 2.0.0
|
|
648
|
-
*/
|
|
649
|
-
export const bothWith = /*#__PURE__*/dual(3, (self, other, combine) => fromStep(effect.map(effect.zip(toStep(self), toStep(other)), ([stepLeft, stepRight]) => (now, input) => Pull.matchEffect(stepLeft(now, input), {
|
|
650
|
-
onSuccess: leftResult => stepRight(now, input).pipe(effect.map(rightResult => [combine(leftResult[0], rightResult[0]), Duration.max(leftResult[1], rightResult[1])]), Pull.catchDone(rightDone => Cause.done(combine(leftResult[0], rightDone)))),
|
|
651
|
-
onDone: leftDone => stepRight(now, input).pipe(effect.flatMap(rightResult => Cause.done(combine(leftDone, rightResult[0]))), Pull.catchDone(rightDone => Cause.done(combine(leftDone, rightDone)))),
|
|
652
|
-
onFailure: effect.failCause
|
|
653
|
-
}))));
|
|
654
|
-
/**
|
|
655
|
-
* Returns a new `Schedule` that follows `self` and outputs the inputs seen so
|
|
656
|
-
* far as an array.
|
|
657
|
-
*
|
|
658
|
-
* **Details**
|
|
659
|
-
*
|
|
660
|
-
* This does not make the schedule run forever. The collected schedule stops
|
|
661
|
-
* when `self` stops and fails when `self` fails.
|
|
662
|
-
*
|
|
663
|
-
* **Example** (Collecting schedule inputs)
|
|
664
|
-
*
|
|
665
|
-
* ```ts
|
|
666
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
667
|
-
*
|
|
668
|
-
* // Collect all inputs passed to the schedule
|
|
669
|
-
* const inputCollector = Schedule.collectInputs(
|
|
670
|
-
* Schedule.spaced("100 millis")
|
|
671
|
-
* )
|
|
672
|
-
*
|
|
673
|
-
* const program = Effect.gen(function*() {
|
|
674
|
-
* let counter = 0
|
|
675
|
-
* yield* Effect.repeat(
|
|
676
|
-
* Effect.gen(function*() {
|
|
677
|
-
* counter++
|
|
678
|
-
* yield* Console.log(`Iteration ${counter}`)
|
|
679
|
-
* return `result-${counter}`
|
|
680
|
-
* }),
|
|
681
|
-
* inputCollector.pipe(Schedule.take(4))
|
|
682
|
-
* )
|
|
683
|
-
* })
|
|
684
|
-
* ```
|
|
685
|
-
*
|
|
686
|
-
* @category collecting
|
|
687
|
-
* @since 4.0.0
|
|
688
|
-
*/
|
|
689
|
-
export const collectInputs = self => collectWhile(passthrough(self), () => effect.succeed(true));
|
|
690
|
-
/**
|
|
691
|
-
* Returns a new `Schedule` that follows `self` and outputs the schedule outputs
|
|
692
|
-
* seen so far as an array.
|
|
693
|
-
*
|
|
694
|
-
* **Details**
|
|
695
|
-
*
|
|
696
|
-
* This does not make the schedule run forever. The collected schedule stops
|
|
697
|
-
* when `self` stops and fails when `self` fails.
|
|
698
|
-
*
|
|
699
|
-
* **Example** (Collecting schedule outputs)
|
|
700
|
-
*
|
|
701
|
-
* ```ts
|
|
702
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
703
|
-
*
|
|
704
|
-
* // Collect all outputs from the schedule
|
|
705
|
-
* const outputCollector = Schedule.collectOutputs(
|
|
706
|
-
* Schedule.recurs(4)
|
|
707
|
-
* )
|
|
708
|
-
*
|
|
709
|
-
* const program = Effect.gen(function*() {
|
|
710
|
-
* yield* Effect.repeat(
|
|
711
|
-
* Effect.gen(function*() {
|
|
712
|
-
* yield* Console.log("Task executed")
|
|
713
|
-
* return "task-result"
|
|
714
|
-
* }),
|
|
715
|
-
* outputCollector.pipe(Schedule.take(4))
|
|
716
|
-
* )
|
|
717
|
-
* })
|
|
718
|
-
* ```
|
|
719
|
-
*
|
|
720
|
-
* @category collecting
|
|
721
490
|
* @since 4.0.0
|
|
722
491
|
*/
|
|
723
|
-
export const
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
*
|
|
743
|
-
* const attempts = yield* Effect.repeat(
|
|
744
|
-
* Effect.gen(function*() {
|
|
745
|
-
* attempt++
|
|
746
|
-
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
747
|
-
* return `attempt-${attempt}`
|
|
748
|
-
* }),
|
|
749
|
-
* collectWhileSmall
|
|
750
|
-
* )
|
|
751
|
-
*
|
|
752
|
-
* yield* Console.log(`Collected attempts: [${attempts.join(", ")}]`)
|
|
753
|
-
* })
|
|
754
|
-
*
|
|
755
|
-
* // Collect with effectful predicate
|
|
756
|
-
* const collectWithCheck = Schedule.collectWhile(
|
|
757
|
-
* Schedule.fixed("1 second"),
|
|
758
|
-
* (metadata) =>
|
|
759
|
-
* Effect.gen(function*() {
|
|
760
|
-
* const shouldContinue = metadata.attempt < 5
|
|
761
|
-
* yield* Console.log(
|
|
762
|
-
* `Check ${metadata.attempt}: continue = ${shouldContinue}`
|
|
763
|
-
* )
|
|
764
|
-
* return shouldContinue
|
|
765
|
-
* })
|
|
766
|
-
* )
|
|
767
|
-
*
|
|
768
|
-
* const effectfulProgram = Effect.gen(function*() {
|
|
769
|
-
* const results = yield* Effect.repeat(
|
|
770
|
-
* Effect.succeed("checked"),
|
|
771
|
-
* collectWithCheck
|
|
772
|
-
* )
|
|
773
|
-
*
|
|
774
|
-
* yield* Console.log(`Final collection: ${results.length} items`)
|
|
775
|
-
* })
|
|
776
|
-
*
|
|
777
|
-
* // Collect samples with condition
|
|
778
|
-
* const samples = [12, 18, 24, 30, 36]
|
|
779
|
-
*
|
|
780
|
-
* const collectSamples = Schedule.collectWhile(
|
|
781
|
-
* Schedule.spaced("200 millis"),
|
|
782
|
-
* (metadata) =>
|
|
783
|
-
* Effect.succeed(metadata.attempt <= 5 && metadata.elapsed < 2000)
|
|
784
|
-
* )
|
|
785
|
-
*
|
|
786
|
-
* const samplingProgram = Effect.gen(function*() {
|
|
787
|
-
* let index = 0
|
|
788
|
-
* const collected = yield* Effect.repeat(
|
|
789
|
-
* Effect.gen(function*() {
|
|
790
|
-
* const sample = samples[index++]
|
|
791
|
-
* yield* Console.log(`Sample: ${sample}`)
|
|
792
|
-
* return sample
|
|
793
|
-
* }),
|
|
794
|
-
* collectSamples
|
|
795
|
-
* )
|
|
796
|
-
*
|
|
797
|
-
* const average = collected.reduce((sum, s) => sum + s, 0) / collected.length
|
|
798
|
-
* yield* Console.log(
|
|
799
|
-
* `Collected ${collected.length} samples, average: ${average.toFixed(1)}`
|
|
800
|
-
* )
|
|
801
|
-
* })
|
|
802
|
-
* ```
|
|
803
|
-
*
|
|
804
|
-
* @category collecting
|
|
805
|
-
* @since 2.0.0
|
|
806
|
-
*/
|
|
807
|
-
export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(while_(self, predicate), () => [], (outputs, output) => {
|
|
808
|
-
outputs.push(output);
|
|
809
|
-
return outputs;
|
|
810
|
-
}));
|
|
492
|
+
export const max = schedules => fromStep(effect.map(effect.all(schedules.map(toStep)), steps => (now, input) => effect.flatMap(effect.forEach(steps, step => Pull.matchEffect(step(now, input), {
|
|
493
|
+
onSuccess: result => effect.succeed(result[1]),
|
|
494
|
+
onDone: () => effect.undefined,
|
|
495
|
+
onFailure: effect.failCause
|
|
496
|
+
})), results => {
|
|
497
|
+
const duration = maxDuration(results);
|
|
498
|
+
if (duration === undefined) {
|
|
499
|
+
return Cause.done(Duration.zero);
|
|
500
|
+
}
|
|
501
|
+
return effect.succeed([duration, duration]);
|
|
502
|
+
})));
|
|
503
|
+
const maxDuration = results => {
|
|
504
|
+
let max = results[0];
|
|
505
|
+
for (let i = 1; i < results.length; i++) {
|
|
506
|
+
max = results[i] && max && Duration.max(max, results[i]);
|
|
507
|
+
if (max === undefined) break;
|
|
508
|
+
}
|
|
509
|
+
return max;
|
|
510
|
+
};
|
|
811
511
|
/**
|
|
812
512
|
* Returns a new `Schedule` that recurs on the specified `Cron` schedule and
|
|
813
513
|
* outputs the duration between recurrences.
|
|
@@ -829,8 +529,8 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
829
529
|
* return "minute"
|
|
830
530
|
* }),
|
|
831
531
|
* everyMinute.pipe(
|
|
832
|
-
* Schedule.
|
|
833
|
-
* Schedule.
|
|
532
|
+
* Schedule.upTo({ times: 3 }), // Run only 3 times for demo
|
|
533
|
+
* Schedule.tap(({ output: duration }) =>
|
|
834
534
|
* Console.log(`Next execution in: ${duration}`)
|
|
835
535
|
* )
|
|
836
536
|
* )
|
|
@@ -850,7 +550,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
850
550
|
* return "backup-done"
|
|
851
551
|
* }),
|
|
852
552
|
* dailyBackup.pipe(
|
|
853
|
-
* Schedule.
|
|
553
|
+
* Schedule.upTo({ times: 2 }) // Run 2 times for demo
|
|
854
554
|
* )
|
|
855
555
|
* )
|
|
856
556
|
* })
|
|
@@ -869,7 +569,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
869
569
|
* yield* Console.log(`Report generated: ${JSON.stringify(report)}`)
|
|
870
570
|
* return report
|
|
871
571
|
* }),
|
|
872
|
-
* weeklyReport.pipe(Schedule.
|
|
572
|
+
* weeklyReport.pipe(Schedule.upTo({ times: 1 }))
|
|
873
573
|
* )
|
|
874
574
|
* })
|
|
875
575
|
*
|
|
@@ -888,7 +588,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
888
588
|
* return status
|
|
889
589
|
* }),
|
|
890
590
|
* businessHoursCheck.pipe(
|
|
891
|
-
* Schedule.
|
|
591
|
+
* Schedule.upTo({ times: 4 }) // Demo with 4 checks
|
|
892
592
|
* )
|
|
893
593
|
* )
|
|
894
594
|
* })
|
|
@@ -904,13 +604,13 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
904
604
|
* yield* Console.log(`Processed ${invoiceCount} invoices`)
|
|
905
605
|
* return { count: invoiceCount, batch: "2024-01-a" }
|
|
906
606
|
* }),
|
|
907
|
-
* monthlyInvoice.pipe(Schedule.
|
|
607
|
+
* monthlyInvoice.pipe(Schedule.upTo({ times: 1 }))
|
|
908
608
|
* )
|
|
909
609
|
* })
|
|
910
610
|
*
|
|
911
611
|
* // Complex cron with error handling
|
|
912
612
|
* const complexCron = Schedule.cron("0 2,4,6 * * *").pipe(
|
|
913
|
-
* Schedule.
|
|
613
|
+
* Schedule.tap(({ output: duration }) =>
|
|
914
614
|
* Console.log(`Scheduled to run again in ${duration}`)
|
|
915
615
|
* )
|
|
916
616
|
* )
|
|
@@ -927,7 +627,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
927
627
|
* }
|
|
928
628
|
* return "success"
|
|
929
629
|
* }),
|
|
930
|
-
* complexCron.pipe(Schedule.
|
|
630
|
+
* complexCron.pipe(Schedule.upTo({ times: 3 }))
|
|
931
631
|
* ).pipe(
|
|
932
632
|
* Effect.catch((error: unknown) =>
|
|
933
633
|
* Console.log(`Cron task error: ${String(error)}`)
|
|
@@ -941,97 +641,17 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
|
|
|
941
641
|
*/
|
|
942
642
|
export const cron = (expression, tz) => {
|
|
943
643
|
const parsed = Cron.isCron(expression) ? Result.succeed(expression) : Cron.parse(expression, tz);
|
|
944
|
-
return fromStep(effect.map(effect.fromResult(parsed), cron => (now, _) =>
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
644
|
+
return fromStep(effect.map(effect.fromResult(parsed), cron => (now, _) => {
|
|
645
|
+
if (now === Number.POSITIVE_INFINITY) {
|
|
646
|
+
return Cause.done(Duration.zero);
|
|
647
|
+
}
|
|
648
|
+
return effect.sync(() => {
|
|
649
|
+
const next = Cron.next(cron, now).getTime();
|
|
650
|
+
const duration = Duration.millis(next - now);
|
|
651
|
+
return [duration, duration];
|
|
652
|
+
});
|
|
653
|
+
}));
|
|
949
654
|
};
|
|
950
|
-
/**
|
|
951
|
-
* Returns a new schedule that outputs the delay between each occurrence.
|
|
952
|
-
*
|
|
953
|
-
* **Example** (Extracting schedule delays)
|
|
954
|
-
*
|
|
955
|
-
* ```ts
|
|
956
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
957
|
-
*
|
|
958
|
-
* // Extract delays from an exponential backoff schedule
|
|
959
|
-
* const exponentialDelays = Schedule.delays(
|
|
960
|
-
* Schedule.exponential("100 millis").pipe(Schedule.take(5))
|
|
961
|
-
* )
|
|
962
|
-
*
|
|
963
|
-
* const delayProgram = Effect.gen(function*() {
|
|
964
|
-
* yield* Effect.repeat(
|
|
965
|
-
* Effect.gen(function*() {
|
|
966
|
-
* yield* Console.log("Task executed")
|
|
967
|
-
* return "task result"
|
|
968
|
-
* }),
|
|
969
|
-
* exponentialDelays.pipe(
|
|
970
|
-
* Schedule.tapOutput((delay) =>
|
|
971
|
-
* Console.log(`Waiting ${delay} before next execution`)
|
|
972
|
-
* )
|
|
973
|
-
* )
|
|
974
|
-
* )
|
|
975
|
-
* })
|
|
976
|
-
*
|
|
977
|
-
* // Monitor delays from a Fibonacci schedule
|
|
978
|
-
* const fibonacciDelays = Schedule.delays(
|
|
979
|
-
* Schedule.fibonacci("200 millis").pipe(Schedule.take(8))
|
|
980
|
-
* )
|
|
981
|
-
*
|
|
982
|
-
* const fibDelayProgram = Effect.gen(function*() {
|
|
983
|
-
* yield* Effect.repeat(
|
|
984
|
-
* Console.log("Fibonacci task"),
|
|
985
|
-
* fibonacciDelays.pipe(
|
|
986
|
-
* Schedule.tapOutput((delay) => Console.log(`Fibonacci delay: ${delay}`))
|
|
987
|
-
* )
|
|
988
|
-
* )
|
|
989
|
-
* })
|
|
990
|
-
*
|
|
991
|
-
* // Extract delays for analysis or logging
|
|
992
|
-
* const analyzeDelays = Schedule.delays(
|
|
993
|
-
* Schedule.spaced("1 second").pipe(Schedule.take(3))
|
|
994
|
-
* ).pipe(
|
|
995
|
-
* Schedule.tapOutput((delay) =>
|
|
996
|
-
* Effect.gen(function*() {
|
|
997
|
-
* yield* Console.log(`Recorded delay: ${delay}`)
|
|
998
|
-
* // In real applications, might send to metrics system
|
|
999
|
-
* })
|
|
1000
|
-
* )
|
|
1001
|
-
* )
|
|
1002
|
-
*
|
|
1003
|
-
* // Combine delays with other schedules for complex timing
|
|
1004
|
-
* const adaptiveSchedule = Schedule.unfold(100, (delay) => Effect.succeed(delay * 1.5)).pipe(
|
|
1005
|
-
* Schedule.take(6)
|
|
1006
|
-
* )
|
|
1007
|
-
*
|
|
1008
|
-
* const adaptiveDelays = Schedule.delays(adaptiveSchedule)
|
|
1009
|
-
*
|
|
1010
|
-
* const adaptiveProgram = Effect.gen(function*() {
|
|
1011
|
-
* yield* Effect.repeat(
|
|
1012
|
-
* Effect.gen(function*() {
|
|
1013
|
-
* yield* Console.log("Adaptive task execution")
|
|
1014
|
-
* return "completed"
|
|
1015
|
-
* }),
|
|
1016
|
-
* adaptiveDelays.pipe(
|
|
1017
|
-
* Schedule.tapOutput((delay) => Console.log(`Adaptive delay: ${delay}`))
|
|
1018
|
-
* )
|
|
1019
|
-
* )
|
|
1020
|
-
* })
|
|
1021
|
-
*
|
|
1022
|
-
* // Use delays to implement custom timing logic
|
|
1023
|
-
* const customTimingSchedule = Schedule.delays(
|
|
1024
|
-
* Schedule.exponential("50 millis").pipe(Schedule.take(4))
|
|
1025
|
-
* ).pipe(
|
|
1026
|
-
* Schedule.map((delay) => Effect.succeed(`Next execution in ${delay}`)),
|
|
1027
|
-
* Schedule.tapOutput((message) => Console.log(message))
|
|
1028
|
-
* )
|
|
1029
|
-
* ```
|
|
1030
|
-
*
|
|
1031
|
-
* @category constructors
|
|
1032
|
-
* @since 2.0.0
|
|
1033
|
-
*/
|
|
1034
|
-
export const delays = self => fromStep(effect.map(toStep(self), step => (now, input) => Pull.catchDone(effect.map(step(now, input), ([_, duration]) => [duration, duration]), _ => Cause.done(Duration.zero))));
|
|
1035
655
|
/**
|
|
1036
656
|
* Returns a schedule that recurs once after the specified duration.
|
|
1037
657
|
*
|
|
@@ -1090,7 +710,7 @@ export const duration = durationInput => {
|
|
|
1090
710
|
* return "task done"
|
|
1091
711
|
* }),
|
|
1092
712
|
* fiveSecondSchedule.pipe(
|
|
1093
|
-
* Schedule.
|
|
713
|
+
* Schedule.tap(({ output: elapsedDuration }) =>
|
|
1094
714
|
* Console.log(`Total elapsed: ${elapsedDuration}`)
|
|
1095
715
|
* )
|
|
1096
716
|
* )
|
|
@@ -1100,10 +720,11 @@ export const duration = durationInput => {
|
|
|
1100
720
|
* })
|
|
1101
721
|
*
|
|
1102
722
|
* // Combine with other schedules for time-bounded execution
|
|
1103
|
-
* const timeAndCountLimited = Schedule.
|
|
1104
|
-
* Schedule.
|
|
1105
|
-
* Schedule.
|
|
1106
|
-
*
|
|
723
|
+
* const timeAndCountLimited = Schedule.max([
|
|
724
|
+
* Schedule.spaced("1 second"),
|
|
725
|
+
* Schedule.during("10 seconds"), // Stop after 10 seconds OR
|
|
726
|
+
* Schedule.recurs(15) // 15 attempts, whichever comes first
|
|
727
|
+
* ])
|
|
1107
728
|
*
|
|
1108
729
|
* // Burst execution within time window
|
|
1109
730
|
* const burstWindow = Schedule.during("3 seconds")
|
|
@@ -1123,9 +744,10 @@ export const duration = durationInput => {
|
|
|
1123
744
|
* })
|
|
1124
745
|
*
|
|
1125
746
|
* // Timed retry window - retry for up to 30 seconds
|
|
1126
|
-
* const timedRetry = Schedule.
|
|
1127
|
-
* Schedule.
|
|
1128
|
-
* )
|
|
747
|
+
* const timedRetry = Schedule.max([
|
|
748
|
+
* Schedule.exponential("200 millis"),
|
|
749
|
+
* Schedule.during("30 seconds")
|
|
750
|
+
* ])
|
|
1129
751
|
*
|
|
1130
752
|
* const retryProgram = Effect.gen(function*() {
|
|
1131
753
|
* let attempt = 0
|
|
@@ -1155,162 +777,52 @@ export const duration = durationInput => {
|
|
|
1155
777
|
* @category constructors
|
|
1156
778
|
* @since 4.0.0
|
|
1157
779
|
*/
|
|
1158
|
-
export const during = duration =>
|
|
1159
|
-
|
|
1160
|
-
|
|
780
|
+
export const during = duration => {
|
|
781
|
+
const durationMillis = Duration.toMillis(duration);
|
|
782
|
+
return fromStepWithMetadata(effect.succeed(meta => {
|
|
783
|
+
const elapsed = Duration.millis(meta.elapsed);
|
|
784
|
+
return meta.elapsed > durationMillis ? effect.succeed([elapsed, Duration.zero]) : Cause.done(elapsed);
|
|
785
|
+
}));
|
|
786
|
+
};
|
|
1161
787
|
/**
|
|
1162
|
-
* Combines
|
|
1163
|
-
*
|
|
1164
|
-
* outputting a tuple of the outputs of both schedules.
|
|
788
|
+
* Combines schedules by recurring while at least one schedule wants to recur,
|
|
789
|
+
* using the minimum delay between recurrences and outputting that minimum delay.
|
|
1165
790
|
*
|
|
1166
791
|
* **When to use**
|
|
1167
792
|
*
|
|
1168
|
-
* Use when
|
|
793
|
+
* Use when a combined policy should continue while any schedule still recurs,
|
|
794
|
+
* and should wait for the fastest schedule between recurrences.
|
|
1169
795
|
*
|
|
1170
|
-
* **Example** (Combining schedules
|
|
796
|
+
* **Example** (Combining retry schedules by their minimum delay)
|
|
1171
797
|
*
|
|
1172
798
|
* ```ts
|
|
1173
799
|
* import { Console, Data, Effect, Schedule } from "effect"
|
|
1174
800
|
*
|
|
1175
801
|
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
1176
802
|
*
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1182
|
-
* const eitherSchedule = Schedule.either(timeBasedSchedule, countBasedSchedule)
|
|
1183
|
-
* // Outputs: [time_result, count_result] tuple
|
|
803
|
+
* const retrySchedule = Schedule.min([
|
|
804
|
+
* Schedule.fixed("5 seconds"),
|
|
805
|
+
* Schedule.exponential("5 seconds"),
|
|
806
|
+
* Schedule.spaced("10 seconds")
|
|
807
|
+
* ])
|
|
1184
808
|
*
|
|
1185
809
|
* const program = Effect.gen(function*() {
|
|
1186
|
-
* const results = yield* Effect.repeat(
|
|
1187
|
-
* Effect.gen(function*() {
|
|
1188
|
-
* yield* Console.log("Task executed")
|
|
1189
|
-
* return "task completed"
|
|
1190
|
-
* }),
|
|
1191
|
-
* eitherSchedule.pipe(
|
|
1192
|
-
* Schedule.tapOutput(([timeResult, countResult]) =>
|
|
1193
|
-
* Console.log(`Time: ${timeResult}, Count: ${countResult}`)
|
|
1194
|
-
* )
|
|
1195
|
-
* )
|
|
1196
|
-
* )
|
|
1197
|
-
*
|
|
1198
|
-
* yield* Console.log(`Total executions: ${results.length}`)
|
|
1199
|
-
* })
|
|
1200
|
-
*
|
|
1201
|
-
* // Either with different delay strategies
|
|
1202
|
-
* const aggressiveRetry = Schedule.exponential("100 millis").pipe(
|
|
1203
|
-
* Schedule.take(3)
|
|
1204
|
-
* )
|
|
1205
|
-
* const fallbackRetry = Schedule.fixed("5 seconds").pipe(Schedule.take(2))
|
|
1206
|
-
*
|
|
1207
|
-
* // Will use the more aggressive retry until it's exhausted, then fallback
|
|
1208
|
-
* const combinedRetry = Schedule.either(aggressiveRetry, fallbackRetry)
|
|
1209
|
-
*
|
|
1210
|
-
* const retryProgram = Effect.gen(function*() {
|
|
1211
810
|
* let attempt = 0
|
|
1212
811
|
*
|
|
1213
|
-
*
|
|
812
|
+
* yield* Effect.retry(
|
|
1214
813
|
* Effect.gen(function*() {
|
|
1215
814
|
* attempt++
|
|
1216
815
|
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
1217
|
-
*
|
|
1218
|
-
* if (attempt < 6) {
|
|
816
|
+
* if (attempt < 3) {
|
|
1219
817
|
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
1220
818
|
* }
|
|
1221
|
-
*
|
|
1222
|
-
* return `Success on attempt ${attempt}`
|
|
1223
|
-
* }),
|
|
1224
|
-
* combinedRetry
|
|
1225
|
-
* )
|
|
1226
|
-
*
|
|
1227
|
-
* yield* Console.log(`Final result: ${result}`)
|
|
1228
|
-
* })
|
|
1229
|
-
*
|
|
1230
|
-
* // Either provides union semantics (OR logic)
|
|
1231
|
-
* // Compare with both, which provides intersection semantics (AND logic)
|
|
1232
|
-
* ```
|
|
1233
|
-
*
|
|
1234
|
-
* @see {@link both} for continuing only while both schedules still recur
|
|
1235
|
-
*
|
|
1236
|
-
* @category combining
|
|
1237
|
-
* @since 2.0.0
|
|
1238
|
-
*/
|
|
1239
|
-
export const either = /*#__PURE__*/dual(2, (self, other) => eitherWith(self, other, (left, right) => [left, right]));
|
|
1240
|
-
/**
|
|
1241
|
-
* Combines two `Schedule`s by recurring if either of the two schedules wants
|
|
1242
|
-
* to recur, using the minimum of the two durations between recurrences and
|
|
1243
|
-
* outputting the result of the left schedule (i.e. `self`).
|
|
1244
|
-
*
|
|
1245
|
-
* **When to use**
|
|
1246
|
-
*
|
|
1247
|
-
* Use when either schedule may keep recurrence going and only the left
|
|
1248
|
-
* schedule's output is needed.
|
|
1249
|
-
*
|
|
1250
|
-
* **Example** (Combining either schedules and keeping the left output)
|
|
1251
|
-
*
|
|
1252
|
-
* ```ts
|
|
1253
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
1254
|
-
*
|
|
1255
|
-
* // Combine two schedules with either semantics, keeping left output
|
|
1256
|
-
* const primarySchedule = Schedule.exponential("100 millis").pipe(
|
|
1257
|
-
* Schedule.map(() => Effect.succeed("primary-result")),
|
|
1258
|
-
* Schedule.take(2)
|
|
1259
|
-
* )
|
|
1260
|
-
* const backupSchedule = Schedule.spaced("500 millis").pipe(
|
|
1261
|
-
* Schedule.map(() => Effect.succeed("backup-result"))
|
|
1262
|
-
* )
|
|
1263
|
-
*
|
|
1264
|
-
* const combined = Schedule.eitherLeft(primarySchedule, backupSchedule)
|
|
1265
|
-
*
|
|
1266
|
-
* const program = Effect.gen(function*() {
|
|
1267
|
-
* yield* Effect.repeat(
|
|
1268
|
-
* Effect.gen(function*() {
|
|
1269
|
-
* yield* Console.log("Task executed")
|
|
1270
|
-
* return "task-done"
|
|
1271
|
-
* }),
|
|
1272
|
-
* combined.pipe(Schedule.take(5))
|
|
1273
|
-
* )
|
|
1274
|
-
* })
|
|
1275
|
-
* ```
|
|
1276
|
-
*
|
|
1277
|
-
* @category combining
|
|
1278
|
-
* @since 4.0.0
|
|
1279
|
-
*/
|
|
1280
|
-
export const eitherLeft = /*#__PURE__*/dual(2, (self, other) => eitherWith(self, other, output => output));
|
|
1281
|
-
/**
|
|
1282
|
-
* Combines two `Schedule`s by recurring if either of the two schedules wants
|
|
1283
|
-
* to recur, using the minimum of the two durations between recurrences and
|
|
1284
|
-
* outputting the result of the right schedule (i.e. `other`).
|
|
1285
|
-
*
|
|
1286
|
-
* **When to use**
|
|
1287
|
-
*
|
|
1288
|
-
* Use when either schedule may keep recurrence going and only the right
|
|
1289
|
-
* schedule's output is needed.
|
|
1290
|
-
*
|
|
1291
|
-
* **Example** (Combining either schedules and keeping the right output)
|
|
1292
|
-
*
|
|
1293
|
-
* ```ts
|
|
1294
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
1295
|
-
*
|
|
1296
|
-
* // Combine two schedules with either semantics, keeping right output
|
|
1297
|
-
* const primarySchedule = Schedule.exponential("100 millis").pipe(
|
|
1298
|
-
* Schedule.map(() => Effect.succeed("primary-result")),
|
|
1299
|
-
* Schedule.take(2)
|
|
1300
|
-
* )
|
|
1301
|
-
* const backupSchedule = Schedule.spaced("500 millis").pipe(
|
|
1302
|
-
* Schedule.map(() => Effect.succeed("backup-result"))
|
|
1303
|
-
* )
|
|
1304
|
-
*
|
|
1305
|
-
* const combined = Schedule.eitherRight(primarySchedule, backupSchedule)
|
|
1306
|
-
*
|
|
1307
|
-
* const program = Effect.gen(function*() {
|
|
1308
|
-
* yield* Effect.repeat(
|
|
1309
|
-
* Effect.gen(function*() {
|
|
1310
|
-
* yield* Console.log("Task executed")
|
|
1311
|
-
* return "task-done"
|
|
819
|
+
* return "success"
|
|
1312
820
|
* }),
|
|
1313
|
-
*
|
|
821
|
+
* retrySchedule.pipe(
|
|
822
|
+
* Schedule.tap(({ output: duration }) =>
|
|
823
|
+
* Console.log(`Waiting for the fastest schedule: ${duration}`)
|
|
824
|
+
* )
|
|
825
|
+
* )
|
|
1314
826
|
* )
|
|
1315
827
|
* })
|
|
1316
828
|
* ```
|
|
@@ -1318,89 +830,27 @@ export const eitherLeft = /*#__PURE__*/dual(2, (self, other) => eitherWith(self,
|
|
|
1318
830
|
* @category combining
|
|
1319
831
|
* @since 4.0.0
|
|
1320
832
|
*/
|
|
1321
|
-
export const
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
* )
|
|
1343
|
-
* const fallbackSchedule = Schedule.spaced("500 millis").pipe(
|
|
1344
|
-
* Schedule.map(() => Effect.succeed("fallback"))
|
|
1345
|
-
* )
|
|
1346
|
-
*
|
|
1347
|
-
* const combined = Schedule.eitherWith(
|
|
1348
|
-
* primarySchedule,
|
|
1349
|
-
* fallbackSchedule,
|
|
1350
|
-
* (primary, fallback) => `${primary}+${fallback}`
|
|
1351
|
-
* )
|
|
1352
|
-
*
|
|
1353
|
-
* const program = Effect.gen(function*() {
|
|
1354
|
-
* yield* Effect.repeat(
|
|
1355
|
-
* Effect.gen(function*() {
|
|
1356
|
-
* yield* Console.log("Task executed")
|
|
1357
|
-
* return "task-result"
|
|
1358
|
-
* }),
|
|
1359
|
-
* combined.pipe(Schedule.take(5))
|
|
1360
|
-
* )
|
|
1361
|
-
* })
|
|
1362
|
-
* ```
|
|
1363
|
-
*
|
|
1364
|
-
* @category combining
|
|
1365
|
-
* @since 2.0.0
|
|
1366
|
-
*/
|
|
1367
|
-
export const eitherWith = /*#__PURE__*/dual(3, (self, other, combine) => fromStep(effect.map(effect.zip(toStep(self), toStep(other)), ([stepLeft, stepRight]) => (now, input) => Pull.matchEffect(stepLeft(now, input), {
|
|
1368
|
-
onSuccess: leftResult => stepRight(now, input).pipe(effect.map(rightResult => [combine(leftResult[0], rightResult[0]), Duration.min(leftResult[1], rightResult[1])]), Pull.catchDone(rightDone => effect.succeed([combine(leftResult[0], rightDone), leftResult[1]]))),
|
|
1369
|
-
onFailure: effect.failCause,
|
|
1370
|
-
onDone: leftDone => stepRight(now, input).pipe(effect.map(rightResult => [combine(leftDone, rightResult[0]), rightResult[1]]), Pull.catchDone(rightDone => Cause.done(combine(leftDone, rightDone))))
|
|
1371
|
-
}))));
|
|
1372
|
-
/**
|
|
1373
|
-
* Schedule that always recurs and returns the total elapsed duration since the
|
|
1374
|
-
* first recurrence.
|
|
1375
|
-
*
|
|
1376
|
-
* **Details**
|
|
1377
|
-
*
|
|
1378
|
-
* This schedule never stops and outputs the cumulative time that has passed since the schedule
|
|
1379
|
-
* started executing. Useful for tracking execution time or implementing time-based logic.
|
|
1380
|
-
*
|
|
1381
|
-
* **Example** (Measuring elapsed schedule time)
|
|
1382
|
-
*
|
|
1383
|
-
* ```ts
|
|
1384
|
-
* import { Console, Duration, Effect, Schedule } from "effect"
|
|
1385
|
-
*
|
|
1386
|
-
* const program = Effect.gen(function*() {
|
|
1387
|
-
* yield* Effect.repeat(
|
|
1388
|
-
* Console.log("Running task..."),
|
|
1389
|
-
* Schedule.spaced("1 second").pipe(
|
|
1390
|
-
* Schedule.both(Schedule.elapsed),
|
|
1391
|
-
* Schedule.tapOutput(([count, duration]) =>
|
|
1392
|
-
* Console.log(`Run ${count}, elapsed: ${Duration.toMillis(duration)}ms`)
|
|
1393
|
-
* ),
|
|
1394
|
-
* Schedule.take(5)
|
|
1395
|
-
* )
|
|
1396
|
-
* )
|
|
1397
|
-
* })
|
|
1398
|
-
* ```
|
|
1399
|
-
*
|
|
1400
|
-
* @category constructors
|
|
1401
|
-
* @since 2.0.0
|
|
1402
|
-
*/
|
|
1403
|
-
export const elapsed = /*#__PURE__*/fromStepWithMetadata(/*#__PURE__*/effect.succeed(meta => effect.succeed([Duration.millis(meta.elapsed), Duration.zero])));
|
|
833
|
+
export const min = schedules => fromStep(effect.map(effect.all(schedules.map(toStep)), steps => (now, input) => effect.flatMap(effect.forEach(steps, step => Pull.matchEffect(step(now, input), {
|
|
834
|
+
onSuccess: result => effect.succeed(result[1]),
|
|
835
|
+
onDone: () => effect.undefined,
|
|
836
|
+
onFailure: effect.failCause
|
|
837
|
+
})), results => {
|
|
838
|
+
const duration = minDuration(results);
|
|
839
|
+
if (duration === undefined) {
|
|
840
|
+
return Cause.done(Duration.zero);
|
|
841
|
+
}
|
|
842
|
+
return effect.succeed([duration, duration]);
|
|
843
|
+
})));
|
|
844
|
+
const minDuration = results => {
|
|
845
|
+
let min = undefined;
|
|
846
|
+
for (let i = 0; i < results.length; i++) {
|
|
847
|
+
const duration = results[i];
|
|
848
|
+
if (duration !== undefined) {
|
|
849
|
+
min = min === undefined ? duration : Duration.min(min, duration);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return min;
|
|
853
|
+
};
|
|
1404
854
|
/**
|
|
1405
855
|
* Schedule that always recurs, but will wait a certain amount between
|
|
1406
856
|
* repetitions, given by `base * factor.pow(n)`, where `n` is the number of
|
|
@@ -1422,9 +872,10 @@ export const elapsed = /*#__PURE__*/fromStepWithMetadata(/*#__PURE__*/effect.suc
|
|
|
1422
872
|
* // Delays: 200ms, 300ms, 450ms, 675ms, 1012ms, ...
|
|
1423
873
|
*
|
|
1424
874
|
* // Retry with exponential backoff (limited to 5 attempts)
|
|
1425
|
-
* const retryPolicy = Schedule.
|
|
1426
|
-
* Schedule.
|
|
1427
|
-
*
|
|
875
|
+
* const retryPolicy = Schedule.max([
|
|
876
|
+
* Schedule.exponential("50 millis"),
|
|
877
|
+
* Schedule.recurs(5)
|
|
878
|
+
* ])
|
|
1428
879
|
*
|
|
1429
880
|
* const program = Effect.gen(function*() {
|
|
1430
881
|
* let attempt = 0
|
|
@@ -1488,9 +939,11 @@ export const exponential = (base, factor = 2) => {
|
|
|
1488
939
|
*
|
|
1489
940
|
* return `Success on attempt ${attempt}`
|
|
1490
941
|
* }),
|
|
1491
|
-
* Schedule.
|
|
1492
|
-
* Schedule.
|
|
1493
|
-
* Schedule.
|
|
942
|
+
* Schedule.max([
|
|
943
|
+
* Schedule.fibonacci("50 millis"),
|
|
944
|
+
* Schedule.recurs(6) // Maximum 6 retries
|
|
945
|
+
* ]).pipe(
|
|
946
|
+
* Schedule.tap(({ output: delay }) => Console.log(`Next retry in ${delay}`))
|
|
1494
947
|
* )
|
|
1495
948
|
* )
|
|
1496
949
|
*
|
|
@@ -1504,7 +957,7 @@ export const exponential = (base, factor = 2) => {
|
|
|
1504
957
|
* }).pipe(
|
|
1505
958
|
* Effect.repeat(
|
|
1506
959
|
* Schedule.fibonacci("200 millis").pipe(
|
|
1507
|
-
* Schedule.
|
|
960
|
+
* Schedule.upTo({ times: 8 }) // First 8 heartbeats
|
|
1508
961
|
* )
|
|
1509
962
|
* )
|
|
1510
963
|
* )
|
|
@@ -1570,7 +1023,7 @@ export const fibonacci = one => {
|
|
|
1570
1023
|
* yield* Effect.sleep("200 millis") // simulate health check work
|
|
1571
1024
|
* return "healthy"
|
|
1572
1025
|
* }).pipe(
|
|
1573
|
-
* Effect.repeat(Schedule.fixed("2 seconds").pipe(Schedule.
|
|
1026
|
+
* Effect.repeat(Schedule.fixed("2 seconds").pipe(Schedule.upTo({ times: 5 })))
|
|
1574
1027
|
* )
|
|
1575
1028
|
*
|
|
1576
1029
|
* // Difference between fixed and spaced:
|
|
@@ -1587,12 +1040,12 @@ export const fibonacci = one => {
|
|
|
1587
1040
|
* // Fixed schedule: if task takes 1.5s but interval is 1s,
|
|
1588
1041
|
* // next execution happens immediately (no pile-up)
|
|
1589
1042
|
* const fixedSchedule = longRunningTask.pipe(
|
|
1590
|
-
* Effect.repeat(Schedule.fixed("1 second").pipe(Schedule.
|
|
1043
|
+
* Effect.repeat(Schedule.fixed("1 second").pipe(Schedule.upTo({ times: 3 })))
|
|
1591
1044
|
* )
|
|
1592
1045
|
*
|
|
1593
1046
|
* // Comparing with spaced (waits 1s AFTER each task)
|
|
1594
1047
|
* const spacedSchedule = longRunningTask.pipe(
|
|
1595
|
-
* Effect.repeat(Schedule.spaced("1 second").pipe(Schedule.
|
|
1048
|
+
* Effect.repeat(Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 3 })))
|
|
1596
1049
|
* )
|
|
1597
1050
|
*
|
|
1598
1051
|
* const program = Effect.gen(function*() {
|
|
@@ -1632,8 +1085,14 @@ export const fixed = interval => {
|
|
|
1632
1085
|
}));
|
|
1633
1086
|
};
|
|
1634
1087
|
/**
|
|
1635
|
-
* Returns a new `Schedule` that maps
|
|
1636
|
-
*
|
|
1088
|
+
* Returns a new `Schedule` that maps each schedule decision to a new output
|
|
1089
|
+
* using the full schedule metadata.
|
|
1090
|
+
*
|
|
1091
|
+
* **Details**
|
|
1092
|
+
*
|
|
1093
|
+
* The callback receives the schedule input, output, selected delay duration,
|
|
1094
|
+
* current attempt, and elapsed timing information. Return either a plain value
|
|
1095
|
+
* or an `Effect` that produces the new output.
|
|
1637
1096
|
*
|
|
1638
1097
|
* **Example** (Mapping schedule outputs)
|
|
1639
1098
|
*
|
|
@@ -1642,17 +1101,17 @@ export const fixed = interval => {
|
|
|
1642
1101
|
*
|
|
1643
1102
|
* // Transform schedule output from number to string
|
|
1644
1103
|
* const countSchedule = Schedule.recurs(5).pipe(
|
|
1645
|
-
* Schedule.map((count) => Effect.succeed(`Execution #${count + 1}`))
|
|
1104
|
+
* Schedule.map(({ output: count }) => Effect.succeed(`Execution #${count + 1}`))
|
|
1646
1105
|
* )
|
|
1647
1106
|
*
|
|
1648
1107
|
* // Map schedule delays to human-readable format
|
|
1649
1108
|
* const readableDelays = Schedule.exponential("100 millis").pipe(
|
|
1650
|
-
* Schedule.map((
|
|
1109
|
+
* Schedule.map(({ output: delay }) => Effect.succeed(`Next retry in ${delay}`))
|
|
1651
1110
|
* )
|
|
1652
1111
|
*
|
|
1653
1112
|
* // Transform numeric output to structured data
|
|
1654
1113
|
* const structuredSchedule = Schedule.spaced("1 second").pipe(
|
|
1655
|
-
* Schedule.map((recurrence) => Effect.succeed({
|
|
1114
|
+
* Schedule.map(({ output: recurrence }) => Effect.succeed({
|
|
1656
1115
|
* iteration: recurrence + 1,
|
|
1657
1116
|
* phase: recurrence < 5 ? "warmup" as const : "steady" as const
|
|
1658
1117
|
* }))
|
|
@@ -1662,8 +1121,8 @@ export const fixed = interval => {
|
|
|
1662
1121
|
* const results = yield* Effect.repeat(
|
|
1663
1122
|
* Effect.succeed("task completed"),
|
|
1664
1123
|
* structuredSchedule.pipe(
|
|
1665
|
-
* Schedule.
|
|
1666
|
-
* Schedule.
|
|
1124
|
+
* Schedule.upTo({ times: 8 }),
|
|
1125
|
+
* Schedule.tap(({ output: info }) =>
|
|
1667
1126
|
* Console.log(
|
|
1668
1127
|
* `${info.phase} phase - iteration ${info.iteration}`
|
|
1669
1128
|
* )
|
|
@@ -1676,7 +1135,7 @@ export const fixed = interval => {
|
|
|
1676
1135
|
*
|
|
1677
1136
|
* // Map with effectful transformation
|
|
1678
1137
|
* const effectfulMap = Schedule.fixed("2 seconds").pipe(
|
|
1679
|
-
* Schedule.map((count) =>
|
|
1138
|
+
* Schedule.map(({ output: count }) =>
|
|
1680
1139
|
* Effect.gen(function*() {
|
|
1681
1140
|
* yield* Console.log(`Processing count: ${count}`)
|
|
1682
1141
|
* return count * 10
|
|
@@ -1684,45 +1143,55 @@ export const fixed = interval => {
|
|
|
1684
1143
|
* )
|
|
1685
1144
|
* )
|
|
1686
1145
|
*
|
|
1687
|
-
* //
|
|
1146
|
+
* // Use timing metadata in the mapped output
|
|
1688
1147
|
* const complexSchedule = Schedule.fibonacci("100 millis").pipe(
|
|
1689
|
-
* Schedule.map((
|
|
1148
|
+
* Schedule.map(({ output: delay, attempt }) =>
|
|
1149
|
+
* Effect.succeed(`Attempt ${attempt} delay: ${delay}`)
|
|
1150
|
+
* )
|
|
1690
1151
|
* )
|
|
1691
1152
|
* ```
|
|
1692
1153
|
*
|
|
1693
1154
|
* @category mapping
|
|
1694
1155
|
* @since 2.0.0
|
|
1695
1156
|
*/
|
|
1696
|
-
export const map = /*#__PURE__*/dual(2, (self, f) => {
|
|
1697
|
-
const
|
|
1157
|
+
export const map = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => {
|
|
1158
|
+
const meta = metadataFn();
|
|
1159
|
+
return (now, input) => Pull.matchEffect(step(now, input), {
|
|
1698
1160
|
onSuccess: ([output, duration]) => {
|
|
1699
|
-
const result = f(
|
|
1161
|
+
const result = f({
|
|
1162
|
+
...meta(now, input),
|
|
1163
|
+
output,
|
|
1164
|
+
duration
|
|
1165
|
+
});
|
|
1700
1166
|
if (!isEffect(result)) return effect.succeed([result, duration]);
|
|
1701
1167
|
return effect.map(result, output => [output, duration]);
|
|
1702
1168
|
},
|
|
1703
1169
|
onFailure: effect.failCause,
|
|
1704
1170
|
onDone: output => {
|
|
1705
|
-
const result = f(
|
|
1171
|
+
const result = f({
|
|
1172
|
+
...meta(now, input),
|
|
1173
|
+
output,
|
|
1174
|
+
duration: Duration.zero
|
|
1175
|
+
});
|
|
1706
1176
|
if (!isEffect(result)) return Cause.done(result);
|
|
1707
1177
|
return effect.flatMap(result, Cause.done);
|
|
1708
1178
|
}
|
|
1709
1179
|
});
|
|
1710
|
-
|
|
1711
|
-
});
|
|
1180
|
+
})));
|
|
1712
1181
|
/**
|
|
1713
1182
|
* Returns a new `Schedule` that modifies the delay of the next recurrence
|
|
1714
1183
|
* of the schedule using the specified effectful function.
|
|
1715
1184
|
*
|
|
1716
|
-
* **Example** (Modifying delays from schedule
|
|
1185
|
+
* **Example** (Modifying delays from schedule metadata)
|
|
1717
1186
|
*
|
|
1718
1187
|
* ```ts
|
|
1719
1188
|
* import { Console, Duration, Effect, Schedule } from "effect"
|
|
1720
1189
|
*
|
|
1721
1190
|
* // Modify delays based on output - increase delay on high iteration counts
|
|
1722
1191
|
* const adaptiveDelay = Schedule.recurs(10).pipe(
|
|
1723
|
-
* Schedule.modifyDelay((output,
|
|
1192
|
+
* Schedule.modifyDelay(({ output, duration }) => {
|
|
1724
1193
|
* // Double the delay if we're seeing high iteration counts
|
|
1725
|
-
* return Effect.succeed(output > 5 ? Duration.times(
|
|
1194
|
+
* return Effect.succeed(output > 5 ? Duration.times(duration, 2) : duration)
|
|
1726
1195
|
* })
|
|
1727
1196
|
* )
|
|
1728
1197
|
*
|
|
@@ -1734,7 +1203,7 @@ export const map = /*#__PURE__*/dual(2, (self, f) => {
|
|
|
1734
1203
|
* yield* Console.log(`Attempt ${counter}`)
|
|
1735
1204
|
* return counter
|
|
1736
1205
|
* }),
|
|
1737
|
-
* adaptiveDelay.pipe(Schedule.
|
|
1206
|
+
* adaptiveDelay.pipe(Schedule.upTo({ times: 8 }))
|
|
1738
1207
|
* )
|
|
1739
1208
|
* })
|
|
1740
1209
|
* ```
|
|
@@ -1742,7 +1211,14 @@ export const map = /*#__PURE__*/dual(2, (self, f) => {
|
|
|
1742
1211
|
* @category delays & timeouts
|
|
1743
1212
|
* @since 2.0.0
|
|
1744
1213
|
*/
|
|
1745
|
-
export const modifyDelay = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step =>
|
|
1214
|
+
export const modifyDelay = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => {
|
|
1215
|
+
const meta = metadataFn();
|
|
1216
|
+
return (now, input) => effect.flatMap(step(now, input), ([output, duration]) => effect.map(f({
|
|
1217
|
+
...meta(now, input),
|
|
1218
|
+
output,
|
|
1219
|
+
duration
|
|
1220
|
+
}), replacement => [output, Duration.fromInputUnsafe(replacement)]));
|
|
1221
|
+
})));
|
|
1746
1222
|
/**
|
|
1747
1223
|
* Returns a new `Schedule` that randomly adjusts each recurrence delay.
|
|
1748
1224
|
*
|
|
@@ -1760,8 +1236,10 @@ export const modifyDelay = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map
|
|
|
1760
1236
|
* @category delays & timeouts
|
|
1761
1237
|
* @since 2.0.0
|
|
1762
1238
|
*/
|
|
1763
|
-
export const jittered = self => modifyDelay(self, (
|
|
1764
|
-
|
|
1239
|
+
export const jittered = self => modifyDelay(self, ({
|
|
1240
|
+
duration
|
|
1241
|
+
}) => effect.map(randomNext, random => {
|
|
1242
|
+
const millis = Duration.toMillis(duration);
|
|
1765
1243
|
return Duration.millis(millis * 0.8 * (1 - random) + millis * 1.2 * random);
|
|
1766
1244
|
}));
|
|
1767
1245
|
/**
|
|
@@ -1774,7 +1252,7 @@ export const jittered = self => modifyDelay(self, (_, delay) => effect.map(rando
|
|
|
1774
1252
|
*
|
|
1775
1253
|
* // Create a schedule that outputs the inputs instead of original outputs
|
|
1776
1254
|
* const inputSchedule = Schedule.passthrough(
|
|
1777
|
-
* Schedule.exponential("100 millis").pipe(Schedule.
|
|
1255
|
+
* Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 3 }))
|
|
1778
1256
|
* )
|
|
1779
1257
|
*
|
|
1780
1258
|
* const program = Effect.gen(function*() {
|
|
@@ -1844,9 +1322,10 @@ export const passthrough = self => fromStep(effect.map(toStep(self), step => (no
|
|
|
1844
1322
|
* })
|
|
1845
1323
|
*
|
|
1846
1324
|
* // Combining recurs with other schedules for sophisticated retry logic
|
|
1847
|
-
* const complexRetry = Schedule.
|
|
1848
|
-
* Schedule.
|
|
1849
|
-
*
|
|
1325
|
+
* const complexRetry = Schedule.max([
|
|
1326
|
+
* Schedule.exponential("100 millis"),
|
|
1327
|
+
* Schedule.recurs(3) // At most 3 retries
|
|
1328
|
+
* ])
|
|
1850
1329
|
*
|
|
1851
1330
|
* // Allow ten recurrences after the initial run
|
|
1852
1331
|
* const tenRecurrences = Effect.gen(function*() {
|
|
@@ -1858,11 +1337,11 @@ export const passthrough = self => fromStep(effect.map(toStep(self), step => (no
|
|
|
1858
1337
|
*
|
|
1859
1338
|
* // The schedule outputs the current recurrence count (0-based)
|
|
1860
1339
|
* const countingSchedule = Schedule.recurs(3).pipe(
|
|
1861
|
-
* Schedule.
|
|
1340
|
+
* Schedule.tap(({ output: count }) => Console.log(`Execution #${count + 1}`))
|
|
1862
1341
|
* )
|
|
1863
1342
|
* ```
|
|
1864
1343
|
*
|
|
1865
|
-
* @see {@link
|
|
1344
|
+
* @see {@link upTo} for limiting an existing schedule
|
|
1866
1345
|
*
|
|
1867
1346
|
* @category constructors
|
|
1868
1347
|
* @since 2.0.0
|
|
@@ -1870,139 +1349,6 @@ export const passthrough = self => fromStep(effect.map(toStep(self), step => (no
|
|
|
1870
1349
|
export const recurs = times => while_(forever, ({
|
|
1871
1350
|
attempt
|
|
1872
1351
|
}) => effect.succeed(attempt <= times));
|
|
1873
|
-
/**
|
|
1874
|
-
* Returns a new `Schedule` that combines the outputs of the provided schedule
|
|
1875
|
-
* using the specified effectful `combine` function and starting from the
|
|
1876
|
-
* specified `initial` state.
|
|
1877
|
-
*
|
|
1878
|
-
* **Example** (Reducing schedule outputs)
|
|
1879
|
-
*
|
|
1880
|
-
* ```ts
|
|
1881
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
1882
|
-
*
|
|
1883
|
-
* // Sum up execution counts from a counter schedule
|
|
1884
|
-
* const sumSchedule = Schedule.reduce(
|
|
1885
|
-
* Schedule.recurs(5),
|
|
1886
|
-
* () => 0, // Initial sum
|
|
1887
|
-
* (sum, count) => Effect.succeed(sum + count) // Add each count to the sum
|
|
1888
|
-
* )
|
|
1889
|
-
*
|
|
1890
|
-
* const sumProgram = Effect.gen(function*() {
|
|
1891
|
-
* const finalSum = yield* Effect.repeat(
|
|
1892
|
-
* Effect.gen(function*() {
|
|
1893
|
-
* yield* Console.log("Task executed")
|
|
1894
|
-
* return "task"
|
|
1895
|
-
* }),
|
|
1896
|
-
* sumSchedule.pipe(
|
|
1897
|
-
* Schedule.tapOutput((sum) => Console.log(`Running sum: ${sum}`))
|
|
1898
|
-
* )
|
|
1899
|
-
* )
|
|
1900
|
-
*
|
|
1901
|
-
* yield* Console.log(`Final sum: ${finalSum}`)
|
|
1902
|
-
* })
|
|
1903
|
-
*
|
|
1904
|
-
* // Build a history of execution counts
|
|
1905
|
-
* const historySchedule = Schedule.reduce(
|
|
1906
|
-
* Schedule.spaced("1 second").pipe(Schedule.take(4)),
|
|
1907
|
-
* () => [] as Array<number>, // Initial empty array
|
|
1908
|
-
* (history, executionNumber) => Effect.succeed([...history, executionNumber])
|
|
1909
|
-
* )
|
|
1910
|
-
*
|
|
1911
|
-
* const historyProgram = Effect.gen(function*() {
|
|
1912
|
-
* const timeline = yield* Effect.repeat(
|
|
1913
|
-
* Effect.gen(function*() {
|
|
1914
|
-
* yield* Console.log("Recording execution...")
|
|
1915
|
-
* return "recorded"
|
|
1916
|
-
* }),
|
|
1917
|
-
* historySchedule
|
|
1918
|
-
* )
|
|
1919
|
-
*
|
|
1920
|
-
* yield* Console.log(
|
|
1921
|
-
* `Execution timeline: ${timeline.join(", ")}`
|
|
1922
|
-
* )
|
|
1923
|
-
* })
|
|
1924
|
-
*
|
|
1925
|
-
* // Accumulate metrics with effectful combination
|
|
1926
|
-
* const metricsAccumulator = Schedule.reduce(
|
|
1927
|
-
* Schedule.recurs(6),
|
|
1928
|
-
* () => ({ total: 0, count: 0, max: 0 }),
|
|
1929
|
-
* (metrics, executionCount) => Effect.succeed({
|
|
1930
|
-
* total: metrics.total + executionCount + 1,
|
|
1931
|
-
* count: metrics.count + 1,
|
|
1932
|
-
* max: Math.max(metrics.max, executionCount + 1)
|
|
1933
|
-
* })
|
|
1934
|
-
* )
|
|
1935
|
-
*
|
|
1936
|
-
* const metricsProgram = Effect.gen(function*() {
|
|
1937
|
-
* const finalMetrics = yield* Effect.repeat(
|
|
1938
|
-
* Effect.gen(function*() {
|
|
1939
|
-
* yield* Console.log("Processing...")
|
|
1940
|
-
* return "processed"
|
|
1941
|
-
* }),
|
|
1942
|
-
* metricsAccumulator
|
|
1943
|
-
* )
|
|
1944
|
-
*
|
|
1945
|
-
* const average = finalMetrics.total / finalMetrics.count
|
|
1946
|
-
* yield* Console.log(`Final metrics: ${finalMetrics.count} executions`)
|
|
1947
|
-
* yield* Console.log(
|
|
1948
|
-
* `Average delay: ${average.toFixed(1)}ms, Max delay: ${finalMetrics.max}ms`
|
|
1949
|
-
* )
|
|
1950
|
-
* })
|
|
1951
|
-
*
|
|
1952
|
-
* // Build configuration state over time
|
|
1953
|
-
* const configBuilder = Schedule.reduce(
|
|
1954
|
-
* Schedule.fixed("500 millis").pipe(Schedule.take(3)),
|
|
1955
|
-
* () => ({ retries: 1, timeout: 1000, backoff: 100 }),
|
|
1956
|
-
* (config, executionNumber) => Effect.succeed({
|
|
1957
|
-
* retries: config.retries + 1,
|
|
1958
|
-
* timeout: config.timeout * 1.5,
|
|
1959
|
-
* backoff: Math.min(config.backoff * 2, 5000)
|
|
1960
|
-
* })
|
|
1961
|
-
* )
|
|
1962
|
-
*
|
|
1963
|
-
* const configProgram = Effect.gen(function*() {
|
|
1964
|
-
* const finalConfig = yield* Effect.repeat(
|
|
1965
|
-
* Effect.gen(function*() {
|
|
1966
|
-
* yield* Console.log("Updating configuration...")
|
|
1967
|
-
* return "updated"
|
|
1968
|
-
* }),
|
|
1969
|
-
* configBuilder.pipe(
|
|
1970
|
-
* Schedule.tapOutput((config) =>
|
|
1971
|
-
* Console.log(
|
|
1972
|
-
* `Config: retries=${config.retries}, timeout=${config.timeout}ms`
|
|
1973
|
-
* )
|
|
1974
|
-
* )
|
|
1975
|
-
* )
|
|
1976
|
-
* )
|
|
1977
|
-
*
|
|
1978
|
-
* yield* Console.log(`Final config: ${JSON.stringify(finalConfig)}`)
|
|
1979
|
-
* })
|
|
1980
|
-
* ```
|
|
1981
|
-
*
|
|
1982
|
-
* @category folding
|
|
1983
|
-
* @since 2.0.0
|
|
1984
|
-
*/
|
|
1985
|
-
export const reduce = /*#__PURE__*/dual(3, (self, initial, combine) => fromStep(effect.map(toStep(self), step => {
|
|
1986
|
-
let state = initial();
|
|
1987
|
-
return (now, input) => Pull.matchEffect(step(now, input), {
|
|
1988
|
-
onSuccess([output, delay]) {
|
|
1989
|
-
const next = combine(state, output);
|
|
1990
|
-
if (!isEffect(next)) {
|
|
1991
|
-
state = next;
|
|
1992
|
-
return effect.succeed([next, delay]);
|
|
1993
|
-
}
|
|
1994
|
-
return effect.map(next, nextState => {
|
|
1995
|
-
state = nextState;
|
|
1996
|
-
return [nextState, delay];
|
|
1997
|
-
});
|
|
1998
|
-
},
|
|
1999
|
-
onFailure: effect.failCause,
|
|
2000
|
-
onDone(output) {
|
|
2001
|
-
const next = combine(state, output);
|
|
2002
|
-
return isEffect(next) ? effect.flatMap(next, Cause.done) : Cause.done(next);
|
|
2003
|
-
}
|
|
2004
|
-
});
|
|
2005
|
-
})));
|
|
2006
1352
|
/**
|
|
2007
1353
|
* Returns a schedule that recurs continuously, each repetition spaced the
|
|
2008
1354
|
* specified duration from the last run.
|
|
@@ -2033,14 +1379,15 @@ export const reduce = /*#__PURE__*/dual(3, (self, initial, combine) => fromStep(
|
|
|
2033
1379
|
* return "Task completed"
|
|
2034
1380
|
* }).pipe(
|
|
2035
1381
|
* Effect.repeat(
|
|
2036
|
-
* Schedule.spaced("1 second").pipe(Schedule.
|
|
1382
|
+
* Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 5 }))
|
|
2037
1383
|
* )
|
|
2038
1384
|
* )
|
|
2039
1385
|
*
|
|
2040
1386
|
* // Simple spaced schedule with limited repetitions
|
|
2041
|
-
* const limitedSpaced = Schedule.
|
|
2042
|
-
* Schedule.
|
|
2043
|
-
*
|
|
1387
|
+
* const limitedSpaced = Schedule.max([
|
|
1388
|
+
* Schedule.spaced("100 millis"),
|
|
1389
|
+
* Schedule.recurs(5) // at most 5 times
|
|
1390
|
+
* ])
|
|
2044
1391
|
*
|
|
2045
1392
|
* const program = Effect.gen(function*() {
|
|
2046
1393
|
* yield* Console.log("Starting spaced execution...")
|
|
@@ -2079,7 +1426,7 @@ export const spaced = duration => {
|
|
|
2079
1426
|
* import { Console, Effect, Schedule } from "effect"
|
|
2080
1427
|
*
|
|
2081
1428
|
* const monitoredSchedule = Schedule.exponential("100 millis").pipe(
|
|
2082
|
-
* Schedule.
|
|
1429
|
+
* Schedule.upTo({ times: 5 }),
|
|
2083
1430
|
* Schedule.tap((metadata) =>
|
|
2084
1431
|
* Console.log(
|
|
2085
1432
|
* `Attempt ${metadata.attempt} produced ${metadata.output} ` +
|
|
@@ -2106,235 +1453,27 @@ export const tap = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(
|
|
|
2106
1453
|
}));
|
|
2107
1454
|
})));
|
|
2108
1455
|
/**
|
|
2109
|
-
* Returns a new `Schedule` that
|
|
2110
|
-
*
|
|
2111
|
-
* the schedule.
|
|
2112
|
-
*
|
|
2113
|
-
* **Example** (Tapping retry inputs)
|
|
2114
|
-
*
|
|
2115
|
-
* ```ts
|
|
2116
|
-
* import { Console, Data, Effect, Schedule } from "effect"
|
|
2117
|
-
*
|
|
2118
|
-
* class RetryError extends Data.TaggedError("RetryError")<{ readonly message: string }> {}
|
|
2119
|
-
*
|
|
2120
|
-
* // Log retry errors for debugging
|
|
2121
|
-
* const errorLoggingSchedule = Schedule.exponential("100 millis").pipe(
|
|
2122
|
-
* Schedule.take(3),
|
|
2123
|
-
* Schedule.tapInput((error: RetryError) =>
|
|
2124
|
-
* Console.log(`Retry triggered by error: ${String(error)}`)
|
|
2125
|
-
* )
|
|
2126
|
-
* )
|
|
2127
|
-
*
|
|
2128
|
-
* const retryProgram = Effect.gen(function*() {
|
|
2129
|
-
* let attempt = 0
|
|
2130
|
-
*
|
|
2131
|
-
* const result = yield* Effect.retry(
|
|
2132
|
-
* Effect.gen(function*() {
|
|
2133
|
-
* attempt++
|
|
2134
|
-
* if (attempt < 4) {
|
|
2135
|
-
* return yield* Effect.fail(new RetryError({ message: `Network timeout on attempt ${attempt}` }))
|
|
2136
|
-
* }
|
|
2137
|
-
* return `Success on attempt ${attempt}`
|
|
2138
|
-
* }),
|
|
2139
|
-
* errorLoggingSchedule
|
|
2140
|
-
* )
|
|
2141
|
-
*
|
|
2142
|
-
* yield* Console.log(`Final result: ${result}`)
|
|
2143
|
-
* })
|
|
2144
|
-
*
|
|
2145
|
-
* // Monitor input frequency for metrics
|
|
2146
|
-
* const inputMonitoringSchedule = Schedule.spaced("1 second").pipe(
|
|
2147
|
-
* Schedule.take(5),
|
|
2148
|
-
* Schedule.tapInput((input: unknown) =>
|
|
2149
|
-
* Effect.gen(function*() {
|
|
2150
|
-
* yield* Console.log(`Input type: ${typeof input}`)
|
|
2151
|
-
* // In real applications, might send metrics to monitoring system
|
|
2152
|
-
* })
|
|
2153
|
-
* )
|
|
2154
|
-
* )
|
|
2155
|
-
*
|
|
2156
|
-
* // Input validation with side effects
|
|
2157
|
-
* const validatingSchedule = Schedule.fixed("500 millis").pipe(
|
|
2158
|
-
* Schedule.take(4),
|
|
2159
|
-
* Schedule.tapInput((input: any) =>
|
|
2160
|
-
* Effect.gen(function*() {
|
|
2161
|
-
* if (typeof input === "object" && input !== null) {
|
|
2162
|
-
* yield* Console.log(`Valid object input: ${JSON.stringify(input)}`)
|
|
2163
|
-
* } else {
|
|
2164
|
-
* yield* Console.log(`Warning: Non-object input received: ${input}`)
|
|
2165
|
-
* }
|
|
2166
|
-
* })
|
|
2167
|
-
* )
|
|
2168
|
-
* )
|
|
2169
|
-
*
|
|
2170
|
-
* const validationProgram = Effect.gen(function*() {
|
|
2171
|
-
* let count = 0
|
|
2172
|
-
*
|
|
2173
|
-
* yield* Effect.repeat(
|
|
2174
|
-
* Effect.gen(function*() {
|
|
2175
|
-
* count++
|
|
2176
|
-
* yield* Console.log("Task with validation")
|
|
2177
|
-
* return { data: `sample-${count}` }
|
|
2178
|
-
* }),
|
|
2179
|
-
* validatingSchedule
|
|
2180
|
-
* )
|
|
2181
|
-
* })
|
|
2182
|
-
*
|
|
2183
|
-
* // Conditional alerting based on input
|
|
2184
|
-
* const alertingSchedule = Schedule.exponential("200 millis").pipe(
|
|
2185
|
-
* Schedule.take(6),
|
|
2186
|
-
* Schedule.tapInput((error: RetryError) =>
|
|
2187
|
-
* Effect.gen(function*() {
|
|
2188
|
-
* if (String(error).includes("critical")) {
|
|
2189
|
-
* yield* Console.log(`Critical error: ${String(error)}`)
|
|
2190
|
-
* // In real applications, might trigger alerts or notifications
|
|
2191
|
-
* } else {
|
|
2192
|
-
* yield* Console.log(`Regular error: ${String(error)}`)
|
|
2193
|
-
* }
|
|
2194
|
-
* })
|
|
2195
|
-
* )
|
|
2196
|
-
* )
|
|
2197
|
-
*
|
|
2198
|
-
* const alertProgram = Effect.gen(function*() {
|
|
2199
|
-
* let attempt = 0
|
|
2200
|
-
*
|
|
2201
|
-
* yield* Effect.retry(
|
|
2202
|
-
* Effect.gen(function*() {
|
|
2203
|
-
* attempt++
|
|
2204
|
-
* const isCritical = attempt === 3
|
|
2205
|
-
* const errorType = isCritical
|
|
2206
|
-
* ? "critical database failure"
|
|
2207
|
-
* : "temporary network issue"
|
|
2208
|
-
* return yield* Effect.fail(new RetryError({ message: errorType }))
|
|
2209
|
-
* }),
|
|
2210
|
-
* alertingSchedule
|
|
2211
|
-
* ).pipe(
|
|
2212
|
-
* Effect.catch((error: unknown) =>
|
|
2213
|
-
* Console.log(`All retries exhausted: ${String(error)}`)
|
|
2214
|
-
* )
|
|
2215
|
-
* )
|
|
2216
|
-
* })
|
|
2217
|
-
*
|
|
2218
|
-
* // Chain multiple input taps for different purposes
|
|
2219
|
-
* const comprehensiveSchedule = Schedule.fibonacci("100 millis").pipe(
|
|
2220
|
-
* Schedule.take(5),
|
|
2221
|
-
* Schedule.tapInput((error: RetryError) =>
|
|
2222
|
-
* Console.log(`Error occurred: ${error._tag}`)
|
|
2223
|
-
* ),
|
|
2224
|
-
* Schedule.tapInput((error: RetryError) =>
|
|
2225
|
-
* String(error).length > 20
|
|
2226
|
-
* ? Console.log("Long error message detected")
|
|
2227
|
-
* : Effect.void
|
|
2228
|
-
* )
|
|
2229
|
-
* )
|
|
2230
|
-
* ```
|
|
2231
|
-
*
|
|
2232
|
-
* @category sequencing
|
|
2233
|
-
* @since 2.0.0
|
|
2234
|
-
*/
|
|
2235
|
-
export const tapInput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => (now, input) => effect.andThen(f(input), step(now, input)))));
|
|
2236
|
-
/**
|
|
2237
|
-
* Returns a new `Schedule` that allows execution of an effectful function for
|
|
2238
|
-
* every output of the schedule, but does not alter the inputs and outputs of
|
|
2239
|
-
* the schedule.
|
|
2240
|
-
*
|
|
2241
|
-
* **Example** (Tapping schedule outputs)
|
|
2242
|
-
*
|
|
2243
|
-
* ```ts
|
|
2244
|
-
* import { Console, Data, Effect, Schedule } from "effect"
|
|
2245
|
-
*
|
|
2246
|
-
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
2247
|
-
*
|
|
2248
|
-
* // Log schedule outputs for debugging/monitoring
|
|
2249
|
-
* const monitoredSchedule = Schedule.exponential("100 millis").pipe(
|
|
2250
|
-
* Schedule.take(5),
|
|
2251
|
-
* Schedule.tapOutput((delay) => Console.log(`Next delay will be: ${delay}`))
|
|
2252
|
-
* )
|
|
2253
|
-
*
|
|
2254
|
-
* const retryProgram = Effect.gen(function*() {
|
|
2255
|
-
* let attempt = 0
|
|
2256
|
-
*
|
|
2257
|
-
* const result = yield* Effect.retry(
|
|
2258
|
-
* Effect.gen(function*() {
|
|
2259
|
-
* attempt++
|
|
2260
|
-
* if (attempt < 4) {
|
|
2261
|
-
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
2262
|
-
* }
|
|
2263
|
-
* return `Success on attempt ${attempt}`
|
|
2264
|
-
* }),
|
|
2265
|
-
* monitoredSchedule
|
|
2266
|
-
* )
|
|
2267
|
-
*
|
|
2268
|
-
* yield* Console.log(`Final result: ${result}`)
|
|
2269
|
-
* })
|
|
2270
|
-
*
|
|
2271
|
-
* // Tap output for metrics collection
|
|
2272
|
-
* const metricsSchedule = Schedule.spaced("1 second").pipe(
|
|
2273
|
-
* Schedule.take(10),
|
|
2274
|
-
* Schedule.tapOutput((executionCount) =>
|
|
2275
|
-
* Effect.gen(function*() {
|
|
2276
|
-
* // Simulate metrics collection
|
|
2277
|
-
* yield* Console.log(`Recording metric: execution_count=${executionCount}`)
|
|
2278
|
-
* // In real code, this might send to monitoring system
|
|
2279
|
-
* })
|
|
2280
|
-
* )
|
|
2281
|
-
* )
|
|
2282
|
-
*
|
|
2283
|
-
* // Tap output with conditional side effects
|
|
2284
|
-
* const alertingSchedule = Schedule.fibonacci("200 millis").pipe(
|
|
2285
|
-
* Schedule.take(8),
|
|
2286
|
-
* Schedule.tapOutput((delay) =>
|
|
2287
|
-
* Effect.gen(function*() {
|
|
2288
|
-
* const delayMs = delay.toString()
|
|
2289
|
-
* if (delayMs.includes("1000")) { // Alert on delays >= 1 second
|
|
2290
|
-
* yield* Console.log(`High delay detected: ${delay}`)
|
|
2291
|
-
* }
|
|
2292
|
-
* })
|
|
2293
|
-
* )
|
|
2294
|
-
* )
|
|
2295
|
-
*
|
|
2296
|
-
* const healthCheckProgram = Effect.gen(function*() {
|
|
2297
|
-
* yield* Effect.repeat(
|
|
2298
|
-
* Effect.gen(function*() {
|
|
2299
|
-
* yield* Console.log("Performing health check...")
|
|
2300
|
-
* return "healthy"
|
|
2301
|
-
* }),
|
|
2302
|
-
* alertingSchedule
|
|
2303
|
-
* )
|
|
2304
|
-
* })
|
|
2305
|
-
*
|
|
2306
|
-
* // Chain multiple taps for different purposes
|
|
2307
|
-
* const comprehensiveSchedule = Schedule.fixed("500 millis").pipe(
|
|
2308
|
-
* Schedule.take(6),
|
|
2309
|
-
* Schedule.tapOutput((count) => Console.log(`Execution ${count + 1}`)),
|
|
2310
|
-
* Schedule.tapOutput((count) =>
|
|
2311
|
-
* count % 3 === 0
|
|
2312
|
-
* ? Console.log("Checkpoint reached")
|
|
2313
|
-
* : Effect.void
|
|
2314
|
-
* )
|
|
2315
|
-
* )
|
|
2316
|
-
* ```
|
|
2317
|
-
*
|
|
2318
|
-
* @category sequencing
|
|
2319
|
-
* @since 2.0.0
|
|
2320
|
-
*/
|
|
2321
|
-
export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => (now, input) => effect.tap(step(now, input), ([output]) => f(output)))));
|
|
2322
|
-
/**
|
|
2323
|
-
* Returns a new `Schedule` that takes at most the specified number of outputs
|
|
2324
|
-
* from the schedule. Once the specified number of outputs is reached, the
|
|
2325
|
-
* schedule will stop.
|
|
1456
|
+
* Returns a new `Schedule` that limits an existing schedule by elapsed
|
|
1457
|
+
* duration, number of outputs, or both.
|
|
2326
1458
|
*
|
|
2327
1459
|
* **When to use**
|
|
2328
1460
|
*
|
|
2329
|
-
* Use to
|
|
1461
|
+
* Use to bound an existing schedule while preserving its output and delay
|
|
1462
|
+
* behavior. When both `duration` and `times` are specified, the schedule
|
|
1463
|
+
* stops as soon as either limit is reached.
|
|
2330
1464
|
*
|
|
2331
1465
|
* **Gotchas**
|
|
2332
1466
|
*
|
|
2333
|
-
* `
|
|
2334
|
-
* effect is evaluated once before the schedule is stepped, so the total
|
|
2335
|
-
* of evaluations can be one greater than the number of
|
|
1467
|
+
* The `times` option limits schedule outputs. When used with repeat or retry,
|
|
1468
|
+
* the effect is evaluated once before the schedule is stepped, so the total
|
|
1469
|
+
* number of evaluations can be one greater than the configured number of
|
|
1470
|
+
* outputs.
|
|
2336
1471
|
*
|
|
2337
|
-
*
|
|
1472
|
+
* The `duration` option is based on the elapsed time observed by the schedule
|
|
1473
|
+
* step. Long-running effects can cause the duration limit to be detected on the
|
|
1474
|
+
* following schedule step.
|
|
1475
|
+
*
|
|
1476
|
+
* **Example** (Limiting by duration and recurrence count)
|
|
2338
1477
|
*
|
|
2339
1478
|
* ```ts
|
|
2340
1479
|
* import { Console, Data, Effect, Schedule } from "effect"
|
|
@@ -2343,7 +1482,7 @@ export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(t
|
|
|
2343
1482
|
*
|
|
2344
1483
|
* // Limit an infinite schedule to five recurrences
|
|
2345
1484
|
* const limitedHeartbeat = Schedule.spaced("1 second").pipe(
|
|
2346
|
-
* Schedule.
|
|
1485
|
+
* Schedule.upTo({ times: 5 })
|
|
2347
1486
|
* )
|
|
2348
1487
|
*
|
|
2349
1488
|
* const heartbeatProgram = Effect.gen(function*() {
|
|
@@ -2358,9 +1497,12 @@ export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(t
|
|
|
2358
1497
|
* yield* Console.log("Heartbeat sequence completed")
|
|
2359
1498
|
* })
|
|
2360
1499
|
*
|
|
2361
|
-
* // Limit retry attempts
|
|
1500
|
+
* // Limit retry attempts by both count and elapsed time
|
|
2362
1501
|
* const limitedRetry = Schedule.exponential("100 millis").pipe(
|
|
2363
|
-
* Schedule.
|
|
1502
|
+
* Schedule.upTo({
|
|
1503
|
+
* duration: "5 seconds",
|
|
1504
|
+
* times: 3
|
|
1505
|
+
* })
|
|
2364
1506
|
* )
|
|
2365
1507
|
*
|
|
2366
1508
|
* const retryProgram = Effect.gen(function*() {
|
|
@@ -2387,138 +1529,22 @@ export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(t
|
|
|
2387
1529
|
* )
|
|
2388
1530
|
* )
|
|
2389
1531
|
*
|
|
2390
|
-
* //
|
|
2391
|
-
* const
|
|
2392
|
-
* Schedule.
|
|
2393
|
-
* Schedule.map((count) => Effect.succeed(`Sample #${count + 1}`))
|
|
1532
|
+
* // Empty options leave the schedule unchanged
|
|
1533
|
+
* const unchanged = Schedule.fixed("500 millis").pipe(
|
|
1534
|
+
* Schedule.upTo({})
|
|
2394
1535
|
* )
|
|
2395
|
-
*
|
|
2396
|
-
* const samplingProgram = Effect.gen(function*() {
|
|
2397
|
-
* yield* Effect.repeat(
|
|
2398
|
-
* Effect.gen(function*() {
|
|
2399
|
-
* const value = "sample"
|
|
2400
|
-
* yield* Console.log(`Sampled value: ${value}`)
|
|
2401
|
-
* return value
|
|
2402
|
-
* }),
|
|
2403
|
-
* samplingSchedule.pipe(
|
|
2404
|
-
* Schedule.tapOutput((label) => Console.log(`Completed: ${label}`))
|
|
2405
|
-
* )
|
|
2406
|
-
* )
|
|
2407
|
-
* })
|
|
2408
1536
|
* ```
|
|
2409
1537
|
*
|
|
2410
|
-
* @
|
|
2411
|
-
*
|
|
2412
|
-
* @category taking
|
|
1538
|
+
* @category filtering
|
|
2413
1539
|
* @since 4.0.0
|
|
2414
1540
|
*/
|
|
2415
|
-
export const
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
* **Example** (Unfolding schedule state)
|
|
2423
|
-
*
|
|
2424
|
-
* ```ts
|
|
2425
|
-
* import { Console, Effect, Schedule } from "effect"
|
|
2426
|
-
*
|
|
2427
|
-
* // Counter schedule that increments by 1 each time
|
|
2428
|
-
* const counterSchedule = Schedule.unfold(0, (n) => Effect.succeed(n + 1))
|
|
2429
|
-
* // Outputs: 0, 1, 2, 3, 4, 5, ...
|
|
2430
|
-
*
|
|
2431
|
-
* const countingProgram = Effect.gen(function*() {
|
|
2432
|
-
* yield* Effect.repeat(
|
|
2433
|
-
* Effect.gen(function*() {
|
|
2434
|
-
* yield* Console.log("Task executed")
|
|
2435
|
-
* return "done"
|
|
2436
|
-
* }),
|
|
2437
|
-
* counterSchedule.pipe(
|
|
2438
|
-
* Schedule.take(5),
|
|
2439
|
-
* Schedule.tapOutput((count) => Console.log(`Count: ${count}`))
|
|
2440
|
-
* )
|
|
2441
|
-
* )
|
|
2442
|
-
* })
|
|
2443
|
-
*
|
|
2444
|
-
* // Fibonacci sequence schedule
|
|
2445
|
-
* const fibonacciSchedule = Schedule.unfold(
|
|
2446
|
-
* [0, 1] as [number, number],
|
|
2447
|
-
* ([a, b]) => Effect.succeed([b, a + b] as [number, number])
|
|
2448
|
-
* )
|
|
2449
|
-
* // Outputs: [0,1], [1,1], [1,2], [2,3], [3,5], [5,8], ...
|
|
2450
|
-
*
|
|
2451
|
-
* const fibProgram = Effect.gen(function*() {
|
|
2452
|
-
* yield* Effect.repeat(
|
|
2453
|
-
* Console.log("Fibonacci step"),
|
|
2454
|
-
* fibonacciSchedule.pipe(
|
|
2455
|
-
* Schedule.take(8),
|
|
2456
|
-
* Schedule.tapOutput(([a, b]) => Console.log(`Fib: ${a}, next: ${b}`))
|
|
2457
|
-
* )
|
|
2458
|
-
* )
|
|
2459
|
-
* })
|
|
2460
|
-
*
|
|
2461
|
-
* // Effectful unfold - exponential backoff with state
|
|
2462
|
-
* const exponentialState = Schedule.unfold(
|
|
2463
|
-
* 100,
|
|
2464
|
-
* (delayMs) =>
|
|
2465
|
-
* Effect.gen(function*() {
|
|
2466
|
-
* yield* Console.log(`Current delay: ${delayMs}ms`)
|
|
2467
|
-
* return Math.min(delayMs * 2, 5000) // Cap at 5 seconds
|
|
2468
|
-
* })
|
|
2469
|
-
* )
|
|
2470
|
-
*
|
|
2471
|
-
* // Deterministic delay adjustment schedule
|
|
2472
|
-
* const adjustedDelaySchedule = Schedule.unfold(
|
|
2473
|
-
* { delay: 1000, adjustment: 100 },
|
|
2474
|
-
* ({ delay, adjustment }) =>
|
|
2475
|
-
* Effect.gen(function*() {
|
|
2476
|
-
* const nextDelay = Math.max(100, delay + adjustment)
|
|
2477
|
-
* yield* Console.log(`Adjusted delay: ${nextDelay}ms`)
|
|
2478
|
-
* return { delay: nextDelay, adjustment: adjustment * -1 }
|
|
2479
|
-
* })
|
|
2480
|
-
* )
|
|
2481
|
-
*
|
|
2482
|
-
* // State machine schedule
|
|
2483
|
-
* type State = "init" | "warming" | "active" | "cooling"
|
|
2484
|
-
* const stateMachineSchedule = Schedule.unfold("init" as State, (state) => {
|
|
2485
|
-
* switch (state) {
|
|
2486
|
-
* case "init":
|
|
2487
|
-
* return Effect.succeed("warming" as State)
|
|
2488
|
-
* case "warming":
|
|
2489
|
-
* return Effect.succeed("active" as State)
|
|
2490
|
-
* case "active":
|
|
2491
|
-
* return Effect.succeed("cooling" as State)
|
|
2492
|
-
* case "cooling":
|
|
2493
|
-
* return Effect.succeed("active" as State)
|
|
2494
|
-
* }
|
|
2495
|
-
* })
|
|
2496
|
-
*
|
|
2497
|
-
* const stateMachineProgram = Effect.gen(function*() {
|
|
2498
|
-
* yield* Effect.repeat(
|
|
2499
|
-
* Effect.gen(function*() {
|
|
2500
|
-
* yield* Console.log("State machine step")
|
|
2501
|
-
* return "step"
|
|
2502
|
-
* }),
|
|
2503
|
-
* stateMachineSchedule.pipe(
|
|
2504
|
-
* Schedule.take(10),
|
|
2505
|
-
* Schedule.tapOutput((state) => Console.log(`State: ${state}`))
|
|
2506
|
-
* )
|
|
2507
|
-
* )
|
|
2508
|
-
* })
|
|
2509
|
-
* ```
|
|
2510
|
-
*
|
|
2511
|
-
* @category constructors
|
|
2512
|
-
* @since 2.0.0
|
|
2513
|
-
*/
|
|
2514
|
-
export const unfold = (initial, next) => fromStep(effect.sync(() => {
|
|
2515
|
-
let state = initial;
|
|
2516
|
-
return constant(effect.map(effect.suspend(() => next(state)), nextState => {
|
|
2517
|
-
const prev = state;
|
|
2518
|
-
state = nextState;
|
|
2519
|
-
return [prev, Duration.zero];
|
|
2520
|
-
}));
|
|
2521
|
-
}));
|
|
1541
|
+
export const upTo = /*#__PURE__*/dual(2, (self, options) => {
|
|
1542
|
+
const duration = options.duration === undefined ? undefined : Duration.fromInputUnsafe(options.duration);
|
|
1543
|
+
return while_(self, ({
|
|
1544
|
+
attempt,
|
|
1545
|
+
elapsed
|
|
1546
|
+
}) => effect.succeed((options.times === undefined || attempt <= options.times) && (duration === undefined || Duration.isLessThanOrEqualTo(Duration.millis(elapsed), duration))));
|
|
1547
|
+
});
|
|
2522
1548
|
const while_ = /*#__PURE__*/dual(2, (self, predicate) => fromStep(effect.map(toStep(self), step => {
|
|
2523
1549
|
const meta = metadataFn();
|
|
2524
1550
|
return (now, input) => effect.flatMap(step(now, input), result => {
|
|
@@ -2546,8 +1572,7 @@ export {
|
|
|
2546
1572
|
* `Effect<boolean, ...>`, preserves the output and delay when it returns
|
|
2547
1573
|
* `true`, and stops the schedule when it returns `false`.
|
|
2548
1574
|
*
|
|
2549
|
-
* @see {@link
|
|
2550
|
-
* @see {@link take} for stopping after a fixed number of schedule outputs
|
|
1575
|
+
* @see {@link upTo} for stopping after a fixed number of schedule outputs
|
|
2551
1576
|
*
|
|
2552
1577
|
* @category filtering
|
|
2553
1578
|
* @since 4.0.0
|
|
@@ -2582,7 +1607,7 @@ while_ as while };
|
|
|
2582
1607
|
* yield* Console.log("Window task executed")
|
|
2583
1608
|
* return "window-task"
|
|
2584
1609
|
* }),
|
|
2585
|
-
* windowSchedule.pipe(Schedule.
|
|
1610
|
+
* windowSchedule.pipe(Schedule.upTo({ times: 4 }))
|
|
2586
1611
|
* )
|
|
2587
1612
|
* })
|
|
2588
1613
|
* ```
|
|
@@ -2616,7 +1641,7 @@ export const windowed = interval => {
|
|
|
2616
1641
|
* yield* Console.log("Running forever...")
|
|
2617
1642
|
* return "continuous-task"
|
|
2618
1643
|
* }),
|
|
2619
|
-
* infiniteSchedule.pipe(Schedule.
|
|
1644
|
+
* infiniteSchedule.pipe(Schedule.upTo({ times: 5 })) // Limit for demo
|
|
2620
1645
|
* )
|
|
2621
1646
|
* })
|
|
2622
1647
|
* ```
|
|
@@ -2647,37 +1672,6 @@ export {
|
|
|
2647
1672
|
* @since 2.0.0
|
|
2648
1673
|
*/
|
|
2649
1674
|
identity_ as identity };
|
|
2650
|
-
/**
|
|
2651
|
-
* Ensures that a schedule's input type extends a given type `T`.
|
|
2652
|
-
*
|
|
2653
|
-
* **When to use**
|
|
2654
|
-
*
|
|
2655
|
-
* Use when you need a generic helper to prove that an existing schedule can
|
|
2656
|
-
* consume a required input type without changing runtime behavior.
|
|
2657
|
-
*
|
|
2658
|
-
* **Example** (Constraining schedule input types)
|
|
2659
|
-
*
|
|
2660
|
-
* ```ts
|
|
2661
|
-
* import { Schedule } from "effect"
|
|
2662
|
-
*
|
|
2663
|
-
* declare const StringInputSchedule: Schedule.Schedule<number, string>
|
|
2664
|
-
* declare const NumberInputSchedule: Schedule.Schedule<number, number>
|
|
2665
|
-
*
|
|
2666
|
-
* const satisfiesStringInput = Schedule.satisfiesInputType<string>()
|
|
2667
|
-
*
|
|
2668
|
-
* // This works because the schedule input type is string.
|
|
2669
|
-
* const validSchedule = satisfiesStringInput(StringInputSchedule)
|
|
2670
|
-
*
|
|
2671
|
-
* // This would cause a TypeScript compilation error:
|
|
2672
|
-
* // const invalidSchedule = satisfiesStringInput(NumberInputSchedule)
|
|
2673
|
-
* ```
|
|
2674
|
-
*
|
|
2675
|
-
* @see {@link setInputType} for adapting an input-agnostic schedule
|
|
2676
|
-
*
|
|
2677
|
-
* @category utility types
|
|
2678
|
-
* @since 4.0.0
|
|
2679
|
-
*/
|
|
2680
|
-
export const satisfiesInputType = () => self => self;
|
|
2681
1675
|
/**
|
|
2682
1676
|
* Sets the input type of the provided schedule without altering its behavior.
|
|
2683
1677
|
*
|
|
@@ -2700,106 +1694,8 @@ export const satisfiesInputType = () => self => self;
|
|
|
2700
1694
|
* )
|
|
2701
1695
|
* ```
|
|
2702
1696
|
*
|
|
2703
|
-
* @see {@link satisfiesInputType} for checking an existing input type
|
|
2704
|
-
*
|
|
2705
1697
|
* @category utility types
|
|
2706
1698
|
* @since 4.0.0
|
|
2707
1699
|
*/
|
|
2708
1700
|
export const setInputType = () => self => self;
|
|
2709
|
-
/**
|
|
2710
|
-
* Ensures that a schedule's output type extends a given type `T`.
|
|
2711
|
-
*
|
|
2712
|
-
* **Details**
|
|
2713
|
-
*
|
|
2714
|
-
* This helper is checked at compile time and does not change the schedule's
|
|
2715
|
-
* runtime behavior.
|
|
2716
|
-
*
|
|
2717
|
-
* **Example** (Constraining schedule output types)
|
|
2718
|
-
*
|
|
2719
|
-
* ```ts
|
|
2720
|
-
* import { Schedule } from "effect"
|
|
2721
|
-
*
|
|
2722
|
-
* declare const StringOutputSchedule: Schedule.Schedule<string>
|
|
2723
|
-
* declare const NumberOutputSchedule: Schedule.Schedule<number>
|
|
2724
|
-
*
|
|
2725
|
-
* const satisfiesStringOutput = Schedule.satisfiesOutputType<string>()
|
|
2726
|
-
*
|
|
2727
|
-
* // This works because the schedule output type is string.
|
|
2728
|
-
* const validSchedule = satisfiesStringOutput(StringOutputSchedule)
|
|
2729
|
-
*
|
|
2730
|
-
* // This would cause a TypeScript compilation error:
|
|
2731
|
-
* // const invalidSchedule = satisfiesStringOutput(NumberOutputSchedule)
|
|
2732
|
-
* ```
|
|
2733
|
-
*
|
|
2734
|
-
* @category utility types
|
|
2735
|
-
* @since 4.0.0
|
|
2736
|
-
*/
|
|
2737
|
-
export const satisfiesOutputType = () => self => self;
|
|
2738
|
-
/**
|
|
2739
|
-
* Ensures that a schedule's error type extends a given type `T`.
|
|
2740
|
-
*
|
|
2741
|
-
* **Details**
|
|
2742
|
-
*
|
|
2743
|
-
* This helper is checked at compile time and does not change the schedule's
|
|
2744
|
-
* runtime behavior.
|
|
2745
|
-
*
|
|
2746
|
-
* **Example** (Constraining schedule error types)
|
|
2747
|
-
*
|
|
2748
|
-
* ```ts
|
|
2749
|
-
* import { Data, Schedule } from "effect"
|
|
2750
|
-
*
|
|
2751
|
-
* // Create a custom error using Data.TaggedError
|
|
2752
|
-
* class CustomError extends Data.TaggedError("CustomError")<{
|
|
2753
|
-
* message: string
|
|
2754
|
-
* }> {}
|
|
2755
|
-
*
|
|
2756
|
-
* declare const CustomErrorSchedule: Schedule.Schedule<number, unknown, CustomError>
|
|
2757
|
-
* declare const StringErrorSchedule: Schedule.Schedule<number, unknown, string>
|
|
2758
|
-
*
|
|
2759
|
-
* const satisfiesCustomError = Schedule.satisfiesErrorType<CustomError>()
|
|
2760
|
-
*
|
|
2761
|
-
* // This works because the schedule error type is CustomError.
|
|
2762
|
-
* const validSchedule = satisfiesCustomError(CustomErrorSchedule)
|
|
2763
|
-
*
|
|
2764
|
-
* // This would cause a TypeScript compilation error:
|
|
2765
|
-
* // const invalidSchedule = satisfiesCustomError(StringErrorSchedule)
|
|
2766
|
-
* ```
|
|
2767
|
-
*
|
|
2768
|
-
* @category utility types
|
|
2769
|
-
* @since 4.0.0
|
|
2770
|
-
*/
|
|
2771
|
-
export const satisfiesErrorType = () => self => self;
|
|
2772
|
-
/**
|
|
2773
|
-
* Ensures that a schedule's context type extends a given type `T`.
|
|
2774
|
-
*
|
|
2775
|
-
* **Details**
|
|
2776
|
-
*
|
|
2777
|
-
* This helper is checked at compile time and does not change the schedule's
|
|
2778
|
-
* runtime behavior.
|
|
2779
|
-
*
|
|
2780
|
-
* **Example** (Constraining schedule service types)
|
|
2781
|
-
*
|
|
2782
|
-
* ```ts
|
|
2783
|
-
* import { Schedule } from "effect"
|
|
2784
|
-
*
|
|
2785
|
-
* interface Logger {
|
|
2786
|
-
* readonly log: (message: string) => void
|
|
2787
|
-
* }
|
|
2788
|
-
*
|
|
2789
|
-
* declare const LoggerSchedule: Schedule.Schedule<number, unknown, never, Logger>
|
|
2790
|
-
* declare const NumberSchedule: Schedule.Schedule<number, unknown, never, number>
|
|
2791
|
-
*
|
|
2792
|
-
* const satisfiesLogger = Schedule.satisfiesServicesType<Logger>()
|
|
2793
|
-
*
|
|
2794
|
-
* // This works because the schedule context type is Logger.
|
|
2795
|
-
* const validSchedule = satisfiesLogger(LoggerSchedule)
|
|
2796
|
-
*
|
|
2797
|
-
* // This would cause a TypeScript compilation error:
|
|
2798
|
-
* // const invalidSchedule = satisfiesLogger(NumberSchedule)
|
|
2799
|
-
* ```
|
|
2800
|
-
*
|
|
2801
|
-
* @category utility types
|
|
2802
|
-
* @since 4.0.0
|
|
2803
|
-
*/
|
|
2804
|
-
export const satisfiesServicesType = () => self => self;
|
|
2805
1701
|
//# sourceMappingURL=Schedule.js.map
|