effect 4.0.3 → 4.0.5
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/AGENTS.md +24 -0
- package/CLAUDE.md +24 -0
- package/ai-docs/package.json +2 -2
- package/ai-docs/src/52_graphql/10_basics.ts +117 -0
- package/ai-docs/src/52_graphql/20_testing.ts +45 -0
- package/ai-docs/src/52_graphql/30_batching.ts +118 -0
- package/ai-docs/src/52_graphql/40_aliased-batching.ts +124 -0
- package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
- package/ai-docs/src/52_graphql/index.md +6 -0
- package/dist/Array.d.ts +90 -6
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +4 -2
- package/dist/Array.js.map +1 -1
- package/dist/Channel.d.ts +6 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +17 -3
- package/dist/Channel.js.map +1 -1
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +33 -32
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +9 -0
- package/dist/Context.js.map +1 -1
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +2 -5
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +61 -19
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +58 -39
- package/dist/Effect.js.map +1 -1
- package/dist/FileSystem.d.ts +23 -9
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/Match.d.ts +20 -6
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +2 -2
- package/dist/Match.js.map +1 -1
- package/dist/Path.d.ts +37 -5
- package/dist/Path.d.ts.map +1 -1
- package/dist/Path.js +36 -5
- package/dist/Path.js.map +1 -1
- package/dist/RequestResolver.d.ts.map +1 -1
- package/dist/RequestResolver.js +4 -10
- package/dist/RequestResolver.js.map +1 -1
- package/dist/Scheduler.d.ts +9 -0
- package/dist/Scheduler.d.ts.map +1 -1
- package/dist/Scheduler.js +9 -0
- package/dist/Scheduler.js.map +1 -1
- package/dist/Schema.d.ts +15 -2
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +16 -2
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaGetter.d.ts +4 -0
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +52 -33
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +38 -17
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts +11 -0
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +16 -1
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +12 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +17 -4
- package/dist/String.js.map +1 -1
- package/dist/TxRef.d.ts.map +1 -1
- package/dist/TxRef.js +3 -2
- package/dist/TxRef.js.map +1 -1
- package/dist/Utils.js +8 -3
- package/dist/Utils.js.map +1 -1
- package/dist/ai/AiError.d.ts +10 -10
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +1 -1
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/AnthropicStructuredOutput.js +0 -2
- package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
- package/dist/ai/Chat.d.ts +2 -2
- package/dist/ai/Chat.d.ts.map +1 -1
- package/dist/ai/Decision.d.ts +70 -19
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +37 -3
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.js +1 -1
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts +38 -7
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +70 -40
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpServer.d.ts +61 -52
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +134 -50
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +28 -5
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +5 -4
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js.map +1 -1
- package/dist/cli/Completions.d.ts +5 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +100 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +33 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/Param.d.ts +87 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +30 -0
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/internal/command.d.ts.map +1 -1
- package/dist/cli/internal/command.js +2 -1
- package/dist/cli/internal/command.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +4 -3
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/completions/descriptor.js +8 -1
- package/dist/cli/internal/completions/descriptor.js.map +1 -1
- package/dist/cli/internal/completions/fish.js +4 -4
- package/dist/cli/internal/completions/fish.js.map +1 -1
- package/dist/cli/internal/completions/powershell.js +3 -2
- package/dist/cli/internal/completions/powershell.js.map +1 -1
- package/dist/cli/internal/completions/zsh.js +7 -3
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/parser.js +11 -3
- package/dist/cli/internal/parser.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +2 -1
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -0
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +113 -21
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +20 -12
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +54 -34
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +6 -4
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +1 -1
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/encoding/Sse.d.ts +6 -0
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +63 -71
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/graphql/GraphQL.d.ts +349 -0
- package/dist/graphql/GraphQL.d.ts.map +1 -0
- package/dist/graphql/GraphQL.js +207 -0
- package/dist/graphql/GraphQL.js.map +1 -0
- package/dist/graphql/GraphQLClient.d.ts +562 -0
- package/dist/graphql/GraphQLClient.d.ts.map +1 -0
- package/dist/graphql/GraphQLClient.js +505 -0
- package/dist/graphql/GraphQLClient.js.map +1 -0
- package/dist/graphql/GraphQLClientError.d.ts +445 -0
- package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
- package/dist/graphql/GraphQLClientError.js +479 -0
- package/dist/graphql/GraphQLClientError.js.map +1 -0
- package/dist/graphql/GraphQLGroup.d.ts +118 -0
- package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
- package/dist/graphql/GraphQLGroup.js +109 -0
- package/dist/graphql/GraphQLGroup.js.map +1 -0
- package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
- package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
- package/dist/graphql/GraphQLMiddleware.js +130 -0
- package/dist/graphql/GraphQLMiddleware.js.map +1 -0
- package/dist/graphql/GraphQLProtocol.d.ts +969 -0
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
- package/dist/graphql/GraphQLProtocol.js +809 -0
- package/dist/graphql/GraphQLProtocol.js.map +1 -0
- package/dist/graphql/GraphQLResolver.d.ts +453 -0
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
- package/dist/graphql/GraphQLResolver.js +582 -0
- package/dist/graphql/GraphQLResolver.js.map +1 -0
- package/dist/graphql/index.d.ts +40 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +41 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/http/FetchHttpClient.d.ts +6 -3
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +6 -3
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +2 -1
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/Headers.d.ts +3 -3
- package/dist/http/Headers.d.ts.map +1 -1
- package/dist/http/Headers.js +6 -5
- package/dist/http/Headers.js.map +1 -1
- package/dist/http/HttpClient.d.ts +27 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +38 -11
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +8 -6
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +147 -4
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +47 -1
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpEffect.d.ts.map +1 -1
- package/dist/http/HttpEffect.js +14 -7
- package/dist/http/HttpEffect.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +60 -0
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +93 -32
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts +35 -0
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +87 -13
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.d.ts.map +1 -1
- package/dist/http/HttpServerError.js +6 -4
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.js +2 -2
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts +8 -6
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +27 -16
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +4 -10
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.js +1 -1
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/Multipart.d.ts.map +1 -1
- package/dist/http/Multipart.js +15 -1
- package/dist/http/Multipart.js.map +1 -1
- package/dist/http/Url.d.ts.map +1 -1
- package/dist/http/Url.js +2 -1
- package/dist/http/Url.js.map +1 -1
- package/dist/http/UrlParams.d.ts +112 -8
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +141 -14
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.d.ts +1 -1
- package/dist/http/internal/compression.d.ts.map +1 -1
- package/dist/http/internal/compression.js +2 -10
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/compressionBody.d.ts +2 -0
- package/dist/http/internal/compressionBody.d.ts.map +1 -0
- package/dist/http/internal/compressionBody.js +36 -0
- package/dist/http/internal/compressionBody.js.map +1 -0
- package/dist/http/internal/decompression.d.ts +2 -0
- package/dist/http/internal/decompression.d.ts.map +1 -0
- package/dist/http/internal/decompression.js +162 -0
- package/dist/http/internal/decompression.js.map +1 -0
- package/dist/http/internal/tracing.js +14 -4
- package/dist/http/internal/tracing.js.map +1 -1
- package/dist/http/internal/urlParams.d.ts +2 -0
- package/dist/http/internal/urlParams.d.ts.map +1 -0
- package/dist/http/internal/urlParams.js +4 -0
- package/dist/http/internal/urlParams.js.map +1 -0
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +2 -1
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiScalar.d.ts +5 -0
- package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
- package/dist/http-api/HttpApiScalar.js.map +1 -1
- package/dist/internal/core.js +17 -1
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/dateTime.js +40 -35
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +13 -6
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/graphql.d.ts +2 -0
- package/dist/internal/graphql.d.ts.map +1 -0
- package/dist/internal/graphql.js +205 -0
- package/dist/internal/graphql.js.map +1 -0
- package/dist/internal/graphqlHeaders.d.ts +4 -0
- package/dist/internal/graphqlHeaders.d.ts.map +1 -0
- package/dist/internal/graphqlHeaders.js +11 -0
- package/dist/internal/graphqlHeaders.js.map +1 -0
- package/dist/internal/request.js +20 -1
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +4 -1
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/net/Host.d.ts +49 -0
- package/dist/net/Host.d.ts.map +1 -1
- package/dist/net/Host.js +55 -0
- package/dist/net/Host.js.map +1 -1
- package/dist/net/NetAddress.d.ts +8 -0
- package/dist/net/NetAddress.d.ts.map +1 -1
- package/dist/net/NetAddress.js +8 -0
- package/dist/net/NetAddress.js.map +1 -1
- package/dist/observability/Otlp.d.ts +15 -0
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +3 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts +8 -0
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +10 -1
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpLogger.d.ts +17 -0
- package/dist/observability/OtlpLogger.d.ts.map +1 -1
- package/dist/observability/OtlpLogger.js +14 -1
- package/dist/observability/OtlpLogger.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts +17 -0
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +13 -0
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts +17 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +15 -2
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +6 -0
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/AsyncResult.js +27 -0
- package/dist/reactivity/AsyncResult.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js +3 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +6 -1
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +36 -9
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/socket/Socket.d.ts +6 -0
- package/dist/socket/Socket.d.ts.map +1 -1
- package/dist/socket/Socket.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +8 -7
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +8 -7
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/testing/TestClock.d.ts +16 -3
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +112 -22
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/workflow/Activity.js +1 -0
- package/dist/workflow/Activity.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +32 -3
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/Workflow.d.ts +22 -0
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js +15 -3
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts +44 -3
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +45 -22
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +6 -3
- package/src/Array.ts +95 -6
- package/src/Channel.ts +24 -3
- package/src/ConfigProvider.ts +40 -44
- package/src/Context.ts +9 -0
- package/src/Duration.ts +4 -5
- package/src/Effect.ts +140 -53
- package/src/FileSystem.ts +23 -9
- package/src/Match.ts +65 -12
- package/src/Path.ts +52 -7
- package/src/RequestResolver.ts +4 -10
- package/src/Scheduler.ts +9 -0
- package/src/Schema.ts +25 -4
- package/src/SchemaGetter.ts +47 -35
- package/src/Sink.ts +45 -18
- package/src/Stream.ts +33 -4
- package/src/String.ts +17 -4
- package/src/TxRef.ts +4 -2
- package/src/Utils.ts +8 -5
- package/src/ai/AiError.ts +3 -1
- package/src/ai/AnthropicStructuredOutput.ts +2 -2
- package/src/ai/Chat.ts +2 -2
- package/src/ai/Decision.ts +70 -21
- package/src/ai/DecisionModel.ts +1 -1
- package/src/ai/LanguageModel.ts +141 -63
- package/src/ai/McpServer.ts +259 -145
- package/src/ai/Prompt.ts +24 -10
- package/src/ai/Response.ts +6 -3
- package/src/cli/Completions.ts +5 -0
- package/src/cli/Flag.ts +101 -0
- package/src/cli/Param.ts +96 -0
- package/src/cli/internal/command.ts +2 -1
- package/src/cli/internal/completions/bash.ts +4 -3
- package/src/cli/internal/completions/descriptor.ts +10 -1
- package/src/cli/internal/completions/fish.ts +4 -4
- package/src/cli/internal/completions/powershell.ts +5 -2
- package/src/cli/internal/completions/zsh.ts +7 -3
- package/src/cli/internal/parser.ts +12 -3
- package/src/cli/internal/wizard.ts +2 -1
- package/src/cluster/ClusterWorkflowEngine.ts +143 -36
- package/src/cluster/MessageStorage.ts +14 -3
- package/src/cluster/Runners.ts +88 -66
- package/src/cluster/Sharding.ts +12 -9
- package/src/cluster/internal/entityManager.ts +1 -1
- package/src/encoding/Sse.ts +70 -80
- package/src/graphql/GraphQL.ts +494 -0
- package/src/graphql/GraphQLClient.ts +924 -0
- package/src/graphql/GraphQLClientError.ts +542 -0
- package/src/graphql/GraphQLGroup.ts +167 -0
- package/src/graphql/GraphQLMiddleware.ts +253 -0
- package/src/graphql/GraphQLProtocol.ts +1540 -0
- package/src/graphql/GraphQLResolver.ts +1038 -0
- package/src/graphql/index.ts +48 -0
- package/src/http/FetchHttpClient.ts +6 -3
- package/src/http/FindMyWay/internal/router.ts +2 -1
- package/src/http/Headers.ts +6 -9
- package/src/http/HttpClient.ts +72 -11
- package/src/http/HttpClientError.ts +10 -6
- package/src/http/HttpClientRequest.ts +173 -7
- package/src/http/HttpEffect.ts +11 -5
- package/src/http/HttpMiddleware.ts +113 -34
- package/src/http/HttpRouter.ts +95 -13
- package/src/http/HttpServerError.ts +8 -4
- package/src/http/HttpServerRequest.ts +2 -2
- package/src/http/HttpServerResponse.ts +28 -16
- package/src/http/HttpStaticServer.ts +4 -10
- package/src/http/HttpTraceContext.ts +1 -1
- package/src/http/Multipart.ts +17 -1
- package/src/http/Url.ts +2 -1
- package/src/http/UrlParams.ts +225 -26
- package/src/http/internal/compression.ts +3 -17
- package/src/http/internal/compressionBody.ts +56 -0
- package/src/http/internal/decompression.ts +226 -0
- package/src/http/internal/tracing.ts +21 -4
- package/src/http/internal/urlParams.ts +5 -0
- package/src/http-api/HttpApiClient.ts +2 -1
- package/src/http-api/HttpApiScalar.ts +5 -0
- package/src/internal/core.ts +21 -1
- package/src/internal/dateTime.ts +13 -10
- package/src/internal/effect.ts +13 -7
- package/src/internal/graphql.ts +286 -0
- package/src/internal/graphqlHeaders.ts +11 -0
- package/src/internal/request.ts +31 -3
- package/src/internal/schema/toCodeDocument.ts +7 -1
- package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
- package/src/internal/version.ts +1 -1
- package/src/net/Host.ts +72 -0
- package/src/net/NetAddress.ts +9 -0
- package/src/observability/Otlp.ts +18 -0
- package/src/observability/OtlpExporter.ts +14 -3
- package/src/observability/OtlpLogger.ts +31 -2
- package/src/observability/OtlpMetrics.ts +30 -1
- package/src/observability/OtlpTracer.ts +32 -3
- package/src/reactivity/AsyncResult.ts +31 -0
- package/src/reactivity/AtomRegistry.ts +3 -1
- package/src/rpc/RpcClient.ts +6 -1
- package/src/rpc/RpcServer.ts +55 -15
- package/src/socket/Socket.ts +6 -0
- package/src/sql/SqlClient.ts +9 -7
- package/src/testing/TestClock.ts +144 -29
- package/src/workflow/Activity.ts +1 -0
- package/src/workflow/DurableDeferred.ts +43 -5
- package/src/workflow/Workflow.ts +31 -5
- package/src/workflow/WorkflowEngine.ts +107 -25
package/src/testing/TestClock.ts
CHANGED
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import * as Arr from "../Array.ts"
|
|
15
15
|
import * as Clock from "../Clock.ts"
|
|
16
|
+
import * as Context from "../Context.ts"
|
|
16
17
|
import * as Data from "../Data.ts"
|
|
17
18
|
import * as Duration from "../Duration.ts"
|
|
18
19
|
import * as Effect from "../Effect.ts"
|
|
19
20
|
import * as Fiber from "../Fiber.ts"
|
|
20
|
-
import { flow } from "../Function.ts"
|
|
21
21
|
import * as Latch from "../Latch.ts"
|
|
22
22
|
import * as Layer from "../Layer.ts"
|
|
23
|
-
import * as
|
|
23
|
+
import * as Scheduler from "../Scheduler.ts"
|
|
24
24
|
import * as Semaphore from "../Semaphore.ts"
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -40,6 +40,9 @@ import * as Semaphore from "../Semaphore.ts"
|
|
|
40
40
|
* the time is set to on or after the time they are scheduled to run. Fork the
|
|
41
41
|
* effect being tested, then adjust the clock time, and finally verify that the
|
|
42
42
|
* expected effects have been performed.
|
|
43
|
+
* The ordered execution of sleeps registered after multiple scheduler hops
|
|
44
|
+
* requires fibers running under {@link layer}; providing a clock from
|
|
45
|
+
* {@link make} by hand does not install the tracking scheduler.
|
|
43
46
|
*
|
|
44
47
|
* **Example** (Testing timeouts deterministically)
|
|
45
48
|
*
|
|
@@ -142,7 +145,8 @@ export declare namespace TestClock {
|
|
|
142
145
|
/**
|
|
143
146
|
* Options used when constructing a `TestClock`. `warningDelay` controls how
|
|
144
147
|
* long the live clock waits before logging a warning when a test uses time
|
|
145
|
-
* without advancing the test clock
|
|
148
|
+
* without advancing the test clock, or when a fiber woken by the test clock
|
|
149
|
+
* keeps running without suspending.
|
|
146
150
|
*
|
|
147
151
|
* **Example** (Configuring the warning delay)
|
|
148
152
|
*
|
|
@@ -170,7 +174,8 @@ export declare namespace TestClock {
|
|
|
170
174
|
export interface Options {
|
|
171
175
|
/**
|
|
172
176
|
* The amount of time to wait before displaying a warning message when a
|
|
173
|
-
* test is using time but is not advancing the `TestClock
|
|
177
|
+
* test is using time but is not advancing the `TestClock`, or when a fiber
|
|
178
|
+
* woken by `adjust` or `setTime` keeps running without suspending.
|
|
174
179
|
*/
|
|
175
180
|
readonly warningDelay?: Duration.Input
|
|
176
181
|
}
|
|
@@ -197,15 +202,30 @@ const warningMessage = "A test is using time, but is not advancing the test " +
|
|
|
197
202
|
"clock, which may result in the test hanging. Use TestClock.adjust to " +
|
|
198
203
|
"manually advance the time."
|
|
199
204
|
|
|
205
|
+
/**
|
|
206
|
+
* The warning message that will be displayed if a fiber woken by the
|
|
207
|
+
* `TestClock` does not suspend within the warning delay.
|
|
208
|
+
*/
|
|
209
|
+
const busyWarningMessage = "A fiber woken by the test clock is still running " +
|
|
210
|
+
"without suspending, so the test clock stopped waiting for it. Sleeps it " +
|
|
211
|
+
"starts later may be scheduled relative to a later time."
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* The live clock of each `TestClock`, so a `TestClock` constructed while
|
|
215
|
+
* another one is the current clock uses the outer clock's live clock instead
|
|
216
|
+
* of the outer `TestClock`, which only advances when adjusted.
|
|
217
|
+
*/
|
|
218
|
+
const liveClocks = new WeakMap<Clock.Clock, Clock.Clock>()
|
|
219
|
+
|
|
220
|
+
interface WakeTracker {
|
|
221
|
+
pending: number
|
|
222
|
+
onIdle: (() => void) | undefined
|
|
223
|
+
}
|
|
224
|
+
|
|
200
225
|
const defaultOptions: Required<TestClock.Options> = {
|
|
201
226
|
warningDelay: "1 second"
|
|
202
227
|
}
|
|
203
228
|
|
|
204
|
-
const SleepOrder = Order.flip(Order.Struct({
|
|
205
|
-
timestamp: Order.Number,
|
|
206
|
-
sequence: Order.Number
|
|
207
|
-
}))
|
|
208
|
-
|
|
209
229
|
const nanosPerMilli = BigInt(1_000_000)
|
|
210
230
|
|
|
211
231
|
const millisToNanos = (millis: number): bigint => {
|
|
@@ -217,6 +237,14 @@ const millisToNanos = (millis: number): bigint => {
|
|
|
217
237
|
/**
|
|
218
238
|
* Creates a `TestClock` with optional configuration.
|
|
219
239
|
*
|
|
240
|
+
* **Gotchas**
|
|
241
|
+
*
|
|
242
|
+
* The guarantee that sleeps registered after multiple scheduler hops run in
|
|
243
|
+
* order applies only to fibers running under {@link layer}, which
|
|
244
|
+
* `@effect/vitest`'s `it.effect` uses. Providing a clock from `make` by hand
|
|
245
|
+
* waits only one scheduler turn after each woken sleep. Prefer `layer` when
|
|
246
|
+
* forked fibers sleep.
|
|
247
|
+
*
|
|
220
248
|
* **Example** (Creating a test clock)
|
|
221
249
|
*
|
|
222
250
|
* ```ts import.meta.vitest
|
|
@@ -245,18 +273,21 @@ const millisToNanos = (millis: number): bigint => {
|
|
|
245
273
|
* @category constructors
|
|
246
274
|
* @since 4.0.0
|
|
247
275
|
*/
|
|
248
|
-
export const make = Effect.
|
|
276
|
+
export const make = (options?: TestClock.Options) => Effect.map(makeWithScheduler(options), ([testClock]) => testClock)
|
|
277
|
+
|
|
278
|
+
const makeWithScheduler = Effect.fnUntraced(function*(
|
|
249
279
|
options?: TestClock.Options
|
|
250
280
|
) {
|
|
251
281
|
const config = { ...defaultOptions, ...options }
|
|
252
|
-
|
|
282
|
+
// Sorted by descending timestamp, so `pop` wakes the earliest sleep first
|
|
253
283
|
const sleeps: Array<{
|
|
254
|
-
readonly sequence: number
|
|
255
284
|
readonly timestamp: number
|
|
256
285
|
readonly latch: Latch.Latch
|
|
257
286
|
}> = []
|
|
258
|
-
const
|
|
287
|
+
const currentClock = yield* Clock.clockWith(Effect.succeed)
|
|
288
|
+
const liveClock = liveClocks.get(currentClock) ?? currentClock
|
|
259
289
|
const warningSemaphore = yield* Semaphore.make(1)
|
|
290
|
+
const parentScheduler = yield* Scheduler.Scheduler
|
|
260
291
|
|
|
261
292
|
let currentTimestamp: number = new Date(0).getTime()
|
|
262
293
|
let currentWallNanos = BigInt(0)
|
|
@@ -332,17 +363,97 @@ export const make = Effect.fnUntraced(function*(
|
|
|
332
363
|
const millis = Duration.toMillis(duration)
|
|
333
364
|
const end = currentTimestamp + millis
|
|
334
365
|
if (end <= currentTimestamp) return
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
366
|
+
yield* Effect.acquireUseRelease(
|
|
367
|
+
Effect.sync(() => {
|
|
368
|
+
const entry = { timestamp: end, latch: Latch.makeUnsafe() }
|
|
369
|
+
// Insert before entries with an equal timestamp, so they wake in
|
|
370
|
+
// registration order
|
|
371
|
+
let low = 0
|
|
372
|
+
let high = sleeps.length
|
|
373
|
+
while (low < high) {
|
|
374
|
+
const mid = (low + high) >>> 1
|
|
375
|
+
if (sleeps[mid].timestamp > end) low = mid + 1
|
|
376
|
+
else high = mid
|
|
377
|
+
}
|
|
378
|
+
sleeps.splice(low, 0, entry)
|
|
379
|
+
return entry
|
|
380
|
+
}),
|
|
381
|
+
(entry) => Effect.andThen(warningStart, entry.latch.await),
|
|
382
|
+
(entry) =>
|
|
383
|
+
Effect.sync(() => {
|
|
384
|
+
// The entry is already gone if `run` popped it
|
|
385
|
+
const index = sleeps.indexOf(entry)
|
|
386
|
+
if (index !== -1) sleeps.splice(index, 1)
|
|
387
|
+
})
|
|
388
|
+
)
|
|
344
389
|
})
|
|
345
390
|
|
|
391
|
+
/**
|
|
392
|
+
* Tasks scheduled while waking a sleeper, and tasks scheduled by those tasks,
|
|
393
|
+
* are counted by that wake's tracker so `run` can wait for the woken fiber,
|
|
394
|
+
* and any fibers it resumes or forks, to suspend before checking the next
|
|
395
|
+
* sleep.
|
|
396
|
+
*/
|
|
397
|
+
let currentTracker: WakeTracker | undefined = undefined
|
|
398
|
+
|
|
399
|
+
function runTracked(tracker: WakeTracker, f: () => void): void {
|
|
400
|
+
const previous = currentTracker
|
|
401
|
+
currentTracker = tracker
|
|
402
|
+
try {
|
|
403
|
+
f()
|
|
404
|
+
} finally {
|
|
405
|
+
currentTracker = previous
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const scheduler: Scheduler.Scheduler = {
|
|
410
|
+
executionMode: parentScheduler.executionMode,
|
|
411
|
+
shouldYield: (fiber) => parentScheduler.shouldYield(fiber),
|
|
412
|
+
makeDispatcher() {
|
|
413
|
+
const dispatcher = parentScheduler.makeDispatcher()
|
|
414
|
+
return {
|
|
415
|
+
scheduleTask(task, priority) {
|
|
416
|
+
const tracker = currentTracker
|
|
417
|
+
if (tracker === undefined) {
|
|
418
|
+
return dispatcher.scheduleTask(task, priority)
|
|
419
|
+
}
|
|
420
|
+
tracker.pending++
|
|
421
|
+
dispatcher.scheduleTask(() => {
|
|
422
|
+
try {
|
|
423
|
+
runTracked(tracker, task)
|
|
424
|
+
} finally {
|
|
425
|
+
if (--tracker.pending === 0) tracker.onIdle?.()
|
|
426
|
+
}
|
|
427
|
+
}, priority)
|
|
428
|
+
},
|
|
429
|
+
flush() {
|
|
430
|
+
dispatcher.flush()
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const wake = (latch: Latch.Latch) =>
|
|
437
|
+
Effect.suspend(() => {
|
|
438
|
+
const tracker: WakeTracker = { pending: 0, onIdle: undefined }
|
|
439
|
+
runTracked(tracker, () => latch.openUnsafe())
|
|
440
|
+
if (tracker.pending === 0) return Effect.yieldNow
|
|
441
|
+
return Effect.callback<void>((resume) => {
|
|
442
|
+
if (tracker.pending === 0) return resume(Effect.void)
|
|
443
|
+
tracker.onIdle = () => resume(Effect.void)
|
|
444
|
+
return Effect.sync(() => {
|
|
445
|
+
tracker.onIdle = undefined
|
|
446
|
+
})
|
|
447
|
+
}).pipe(
|
|
448
|
+
Effect.timeoutOrElse({
|
|
449
|
+
duration: config.warningDelay,
|
|
450
|
+
orElse: () => Effect.logWarning(busyWarningMessage)
|
|
451
|
+
}),
|
|
452
|
+
withLive,
|
|
453
|
+
Effect.andThen(Effect.yieldNow)
|
|
454
|
+
)
|
|
455
|
+
})
|
|
456
|
+
|
|
346
457
|
const runSemaphore = yield* Semaphore.make(1)
|
|
347
458
|
const run = Effect.fnUntraced(function*(
|
|
348
459
|
step: (currentTimestamp: number) => number,
|
|
@@ -366,8 +477,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
366
477
|
if (Arr.lastNonEmpty(sleeps).timestamp > endTimestamp) break
|
|
367
478
|
const entry = sleeps.pop()!
|
|
368
479
|
advanceTo(entry.timestamp)
|
|
369
|
-
entry.latch
|
|
370
|
-
yield* Effect.yieldNow
|
|
480
|
+
yield* wake(entry.latch)
|
|
371
481
|
}
|
|
372
482
|
advanceTo(endTimestamp)
|
|
373
483
|
if (adjustmentNanos !== undefined && Number.isFinite(endTimestamp)) {
|
|
@@ -391,7 +501,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
391
501
|
|
|
392
502
|
yield* Effect.addFinalizer(() => warningDone)
|
|
393
503
|
|
|
394
|
-
|
|
504
|
+
const testClock = {
|
|
395
505
|
currentTimeMillisUnsafe,
|
|
396
506
|
currentTimeNanosUnsafe,
|
|
397
507
|
monotonicTimeNanosUnsafe,
|
|
@@ -403,6 +513,8 @@ export const make = Effect.fnUntraced(function*(
|
|
|
403
513
|
sleep,
|
|
404
514
|
withLive
|
|
405
515
|
}
|
|
516
|
+
liveClocks.set(testClock, liveClock)
|
|
517
|
+
return [testClock, scheduler] as const
|
|
406
518
|
})
|
|
407
519
|
|
|
408
520
|
/**
|
|
@@ -438,10 +550,13 @@ export const make = Effect.fnUntraced(function*(
|
|
|
438
550
|
* @category layers
|
|
439
551
|
* @since 4.0.0
|
|
440
552
|
*/
|
|
441
|
-
export const layer
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
)
|
|
553
|
+
export const layer = (options?: TestClock.Options): Layer.Layer<TestClock> =>
|
|
554
|
+
Layer.effectContext(
|
|
555
|
+
Effect.map(makeWithScheduler(options), ([testClock, scheduler]) =>
|
|
556
|
+
Context.make(Clock.Clock, testClock).pipe(
|
|
557
|
+
Context.add(Scheduler.Scheduler, scheduler)
|
|
558
|
+
))
|
|
559
|
+
) as any
|
|
445
560
|
|
|
446
561
|
/**
|
|
447
562
|
* Retrieves the `TestClock` service for this test and uses it to run the
|
package/src/workflow/Activity.ts
CHANGED
|
@@ -347,6 +347,7 @@ const makeExecute = Effect.fnUntraced(function*<
|
|
|
347
347
|
(_) => _._tag === "Suspended"
|
|
348
348
|
)
|
|
349
349
|
if (result._tag === "Suspended") {
|
|
350
|
+
if (result.failed) instance.failed = true
|
|
350
351
|
return yield* Workflow.suspend(instance)
|
|
351
352
|
}
|
|
352
353
|
return yield* result.exit
|
|
@@ -134,6 +134,25 @@ const CurrentAttempt = Context.Reference<number>(
|
|
|
134
134
|
{ defaultValue: () => 1 }
|
|
135
135
|
)
|
|
136
136
|
|
|
137
|
+
/** Awaits registered under the instance copy of a `recordHeld` body. */
|
|
138
|
+
const awaitOwners = new WeakMap<WorkflowInstance["Service"], Array<string>>()
|
|
139
|
+
|
|
140
|
+
const registerAwait = (instance: WorkflowInstance["Service"], name: string) => {
|
|
141
|
+
instance.awaitedDeferreds.set(name, (instance.awaitedDeferreds.get(name) ?? 0) + 1)
|
|
142
|
+
awaitOwners.get(instance)?.push(name)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const releaseAwaits = (instance: WorkflowInstance["Service"], names: Array<string>) => {
|
|
146
|
+
for (const name of names) {
|
|
147
|
+
const count = instance.awaitedDeferreds.get(name)! - 1
|
|
148
|
+
if (count === 0) {
|
|
149
|
+
instance.awaitedDeferreds.delete(name)
|
|
150
|
+
} else {
|
|
151
|
+
instance.awaitedDeferreds.set(name, count)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
137
156
|
const await_: <Success extends Schema.Constraint, Error extends Schema.Constraint>(
|
|
138
157
|
self: DurableDeferred<Success, Error>
|
|
139
158
|
) => Effect.Effect<
|
|
@@ -150,7 +169,7 @@ const await_: <Success extends Schema.Constraint, Error extends Schema.Constrain
|
|
|
150
169
|
const engine = yield* EngineTag
|
|
151
170
|
const instance = yield* InstanceTag
|
|
152
171
|
// Register before the read so any later completion can preempt the run.
|
|
153
|
-
instance
|
|
172
|
+
registerAwait(instance, self.name)
|
|
154
173
|
const exit = yield* Workflow.wrapActivityResult(
|
|
155
174
|
engine.deferredResult(self),
|
|
156
175
|
Option.isNone
|
|
@@ -343,6 +362,10 @@ const recordHeld = Effect.fnUntraced(function*<A, E, R>(
|
|
|
343
362
|
suspended: false,
|
|
344
363
|
activityState: { count: 0, latch: Latch.makeUnsafe() }
|
|
345
364
|
}
|
|
365
|
+
// A losing branch parked on a durable wait has already exited when the
|
|
366
|
+
// race settles, so this body owns the waits registered beneath it.
|
|
367
|
+
const owned: Array<string> = []
|
|
368
|
+
awaitOwners.set(local, owned)
|
|
346
369
|
// A parked `effect` interrupts the fiber it runs on. The child fiber
|
|
347
370
|
// keeps that from skipping the suspension handling below.
|
|
348
371
|
const fiber = yield* effect.pipe(
|
|
@@ -350,10 +373,25 @@ const recordHeld = Effect.fnUntraced(function*<A, E, R>(
|
|
|
350
373
|
Effect.onExit((exit) => recordExit(engine, instance, self, exit)),
|
|
351
374
|
Effect.forkChild({ startImmediately: true })
|
|
352
375
|
)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
376
|
+
return yield* Effect.onInterrupt(Fiber.await(fiber), () => Fiber.interrupt(fiber)).pipe(
|
|
377
|
+
Effect.map((exit) =>
|
|
378
|
+
local.suspended && Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)
|
|
379
|
+
? Option.none()
|
|
380
|
+
: Option.some(exit)
|
|
381
|
+
),
|
|
382
|
+
// The waits are over once the body has a result. Otherwise every branch
|
|
383
|
+
// parked, or an enclosing race interrupted the body, and the waits move
|
|
384
|
+
// to the enclosing owner, if any, to be released when that race settles.
|
|
385
|
+
Effect.onExit((result) =>
|
|
386
|
+
Effect.sync(() => {
|
|
387
|
+
if (Exit.isSuccess(result) && Option.isSome(result.value)) {
|
|
388
|
+
releaseAwaits(instance, owned)
|
|
389
|
+
} else {
|
|
390
|
+
awaitOwners.get(instance)?.push(...owned)
|
|
391
|
+
}
|
|
392
|
+
})
|
|
393
|
+
)
|
|
394
|
+
)
|
|
357
395
|
}),
|
|
358
396
|
// Every branch of `effect` parked: release the hold and let the enclosing
|
|
359
397
|
// activities finish before suspending. External preemption does not wait.
|
package/src/workflow/Workflow.ts
CHANGED
|
@@ -78,11 +78,26 @@ export interface Workflow<
|
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Execute the workflow with the given payload.
|
|
81
|
+
*
|
|
82
|
+
* **Details**
|
|
83
|
+
*
|
|
84
|
+
* `discard: true` returns the execution ID without waiting for the result.
|
|
85
|
+
* The child remains linked to its parent for completion wakes and interruption.
|
|
86
|
+
*
|
|
87
|
+
* With `discard: true, detached: true`, the child neither wakes its parent
|
|
88
|
+
* nor gets interrupted with it. The cluster engine retains the parent for
|
|
89
|
+
* observability.
|
|
90
|
+
*
|
|
91
|
+
* **Gotchas**
|
|
92
|
+
*
|
|
93
|
+
* Do not await a detached execution later. Executing the same payload joins
|
|
94
|
+
* it, but its completion will not wake the awaiting workflow.
|
|
81
95
|
*/
|
|
82
96
|
readonly execute: <const Discard extends boolean = false>(
|
|
83
97
|
payload: Payload["~type.make.in"],
|
|
84
98
|
options?: {
|
|
85
99
|
readonly discard?: Discard
|
|
100
|
+
readonly detached?: [Discard] extends [true] ? boolean | undefined : undefined
|
|
86
101
|
}
|
|
87
102
|
) => Effect.Effect<
|
|
88
103
|
Discard extends true ? string : Success["Type"],
|
|
@@ -248,7 +263,7 @@ export interface AnyWithProps extends Any {
|
|
|
248
263
|
readonly errorSchema: Schema.Top
|
|
249
264
|
readonly execute: (
|
|
250
265
|
payload: any,
|
|
251
|
-
options?: { readonly discard?: boolean }
|
|
266
|
+
options?: { readonly discard?: boolean; readonly detached?: boolean | undefined }
|
|
252
267
|
) => Effect.Effect<any, any, any>
|
|
253
268
|
readonly resume: (
|
|
254
269
|
executionId: string
|
|
@@ -352,7 +367,7 @@ const Proto = {
|
|
|
352
367
|
execute<const Discard extends boolean = false>(
|
|
353
368
|
this: AnyWithProps,
|
|
354
369
|
fields: any,
|
|
355
|
-
opts?: { readonly discard?: Discard } | undefined
|
|
370
|
+
opts?: { readonly discard?: Discard; readonly detached?: boolean | undefined } | undefined
|
|
356
371
|
) {
|
|
357
372
|
return Effect.suspend(() => {
|
|
358
373
|
const payload = this.payloadSchema.make(fields)
|
|
@@ -366,6 +381,7 @@ const Proto = {
|
|
|
366
381
|
executionId,
|
|
367
382
|
payload,
|
|
368
383
|
discard: opts?.discard,
|
|
384
|
+
detached: opts?.detached,
|
|
369
385
|
suspendedRetrySchedule: this.suspendedRetrySchedule
|
|
370
386
|
})
|
|
371
387
|
))
|
|
@@ -617,6 +633,11 @@ export class Complete<A, E> extends Data.TaggedClass("Complete")<{
|
|
|
617
633
|
* Represents a suspended workflow execution, optionally carrying the cause that
|
|
618
634
|
* triggered suspension.
|
|
619
635
|
*
|
|
636
|
+
* **Details**
|
|
637
|
+
*
|
|
638
|
+
* `failed` marks this execution's own `SuspendOnFailure` and requires explicit
|
|
639
|
+
* `resume` or `interrupt`. Inherited child failures do not set it.
|
|
640
|
+
*
|
|
620
641
|
* @stability unstable
|
|
621
642
|
* @category schemas
|
|
622
643
|
* @since 4.0.0
|
|
@@ -625,7 +646,8 @@ export class Suspended extends Schema.Class<Suspended>(
|
|
|
625
646
|
"effect/workflow/Workflow/Suspended"
|
|
626
647
|
)({
|
|
627
648
|
_tag: Schema.tag("Suspended"),
|
|
628
|
-
cause: Schema.optional(Schema.Cause(Schema.Never, Schema.Defect()))
|
|
649
|
+
cause: Schema.optional(Schema.Cause(Schema.Never, Schema.Defect())),
|
|
650
|
+
failed: Schema.optional(Schema.Boolean)
|
|
629
651
|
}) {
|
|
630
652
|
/**
|
|
631
653
|
* Marks this value as a workflow result for runtime guards.
|
|
@@ -697,11 +719,13 @@ export const intoResult = <A, E, R>(
|
|
|
697
719
|
Effect.interruptible,
|
|
698
720
|
suspendOnFailure
|
|
699
721
|
? Effect.catchCause((cause) => {
|
|
700
|
-
if (instance.abandoned) {
|
|
722
|
+
if (instance.abandoned || instance.interrupted) {
|
|
701
723
|
return Effect.failCause(cause)
|
|
702
724
|
}
|
|
703
725
|
instance.suspended = true
|
|
726
|
+
// Ordinary suspension is a self-interrupt and also reaches here.
|
|
704
727
|
if (!Cause.hasInterruptsOnly(cause)) {
|
|
728
|
+
instance.failed = true
|
|
705
729
|
instance.cause = Cause.die(Cause.squash(cause))
|
|
706
730
|
}
|
|
707
731
|
return Effect.interrupt
|
|
@@ -720,7 +744,9 @@ export const intoResult = <A, E, R>(
|
|
|
720
744
|
const abandoned = instance.abandoned && !instance.interrupted && hasInterruptsOnly
|
|
721
745
|
instance.abandoned = abandoned
|
|
722
746
|
if (instance.suspended && hasInterruptsOnly && !abandoned) {
|
|
723
|
-
return Effect.succeed(
|
|
747
|
+
return Effect.succeed(
|
|
748
|
+
new Suspended(instance.failed ? { cause: instance.cause, failed: true } : { cause: instance.cause })
|
|
749
|
+
)
|
|
724
750
|
}
|
|
725
751
|
if (!instance.interrupted && hasInterruptsOnly) {
|
|
726
752
|
// External interrupts exit without a result. When the cluster has
|