effect 4.1.0 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/THIRD_PARTY_NOTICES.md +62 -0
- package/ai-docs/package.json +2 -2
- package/dist/BigDecimal.d.ts +139 -7
- package/dist/BigDecimal.d.ts.map +1 -1
- package/dist/BigDecimal.js +83 -14
- package/dist/BigDecimal.js.map +1 -1
- package/dist/ByteSize.d.ts.map +1 -1
- package/dist/ByteSize.js +27 -14
- package/dist/ByteSize.js.map +1 -1
- package/dist/Equal.d.ts +2 -2
- package/dist/Equal.d.ts.map +1 -1
- package/dist/Equal.js +3 -3
- package/dist/Equal.js.map +1 -1
- package/dist/Hash.d.ts +3 -2
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +5 -4
- package/dist/Hash.js.map +1 -1
- package/dist/Iterable.d.ts.map +1 -1
- package/dist/Iterable.js +38 -32
- package/dist/Iterable.js.map +1 -1
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +27 -6
- package/dist/JsonSchema.js.map +1 -1
- package/dist/MutableRef.d.ts.map +1 -1
- package/dist/MutableRef.js +0 -7
- package/dist/MutableRef.js.map +1 -1
- package/dist/Path.d.ts.map +1 -1
- package/dist/Path.js +5 -1
- package/dist/Path.js.map +1 -1
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +2 -1
- package/dist/Pool.js.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +0 -8
- package/dist/Ref.js.map +1 -1
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +8 -3
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +2 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +2 -1
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +4 -2
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +4 -2
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +2 -2
- package/dist/SchemaTransformation.js +2 -2
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +6 -5
- package/dist/Stream.js.map +1 -1
- package/dist/ai/McpClient.d.ts +171 -19
- package/dist/ai/McpClient.d.ts.map +1 -1
- package/dist/ai/McpClient.js +277 -66
- package/dist/ai/McpClient.js.map +1 -1
- package/dist/ai/McpSchema.d.ts +108 -0
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpSchema.js +99 -0
- package/dist/ai/McpSchema.js.map +1 -1
- package/dist/ai/McpServer.d.ts +120 -6
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +258 -49
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +20 -11
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js +5 -7
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/internal/mcpCore.js +72 -3
- package/dist/ai/internal/mcpCore.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +3 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +3 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +3 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +3 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +44 -8
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js +12 -0
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +3 -3
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/ai/internal/mcpSkills.d.ts +2 -0
- package/dist/ai/internal/mcpSkills.d.ts.map +1 -0
- package/dist/ai/internal/mcpSkills.js +428 -0
- package/dist/ai/internal/mcpSkills.js.map +1 -0
- package/dist/ai/internal/structured-output.js +11 -2
- package/dist/ai/internal/structured-output.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +30 -11
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/Entity.d.ts +26 -0
- package/dist/cluster/Entity.d.ts.map +1 -1
- package/dist/cluster/Entity.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +6 -6
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +1 -3
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Reply.d.ts +1 -1
- package/dist/cluster/Reply.d.ts.map +1 -1
- package/dist/cluster/Reply.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +13 -2
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts +13 -0
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +4 -1
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/internal/clusterAbandon.d.ts.map +1 -1
- package/dist/cluster/internal/clusterAbandon.js +6 -4
- package/dist/cluster/internal/clusterAbandon.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +63 -11
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/cluster/internal/transactionNotifications.d.ts +5 -0
- package/dist/cluster/internal/transactionNotifications.d.ts.map +1 -0
- package/dist/cluster/internal/transactionNotifications.js +5 -0
- package/dist/cluster/internal/transactionNotifications.js.map +1 -0
- package/dist/crypto/Aead.d.ts +2 -1
- package/dist/crypto/Aead.d.ts.map +1 -1
- package/dist/crypto/Aead.js +2 -2
- package/dist/crypto/Aead.js.map +1 -1
- package/dist/crypto/Cipher.d.ts +2 -1
- package/dist/crypto/Cipher.d.ts.map +1 -1
- package/dist/crypto/Cipher.js +2 -2
- package/dist/crypto/Cipher.js.map +1 -1
- package/dist/crypto/KeyAgreement.d.ts +3 -2
- package/dist/crypto/KeyAgreement.d.ts.map +1 -1
- package/dist/crypto/KeyAgreement.js +2 -2
- package/dist/crypto/KeyAgreement.js.map +1 -1
- package/dist/crypto/KeyFormat.d.ts +33 -1
- package/dist/crypto/KeyFormat.d.ts.map +1 -1
- package/dist/crypto/KeyFormat.js.map +1 -1
- package/dist/crypto/KeyWrap.d.ts +4 -3
- package/dist/crypto/KeyWrap.d.ts.map +1 -1
- package/dist/crypto/KeyWrap.js +2 -2
- package/dist/crypto/KeyWrap.js.map +1 -1
- package/dist/crypto/Mac.d.ts +2 -1
- package/dist/crypto/Mac.d.ts.map +1 -1
- package/dist/crypto/Mac.js +2 -2
- package/dist/crypto/Mac.js.map +1 -1
- package/dist/crypto/Signature.d.ts +3 -2
- package/dist/crypto/Signature.d.ts.map +1 -1
- package/dist/crypto/Signature.js +2 -2
- package/dist/crypto/Signature.js.map +1 -1
- package/dist/crypto/WebCrypto.d.ts +19 -0
- package/dist/crypto/WebCrypto.d.ts.map +1 -1
- package/dist/crypto/WebCrypto.js.map +1 -1
- package/dist/crypto/internal/asymmetric.js.map +1 -1
- package/dist/crypto/internal/key.js +3 -2
- package/dist/crypto/internal/key.js.map +1 -1
- package/dist/encoding/Base64Url.d.ts.map +1 -1
- package/dist/encoding/Base64Url.js +26 -3
- package/dist/encoding/Base64Url.js.map +1 -1
- package/dist/encoding/Json5.d.ts +44 -0
- package/dist/encoding/Json5.d.ts.map +1 -0
- package/dist/encoding/Json5.js +56 -0
- package/dist/encoding/Json5.js.map +1 -0
- package/dist/encoding/Jsonc.d.ts +47 -0
- package/dist/encoding/Jsonc.d.ts.map +1 -0
- package/dist/encoding/Jsonc.js +120 -0
- package/dist/encoding/Jsonc.js.map +1 -0
- package/dist/encoding/Ndjson.d.ts +5 -4
- package/dist/encoding/Ndjson.d.ts.map +1 -1
- package/dist/encoding/Ndjson.js +6 -5
- package/dist/encoding/Ndjson.js.map +1 -1
- package/dist/encoding/SchemaBinary.d.ts +94 -0
- package/dist/encoding/SchemaBinary.d.ts.map +1 -1
- package/dist/encoding/SchemaBinary.js +219 -6
- package/dist/encoding/SchemaBinary.js.map +1 -1
- package/dist/encoding/Sse.d.ts +3 -1
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +5 -3
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/encoding/index.d.ts +10 -0
- package/dist/encoding/index.d.ts.map +1 -1
- package/dist/encoding/index.js +10 -0
- package/dist/encoding/index.js.map +1 -1
- package/dist/eventlog/EventLog.d.ts +7 -0
- package/dist/eventlog/EventLog.d.ts.map +1 -1
- package/dist/eventlog/EventLog.js +7 -0
- package/dist/eventlog/EventLog.js.map +1 -1
- package/dist/eventlog/EventLogServer.d.ts +7 -1
- package/dist/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/eventlog/EventLogServer.js +55 -24
- package/dist/eventlog/EventLogServer.js.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.d.ts +10 -0
- package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/EventLogServerUnencrypted.d.ts +17 -0
- package/dist/eventlog/EventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerUnencrypted.js +14 -2
- package/dist/eventlog/EventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.d.ts +21 -0
- package/dist/eventlog/EventLogSessionAuth.d.ts.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.js +22 -0
- package/dist/eventlog/EventLogSessionAuth.js.map +1 -1
- package/dist/graphql/GraphQLClient.d.ts +3 -1
- package/dist/graphql/GraphQLClient.d.ts.map +1 -1
- package/dist/graphql/GraphQLClient.js.map +1 -1
- package/dist/graphql/GraphQLClientError.d.ts +14 -9
- package/dist/graphql/GraphQLClientError.d.ts.map +1 -1
- package/dist/graphql/GraphQLClientError.js +14 -21
- package/dist/graphql/GraphQLClientError.js.map +1 -1
- package/dist/graphql/GraphQLProtocol.d.ts +12 -3
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
- package/dist/graphql/GraphQLProtocol.js +4 -1
- package/dist/graphql/GraphQLProtocol.js.map +1 -1
- package/dist/http/HttpClient.d.ts +204 -16
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +93 -13
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +38 -22
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/internal/mimeTypes.d.ts +4 -1
- package/dist/http/internal/mimeTypes.d.ts.map +1 -1
- package/dist/http/internal/mimeTypes.js +4 -1
- package/dist/http/internal/mimeTypes.js.map +1 -1
- package/dist/http-api/HttpApiSchema.js +1 -1
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/internal/dateTime.js +66 -27
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +10 -0
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/glob.js +234 -56
- package/dist/internal/glob.js.map +1 -1
- package/dist/internal/graphql.js +21 -7
- package/dist/internal/graphql.js.map +1 -1
- package/dist/internal/graphqlHeaders.d.ts +7 -0
- package/dist/internal/graphqlHeaders.d.ts.map +1 -1
- package/dist/internal/graphqlHeaders.js +11 -0
- package/dist/internal/graphqlHeaders.js.map +1 -1
- package/dist/internal/jsonParser.d.ts +5 -0
- package/dist/internal/jsonParser.d.ts.map +1 -0
- package/dist/internal/jsonParser.js +280 -0
- package/dist/internal/jsonParser.js.map +1 -0
- package/dist/internal/persistence.js +8 -1
- package/dist/internal/persistence.js.map +1 -1
- package/dist/internal/request.js +29 -42
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/schema/fromJsonSchemaDocument.js +7 -8
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/sql.js +16 -0
- package/dist/internal/sql.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/jose/JoseError.d.ts +285 -0
- package/dist/jose/JoseError.d.ts.map +1 -0
- package/dist/jose/JoseError.js +269 -0
- package/dist/jose/JoseError.js.map +1 -0
- package/dist/jose/Jwe.d.ts +128 -0
- package/dist/jose/Jwe.d.ts.map +1 -0
- package/dist/jose/Jwe.js +134 -0
- package/dist/jose/Jwe.js.map +1 -0
- package/dist/jose/Jwk.d.ts +597 -0
- package/dist/jose/Jwk.d.ts.map +1 -0
- package/dist/jose/Jwk.js +503 -0
- package/dist/jose/Jwk.js.map +1 -0
- package/dist/jose/Jwks.d.ts +236 -0
- package/dist/jose/Jwks.d.ts.map +1 -0
- package/dist/jose/Jwks.js +306 -0
- package/dist/jose/Jwks.js.map +1 -0
- package/dist/jose/Jws.d.ts +177 -0
- package/dist/jose/Jws.d.ts.map +1 -0
- package/dist/jose/Jws.js +183 -0
- package/dist/jose/Jws.js.map +1 -0
- package/dist/jose/Jwt.d.ts +270 -0
- package/dist/jose/Jwt.d.ts.map +1 -0
- package/dist/jose/Jwt.js +293 -0
- package/dist/jose/Jwt.js.map +1 -0
- package/dist/jose/index.d.ts +51 -0
- package/dist/jose/index.d.ts.map +1 -0
- package/dist/jose/index.js +52 -0
- package/dist/jose/index.js.map +1 -0
- package/dist/jose/internal/compact.d.ts +2 -0
- package/dist/jose/internal/compact.d.ts.map +1 -0
- package/dist/jose/internal/compact.js +179 -0
- package/dist/jose/internal/compact.js.map +1 -0
- package/dist/net/Host.d.ts.map +1 -1
- package/dist/net/Host.js +5 -10
- package/dist/net/Host.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts +4 -0
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +40 -12
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpSerialization.d.ts +1 -1
- package/dist/observability/OtlpSerialization.d.ts.map +1 -1
- package/dist/observability/OtlpSerialization.js +10 -4
- package/dist/observability/OtlpSerialization.js.map +1 -1
- package/dist/observability/internal/otlpProtobuf.js +3 -3
- package/dist/observability/internal/otlpProtobuf.js.map +1 -1
- package/dist/observability/internal/protobuf.js +6 -0
- package/dist/observability/internal/protobuf.js.map +1 -1
- package/dist/persistence/CircuitBreaker.d.ts +98 -38
- package/dist/persistence/CircuitBreaker.d.ts.map +1 -1
- package/dist/persistence/CircuitBreaker.js +67 -29
- package/dist/persistence/CircuitBreaker.js.map +1 -1
- package/dist/persistence/RateLimiter.d.ts +15 -0
- package/dist/persistence/RateLimiter.d.ts.map +1 -1
- package/dist/persistence/RateLimiter.js +76 -16
- package/dist/persistence/RateLimiter.js.map +1 -1
- package/dist/persistence/index.d.ts +1 -1
- package/dist/persistence/index.js +1 -1
- package/dist/reactivity/AtomRegistry.js +17 -7
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/Rpc.d.ts +1 -1
- package/dist/rpc/Rpc.d.ts.map +1 -1
- package/dist/rpc/Rpc.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +14 -2
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +38 -21
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcMessage.d.ts +3 -2
- package/dist/rpc/RpcMessage.d.ts.map +1 -1
- package/dist/rpc/RpcMessage.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +10 -1
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/sql/Migrator.d.ts +9 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +18 -6
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +46 -3
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +40 -15
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/Statement.d.ts +46 -3
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +32 -26
- package/dist/sql/Statement.js.map +1 -1
- package/dist/workflow/Workflow.d.ts +4 -0
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +5 -0
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +7 -3
- package/src/BigDecimal.ts +170 -16
- package/src/ByteSize.ts +29 -14
- package/src/Equal.ts +3 -3
- package/src/Hash.ts +5 -4
- package/src/Iterable.ts +28 -19
- package/src/JsonSchema.ts +45 -7
- package/src/MutableRef.ts +1 -8
- package/src/Path.ts +6 -1
- package/src/Pool.ts +2 -1
- package/src/Ref.ts +0 -8
- package/src/Schedule.ts +8 -6
- package/src/Schema.ts +3 -2
- package/src/SchemaRepresentation.ts +4 -2
- package/src/SchemaTransformation.ts +2 -2
- package/src/Stream.ts +6 -5
- package/src/ai/McpClient.ts +488 -91
- package/src/ai/McpSchema.ts +119 -0
- package/src/ai/McpServer.ts +302 -56
- package/src/ai/Prompt.ts +16 -11
- package/src/ai/Tool.ts +5 -10
- package/src/ai/internal/mcpCore.ts +165 -12
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +3 -1
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +3 -1
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +3 -1
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +3 -1
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +42 -9
- package/src/ai/internal/mcpProtocol.ts +15 -0
- package/src/ai/internal/mcpRuntime.ts +6 -3
- package/src/ai/internal/mcpSkills.ts +480 -0
- package/src/ai/internal/structured-output.ts +10 -4
- package/src/cluster/ClusterWorkflowEngine.ts +48 -33
- package/src/cluster/Entity.ts +52 -0
- package/src/cluster/MessageStorage.ts +3 -6
- package/src/cluster/Reply.ts +1 -1
- package/src/cluster/Runners.ts +16 -2
- package/src/cluster/Sharding.ts +17 -1
- package/src/cluster/internal/clusterAbandon.ts +7 -7
- package/src/cluster/internal/entityManager.ts +89 -15
- package/src/cluster/internal/transactionNotifications.ts +7 -0
- package/src/crypto/Aead.ts +3 -3
- package/src/crypto/Cipher.ts +3 -3
- package/src/crypto/KeyAgreement.ts +4 -4
- package/src/crypto/KeyFormat.ts +30 -1
- package/src/crypto/KeyWrap.ts +6 -6
- package/src/crypto/Mac.ts +3 -3
- package/src/crypto/Signature.ts +4 -4
- package/src/crypto/WebCrypto.ts +20 -0
- package/src/crypto/internal/asymmetric.ts +2 -1
- package/src/crypto/internal/key.ts +12 -5
- package/src/encoding/Base64Url.ts +27 -3
- package/src/encoding/Json5.ts +59 -0
- package/src/encoding/Jsonc.ts +126 -0
- package/src/encoding/Ndjson.ts +6 -5
- package/src/encoding/SchemaBinary.ts +228 -7
- package/src/encoding/Sse.ts +5 -3
- package/src/encoding/index.ts +12 -0
- package/src/eventlog/EventLog.ts +7 -0
- package/src/eventlog/EventLogServer.ts +67 -24
- package/src/eventlog/EventLogServerEncrypted.ts +5 -0
- package/src/eventlog/EventLogServerUnencrypted.ts +19 -2
- package/src/eventlog/EventLogSessionAuth.ts +26 -0
- package/src/graphql/GraphQLClient.ts +3 -1
- package/src/graphql/GraphQLClientError.ts +15 -22
- package/src/graphql/GraphQLProtocol.ts +12 -3
- package/src/http/HttpClient.ts +244 -33
- package/src/http/HttpServerRequest.ts +61 -23
- package/src/http/internal/mimeTypes.ts +4 -1
- package/src/http-api/HttpApiSchema.ts +1 -1
- package/src/internal/dateTime.ts +80 -27
- package/src/internal/effect.ts +6 -0
- package/src/internal/glob.ts +279 -63
- package/src/internal/graphql.ts +27 -9
- package/src/internal/graphqlHeaders.ts +13 -0
- package/src/internal/jsonParser.ts +307 -0
- package/src/internal/persistence.ts +9 -1
- package/src/internal/request.ts +51 -58
- package/src/internal/schema/fromJsonSchemaDocument.ts +11 -10
- package/src/internal/sql.ts +25 -0
- package/src/internal/version.ts +1 -1
- package/src/jose/JoseError.ts +329 -0
- package/src/jose/Jwe.ts +196 -0
- package/src/jose/Jwk.ts +777 -0
- package/src/jose/Jwks.ts +418 -0
- package/src/jose/Jws.ts +312 -0
- package/src/jose/Jwt.ts +493 -0
- package/src/jose/index.ts +58 -0
- package/src/jose/internal/compact.ts +195 -0
- package/src/net/Host.ts +5 -10
- package/src/observability/OtlpExporter.ts +42 -18
- package/src/observability/OtlpSerialization.ts +13 -5
- package/src/observability/internal/otlpProtobuf.ts +6 -6
- package/src/observability/internal/protobuf.ts +10 -0
- package/src/persistence/CircuitBreaker.ts +113 -48
- package/src/persistence/RateLimiter.ts +97 -19
- package/src/persistence/index.ts +1 -1
- package/src/reactivity/AtomRegistry.ts +19 -8
- package/src/rpc/Rpc.ts +3 -1
- package/src/rpc/RpcClient.ts +44 -24
- package/src/rpc/RpcMessage.ts +3 -2
- package/src/rpc/RpcServer.ts +12 -1
- package/src/sql/Migrator.ts +35 -18
- package/src/sql/SqlClient.ts +91 -22
- package/src/sql/Statement.ts +60 -35
- package/src/workflow/Workflow.ts +4 -0
- package/src/workflow/WorkflowEngine.ts +5 -0
|
@@ -16,6 +16,8 @@ import { WebCrypto } from "../crypto/WebCrypto.ts"
|
|
|
16
16
|
import * as Data from "../Data.ts"
|
|
17
17
|
import * as Effect from "../Effect.ts"
|
|
18
18
|
import * as Layer from "../Layer.ts"
|
|
19
|
+
import type { Identity } from "./EventLog.ts"
|
|
20
|
+
import { makeGetIdentityRootSecretMaterial } from "./internal/identityRootSecretDerivation.ts"
|
|
19
21
|
|
|
20
22
|
const textEncoder = new TextEncoder()
|
|
21
23
|
const textDecoder = new TextDecoder("utf-8", { fatal: true })
|
|
@@ -524,3 +526,27 @@ export const verifySessionAuthenticateRequest = Effect.fnUntraced(function*(opti
|
|
|
524
526
|
signature: options.signature
|
|
525
527
|
})
|
|
526
528
|
})
|
|
529
|
+
|
|
530
|
+
const getIdentityRootSecretMaterial = makeGetIdentityRootSecretMaterial()
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Derives the Ed25519 signing public key an identity presents during session
|
|
534
|
+
* authentication.
|
|
535
|
+
*
|
|
536
|
+
* **When to use**
|
|
537
|
+
*
|
|
538
|
+
* Use when provisioning an identity to record its signing key, so that server
|
|
539
|
+
* authorization can reject any other key presented for the identity's
|
|
540
|
+
* `publicKey`.
|
|
541
|
+
*
|
|
542
|
+
* **Details**
|
|
543
|
+
*
|
|
544
|
+
* The key is derived from the identity's private key on the `WebCrypto`
|
|
545
|
+
* reference.
|
|
546
|
+
*
|
|
547
|
+
* @stability unstable
|
|
548
|
+
* @category signing
|
|
549
|
+
* @since 4.1.1
|
|
550
|
+
*/
|
|
551
|
+
export const deriveSigningPublicKey = (identity: Identity["Service"]): Effect.Effect<Uint8Array<ArrayBuffer>> =>
|
|
552
|
+
Effect.map(getIdentityRootSecretMaterial(identity), (material) => material.signingPublicKey)
|
|
@@ -70,7 +70,9 @@ type ArgsWithOptions<Variables, Options> = {} extends Variables ? [variables: Va
|
|
|
70
70
|
* `partial: false`, it returns the decoded result and fails with a
|
|
71
71
|
* `ResponseError` on any `errors`. With `partial: true` it returns
|
|
72
72
|
* `{ data, errors }`. `partial` must be a literal `true` or `false`, not
|
|
73
|
-
* an arbitrary `boolean`.
|
|
73
|
+
* an arbitrary `boolean`. A non-2xx HTTP response never succeeds, even with
|
|
74
|
+
* `partial: true`: it fails with a `ResponseError` when it has `errors`, and
|
|
75
|
+
* with a `TransportError` otherwise.
|
|
74
76
|
*
|
|
75
77
|
* An operation without variables is called as `client.Viewer()` or, with
|
|
76
78
|
* options, `client.Viewer(undefined, { headers })`.
|
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
* @since 4.0.0
|
|
7
7
|
*/
|
|
8
8
|
import type * as Duration from "../Duration.ts"
|
|
9
|
-
import * as Headers from "../http/Headers.ts"
|
|
9
|
+
import type * as Headers from "../http/Headers.ts"
|
|
10
10
|
import type * as HttpClientError from "../http/HttpClientError.ts"
|
|
11
|
-
import { HeadersSchema } from "../internal/graphqlHeaders.ts"
|
|
11
|
+
import { HeadersSchema, parseRetryAfter } from "../internal/graphqlHeaders.ts"
|
|
12
12
|
import { hasProperty } from "../Predicate.ts"
|
|
13
|
-
import * as Result from "../Result.ts"
|
|
14
13
|
import * as Schema from "../Schema.ts"
|
|
15
14
|
|
|
16
15
|
const TypeId = "~effect/graphql/GraphQLClientError"
|
|
@@ -74,8 +73,9 @@ export type GraphQLError = typeof GraphQLError.Type
|
|
|
74
73
|
* `{ partial: true }` to receive decoded `{ data, errors }` instead.
|
|
75
74
|
*
|
|
76
75
|
* On this error, `data` is raw. `GraphQLError.path[0]` identifies the response
|
|
77
|
-
* key (or alias). Non-2xx HTTP responses with a GraphQL body
|
|
78
|
-
* reason rather than `TransportError
|
|
76
|
+
* key (or alias). Non-2xx HTTP responses with a GraphQL body and `errors`
|
|
77
|
+
* also use this reason rather than `TransportError`, even when they carry
|
|
78
|
+
* `data` and the call used `{ partial: true }`.
|
|
79
79
|
*
|
|
80
80
|
* `status` and `headers` are the HTTP status and response headers, as the
|
|
81
81
|
* transport reported them and middleware left them. Headers use
|
|
@@ -220,27 +220,18 @@ export const isFatalCloseCode = (code: number): boolean =>
|
|
|
220
220
|
|
|
221
221
|
const isRetryableStatus = (status: number): boolean => status === 429 || (status >= 500 && status < 600)
|
|
222
222
|
|
|
223
|
-
/**
|
|
224
|
-
* Parses a `Retry-After` header value, either whole seconds or an HTTP date,
|
|
225
|
-
* into a `Duration` measured from `now` (epoch milliseconds). Anything else,
|
|
226
|
-
* such as `1.5` or `-1`, yields `undefined`.
|
|
227
|
-
*/
|
|
228
|
-
const parseRetryAfter = (value: string | undefined, now: number): Duration.Duration | undefined => {
|
|
229
|
-
if (value === undefined) return undefined
|
|
230
|
-
const retryAfter = Headers.parseRetryAfter(value)
|
|
231
|
-
return Result.isSuccess(retryAfter) ? Headers.retryAfterDelay(retryAfter.success, now) : undefined
|
|
232
|
-
}
|
|
233
|
-
|
|
234
223
|
/**
|
|
235
224
|
* The client could not get a GraphQL response from the server: a network
|
|
236
|
-
* failure, an HTTP response that is not a GraphQL response,
|
|
237
|
-
* WebSocket
|
|
225
|
+
* failure, an HTTP response that is not a GraphQL response, a non-2xx HTTP
|
|
226
|
+
* response whose GraphQL body has no `errors`, or a closed WebSocket
|
|
227
|
+
* connection.
|
|
238
228
|
*
|
|
239
229
|
* **Details**
|
|
240
230
|
*
|
|
241
231
|
* - `status` and `headers` are only set for an HTTP response that is not a
|
|
242
|
-
* GraphQL response
|
|
243
|
-
*
|
|
232
|
+
* GraphQL response, or a non-2xx GraphQL response without `errors`.
|
|
233
|
+
* Headers use `Headers.Headers` at runtime and encode as a plain string
|
|
234
|
+
* record; decoding restores the header collection.
|
|
244
235
|
* - `retryAfter` comes from the `Retry-After` header (whole seconds or an
|
|
245
236
|
* HTTP date) and is encoded as milliseconds. When it is set, the error is
|
|
246
237
|
* retryable at any status, unless the close code is fatal.
|
|
@@ -360,8 +351,10 @@ export class EncodeError
|
|
|
360
351
|
*
|
|
361
352
|
* **Details**
|
|
362
353
|
*
|
|
363
|
-
* `data: null` without `errors` also produces a `DecodeError
|
|
364
|
-
*
|
|
354
|
+
* `data: null` without `errors` also produces a `DecodeError` for a 2xx
|
|
355
|
+
* response or a result without an HTTP status, since `ResponseError`
|
|
356
|
+
* requires a non-empty errors array. On a non-2xx response it is a
|
|
357
|
+
* `TransportError`.
|
|
365
358
|
*
|
|
366
359
|
* @stability experimental
|
|
367
360
|
* @category errors
|
|
@@ -522,7 +522,10 @@ export const makeHttp: {
|
|
|
522
522
|
* (or `null`). Media types match case-insensitively. Anything else
|
|
523
523
|
* is a `TransportError` with the response `status` and `headers`, and a
|
|
524
524
|
* `Retry-After` header (whole seconds or an HTTP date, measured from when the
|
|
525
|
-
* response arrived) becomes `retryAfter`.
|
|
525
|
+
* response arrived) becomes `retryAfter`. A non-2xx GraphQL response is passed
|
|
526
|
+
* to the client, which never treats it as a success: it fails with a
|
|
527
|
+
* `ResponseError` when the body has `errors`, and with a `TransportError`
|
|
528
|
+
* carrying the same metadata otherwise.
|
|
526
529
|
*
|
|
527
530
|
* A subscription is a `POST` with `Accept: text/event-stream`. Each `next`
|
|
528
531
|
* event is emitted with the response headers but no status, and the stream
|
|
@@ -738,7 +741,10 @@ export const layerHttp: {
|
|
|
738
741
|
* (or `null`). Media types match case-insensitively. Anything else
|
|
739
742
|
* is a `TransportError` with the response `status` and `headers`, and a
|
|
740
743
|
* `Retry-After` header (whole seconds or an HTTP date, measured from when the
|
|
741
|
-
* response arrived) becomes `retryAfter`.
|
|
744
|
+
* response arrived) becomes `retryAfter`. A non-2xx GraphQL response is passed
|
|
745
|
+
* to the client, which never treats it as a success: it fails with a
|
|
746
|
+
* `ResponseError` when the body has `errors`, and with a `TransportError`
|
|
747
|
+
* carrying the same metadata otherwise.
|
|
742
748
|
*
|
|
743
749
|
* A subscription is a `POST` with `Accept: text/event-stream`. Each `next`
|
|
744
750
|
* event is emitted with the response headers but no status, and the stream
|
|
@@ -969,7 +975,10 @@ export const layerHttp: {
|
|
|
969
975
|
* (or `null`). Media types match case-insensitively. Anything else
|
|
970
976
|
* is a `TransportError` with the response `status` and `headers`, and a
|
|
971
977
|
* `Retry-After` header (whole seconds or an HTTP date, measured from when the
|
|
972
|
-
* response arrived) becomes `retryAfter`.
|
|
978
|
+
* response arrived) becomes `retryAfter`. A non-2xx GraphQL response is passed
|
|
979
|
+
* to the client, which never treats it as a success: it fails with a
|
|
980
|
+
* `ResponseError` when the body has `errors`, and with a `TransportError`
|
|
981
|
+
* carrying the same metadata otherwise.
|
|
973
982
|
*
|
|
974
983
|
* A subscription is a `POST` with `Accept: text/event-stream`. Each `next`
|
|
975
984
|
* event is emitted with the response headers but no status, and the stream
|
package/src/http/HttpClient.ts
CHANGED
|
@@ -1335,6 +1335,208 @@ export const retryTransient: {
|
|
|
1335
1335
|
}
|
|
1336
1336
|
)
|
|
1337
1337
|
|
|
1338
|
+
/**
|
|
1339
|
+
* Fails requests that do not receive a response within the given duration.
|
|
1340
|
+
*
|
|
1341
|
+
* **When to use**
|
|
1342
|
+
*
|
|
1343
|
+
* Use to configure a timeout once on the client, for example when providing
|
|
1344
|
+
* the `HttpClient` service, while keeping the standard `HttpClientError` error
|
|
1345
|
+
* model.
|
|
1346
|
+
*
|
|
1347
|
+
* **Details**
|
|
1348
|
+
*
|
|
1349
|
+
* A timed out request is interrupted and fails with an `HttpClientError` whose
|
|
1350
|
+
* reason is a `TransportError` with a `Cause.TimeoutError` cause.
|
|
1351
|
+
* `retryTransient` treats it as transient. Interrupting a request aborts the
|
|
1352
|
+
* underlying transport, unless the request is attached to a scope with
|
|
1353
|
+
* `withScope`, in which case it stays open until the scope closes.
|
|
1354
|
+
*
|
|
1355
|
+
* The timer starts after request preprocessing and covers everything the
|
|
1356
|
+
* wrapped client does to produce a response. For a plain client this ends when
|
|
1357
|
+
* the response headers arrive, but response middleware applied before
|
|
1358
|
+
* `timeout`, such as `tap` or `retryTransient`, runs inside the budget,
|
|
1359
|
+
* including any body reads it performs. Composition order therefore decides
|
|
1360
|
+
* how it interacts with retries: applying `timeout` before `retryTransient`
|
|
1361
|
+
* gives each attempt its own budget, while applying it after bounds the whole
|
|
1362
|
+
* retry loop.
|
|
1363
|
+
*
|
|
1364
|
+
* **Gotchas**
|
|
1365
|
+
*
|
|
1366
|
+
* Body reads outside the timed client are not covered, including those made
|
|
1367
|
+
* by response middleware applied after `timeout` and by consumers of the
|
|
1368
|
+
* `HttpClient` service. Apply a separate timeout to body reads such as
|
|
1369
|
+
* `response.json` or `response.stream` when needed.
|
|
1370
|
+
*
|
|
1371
|
+
* **Example** (Timing out each attempt)
|
|
1372
|
+
*
|
|
1373
|
+
* ```ts
|
|
1374
|
+
* import { Effect, Layer } from "effect"
|
|
1375
|
+
* import { FetchHttpClient, HttpClient } from "effect/http"
|
|
1376
|
+
*
|
|
1377
|
+
* const TimedHttpClient = Layer.effect(
|
|
1378
|
+
* HttpClient.HttpClient,
|
|
1379
|
+
* Effect.map(
|
|
1380
|
+
* HttpClient.HttpClient,
|
|
1381
|
+
* HttpClient.timeout("5 seconds")
|
|
1382
|
+
* )
|
|
1383
|
+
* ).pipe(Layer.provide(FetchHttpClient.layer))
|
|
1384
|
+
*
|
|
1385
|
+
* const program = Effect.gen(function*() {
|
|
1386
|
+
* const client = (yield* HttpClient.HttpClient).pipe(
|
|
1387
|
+
* HttpClient.retryTransient({ times: 3 })
|
|
1388
|
+
* )
|
|
1389
|
+
* return yield* client.get("https://example.com")
|
|
1390
|
+
* }).pipe(Effect.provide(TimedHttpClient))
|
|
1391
|
+
* ```
|
|
1392
|
+
*
|
|
1393
|
+
* @stability unstable
|
|
1394
|
+
* @category error handling
|
|
1395
|
+
* @since 4.1.0
|
|
1396
|
+
*/
|
|
1397
|
+
export const timeout: {
|
|
1398
|
+
/**
|
|
1399
|
+
* Fails requests that do not receive a response within the given duration.
|
|
1400
|
+
*
|
|
1401
|
+
* **When to use**
|
|
1402
|
+
*
|
|
1403
|
+
* Use to configure a timeout once on the client, for example when providing
|
|
1404
|
+
* the `HttpClient` service, while keeping the standard `HttpClientError` error
|
|
1405
|
+
* model.
|
|
1406
|
+
*
|
|
1407
|
+
* **Details**
|
|
1408
|
+
*
|
|
1409
|
+
* A timed out request is interrupted and fails with an `HttpClientError` whose
|
|
1410
|
+
* reason is a `TransportError` with a `Cause.TimeoutError` cause.
|
|
1411
|
+
* `retryTransient` treats it as transient. Interrupting a request aborts the
|
|
1412
|
+
* underlying transport, unless the request is attached to a scope with
|
|
1413
|
+
* `withScope`, in which case it stays open until the scope closes.
|
|
1414
|
+
*
|
|
1415
|
+
* The timer starts after request preprocessing and covers everything the
|
|
1416
|
+
* wrapped client does to produce a response. For a plain client this ends when
|
|
1417
|
+
* the response headers arrive, but response middleware applied before
|
|
1418
|
+
* `timeout`, such as `tap` or `retryTransient`, runs inside the budget,
|
|
1419
|
+
* including any body reads it performs. Composition order therefore decides
|
|
1420
|
+
* how it interacts with retries: applying `timeout` before `retryTransient`
|
|
1421
|
+
* gives each attempt its own budget, while applying it after bounds the whole
|
|
1422
|
+
* retry loop.
|
|
1423
|
+
*
|
|
1424
|
+
* **Gotchas**
|
|
1425
|
+
*
|
|
1426
|
+
* Body reads outside the timed client are not covered, including those made
|
|
1427
|
+
* by response middleware applied after `timeout` and by consumers of the
|
|
1428
|
+
* `HttpClient` service. Apply a separate timeout to body reads such as
|
|
1429
|
+
* `response.json` or `response.stream` when needed.
|
|
1430
|
+
*
|
|
1431
|
+
* **Example** (Timing out each attempt)
|
|
1432
|
+
*
|
|
1433
|
+
* ```ts
|
|
1434
|
+
* import { Effect, Layer } from "effect"
|
|
1435
|
+
* import { FetchHttpClient, HttpClient } from "effect/http"
|
|
1436
|
+
*
|
|
1437
|
+
* const TimedHttpClient = Layer.effect(
|
|
1438
|
+
* HttpClient.HttpClient,
|
|
1439
|
+
* Effect.map(
|
|
1440
|
+
* HttpClient.HttpClient,
|
|
1441
|
+
* HttpClient.timeout("5 seconds")
|
|
1442
|
+
* )
|
|
1443
|
+
* ).pipe(Layer.provide(FetchHttpClient.layer))
|
|
1444
|
+
*
|
|
1445
|
+
* const program = Effect.gen(function*() {
|
|
1446
|
+
* const client = (yield* HttpClient.HttpClient).pipe(
|
|
1447
|
+
* HttpClient.retryTransient({ times: 3 })
|
|
1448
|
+
* )
|
|
1449
|
+
* return yield* client.get("https://example.com")
|
|
1450
|
+
* }).pipe(Effect.provide(TimedHttpClient))
|
|
1451
|
+
* ```
|
|
1452
|
+
*
|
|
1453
|
+
* @stability unstable
|
|
1454
|
+
* @category error handling
|
|
1455
|
+
* @since 4.1.0
|
|
1456
|
+
*/
|
|
1457
|
+
(duration: Duration.Input): <E, R>(self: HttpClient.With<E, R>) => HttpClient.With<E | Error.HttpClientError, R>
|
|
1458
|
+
/**
|
|
1459
|
+
* Fails requests that do not receive a response within the given duration.
|
|
1460
|
+
*
|
|
1461
|
+
* **When to use**
|
|
1462
|
+
*
|
|
1463
|
+
* Use to configure a timeout once on the client, for example when providing
|
|
1464
|
+
* the `HttpClient` service, while keeping the standard `HttpClientError` error
|
|
1465
|
+
* model.
|
|
1466
|
+
*
|
|
1467
|
+
* **Details**
|
|
1468
|
+
*
|
|
1469
|
+
* A timed out request is interrupted and fails with an `HttpClientError` whose
|
|
1470
|
+
* reason is a `TransportError` with a `Cause.TimeoutError` cause.
|
|
1471
|
+
* `retryTransient` treats it as transient. Interrupting a request aborts the
|
|
1472
|
+
* underlying transport, unless the request is attached to a scope with
|
|
1473
|
+
* `withScope`, in which case it stays open until the scope closes.
|
|
1474
|
+
*
|
|
1475
|
+
* The timer starts after request preprocessing and covers everything the
|
|
1476
|
+
* wrapped client does to produce a response. For a plain client this ends when
|
|
1477
|
+
* the response headers arrive, but response middleware applied before
|
|
1478
|
+
* `timeout`, such as `tap` or `retryTransient`, runs inside the budget,
|
|
1479
|
+
* including any body reads it performs. Composition order therefore decides
|
|
1480
|
+
* how it interacts with retries: applying `timeout` before `retryTransient`
|
|
1481
|
+
* gives each attempt its own budget, while applying it after bounds the whole
|
|
1482
|
+
* retry loop.
|
|
1483
|
+
*
|
|
1484
|
+
* **Gotchas**
|
|
1485
|
+
*
|
|
1486
|
+
* Body reads outside the timed client are not covered, including those made
|
|
1487
|
+
* by response middleware applied after `timeout` and by consumers of the
|
|
1488
|
+
* `HttpClient` service. Apply a separate timeout to body reads such as
|
|
1489
|
+
* `response.json` or `response.stream` when needed.
|
|
1490
|
+
*
|
|
1491
|
+
* **Example** (Timing out each attempt)
|
|
1492
|
+
*
|
|
1493
|
+
* ```ts
|
|
1494
|
+
* import { Effect, Layer } from "effect"
|
|
1495
|
+
* import { FetchHttpClient, HttpClient } from "effect/http"
|
|
1496
|
+
*
|
|
1497
|
+
* const TimedHttpClient = Layer.effect(
|
|
1498
|
+
* HttpClient.HttpClient,
|
|
1499
|
+
* Effect.map(
|
|
1500
|
+
* HttpClient.HttpClient,
|
|
1501
|
+
* HttpClient.timeout("5 seconds")
|
|
1502
|
+
* )
|
|
1503
|
+
* ).pipe(Layer.provide(FetchHttpClient.layer))
|
|
1504
|
+
*
|
|
1505
|
+
* const program = Effect.gen(function*() {
|
|
1506
|
+
* const client = (yield* HttpClient.HttpClient).pipe(
|
|
1507
|
+
* HttpClient.retryTransient({ times: 3 })
|
|
1508
|
+
* )
|
|
1509
|
+
* return yield* client.get("https://example.com")
|
|
1510
|
+
* }).pipe(Effect.provide(TimedHttpClient))
|
|
1511
|
+
* ```
|
|
1512
|
+
*
|
|
1513
|
+
* @stability unstable
|
|
1514
|
+
* @category error handling
|
|
1515
|
+
* @since 4.1.0
|
|
1516
|
+
*/
|
|
1517
|
+
<E, R>(self: HttpClient.With<E, R>, duration: Duration.Input): HttpClient.With<E | Error.HttpClientError, R>
|
|
1518
|
+
} = dual(
|
|
1519
|
+
2,
|
|
1520
|
+
<E, R>(self: HttpClient.With<E, R>, duration: Duration.Input): HttpClient.With<E | Error.HttpClientError, R> => {
|
|
1521
|
+
const decoded = Duration.fromInputUnsafe(duration)
|
|
1522
|
+
const description = `timed out after ${Duration.format(decoded)}`
|
|
1523
|
+
return transform(self, (effect, request) =>
|
|
1524
|
+
Effect.timeoutOrElse(effect, {
|
|
1525
|
+
duration: decoded,
|
|
1526
|
+
orElse: () =>
|
|
1527
|
+
Effect.fail(
|
|
1528
|
+
new Error.HttpClientError({
|
|
1529
|
+
reason: new Error.TransportError({
|
|
1530
|
+
request,
|
|
1531
|
+
cause: new Cause.TimeoutError(`Operation ${description}`),
|
|
1532
|
+
description
|
|
1533
|
+
})
|
|
1534
|
+
})
|
|
1535
|
+
)
|
|
1536
|
+
}))
|
|
1537
|
+
}
|
|
1538
|
+
)
|
|
1539
|
+
|
|
1338
1540
|
/**
|
|
1339
1541
|
* Namespace containing configuration types for `withRateLimiter`.
|
|
1340
1542
|
*
|
|
@@ -1680,7 +1882,7 @@ export const withRateLimiter: {
|
|
|
1680
1882
|
* Namespace containing configuration types for `withCircuitBreaker`.
|
|
1681
1883
|
*
|
|
1682
1884
|
* @stability experimental
|
|
1683
|
-
* @since 4.0.
|
|
1885
|
+
* @since 4.0.7
|
|
1684
1886
|
*/
|
|
1685
1887
|
export declare namespace WithCircuitBreaker {
|
|
1686
1888
|
/**
|
|
@@ -1688,7 +1890,7 @@ export declare namespace WithCircuitBreaker {
|
|
|
1688
1890
|
*
|
|
1689
1891
|
* @stability experimental
|
|
1690
1892
|
* @category circuit breaking
|
|
1691
|
-
* @since 4.0.
|
|
1893
|
+
* @since 4.0.7
|
|
1692
1894
|
*/
|
|
1693
1895
|
export interface Options<E, R2 = never> {
|
|
1694
1896
|
/**
|
|
@@ -1703,13 +1905,10 @@ export declare namespace WithCircuitBreaker {
|
|
|
1703
1905
|
readonly key?: string | ((request: HttpClientRequest.HttpClientRequest) => string) | undefined
|
|
1704
1906
|
/**
|
|
1705
1907
|
* Classifies the `Exit` of each request that the breaker admitted.
|
|
1908
|
+
* `context.probe` is `true` when the request is the HalfOpen probe.
|
|
1706
1909
|
* Defaults to `circuitBreakerClassifier`.
|
|
1707
1910
|
*/
|
|
1708
|
-
readonly classify?:
|
|
1709
|
-
| ((
|
|
1710
|
-
exit: Exit.Exit<HttpClientResponse.HttpClientResponse, E>
|
|
1711
|
-
) => CircuitBreaker.Outcome | Effect.Effect<CircuitBreaker.Outcome, never, R2>)
|
|
1712
|
-
| undefined
|
|
1911
|
+
readonly classify?: CircuitBreaker.Classifier<HttpClientResponse.HttpClientResponse, E, R2> | undefined
|
|
1713
1912
|
}
|
|
1714
1913
|
}
|
|
1715
1914
|
|
|
@@ -1830,7 +2029,7 @@ export declare namespace WithCircuitBreaker {
|
|
|
1830
2029
|
*
|
|
1831
2030
|
* @stability experimental
|
|
1832
2031
|
* @category circuit breaking
|
|
1833
|
-
* @since 4.0.
|
|
2032
|
+
* @since 4.0.7
|
|
1834
2033
|
*/
|
|
1835
2034
|
export const withCircuitBreaker: {
|
|
1836
2035
|
/**
|
|
@@ -1950,7 +2149,7 @@ export const withCircuitBreaker: {
|
|
|
1950
2149
|
*
|
|
1951
2150
|
* @stability experimental
|
|
1952
2151
|
* @category circuit breaking
|
|
1953
|
-
* @since 4.0.
|
|
2152
|
+
* @since 4.0.7
|
|
1954
2153
|
*/
|
|
1955
2154
|
<E, R2 = never>(options: WithCircuitBreaker.Options<E, R2>): <R>(
|
|
1956
2155
|
self: HttpClient.With<E, R>
|
|
@@ -2072,7 +2271,7 @@ export const withCircuitBreaker: {
|
|
|
2072
2271
|
*
|
|
2073
2272
|
* @stability experimental
|
|
2074
2273
|
* @category circuit breaking
|
|
2075
|
-
* @since 4.0.
|
|
2274
|
+
* @since 4.0.7
|
|
2076
2275
|
*/
|
|
2077
2276
|
<E, R, R2 = never>(self: HttpClient.With<E, R>, options: WithCircuitBreaker.Options<E, R2>): HttpClient.With<E | CircuitBreaker.CircuitBreakerError, R | R2>
|
|
2078
2277
|
} = dual(2, <E, R, R2>(
|
|
@@ -2120,7 +2319,7 @@ const requestOrigin = (request: HttpClientRequest.HttpClientRequest): string =>
|
|
|
2120
2319
|
*
|
|
2121
2320
|
* @stability experimental
|
|
2122
2321
|
* @category circuit breaking
|
|
2123
|
-
* @since 4.0.
|
|
2322
|
+
* @since 4.0.7
|
|
2124
2323
|
*/
|
|
2125
2324
|
export const circuitBreakerClassifier = <E>(
|
|
2126
2325
|
exit: Exit.Exit<HttpClientResponse.HttpClientResponse, E>
|
|
@@ -2467,9 +2666,11 @@ export const tapRequest: {
|
|
|
2467
2666
|
* **Details**
|
|
2468
2667
|
*
|
|
2469
2668
|
* Response cookies are merged into the ref with `Cookies.mergeIntoArray` for
|
|
2470
|
-
* the response URL.
|
|
2471
|
-
* the cookies for
|
|
2472
|
-
*
|
|
2669
|
+
* the response URL. When a request is sent, `Cookies.toRequestCookieHeader`
|
|
2670
|
+
* selects the cookies for its final URL, after later transformations such as
|
|
2671
|
+
* `HttpClientRequest.prependUrl`, and sets them as the `cookie` header. With
|
|
2672
|
+
* `followRedirects` applied after `withCookiesRef`, this runs for every hop.
|
|
2673
|
+
* Expiry uses the current `Clock`.
|
|
2473
2674
|
*
|
|
2474
2675
|
* @stability unstable
|
|
2475
2676
|
* @category cookies
|
|
@@ -2488,9 +2689,11 @@ export const withCookiesRef: {
|
|
|
2488
2689
|
* **Details**
|
|
2489
2690
|
*
|
|
2490
2691
|
* Response cookies are merged into the ref with `Cookies.mergeIntoArray` for
|
|
2491
|
-
* the response URL.
|
|
2492
|
-
* the cookies for
|
|
2493
|
-
*
|
|
2692
|
+
* the response URL. When a request is sent, `Cookies.toRequestCookieHeader`
|
|
2693
|
+
* selects the cookies for its final URL, after later transformations such as
|
|
2694
|
+
* `HttpClientRequest.prependUrl`, and sets them as the `cookie` header. With
|
|
2695
|
+
* `followRedirects` applied after `withCookiesRef`, this runs for every hop.
|
|
2696
|
+
* Expiry uses the current `Clock`.
|
|
2494
2697
|
*
|
|
2495
2698
|
* @stability unstable
|
|
2496
2699
|
* @category cookies
|
|
@@ -2509,9 +2712,11 @@ export const withCookiesRef: {
|
|
|
2509
2712
|
* **Details**
|
|
2510
2713
|
*
|
|
2511
2714
|
* Response cookies are merged into the ref with `Cookies.mergeIntoArray` for
|
|
2512
|
-
* the response URL.
|
|
2513
|
-
* the cookies for
|
|
2514
|
-
*
|
|
2715
|
+
* the response URL. When a request is sent, `Cookies.toRequestCookieHeader`
|
|
2716
|
+
* selects the cookies for its final URL, after later transformations such as
|
|
2717
|
+
* `HttpClientRequest.prependUrl`, and sets them as the `cookie` header. With
|
|
2718
|
+
* `followRedirects` applied after `withCookiesRef`, this runs for every hop.
|
|
2719
|
+
* Expiry uses the current `Clock`.
|
|
2515
2720
|
*
|
|
2516
2721
|
* @stability unstable
|
|
2517
2722
|
* @category cookies
|
|
@@ -2523,21 +2728,27 @@ export const withCookiesRef: {
|
|
|
2523
2728
|
<E, R>(
|
|
2524
2729
|
self: HttpClient.With<E, R>,
|
|
2525
2730
|
ref: Ref.Ref<ReadonlyArray<Cookies.Cookie>>
|
|
2526
|
-
): HttpClient.With<E, R> =>
|
|
2527
|
-
|
|
2731
|
+
): HttpClient.With<E, R> => {
|
|
2732
|
+
const now = () => Fiber.getCurrent()!.getRef(Clock).currentTimeMillisUnsafe()
|
|
2733
|
+
const addCookies = (request: HttpClientRequest.HttpClientRequest) =>
|
|
2734
|
+
Effect.map(Ref.get(ref), (cookies) => {
|
|
2735
|
+
const header = Cookies.toRequestCookieHeader(cookies, request.url, now())
|
|
2736
|
+
if (header === undefined) return request
|
|
2737
|
+
const withCookies = HttpClientRequest.setHeader(request, "cookie", header)
|
|
2738
|
+
// setHeader returns a new request, so carry over the withScope controller
|
|
2739
|
+
const controller = scopedRequests.get(request)
|
|
2740
|
+
if (controller !== undefined) scopedRequests.set(withCookies, controller)
|
|
2741
|
+
return withCookies
|
|
2742
|
+
})
|
|
2743
|
+
return makeWith(
|
|
2528
2744
|
(request: Effect.Effect<HttpClientRequest.HttpClientRequest, E, R>) =>
|
|
2529
|
-
Effect.tap(
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
Effect.flatMap(self.preprocess(request), (request) =>
|
|
2535
|
-
Effect.map(Ref.get(ref), (cookies) => {
|
|
2536
|
-
const now = Fiber.getCurrent()!.getRef(Clock).currentTimeMillisUnsafe()
|
|
2537
|
-
const header = Cookies.toRequestCookieHeader(cookies, request.url, now)
|
|
2538
|
-
return header === undefined ? request : HttpClientRequest.setHeader(request, "cookie", header)
|
|
2539
|
-
}))
|
|
2745
|
+
Effect.tap(
|
|
2746
|
+
self.postprocess(Effect.flatMap(request, addCookies)),
|
|
2747
|
+
(response) => Ref.update(ref, Cookies.mergeIntoArray(response.url, response.cookies, now()))
|
|
2748
|
+
),
|
|
2749
|
+
self.preprocess
|
|
2540
2750
|
)
|
|
2751
|
+
}
|
|
2541
2752
|
)
|
|
2542
2753
|
|
|
2543
2754
|
/**
|
|
@@ -836,32 +836,37 @@ class ClientRequestImpl extends Inspectable.Class implements HttpServerRequest {
|
|
|
836
836
|
if (this.bytesEffect) {
|
|
837
837
|
return this.bytesEffect
|
|
838
838
|
}
|
|
839
|
+
this.bytesEffect = Effect.withFiber((fiber) => {
|
|
840
|
+
const maxBodySize = fiber.getRef(HttpIncomingMessage.MaxBodySize)
|
|
841
|
+
return this.readBytes(maxBodySize === undefined ? undefined : Number(maxBodySize))
|
|
842
|
+
}).pipe(
|
|
843
|
+
Effect.cached,
|
|
844
|
+
Effect.runSync
|
|
845
|
+
)
|
|
846
|
+
return this.bytesEffect
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
private readBytes(maxBytes: number | undefined): Effect.Effect<Uint8Array, HttpServerError> {
|
|
839
850
|
const body = this.source.body
|
|
840
|
-
let effect: Effect.Effect<Uint8Array, HttpServerError>
|
|
841
851
|
switch (body._tag) {
|
|
842
852
|
case "Empty": {
|
|
843
|
-
|
|
844
|
-
break
|
|
853
|
+
return Effect.succeed(new Uint8Array(0))
|
|
845
854
|
}
|
|
846
855
|
case "Uint8Array": {
|
|
847
|
-
|
|
848
|
-
|
|
856
|
+
return maxBytes !== undefined && body.body.byteLength > maxBytes
|
|
857
|
+
? Effect.fail(bodyTooLargeError(this, new BodyTooLargeError(maxBytes)))
|
|
858
|
+
: Effect.succeed(body.body)
|
|
849
859
|
}
|
|
850
860
|
case "FormData": {
|
|
851
|
-
|
|
852
|
-
break
|
|
861
|
+
return bytesFromWeb(this, () => new Response(body.formData), maxBytes)
|
|
853
862
|
}
|
|
854
863
|
case "Stream": {
|
|
855
|
-
|
|
856
|
-
break
|
|
864
|
+
return Stream.mkUint8Array(maxBytes === undefined ? this.stream : limitStream(this, this.stream, maxBytes))
|
|
857
865
|
}
|
|
858
866
|
case "Raw": {
|
|
859
|
-
|
|
860
|
-
break
|
|
867
|
+
return rawBodyBytes(this, body.body, maxBytes)
|
|
861
868
|
}
|
|
862
869
|
}
|
|
863
|
-
this.bytesEffect = Effect.runSync(Effect.cached(effect))
|
|
864
|
-
return this.bytesEffect
|
|
865
870
|
}
|
|
866
871
|
|
|
867
872
|
get text(): Effect.Effect<string, HttpServerError> {
|
|
@@ -962,23 +967,38 @@ const rawBodyStream = (request: HttpServerRequest, body: unknown): Stream.Stream
|
|
|
962
967
|
return Stream.fail(requestParseError(request, "Unsupported body type"))
|
|
963
968
|
}
|
|
964
969
|
|
|
965
|
-
const rawBodyBytes = (
|
|
970
|
+
const rawBodyBytes = (
|
|
971
|
+
request: HttpServerRequest,
|
|
972
|
+
body: unknown,
|
|
973
|
+
maxBytes: number | undefined
|
|
974
|
+
): Effect.Effect<Uint8Array, HttpServerError> => {
|
|
966
975
|
if (body instanceof Request) {
|
|
967
|
-
return
|
|
968
|
-
try: () => body.arrayBuffer().then((buffer) => new Uint8Array(buffer)),
|
|
969
|
-
catch: (cause) => requestParseError(request, undefined, cause)
|
|
970
|
-
})
|
|
976
|
+
return bytesFromWeb(request, () => body, maxBytes)
|
|
971
977
|
}
|
|
972
978
|
if (isBodyInit(body)) {
|
|
973
|
-
return
|
|
979
|
+
return bytesFromWeb(request, () => new Response(body), maxBytes)
|
|
974
980
|
}
|
|
975
981
|
return Effect.fail(requestParseError(request, "Unsupported body type"))
|
|
976
982
|
}
|
|
977
983
|
|
|
978
|
-
const
|
|
984
|
+
const bytesFromWeb = (
|
|
985
|
+
request: HttpServerRequest,
|
|
986
|
+
// Evaluated inside `try`, as wrapping an unreadable body in a `Response` throws.
|
|
987
|
+
evaluate: () => Request | Response,
|
|
988
|
+
maxBytes: number | undefined
|
|
989
|
+
): Effect.Effect<Uint8Array, HttpServerError> =>
|
|
979
990
|
Effect.tryPromise({
|
|
980
|
-
try:
|
|
981
|
-
|
|
991
|
+
try: async (signal) => {
|
|
992
|
+
const source = evaluate()
|
|
993
|
+
const buffer = maxBytes === undefined
|
|
994
|
+
? await source.arrayBuffer()
|
|
995
|
+
: await readArrayBufferLimited(source, maxBytes, signal)
|
|
996
|
+
return new Uint8Array(buffer)
|
|
997
|
+
},
|
|
998
|
+
catch: (cause) =>
|
|
999
|
+
cause instanceof BodyTooLargeError
|
|
1000
|
+
? bodyTooLargeError(request, cause)
|
|
1001
|
+
: requestParseError(request, undefined, cause)
|
|
982
1002
|
})
|
|
983
1003
|
|
|
984
1004
|
const streamFromReadable = (
|
|
@@ -1005,6 +1025,24 @@ const requestParseError = (
|
|
|
1005
1025
|
})
|
|
1006
1026
|
})
|
|
1007
1027
|
|
|
1028
|
+
const limitStream = (
|
|
1029
|
+
request: HttpServerRequest,
|
|
1030
|
+
stream: Stream.Stream<Uint8Array, HttpServerError>,
|
|
1031
|
+
maxBytes: number
|
|
1032
|
+
): Stream.Stream<Uint8Array, HttpServerError> =>
|
|
1033
|
+
Stream.suspend(() => {
|
|
1034
|
+
let bytes = 0
|
|
1035
|
+
return Stream.mapEffect(stream, (chunk) => {
|
|
1036
|
+
bytes += chunk.byteLength
|
|
1037
|
+
return bytes > maxBytes
|
|
1038
|
+
? Effect.fail(bodyTooLargeError(request, new BodyTooLargeError(maxBytes)))
|
|
1039
|
+
: Effect.succeed(chunk)
|
|
1040
|
+
})
|
|
1041
|
+
})
|
|
1042
|
+
|
|
1043
|
+
const bodyTooLargeError = (request: HttpServerRequest, cause: BodyTooLargeError) =>
|
|
1044
|
+
new HttpServerError({ reason: new RequestParseError({ request, reason: "BodyTooLarge", cause }) })
|
|
1045
|
+
|
|
1008
1046
|
const formDataToParts = (formData: FormData): Array<Multipart.Part> => {
|
|
1009
1047
|
const parts: Array<Multipart.Part> = []
|
|
1010
1048
|
for (const [key, value] of formData.entries()) {
|
|
@@ -1102,7 +1140,7 @@ class BodyTooLargeError extends Error {
|
|
|
1102
1140
|
}
|
|
1103
1141
|
|
|
1104
1142
|
const readArrayBufferLimited = async (
|
|
1105
|
-
source: Request,
|
|
1143
|
+
source: Request | Response,
|
|
1106
1144
|
maxBytes: number,
|
|
1107
1145
|
signal: AbortSignal
|
|
1108
1146
|
): Promise<ArrayBuffer> => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Standard MIME type data copied from mime 4.1.0
|
|
2
|
+
* Standard MIME type data copied from mime 4.1.0, plus `text/x-python` and
|
|
3
|
+
* `text/x-shellscript` for `py` and `sh` scripts.
|
|
3
4
|
*
|
|
4
5
|
* MIT License
|
|
5
6
|
*
|
|
@@ -370,6 +371,8 @@ const types = {
|
|
|
370
371
|
"text/vcard": ["vcard"],
|
|
371
372
|
"text/vtt": ["vtt"],
|
|
372
373
|
"text/wgsl": ["wgsl"],
|
|
374
|
+
"text/x-python": ["py"],
|
|
375
|
+
"text/x-shellscript": ["sh"],
|
|
373
376
|
"text/xml": ["*xml"],
|
|
374
377
|
"text/yaml": ["yaml", "yml"],
|
|
375
378
|
"video/3gpp": ["3gp", "3gpp"],
|
|
@@ -600,7 +600,7 @@ export const StreamSse: {
|
|
|
600
600
|
}): StreamSse<Sse.EventCodec, Schema.Top, unknown> => {
|
|
601
601
|
const events = options.events ?? (options.data === undefined ? undefined : Schema.Struct({
|
|
602
602
|
...Sse.EventEncoded.fields,
|
|
603
|
-
data: Schema.fromJsonString(options.data)
|
|
603
|
+
data: Schema.fromJsonString(Schema.toCodecJson(options.data))
|
|
604
604
|
}))
|
|
605
605
|
if (events === undefined) {
|
|
606
606
|
throw new Error("StreamSse requires either an events schema or a data schema")
|