effect 4.0.6 → 4.0.7
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/Arbitrary.d.ts +10 -2
- package/dist/Arbitrary.d.ts.map +1 -1
- package/dist/Arbitrary.js +2 -1
- package/dist/Arbitrary.js.map +1 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +21 -6
- package/dist/Channel.js.map +1 -1
- package/dist/Data.d.ts +54 -235
- package/dist/Data.d.ts.map +1 -1
- package/dist/Data.js.map +1 -1
- package/dist/Effect.d.ts +1 -1
- package/dist/Effect.js +1 -1
- package/dist/Equal.d.ts.map +1 -1
- package/dist/Equal.js +8 -1
- package/dist/Equal.js.map +1 -1
- package/dist/Exit.d.ts +3 -3
- package/dist/Exit.d.ts.map +1 -1
- package/dist/Exit.js.map +1 -1
- package/dist/Formatter.d.ts.map +1 -1
- package/dist/Formatter.js +27 -13
- package/dist/Formatter.js.map +1 -1
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +4 -1
- package/dist/Hash.js.map +1 -1
- package/dist/JsonPatch.js +4 -0
- package/dist/JsonPatch.js.map +1 -1
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +13 -40
- package/dist/JsonSchema.js.map +1 -1
- package/dist/Metric.d.ts +3 -3
- package/dist/MutableList.d.ts +5 -2
- package/dist/MutableList.d.ts.map +1 -1
- package/dist/MutableList.js +7 -5
- package/dist/MutableList.js.map +1 -1
- package/dist/MutableRef.d.ts.map +1 -1
- package/dist/MutableRef.js +7 -0
- package/dist/MutableRef.js.map +1 -1
- package/dist/PartitionedSemaphore.d.ts +2 -1
- package/dist/PartitionedSemaphore.d.ts.map +1 -1
- package/dist/PartitionedSemaphore.js +22 -12
- package/dist/PartitionedSemaphore.js.map +1 -1
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +77 -27
- package/dist/Pool.js.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/PubSub.js +5 -6
- package/dist/PubSub.js.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +8 -0
- package/dist/Ref.js.map +1 -1
- package/dist/Schedule.js +1 -1
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +24 -8
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +37 -28
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +4 -2
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +14 -17
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +48 -22
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +19 -10
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +23 -13
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +4 -1
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +9 -2
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Semaphore.js +54 -35
- package/dist/Semaphore.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +7 -2
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +22 -10
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +3 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +3 -0
- package/dist/String.js.map +1 -1
- package/dist/Tracer.d.ts +11 -1
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Tracer.js +6 -1
- package/dist/Tracer.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +9 -0
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpSchema.d.ts +110 -110
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +21 -15
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts +52 -0
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +38 -0
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +16 -3
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +4 -0
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +24 -0
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js +5 -2
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/Toolkit.d.ts.map +1 -1
- package/dist/ai/Toolkit.js +8 -1
- package/dist/ai/Toolkit.js.map +1 -1
- package/dist/cli/Argument.d.ts +15 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +5 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliError.d.ts +78 -0
- package/dist/cli/CliError.d.ts.map +1 -1
- package/dist/cli/CliError.js +65 -3
- package/dist/cli/CliError.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +155 -6
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +62 -6
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +24 -16
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +59 -29
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +58 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js +49 -9
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +15 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +5 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +15 -7
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/Param.d.ts +9 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +21 -2
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/TerminalCapabilities.d.ts +3 -2
- package/dist/cli/TerminalCapabilities.d.ts.map +1 -1
- package/dist/cli/TerminalCapabilities.js +3 -1
- package/dist/cli/TerminalCapabilities.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +73 -27
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +45 -10
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +23 -45
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +6 -7
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +61 -21
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +10 -0
- package/dist/cluster/ShardingConfig.d.ts.map +1 -1
- package/dist/cluster/ShardingConfig.js.map +1 -1
- package/dist/cluster/Snowflake.d.ts.map +1 -1
- package/dist/cluster/Snowflake.js +3 -7
- package/dist/cluster/Snowflake.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +87 -39
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +54 -20
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/devtools/DevToolsClient.d.ts.map +1 -1
- package/dist/devtools/DevToolsClient.js +2 -0
- package/dist/devtools/DevToolsClient.js.map +1 -1
- package/dist/encoding/Base64.js +36 -0
- package/dist/encoding/Base64.js.map +1 -1
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +3 -3
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +21 -16
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +47 -27
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/internal/conflicts.d.ts +0 -1
- package/dist/eventlog/internal/conflicts.d.ts.map +1 -1
- package/dist/eventlog/internal/conflicts.js +0 -3
- package/dist/eventlog/internal/conflicts.js.map +1 -1
- package/dist/http/Cookies.d.ts.map +1 -1
- package/dist/http/Cookies.js +10 -9
- package/dist/http/Cookies.js.map +1 -1
- package/dist/http/HttpClient.d.ts +423 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +231 -7
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts +8 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +37 -1
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +1 -1
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +1 -1
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +14 -16
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +2 -1
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.js +2 -2
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +6 -1
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +73 -10
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +48 -21
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.js +3 -3
- package/dist/http/UrlParams.d.ts +3 -1
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +4 -2
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.js +4 -5
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/decompression.js +3 -0
- package/dist/http/internal/decompression.js.map +1 -1
- package/dist/http/internal/httpBody.js +8 -1
- package/dist/http/internal/httpBody.js.map +1 -1
- package/dist/http/internal/urlParams.js +25 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http-api/HttpApi.d.ts +3 -6
- package/dist/http-api/HttpApi.d.ts.map +1 -1
- package/dist/http-api/HttpApi.js +3 -6
- package/dist/http-api/HttpApi.js.map +1 -1
- package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
- package/dist/http-api/HttpApiBuilder.js +27 -11
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +77 -7
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +142 -44
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts +24 -7
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +109 -27
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +76 -29
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +70 -59
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/http-api/HttpApiTest.d.ts.map +1 -1
- package/dist/http-api/HttpApiTest.js +3 -2
- package/dist/http-api/HttpApiTest.js.map +1 -1
- package/dist/http-api/OpenApi.d.ts.map +1 -1
- package/dist/http-api/OpenApi.js +25 -16
- package/dist/http-api/OpenApi.js.map +1 -1
- package/dist/http-api/internal/toCodecHttpProperties.d.ts +2 -0
- package/dist/http-api/internal/toCodecHttpProperties.d.ts.map +1 -0
- package/dist/http-api/internal/toCodecHttpProperties.js +38 -0
- package/dist/http-api/internal/toCodecHttpProperties.js.map +1 -0
- package/dist/internal/arbitrary/runner.d.ts.map +1 -1
- package/dist/internal/arbitrary/runner.js +120 -44
- package/dist/internal/arbitrary/runner.js.map +1 -1
- package/dist/internal/core.js +2 -0
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/effect.js +21 -13
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/equal.js +14 -0
- package/dist/internal/equal.js.map +1 -1
- package/dist/internal/jsonSchema.d.ts +2 -0
- package/dist/internal/jsonSchema.d.ts.map +1 -0
- package/dist/internal/jsonSchema.js +28 -0
- package/dist/internal/jsonSchema.js.map +1 -0
- package/dist/internal/matcher.js +1 -1
- package/dist/internal/matcher.js.map +1 -1
- package/dist/internal/schema/compilerRegistry.js +4 -1
- package/dist/internal/schema/compilerRegistry.js.map +1 -1
- package/dist/internal/schema/content.d.ts +2 -0
- package/dist/internal/schema/content.d.ts.map +1 -0
- package/dist/internal/schema/content.js +13 -0
- package/dist/internal/schema/content.js.map +1 -0
- package/dist/internal/schema/fromJsonSchemaDocument.js +173 -185
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/fromRepresentation.js +2 -1
- package/dist/internal/schema/fromRepresentation.js.map +1 -1
- package/dist/internal/schema/standardSchema.js +8 -2
- package/dist/internal/schema/standardSchema.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +3 -3
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +21 -24
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +205 -140
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/toRepresentation.js +107 -129
- package/dist/internal/schema/toRepresentation.js.map +1 -1
- package/dist/internal/sql.d.ts +2 -0
- package/dist/internal/sql.d.ts.map +1 -0
- package/dist/internal/sql.js +13 -0
- package/dist/internal/sql.js.map +1 -0
- package/dist/internal/version.js +1 -1
- package/dist/observability/OtlpProxy.d.ts +154 -0
- package/dist/observability/OtlpProxy.d.ts.map +1 -0
- package/dist/observability/OtlpProxy.js +235 -0
- package/dist/observability/OtlpProxy.js.map +1 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +4 -0
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/observability/index.d.ts +5 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +5 -0
- package/dist/observability/index.js.map +1 -1
- package/dist/persistence/CircuitBreaker.d.ts +897 -0
- package/dist/persistence/CircuitBreaker.d.ts.map +1 -0
- package/dist/persistence/CircuitBreaker.js +1165 -0
- package/dist/persistence/CircuitBreaker.js.map +1 -0
- package/dist/persistence/Redis.d.ts +78 -2
- package/dist/persistence/Redis.d.ts.map +1 -1
- package/dist/persistence/Redis.js +62 -7
- package/dist/persistence/Redis.js.map +1 -1
- package/dist/persistence/index.d.ts +5 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +5 -0
- package/dist/persistence/index.js.map +1 -1
- package/dist/process/ChildProcess.d.ts +30 -4
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/process/ChildProcessSpawner.d.ts +30 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/process/ChildProcessSpawner.js +5 -2
- package/dist/process/ChildProcessSpawner.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +1 -1
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +9 -8
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts +14 -0
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +20 -8
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +11 -1
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/rpc/RpcTest.d.ts +1 -0
- package/dist/rpc/RpcTest.d.ts.map +1 -1
- package/dist/rpc/RpcTest.js +1 -0
- package/dist/rpc/RpcTest.js.map +1 -1
- package/dist/sql/Migrator.d.ts +2 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +11 -8
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +9 -4
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +8 -1
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/SqlResolver.d.ts +4 -0
- package/dist/sql/SqlResolver.d.ts.map +1 -1
- package/dist/sql/SqlResolver.js +18 -4
- package/dist/sql/SqlResolver.js.map +1 -1
- package/dist/sql/Statement.d.ts +7 -0
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +21 -2
- package/dist/sql/Statement.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +21 -2
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/package.json +1 -1
- package/src/Arbitrary.ts +10 -2
- package/src/Channel.ts +47 -18
- package/src/Data.ts +60 -265
- package/src/Effect.ts +1 -1
- package/src/Equal.ts +8 -1
- package/src/Exit.ts +3 -3
- package/src/Formatter.ts +28 -13
- package/src/Hash.ts +4 -1
- package/src/JsonPatch.ts +4 -0
- package/src/JsonSchema.ts +12 -40
- package/src/Metric.ts +3 -3
- package/src/MutableList.ts +7 -5
- package/src/MutableRef.ts +8 -1
- package/src/PartitionedSemaphore.ts +24 -13
- package/src/Pool.ts +109 -37
- package/src/PubSub.ts +5 -6
- package/src/Ref.ts +8 -0
- package/src/Schedule.ts +1 -1
- package/src/Schema.ts +48 -25
- package/src/SchemaAST.ts +20 -20
- package/src/SchemaParser.ts +51 -18
- package/src/SchemaRepresentation.ts +31 -34
- package/src/SchemaTransformation.ts +9 -2
- package/src/Semaphore.ts +67 -40
- package/src/Sink.ts +15 -2
- package/src/Stream.ts +33 -16
- package/src/String.ts +3 -0
- package/src/Tracer.ts +15 -1
- package/src/ai/LanguageModel.ts +9 -0
- package/src/ai/McpServer.ts +14 -13
- package/src/ai/Prompt.ts +65 -0
- package/src/ai/Response.ts +34 -9
- package/src/ai/Tool.ts +38 -2
- package/src/ai/Toolkit.ts +4 -1
- package/src/cli/Argument.ts +15 -0
- package/src/cli/CliError.ts +90 -3
- package/src/cli/CliOutput.ts +183 -6
- package/src/cli/Command.ts +53 -41
- package/src/cli/Completions.ts +51 -0
- package/src/cli/Flag.ts +15 -0
- package/src/cli/GlobalFlag.ts +6 -7
- package/src/cli/Param.ts +29 -6
- package/src/cli/TerminalCapabilities.ts +6 -3
- package/src/cli/internal/completions/bash.ts +79 -29
- package/src/cluster/ClusterWorkflowEngine.ts +46 -16
- package/src/cluster/MessageStorage.ts +19 -14
- package/src/cluster/Sharding.ts +83 -21
- package/src/cluster/ShardingConfig.ts +5 -0
- package/src/cluster/Snowflake.ts +3 -7
- package/src/cluster/SqlRunnerStorage.ts +110 -47
- package/src/cluster/internal/entityManager.ts +75 -22
- package/src/devtools/DevToolsClient.ts +2 -0
- package/src/encoding/Base64.ts +38 -0
- package/src/encoding/Sse.ts +4 -3
- package/src/encoding/Toml.ts +33 -16
- package/src/eventlog/SqlEventJournal.ts +68 -45
- package/src/eventlog/internal/conflicts.ts +0 -4
- package/src/http/Cookies.ts +10 -11
- package/src/http/HttpClient.ts +547 -7
- package/src/http/HttpClientError.ts +35 -1
- package/src/http/HttpClientRequest.ts +9 -1
- package/src/http/HttpMiddleware.ts +15 -18
- package/src/http/HttpRouter.ts +2 -1
- package/src/http/HttpServerError.ts +2 -2
- package/src/http/HttpServerRequest.ts +102 -16
- package/src/http/HttpStaticServer.ts +51 -22
- package/src/http/MultipartParser/internal/contentType.ts +3 -3
- package/src/http/UrlParams.ts +6 -1
- package/src/http/internal/compression.ts +4 -5
- package/src/http/internal/decompression.ts +6 -0
- package/src/http/internal/httpBody.ts +10 -2
- package/src/http/internal/urlParams.ts +29 -0
- package/src/http-api/HttpApi.ts +3 -6
- package/src/http-api/HttpApiBuilder.ts +45 -15
- package/src/http-api/HttpApiClient.ts +218 -72
- package/src/http-api/HttpApiEndpoint.ts +121 -30
- package/src/http-api/HttpApiSchema.ts +141 -48
- package/src/http-api/HttpApiTest.ts +3 -2
- package/src/http-api/OpenApi.ts +20 -17
- package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
- package/src/internal/arbitrary/runner.ts +133 -36
- package/src/internal/core.ts +2 -0
- package/src/internal/effect.ts +24 -16
- package/src/internal/equal.ts +17 -0
- package/src/internal/jsonSchema.ts +27 -0
- package/src/internal/matcher.ts +1 -1
- package/src/internal/schema/compilerRegistry.ts +6 -1
- package/src/internal/schema/content.ts +18 -0
- package/src/internal/schema/fromJsonSchemaDocument.ts +228 -190
- package/src/internal/schema/fromRepresentation.ts +2 -1
- package/src/internal/schema/standardSchema.ts +2 -2
- package/src/internal/schema/toCodeDocument.ts +4 -4
- package/src/internal/schema/toCodec.ts +26 -22
- package/src/internal/schema/toJsonSchemaDocument.ts +189 -167
- package/src/internal/schema/toRepresentation.ts +122 -140
- package/src/internal/sql.ts +14 -0
- package/src/internal/version.ts +1 -1
- package/src/observability/OtlpProxy.ts +314 -0
- package/src/observability/OtlpTracer.ts +4 -0
- package/src/observability/index.ts +6 -0
- package/src/persistence/CircuitBreaker.ts +1678 -0
- package/src/persistence/Redis.ts +129 -8
- package/src/persistence/index.ts +6 -0
- package/src/process/ChildProcess.ts +30 -4
- package/src/process/ChildProcessSpawner.ts +41 -2
- package/src/reactivity/AsyncResult.ts +1 -1
- package/src/rpc/RpcClient.ts +13 -10
- package/src/rpc/RpcSerialization.ts +32 -9
- package/src/rpc/RpcServer.ts +16 -1
- package/src/rpc/RpcTest.ts +3 -0
- package/src/sql/Migrator.ts +12 -7
- package/src/sql/SqlClient.ts +11 -4
- package/src/sql/SqlResolver.ts +23 -9
- package/src/sql/Statement.ts +30 -2
- package/src/workflow/DurableDeferred.ts +23 -6
package/src/persistence/Redis.ts
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
* Redis support shared by persistence modules.
|
|
3
3
|
*
|
|
4
4
|
* This module defines a `Redis` service that can send Redis commands, subscribe
|
|
5
|
-
* to pub/sub channels,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* them later by their cached Redis
|
|
5
|
+
* to pub/sub channels, run Lua scripts, and reserve a dedicated connection from
|
|
6
|
+
* a pool. It does not create a Redis client itself; callers provide the
|
|
7
|
+
* client-specific operations. The module also provides helpers for describing
|
|
8
|
+
* Lua scripts, loading them once, and running them later by their cached Redis
|
|
9
|
+
* id.
|
|
9
10
|
*
|
|
10
11
|
* @stability unstable
|
|
11
12
|
* @since 4.0.0
|
|
12
13
|
*/
|
|
13
14
|
import * as Cache from "../Cache.ts"
|
|
14
|
-
import
|
|
15
|
+
import * as Cause from "../Cause.ts"
|
|
15
16
|
import * as Context from "../Context.ts"
|
|
16
17
|
import * as Duration from "../Duration.ts"
|
|
17
18
|
import * as Effect from "../Effect.ts"
|
|
@@ -19,6 +20,7 @@ import * as Equal from "../Equal.ts"
|
|
|
19
20
|
import * as Exit from "../Exit.ts"
|
|
20
21
|
import { constant, identity } from "../Function.ts"
|
|
21
22
|
import * as Hash from "../Hash.ts"
|
|
23
|
+
import * as Pool from "../Pool.ts"
|
|
22
24
|
import * as Queue from "../Queue.ts"
|
|
23
25
|
import * as Schema from "../Schema.ts"
|
|
24
26
|
import * as Scope from "../Scope.ts"
|
|
@@ -63,8 +65,63 @@ export class Redis extends Context.Service<Redis, {
|
|
|
63
65
|
readonly result: unknown
|
|
64
66
|
}
|
|
65
67
|
>(script: Script<Config>) => (...params: Config["params"]) => Effect.Effect<Config["result"], RedisError>
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Reserves a pooled connection that no other caller shares for the lifetime
|
|
71
|
+
* of the current scope.
|
|
72
|
+
*
|
|
73
|
+
* Use it for blocking commands such as `XREAD BLOCK`, `XREADGROUP BLOCK`,
|
|
74
|
+
* `BLPOP`, `BRPOP`, `BLMOVE`, `BLMPOP` and `WAIT`, which would otherwise
|
|
75
|
+
* hold up every command queued behind them on the shared connection.
|
|
76
|
+
*
|
|
77
|
+
* When the scope closes, the connection returns to the pool. If a command on
|
|
78
|
+
* it failed, was interrupted, or is still running, the connection is closed
|
|
79
|
+
* instead, because Redis may still be processing the command.
|
|
80
|
+
*/
|
|
81
|
+
readonly reserve: Effect.Effect<Connection, RedisError, Scope.Scope>
|
|
66
82
|
}>()("effect/persistence/Redis") {}
|
|
67
83
|
|
|
84
|
+
/**
|
|
85
|
+
* A dedicated Redis connection obtained from `Redis.reserve`.
|
|
86
|
+
*
|
|
87
|
+
* **Details**
|
|
88
|
+
*
|
|
89
|
+
* `eval` loads scripts through the shared connection and runs `EVALSHA` on
|
|
90
|
+
* this connection.
|
|
91
|
+
*
|
|
92
|
+
* @stability unstable
|
|
93
|
+
* @category models
|
|
94
|
+
* @since 4.0.7
|
|
95
|
+
*/
|
|
96
|
+
export interface Connection {
|
|
97
|
+
readonly send: Redis["Service"]["send"]
|
|
98
|
+
readonly eval: Redis["Service"]["eval"]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Options for the pool of connections behind `Redis.reserve`.
|
|
103
|
+
*
|
|
104
|
+
* **Details**
|
|
105
|
+
*
|
|
106
|
+
* - `maxConnections`: maximum number of reserved connections, default `10`.
|
|
107
|
+
* Further `reserve` calls wait for a connection to be released.
|
|
108
|
+
* - `minConnections`: connections kept open while idle, default `0`.
|
|
109
|
+
* - `idleTimeout`: how long a connection above `minConnections` stays idle
|
|
110
|
+
* before it is closed, default 60 seconds.
|
|
111
|
+
* - `acquireTimeout`: how long `reserve` waits for a connection before failing
|
|
112
|
+
* with a `RedisError`. Unbounded by default.
|
|
113
|
+
*
|
|
114
|
+
* @stability unstable
|
|
115
|
+
* @category models
|
|
116
|
+
* @since 4.0.7
|
|
117
|
+
*/
|
|
118
|
+
export interface PoolOptions {
|
|
119
|
+
readonly maxConnections?: number | undefined
|
|
120
|
+
readonly minConnections?: number | undefined
|
|
121
|
+
readonly idleTimeout?: Duration.Input | undefined
|
|
122
|
+
readonly acquireTimeout?: Duration.Input | undefined
|
|
123
|
+
}
|
|
124
|
+
|
|
68
125
|
/**
|
|
69
126
|
* Creates a `Redis` service from raw command and subscription operations.
|
|
70
127
|
*
|
|
@@ -73,6 +130,11 @@ export class Redis extends Context.Service<Redis, {
|
|
|
73
130
|
* Lua scripts are loaded through `SCRIPT LOAD`, cached, and then invoked with
|
|
74
131
|
* `EVALSHA`.
|
|
75
132
|
*
|
|
133
|
+
* `connect` opens the dedicated connections behind `reserve`. Its `close` must
|
|
134
|
+
* fail any command still in flight on that connection. Connections are pooled
|
|
135
|
+
* according to `pool`, and closing the scope closes every connection,
|
|
136
|
+
* including reserved ones with a command in flight.
|
|
137
|
+
*
|
|
76
138
|
* @stability unstable
|
|
77
139
|
* @category constructors
|
|
78
140
|
* @since 4.0.0
|
|
@@ -84,6 +146,11 @@ export const make = Effect.fnUntraced(function*(
|
|
|
84
146
|
channel: string,
|
|
85
147
|
onMessage: (message: RedisMessage) => void
|
|
86
148
|
) => Effect.Effect<Effect.Effect<void, RedisError>, RedisError, Scope.Scope>
|
|
149
|
+
readonly connect: Effect.Effect<{
|
|
150
|
+
readonly send: <A = unknown>(command: string, ...args: ReadonlyArray<string>) => Effect.Effect<A, RedisError>
|
|
151
|
+
readonly close: Effect.Effect<void>
|
|
152
|
+
}, RedisError>
|
|
153
|
+
readonly pool?: PoolOptions | undefined
|
|
87
154
|
}
|
|
88
155
|
) {
|
|
89
156
|
const scriptCache = yield* Cache.makeWith(
|
|
@@ -94,7 +161,8 @@ export const make = Effect.fnUntraced(function*(
|
|
|
94
161
|
}
|
|
95
162
|
)
|
|
96
163
|
|
|
97
|
-
const
|
|
164
|
+
const makeEval = (send: Redis["Service"]["send"]): Redis["Service"]["eval"] =>
|
|
165
|
+
<
|
|
98
166
|
Config extends {
|
|
99
167
|
readonly params: ReadonlyArray<unknown>
|
|
100
168
|
readonly result: unknown
|
|
@@ -104,7 +172,7 @@ export const make = Effect.fnUntraced(function*(
|
|
|
104
172
|
) =>
|
|
105
173
|
(...params: Config["params"]): Effect.Effect<Config["result"], RedisError> => {
|
|
106
174
|
const evalSha = (sha: string) =>
|
|
107
|
-
|
|
175
|
+
send<Config["result"]>(
|
|
108
176
|
"EVALSHA",
|
|
109
177
|
sha,
|
|
110
178
|
script.numberOfKeys(...params).toString(),
|
|
@@ -119,6 +187,58 @@ export const make = Effect.fnUntraced(function*(
|
|
|
119
187
|
)
|
|
120
188
|
}
|
|
121
189
|
|
|
190
|
+
// Closing a connection fails its in-flight command, which releases the
|
|
191
|
+
// reservation. The pool waits for reservations on shutdown, so connections
|
|
192
|
+
// are closed before it shuts down.
|
|
193
|
+
const connections = new Set<Effect.Effect<void>>()
|
|
194
|
+
const pool = yield* Pool.makeWithTTL({
|
|
195
|
+
acquire: Effect.acquireRelease(
|
|
196
|
+
Effect.map(options.connect, (connection) => {
|
|
197
|
+
const close: Effect.Effect<void> = Effect.suspend(() =>
|
|
198
|
+
connections.delete(close) ? connection.close : Effect.void
|
|
199
|
+
)
|
|
200
|
+
connections.add(close)
|
|
201
|
+
return { send: connection.send, close, healthy: true, active: 0 }
|
|
202
|
+
}),
|
|
203
|
+
(connection) => connection.close
|
|
204
|
+
),
|
|
205
|
+
min: options.pool?.minConnections ?? 0,
|
|
206
|
+
max: options.pool?.maxConnections ?? 10,
|
|
207
|
+
concurrency: 1,
|
|
208
|
+
timeToLive: options.pool?.idleTimeout ?? Duration.seconds(60)
|
|
209
|
+
})
|
|
210
|
+
yield* Effect.addFinalizer(() => Effect.forEach(connections, identity, { discard: true }))
|
|
211
|
+
|
|
212
|
+
const acquireTimeout = options.pool?.acquireTimeout
|
|
213
|
+
const get = acquireTimeout === undefined ? Pool.get(pool) : Pool.get(pool).pipe(
|
|
214
|
+
Effect.timeoutOrElse({
|
|
215
|
+
duration: acquireTimeout,
|
|
216
|
+
orElse: () =>
|
|
217
|
+
Effect.fail(
|
|
218
|
+
new RedisError({ cause: new Cause.TimeoutError("Timed out waiting for a reserved Redis connection") })
|
|
219
|
+
)
|
|
220
|
+
})
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
const reserve = Effect.gen(function*() {
|
|
224
|
+
const connection = yield* get
|
|
225
|
+
yield* Effect.addFinalizer(() =>
|
|
226
|
+
connection.healthy && connection.active === 0 ? Effect.void : Pool.invalidate(pool, connection)
|
|
227
|
+
)
|
|
228
|
+
const send = <A = unknown>(command: string, ...args: ReadonlyArray<string>) =>
|
|
229
|
+
Effect.suspend(() => {
|
|
230
|
+
connection.active++
|
|
231
|
+
return connection.send<A>(command, ...args).pipe(
|
|
232
|
+
Effect.onExit((exit) => {
|
|
233
|
+
connection.active--
|
|
234
|
+
if (Exit.isFailure(exit)) connection.healthy = false
|
|
235
|
+
return Effect.void
|
|
236
|
+
})
|
|
237
|
+
)
|
|
238
|
+
})
|
|
239
|
+
return identity<Connection>({ send, eval: makeEval(send) })
|
|
240
|
+
})
|
|
241
|
+
|
|
122
242
|
const subscribe = Effect.fnUntraced(function*(channel: string) {
|
|
123
243
|
const queue = yield* Queue.unbounded<RedisMessage, RedisError>()
|
|
124
244
|
yield* Scope.addFinalizer(yield* Effect.scope, Queue.shutdown(queue))
|
|
@@ -135,7 +255,8 @@ export const make = Effect.fnUntraced(function*(
|
|
|
135
255
|
return identity<Redis["Service"]>({
|
|
136
256
|
send: options.send,
|
|
137
257
|
subscribe,
|
|
138
|
-
eval:
|
|
258
|
+
eval: makeEval(options.send),
|
|
259
|
+
reserve
|
|
139
260
|
})
|
|
140
261
|
})
|
|
141
262
|
|
package/src/persistence/index.ts
CHANGED
|
@@ -319,10 +319,17 @@ export interface StdoutConfig {
|
|
|
319
319
|
* Can be a string indicating how the operating system should configure the
|
|
320
320
|
* pipe established between the child process `stdout` and the parent process.
|
|
321
321
|
*
|
|
322
|
-
* A `Sink` can also be passed
|
|
323
|
-
*
|
|
322
|
+
* A `Sink` can also be passed. The output is transduced through the sink as
|
|
323
|
+
* `handle.stdout` is consumed, and `handle.stdout` emits the results produced by
|
|
324
|
+
* the sink instead of the raw output.
|
|
324
325
|
*
|
|
325
326
|
* Defaults to "pipe".
|
|
327
|
+
*
|
|
328
|
+
* **Gotchas**
|
|
329
|
+
*
|
|
330
|
+
* A `Sink` only receives data while `handle.stdout` is being consumed. If
|
|
331
|
+
* it is never consumed, the sink receives nothing and a child process that
|
|
332
|
+
* writes more than the pipe buffer can block before it exits.
|
|
326
333
|
*/
|
|
327
334
|
readonly stream?: CommandOutput | undefined
|
|
328
335
|
}
|
|
@@ -343,10 +350,17 @@ export interface StderrConfig {
|
|
|
343
350
|
* Can be a string indicating how the operating system should configure the
|
|
344
351
|
* pipe established between the child process `stderr` and the parent process.
|
|
345
352
|
*
|
|
346
|
-
* A `Sink` can also be passed
|
|
347
|
-
*
|
|
353
|
+
* A `Sink` can also be passed. The output is transduced through the sink as
|
|
354
|
+
* `handle.stderr` is consumed, and `handle.stderr` emits the results produced by
|
|
355
|
+
* the sink instead of the raw output.
|
|
348
356
|
*
|
|
349
357
|
* Defaults to "pipe".
|
|
358
|
+
*
|
|
359
|
+
* **Gotchas**
|
|
360
|
+
*
|
|
361
|
+
* A `Sink` only receives data while `handle.stderr` is being consumed. If
|
|
362
|
+
* it is never consumed, the sink receives nothing and a child process that
|
|
363
|
+
* writes more than the pipe buffer can block before it exits.
|
|
350
364
|
*/
|
|
351
365
|
readonly stream?: CommandOutput | undefined
|
|
352
366
|
}
|
|
@@ -382,6 +396,18 @@ export type AdditionalFdConfig =
|
|
|
382
396
|
/**
|
|
383
397
|
* For output file descriptors, an optional sink which receives data from
|
|
384
398
|
* the file descriptor.
|
|
399
|
+
*
|
|
400
|
+
* **Details**
|
|
401
|
+
*
|
|
402
|
+
* The data is transduced through the sink as `handle.getOutputFd(fd)` is
|
|
403
|
+
* consumed, and that stream emits the results produced by the sink
|
|
404
|
+
* instead of the raw output.
|
|
405
|
+
*
|
|
406
|
+
* **Gotchas**
|
|
407
|
+
*
|
|
408
|
+
* The sink only receives data while `handle.getOutputFd(fd)` is being
|
|
409
|
+
* consumed. If it is never consumed, the sink receives nothing and a child
|
|
410
|
+
* process that writes more than the pipe buffer can block before it exits.
|
|
385
411
|
*/
|
|
386
412
|
readonly sink?: Sink.Sink<Uint8Array, Uint8Array, never, PlatformError.PlatformError> | undefined
|
|
387
413
|
}
|
|
@@ -230,11 +230,13 @@ export const makeHandle = (params: Omit<ChildProcessHandle, typeof HandleTypeId>
|
|
|
230
230
|
* @since 4.0.0
|
|
231
231
|
*/
|
|
232
232
|
export const make = (spawn: ChildProcessSpawner["Service"]["spawn"]): ChildProcessSpawner["Service"] => {
|
|
233
|
+
// The helpers own the handle, so they drain any output they do not return
|
|
234
|
+
// to keep a full pipe from blocking the child.
|
|
233
235
|
const streamString: ChildProcessSpawner["Service"]["streamLines"] = (command, options) =>
|
|
234
236
|
spawn(command).pipe(
|
|
235
237
|
Effect.map((handle) =>
|
|
236
238
|
Stream.decodeText(
|
|
237
|
-
options?.includeStderr === true ? handle.all : handle.stdout
|
|
239
|
+
options?.includeStderr === true ? handle.all : Stream.drainFork(handle.stdout, handle.stderr)
|
|
238
240
|
)
|
|
239
241
|
),
|
|
240
242
|
Stream.unwrap
|
|
@@ -244,7 +246,14 @@ export const make = (spawn: ChildProcessSpawner["Service"]["spawn"]): ChildProce
|
|
|
244
246
|
|
|
245
247
|
return ChildProcessSpawner.of({
|
|
246
248
|
spawn,
|
|
247
|
-
|
|
249
|
+
// Return once the process exits, even if descendants keep the pipes open.
|
|
250
|
+
exitCode: (command) =>
|
|
251
|
+
Effect.scoped(
|
|
252
|
+
Effect.flatMap(
|
|
253
|
+
spawn(command),
|
|
254
|
+
(handle) => Effect.raceFirst(handle.exitCode, Effect.andThen(Stream.runDrain(handle.all), Effect.never))
|
|
255
|
+
)
|
|
256
|
+
),
|
|
248
257
|
streamString,
|
|
249
258
|
streamLines,
|
|
250
259
|
lines: (command, options) => Stream.runCollect(streamLines(command, options)),
|
|
@@ -269,6 +278,12 @@ export class ChildProcessSpawner extends Context.Service<ChildProcessSpawner, {
|
|
|
269
278
|
|
|
270
279
|
/**
|
|
271
280
|
* Run a command and return its exit code.
|
|
281
|
+
*
|
|
282
|
+
* **Details**
|
|
283
|
+
*
|
|
284
|
+
* Piped `stdout` and `stderr` are read and discarded until the process
|
|
285
|
+
* exits. A read failure before then, such as from an output `Sink`, fails
|
|
286
|
+
* the effect.
|
|
272
287
|
*/
|
|
273
288
|
exitCode(
|
|
274
289
|
command: Command
|
|
@@ -277,6 +292,12 @@ export class ChildProcessSpawner extends Context.Service<ChildProcessSpawner, {
|
|
|
277
292
|
/**
|
|
278
293
|
* Stream the output of a command as strings. Optionally include stderr output
|
|
279
294
|
* interleaved with stdout.
|
|
295
|
+
*
|
|
296
|
+
* **Details**
|
|
297
|
+
*
|
|
298
|
+
* Without `includeStderr`, piped `stderr` is read and discarded until
|
|
299
|
+
* `stdout` ends. A read failure before then, such as from an output `Sink`,
|
|
300
|
+
* fails the result.
|
|
280
301
|
*/
|
|
281
302
|
streamString(command: Command, options?: {
|
|
282
303
|
readonly includeStderr?: boolean | undefined
|
|
@@ -285,6 +306,12 @@ export class ChildProcessSpawner extends Context.Service<ChildProcessSpawner, {
|
|
|
285
306
|
/**
|
|
286
307
|
* Stream the output of a command as lines. Optionally include stderr output
|
|
287
308
|
* interleaved with stdout.
|
|
309
|
+
*
|
|
310
|
+
* **Details**
|
|
311
|
+
*
|
|
312
|
+
* Without `includeStderr`, piped `stderr` is read and discarded until
|
|
313
|
+
* `stdout` ends. A read failure before then, such as from an output `Sink`,
|
|
314
|
+
* fails the result.
|
|
288
315
|
*/
|
|
289
316
|
streamLines(command: Command, options?: {
|
|
290
317
|
readonly includeStderr?: boolean | undefined
|
|
@@ -292,6 +319,12 @@ export class ChildProcessSpawner extends Context.Service<ChildProcessSpawner, {
|
|
|
292
319
|
|
|
293
320
|
/**
|
|
294
321
|
* Run a command and return the lines of its output as an array of strings.
|
|
322
|
+
*
|
|
323
|
+
* **Details**
|
|
324
|
+
*
|
|
325
|
+
* Without `includeStderr`, piped `stderr` is read and discarded until
|
|
326
|
+
* `stdout` ends. A read failure before then, such as from an output `Sink`,
|
|
327
|
+
* fails the result.
|
|
295
328
|
*/
|
|
296
329
|
lines(command: Command, options?: {
|
|
297
330
|
readonly includeStderr?: boolean | undefined
|
|
@@ -299,6 +332,12 @@ export class ChildProcessSpawner extends Context.Service<ChildProcessSpawner, {
|
|
|
299
332
|
|
|
300
333
|
/**
|
|
301
334
|
* Run a command and return its output as a string.
|
|
335
|
+
*
|
|
336
|
+
* **Details**
|
|
337
|
+
*
|
|
338
|
+
* Without `includeStderr`, piped `stderr` is read and discarded until
|
|
339
|
+
* `stdout` ends. A read failure before then, such as from an output `Sink`,
|
|
340
|
+
* fails the result.
|
|
302
341
|
*/
|
|
303
342
|
string(command: Command, options?: {
|
|
304
343
|
readonly includeStderr?: boolean | undefined
|
|
@@ -309,7 +309,7 @@ export const isFailure = <A, E>(result: AsyncResult<A, E>): result is Failure<A,
|
|
|
309
309
|
* @category guards
|
|
310
310
|
* @since 4.0.0
|
|
311
311
|
*/
|
|
312
|
-
export const isInterrupted = <A, E>(result: AsyncResult<A, E>):
|
|
312
|
+
export const isInterrupted = <A, E>(result: AsyncResult<A, E>): boolean =>
|
|
313
313
|
result._tag === "Failure" && Cause.hasInterruptsOnly(result.cause)
|
|
314
314
|
|
|
315
315
|
/**
|
package/src/rpc/RpcClient.ts
CHANGED
|
@@ -689,9 +689,9 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
|
|
|
689
689
|
readonly schemas: RpcSchemas
|
|
690
690
|
}
|
|
691
691
|
const entries = new Map<RequestId, ClientEntry>()
|
|
692
|
-
//
|
|
693
|
-
// it shuts down are not handed to a transport that is being torn down.
|
|
694
|
-
|
|
692
|
+
// Completed before the protocol stops running this client, so requests made
|
|
693
|
+
// while it shuts down are not handed to a transport that is being torn down.
|
|
694
|
+
const closing = Deferred.makeUnsafe<void>()
|
|
695
695
|
|
|
696
696
|
const interruptRequest = (requestId: RequestId): Effect.Effect<void, RpcClientError> => {
|
|
697
697
|
if (!entries.has(requestId)) return Effect.void
|
|
@@ -723,7 +723,7 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
|
|
|
723
723
|
Effect.flatMap((payload) => {
|
|
724
724
|
// Checked after encoding, which can suspend while the client
|
|
725
725
|
// starts shutting down.
|
|
726
|
-
if (
|
|
726
|
+
if (Deferred.isDoneUnsafe(closing)) {
|
|
727
727
|
entries.delete(message.id)
|
|
728
728
|
return Effect.interrupt
|
|
729
729
|
}
|
|
@@ -775,7 +775,14 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
|
|
|
775
775
|
).pipe(
|
|
776
776
|
Effect.onError((cause) =>
|
|
777
777
|
write({ _tag: "Exit", clientId: 0, requestId, exit: Exit.failCause(cause) }).pipe(
|
|
778
|
-
Effect.andThen(
|
|
778
|
+
Effect.andThen(
|
|
779
|
+
Cause.hasInterrupts(cause) ? Effect.void : Effect.raceFirst(
|
|
780
|
+
Effect.ignore(interruptRequest(requestId)),
|
|
781
|
+
// Best-effort once the client closes: a disconnected transport
|
|
782
|
+
// can wait for a reconnect that never comes.
|
|
783
|
+
Deferred.await(closing)
|
|
784
|
+
)
|
|
785
|
+
)
|
|
779
786
|
)
|
|
780
787
|
),
|
|
781
788
|
// a decode failure only ends its own request; interruption still propagates
|
|
@@ -821,11 +828,7 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
|
|
|
821
828
|
Effect.forkScoped
|
|
822
829
|
)
|
|
823
830
|
// Finalizers run in reverse order, so this runs before `run` is interrupted.
|
|
824
|
-
yield* Effect.addFinalizer(() =>
|
|
825
|
-
Effect.sync(() => {
|
|
826
|
-
isClosing = true
|
|
827
|
-
})
|
|
828
|
-
)
|
|
831
|
+
yield* Effect.addFinalizer(() => Deferred.succeed(closing, void 0))
|
|
829
832
|
|
|
830
833
|
return client
|
|
831
834
|
})
|
|
@@ -230,18 +230,25 @@ export const ndjson: RpcSerialization["Service"] = makeNdjson()
|
|
|
230
230
|
* Creates a JSON-RPC 2.0 serialization for RPC protocol messages without
|
|
231
231
|
* additional message framing.
|
|
232
232
|
*
|
|
233
|
+
* **Details**
|
|
234
|
+
*
|
|
235
|
+
* Set `controlMessages` to `false` for plain JSON-RPC peers, so
|
|
236
|
+
* `@effect/rpc/*` methods are not decoded as RPC control messages.
|
|
237
|
+
*
|
|
233
238
|
* @stability unstable
|
|
234
239
|
* @category serialization
|
|
235
240
|
* @since 4.0.0
|
|
236
241
|
*/
|
|
237
242
|
export const jsonRpc = (options?: {
|
|
238
243
|
readonly contentType?: string | undefined
|
|
244
|
+
readonly controlMessages?: boolean | undefined
|
|
239
245
|
}): RpcSerialization["Service"] =>
|
|
240
246
|
RpcSerialization.of({
|
|
241
247
|
contentType: options?.contentType ?? "application/json",
|
|
242
248
|
includesFraming: false,
|
|
243
249
|
codecFor: codecForJson,
|
|
244
250
|
makeUnsafe: () => {
|
|
251
|
+
const controlMessages = options?.controlMessages ?? true
|
|
245
252
|
const batches = new Map<string | number, {
|
|
246
253
|
readonly size: number
|
|
247
254
|
readonly responses: Map<string | number, RpcMessage.FromServerEncoded>
|
|
@@ -251,7 +258,7 @@ export const jsonRpc = (options?: {
|
|
|
251
258
|
const decoded: unknown = JSON.parse(
|
|
252
259
|
typeof bytes === "string" ? bytes : decodeText(bytes)
|
|
253
260
|
)
|
|
254
|
-
return decodeJsonRpcRaw(decoded, batches)
|
|
261
|
+
return decodeJsonRpcRaw(decoded, batches, controlMessages)
|
|
255
262
|
},
|
|
256
263
|
encode: (response) => {
|
|
257
264
|
const encoded = encodeJsonRpcResponse(response as any, batches)
|
|
@@ -265,6 +272,11 @@ export const jsonRpc = (options?: {
|
|
|
265
272
|
* Creates a newline-delimited JSON-RPC 2.0 serialization for RPC protocol
|
|
266
273
|
* messages.
|
|
267
274
|
*
|
|
275
|
+
* **Details**
|
|
276
|
+
*
|
|
277
|
+
* Set `controlMessages` to `false` for plain JSON-RPC peers, so
|
|
278
|
+
* `@effect/rpc/*` methods are not decoded as RPC control messages.
|
|
279
|
+
*
|
|
268
280
|
* @stability unstable
|
|
269
281
|
* @category serialization
|
|
270
282
|
* @since 4.0.0
|
|
@@ -272,6 +284,7 @@ export const jsonRpc = (options?: {
|
|
|
272
284
|
export const ndJsonRpc = (options?: {
|
|
273
285
|
readonly contentType?: string | undefined
|
|
274
286
|
readonly maxBufferSize?: number | "unbounded" | undefined
|
|
287
|
+
readonly controlMessages?: boolean | undefined
|
|
275
288
|
}): RpcSerialization["Service"] =>
|
|
276
289
|
RpcSerialization.of({
|
|
277
290
|
contentType: options?.contentType ?? "application/json-rpc",
|
|
@@ -279,6 +292,7 @@ export const ndJsonRpc = (options?: {
|
|
|
279
292
|
codecFor: codecForJson,
|
|
280
293
|
makeUnsafe: () => {
|
|
281
294
|
const parser = makeNdjson({ maxBufferSize: options?.maxBufferSize }).makeUnsafe()
|
|
295
|
+
const controlMessages = options?.controlMessages ?? true
|
|
282
296
|
const batches = new Map<string, {
|
|
283
297
|
readonly size: number
|
|
284
298
|
readonly responses: Map<string, RpcMessage.FromServerEncoded>
|
|
@@ -289,7 +303,7 @@ export const ndJsonRpc = (options?: {
|
|
|
289
303
|
if (frames.length === 0) return []
|
|
290
304
|
const messages: Array<RpcMessage.FromClientEncoded | RpcMessage.FromServerEncoded> = []
|
|
291
305
|
for (let i = 0; i < frames.length; i++) {
|
|
292
|
-
messages.push(...decodeJsonRpcRaw(frames[i], batches))
|
|
306
|
+
messages.push(...decodeJsonRpcRaw(frames[i], batches, controlMessages))
|
|
293
307
|
}
|
|
294
308
|
return messages
|
|
295
309
|
},
|
|
@@ -306,7 +320,8 @@ function decodeJsonRpcRaw(
|
|
|
306
320
|
batches: Map<string | number, {
|
|
307
321
|
readonly size: number
|
|
308
322
|
readonly responses: Map<string | number, RpcMessage.FromServerEncoded>
|
|
309
|
-
}
|
|
323
|
+
}>,
|
|
324
|
+
controlMessages: boolean
|
|
310
325
|
) {
|
|
311
326
|
if (Array.isArray(decoded)) {
|
|
312
327
|
const batch = {
|
|
@@ -317,7 +332,7 @@ function decodeJsonRpcRaw(
|
|
|
317
332
|
for (let i = 0; i < decoded.length; i++) {
|
|
318
333
|
const item = decoded[i]
|
|
319
334
|
if (!Predicate.isObject(item)) continue
|
|
320
|
-
const message = decodeJsonRpcMessage(item as unknown as JsonRpcMessage)
|
|
335
|
+
const message = decodeJsonRpcMessage(item as unknown as JsonRpcMessage, controlMessages)
|
|
321
336
|
messages.push(message)
|
|
322
337
|
if (message._tag === "Request" && !message.isNotification) {
|
|
323
338
|
batch.size++
|
|
@@ -326,14 +341,20 @@ function decodeJsonRpcRaw(
|
|
|
326
341
|
}
|
|
327
342
|
return messages
|
|
328
343
|
}
|
|
329
|
-
return Predicate.isObject(decoded)
|
|
344
|
+
return Predicate.isObject(decoded)
|
|
345
|
+
? [decodeJsonRpcMessage(decoded as unknown as JsonRpcMessage, controlMessages)]
|
|
346
|
+
: []
|
|
330
347
|
}
|
|
331
348
|
|
|
332
|
-
function decodeJsonRpcMessage(
|
|
349
|
+
function decodeJsonRpcMessage(
|
|
350
|
+
decoded: JsonRpcMessage,
|
|
351
|
+
controlMessages: boolean
|
|
352
|
+
): RpcMessage.FromClientEncoded | RpcMessage.FromServerEncoded {
|
|
333
353
|
if (Object.hasOwn(decoded, "method")) {
|
|
334
354
|
const request = decoded as JsonRpcRequest
|
|
335
355
|
if (
|
|
336
|
-
Predicate.isNullish(request.id) && Predicate.isString(request.method) &&
|
|
356
|
+
controlMessages && Predicate.isNullish(request.id) && Predicate.isString(request.method) &&
|
|
357
|
+
request.method.startsWith("@effect/rpc/")
|
|
337
358
|
) {
|
|
338
359
|
const tag = request.method.slice("@effect/rpc/".length) as
|
|
339
360
|
| RpcMessage.FromServerEncoded["_tag"]
|
|
@@ -403,13 +424,13 @@ function encodeJsonRpcRaw(
|
|
|
403
424
|
readonly responses: Map<string | number, RpcMessage.FromServerEncoded>
|
|
404
425
|
}>
|
|
405
426
|
) {
|
|
406
|
-
if (
|
|
427
|
+
if (response._tag !== "Exit") {
|
|
407
428
|
return encodeJsonRpcMessage(response)
|
|
408
429
|
}
|
|
409
430
|
const batch = batches.get(response.requestId)
|
|
410
431
|
if (batch) {
|
|
411
432
|
batches.delete(response.requestId)
|
|
412
|
-
batch.responses.set(response.requestId, response
|
|
433
|
+
batch.responses.set(response.requestId, response)
|
|
413
434
|
if (batch.size === batch.responses.size) {
|
|
414
435
|
return Array.from(batch.responses.values(), encodeJsonRpcMessage)
|
|
415
436
|
}
|
|
@@ -644,6 +665,7 @@ export const layerNdjsonWith = (options?: StreamOptions): Layer.Layer<RpcSeriali
|
|
|
644
665
|
*/
|
|
645
666
|
export const layerJsonRpc = (options?: {
|
|
646
667
|
readonly contentType?: string | undefined
|
|
668
|
+
readonly controlMessages?: boolean | undefined
|
|
647
669
|
}): Layer.Layer<RpcSerialization> => Layer.succeed(RpcSerialization)(jsonRpc(options))
|
|
648
670
|
|
|
649
671
|
/**
|
|
@@ -657,6 +679,7 @@ export const layerJsonRpc = (options?: {
|
|
|
657
679
|
export const layerNdJsonRpc = (options?: {
|
|
658
680
|
readonly contentType?: string | undefined
|
|
659
681
|
readonly maxBufferSize?: number | "unbounded" | undefined
|
|
682
|
+
readonly controlMessages?: boolean | undefined
|
|
660
683
|
}): Layer.Layer<RpcSerialization> => Layer.succeed(RpcSerialization)(ndJsonRpc(options))
|
|
661
684
|
|
|
662
685
|
/**
|
package/src/rpc/RpcServer.ts
CHANGED
|
@@ -278,7 +278,7 @@ export const makeNoSerialization: <Rpcs extends Rpc.Any>(
|
|
|
278
278
|
headers: request.headers,
|
|
279
279
|
payload: request.payload
|
|
280
280
|
}
|
|
281
|
-
const result = entry
|
|
281
|
+
const result = runHandler(entry, request.payload, metadata)
|
|
282
282
|
|
|
283
283
|
// if the handler requested forking, then we skip the concurrency control
|
|
284
284
|
const isWrapper = Rpc.isWrapper(result)
|
|
@@ -574,6 +574,21 @@ const handlerContext = (
|
|
|
574
574
|
return merged
|
|
575
575
|
}
|
|
576
576
|
|
|
577
|
+
// a synchronous throw is handled like a returned `Effect.die`, so it goes
|
|
578
|
+
// through the request exit handling. Stream handlers may also return an
|
|
579
|
+
// Effect, so a single `Effect.die` covers both kinds of rpc.
|
|
580
|
+
const runHandler = (
|
|
581
|
+
entry: Rpc.Handler<string>,
|
|
582
|
+
payload: unknown,
|
|
583
|
+
metadata: Parameters<Rpc.Handler<string>["handler"]>[1]
|
|
584
|
+
) => {
|
|
585
|
+
try {
|
|
586
|
+
return entry.handler(payload, metadata)
|
|
587
|
+
} catch (defect) {
|
|
588
|
+
return Effect.die(defect)
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
577
592
|
const applyMiddleware = <A, E, R>(
|
|
578
593
|
context: Context.Context<never>,
|
|
579
594
|
handler: Effect.Effect<A, E, R>,
|
package/src/rpc/RpcTest.ts
CHANGED
|
@@ -29,6 +29,7 @@ export const makeClient: <Rpcs extends Rpc.Any, const Flatten extends boolean =
|
|
|
29
29
|
group: RpcGroup.RpcGroup<Rpcs>,
|
|
30
30
|
options?: {
|
|
31
31
|
readonly flatten?: Flatten | undefined
|
|
32
|
+
readonly disableFatalDefects?: boolean | undefined
|
|
32
33
|
}
|
|
33
34
|
) => Effect.Effect<
|
|
34
35
|
Flatten extends true ? RpcClient.RpcClient.Flat<Rpcs> : RpcClient.RpcClient<Rpcs>,
|
|
@@ -38,11 +39,13 @@ export const makeClient: <Rpcs extends Rpc.Any, const Flatten extends boolean =
|
|
|
38
39
|
group: RpcGroup.RpcGroup<Rpcs>,
|
|
39
40
|
options?: {
|
|
40
41
|
readonly flatten?: Flatten | undefined
|
|
42
|
+
readonly disableFatalDefects?: boolean | undefined
|
|
41
43
|
}
|
|
42
44
|
) {
|
|
43
45
|
// oxlint-disable-next-line prefer-const
|
|
44
46
|
let client!: Effect.Success<ReturnType<typeof RpcClient.makeNoSerialization<Rpcs, never, Flatten>>>
|
|
45
47
|
const server = yield* RpcServer.makeNoSerialization(group, {
|
|
48
|
+
disableFatalDefects: options?.disableFatalDefects,
|
|
46
49
|
onFromServer(response) {
|
|
47
50
|
return client.write(response)
|
|
48
51
|
}
|