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
package/src/cluster/Entity.ts
CHANGED
|
@@ -148,7 +148,20 @@ export interface Entity<
|
|
|
148
148
|
readonly concurrency?: number | "unbounded" | undefined
|
|
149
149
|
readonly mailboxCapacity?: number | "unbounded" | undefined
|
|
150
150
|
readonly mailboxMetrics?: boolean | undefined
|
|
151
|
+
/**
|
|
152
|
+
* When `true`, a handler defect fails only its request instead of
|
|
153
|
+
* restarting the entity and replaying its in-flight requests.
|
|
154
|
+
*/
|
|
151
155
|
readonly disableFatalDefects?: boolean | undefined
|
|
156
|
+
/**
|
|
157
|
+
* Schedule for restarting an entity after a defect and for retrying failed
|
|
158
|
+
* handler construction.
|
|
159
|
+
*
|
|
160
|
+
* Backoff is tracked per entity and resets once a request completes.
|
|
161
|
+
* When the policy ends, the default (500 ms growing by 1.5x, capped at 10
|
|
162
|
+
* seconds) continues, so restarts never stop; use `disableFatalDefects` to
|
|
163
|
+
* avoid them.
|
|
164
|
+
*/
|
|
152
165
|
readonly defectRetryPolicy?: Schedule.Schedule<any, unknown> | undefined
|
|
153
166
|
readonly spanAttributes?: Record<string, string> | undefined
|
|
154
167
|
}
|
|
@@ -193,7 +206,20 @@ export interface Entity<
|
|
|
193
206
|
readonly maxIdleTime?: Duration.Input | undefined
|
|
194
207
|
readonly mailboxCapacity?: number | "unbounded" | undefined
|
|
195
208
|
readonly mailboxMetrics?: boolean | undefined
|
|
209
|
+
/**
|
|
210
|
+
* When `true`, a handler defect fails only its request instead of
|
|
211
|
+
* restarting the entity and replaying its in-flight requests.
|
|
212
|
+
*/
|
|
196
213
|
readonly disableFatalDefects?: boolean | undefined
|
|
214
|
+
/**
|
|
215
|
+
* Schedule for restarting an entity after a defect and for retrying failed
|
|
216
|
+
* handler construction.
|
|
217
|
+
*
|
|
218
|
+
* Backoff is tracked per entity and resets once a request completes.
|
|
219
|
+
* When the policy ends, the default (500 ms growing by 1.5x, capped at 10
|
|
220
|
+
* seconds) continues, so restarts never stop; use `disableFatalDefects` to
|
|
221
|
+
* avoid them.
|
|
222
|
+
*/
|
|
197
223
|
readonly defectRetryPolicy?: Schedule.Schedule<any, unknown> | undefined
|
|
198
224
|
readonly spanAttributes?: Record<string, string> | undefined
|
|
199
225
|
}
|
|
@@ -290,7 +316,20 @@ const Proto = {
|
|
|
290
316
|
readonly concurrency?: number | "unbounded" | undefined
|
|
291
317
|
readonly mailboxCapacity?: number | "unbounded" | undefined
|
|
292
318
|
readonly mailboxMetrics?: boolean | undefined
|
|
319
|
+
/**
|
|
320
|
+
* When `true`, a handler defect fails only its request instead of
|
|
321
|
+
* restarting the entity and replaying its in-flight requests.
|
|
322
|
+
*/
|
|
293
323
|
readonly disableFatalDefects?: boolean | undefined
|
|
324
|
+
/**
|
|
325
|
+
* Schedule for restarting an entity after a defect and for retrying failed
|
|
326
|
+
* handler construction.
|
|
327
|
+
*
|
|
328
|
+
* Backoff is tracked per entity and resets once a request completes.
|
|
329
|
+
* When the policy ends, the default (500 ms growing by 1.5x, capped at 10
|
|
330
|
+
* seconds) continues, so restarts never stop; use `disableFatalDefects` to
|
|
331
|
+
* avoid them.
|
|
332
|
+
*/
|
|
294
333
|
readonly defectRetryPolicy?: Schedule.Schedule<any, unknown> | undefined
|
|
295
334
|
readonly spanAttributes?: Record<string, string> | undefined
|
|
296
335
|
}
|
|
@@ -339,7 +378,20 @@ const Proto = {
|
|
|
339
378
|
readonly maxIdleTime?: Duration.Input | undefined
|
|
340
379
|
readonly mailboxCapacity?: number | "unbounded" | undefined
|
|
341
380
|
readonly mailboxMetrics?: boolean | undefined
|
|
381
|
+
/**
|
|
382
|
+
* When `true`, a handler defect fails only its request instead of
|
|
383
|
+
* restarting the entity and replaying its in-flight requests.
|
|
384
|
+
*/
|
|
342
385
|
readonly disableFatalDefects?: boolean | undefined
|
|
386
|
+
/**
|
|
387
|
+
* Schedule for restarting an entity after a defect and for retrying failed
|
|
388
|
+
* handler construction.
|
|
389
|
+
*
|
|
390
|
+
* Backoff is tracked per entity and resets once a request completes.
|
|
391
|
+
* When the policy ends, the default (500 ms growing by 1.5x, capped at 10
|
|
392
|
+
* seconds) continues, so restarts never stop; use `disableFatalDefects` to
|
|
393
|
+
* avoid them.
|
|
394
|
+
*/
|
|
343
395
|
readonly defectRetryPolicy?: Schedule.Schedule<any, unknown> | undefined
|
|
344
396
|
readonly spanAttributes?: Record<string, string> | undefined
|
|
345
397
|
}
|
|
@@ -30,6 +30,7 @@ import * as DeliverAt from "./DeliverAt.ts"
|
|
|
30
30
|
import type { EntityAddress } from "./EntityAddress.ts"
|
|
31
31
|
import * as Envelope from "./Envelope.ts"
|
|
32
32
|
import * as ClusterAbandon from "./internal/clusterAbandon.ts"
|
|
33
|
+
import { TransactionNotifications } from "./internal/transactionNotifications.ts"
|
|
33
34
|
import * as Message from "./Message.ts"
|
|
34
35
|
import * as Reply from "./Reply.ts"
|
|
35
36
|
import * as ShardId from "./ShardId.ts"
|
|
@@ -223,8 +224,8 @@ export class MessageStorage extends Context.Service<MessageStorage, {
|
|
|
223
224
|
/**
|
|
224
225
|
* Wraps requests in storage transactions.
|
|
225
226
|
*
|
|
226
|
-
* `WithExit` replies saved in a transaction notify
|
|
227
|
-
* commit; stream chunks notify immediately. Replies saved in a failed
|
|
227
|
+
* `WithExit` replies and discarded sends saved in a transaction notify after
|
|
228
|
+
* the outermost commit; stream chunks notify immediately. Replies saved in a failed
|
|
228
229
|
* transaction must be discarded. The wrapper may fail only with the wrapped
|
|
229
230
|
* effect's own failure or a defect.
|
|
230
231
|
*/
|
|
@@ -532,10 +533,6 @@ export type EncodedRepliesOptions<A> = {
|
|
|
532
533
|
readonly cursor: Option.Option<A>
|
|
533
534
|
}
|
|
534
535
|
|
|
535
|
-
const TransactionNotifications = Context.Reference<
|
|
536
|
-
Array<Effect.Effect<void, PersistenceError | MalformedMessage>> | undefined
|
|
537
|
-
>("effect/cluster/MessageStorage/TransactionNotifications", { defaultValue: () => undefined })
|
|
538
|
-
|
|
539
536
|
/**
|
|
540
537
|
* Wraps a concrete message storage implementation with reply-handler management.
|
|
541
538
|
*
|
package/src/cluster/Reply.ts
CHANGED
|
@@ -220,7 +220,7 @@ export class Chunk<R extends Rpc.Any> extends Data.TaggedClass("Chunk")<{
|
|
|
220
220
|
* @stability unstable
|
|
221
221
|
* @since 4.0.0
|
|
222
222
|
*/
|
|
223
|
-
static readonly Any = Schema.declare((u): u is Chunk<
|
|
223
|
+
static readonly Any = Schema.declare((u): u is Chunk<Rpc.Any> => isReply(u) && u._tag === "Chunk")
|
|
224
224
|
|
|
225
225
|
/**
|
|
226
226
|
* Transformation between encoded chunk records and `Chunk` instances.
|
package/src/cluster/Runners.ts
CHANGED
|
@@ -32,6 +32,7 @@ import type { MalformedMessage, PersistenceError } from "./ClusterError.ts"
|
|
|
32
32
|
import { AlreadyProcessingMessage, EntityNotAssignedToRunner, MailboxFull, RunnerUnavailable } from "./ClusterError.ts"
|
|
33
33
|
import { Persisted } from "./ClusterSchema.ts"
|
|
34
34
|
import * as Envelope from "./Envelope.ts"
|
|
35
|
+
import { TransactionNotifications } from "./internal/transactionNotifications.ts"
|
|
35
36
|
import * as Message from "./Message.ts"
|
|
36
37
|
import * as MessageStorage from "./MessageStorage.ts"
|
|
37
38
|
import * as Reply from "./Reply.ts"
|
|
@@ -180,6 +181,19 @@ export const make: (
|
|
|
180
181
|
|
|
181
182
|
const requestIdRewrites = new Map<Snowflake.Snowflake, Snowflake.Snowflake>()
|
|
182
183
|
|
|
184
|
+
// A message saved in a transaction is invisible to readers until the commit,
|
|
185
|
+
// so its wake-up waits for the commit. A failure then can no longer be
|
|
186
|
+
// returned and is dropped; the next storage poll delivers the message.
|
|
187
|
+
const notifyAfterCommit = <E>(message: Message.Outgoing<any>, notify: Effect.Effect<void, E>) => {
|
|
188
|
+
const rpc = message.rpc as any as Rpc.AnyWithProps
|
|
189
|
+
if (!Context.get(rpc.annotations, Persisted)) return notify
|
|
190
|
+
return TransactionNotifications.use((notifications) =>
|
|
191
|
+
notifications === undefined ? notify : Effect.sync(() => {
|
|
192
|
+
notifications.push(Effect.ignore(notify))
|
|
193
|
+
})
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
183
197
|
function notifyWith<E>(
|
|
184
198
|
message: Message.Outgoing<any>,
|
|
185
199
|
afterPersist: (message: Message.Outgoing<any>, isDuplicate: boolean) => Effect.Effect<void, E>
|
|
@@ -471,7 +485,7 @@ export const make: (
|
|
|
471
485
|
const { discard, message } = options_
|
|
472
486
|
return notifyWith(message, (message, duplicate) => {
|
|
473
487
|
if (discard || message._tag === "OutgoingEnvelope") {
|
|
474
|
-
return options.notify(options_)
|
|
488
|
+
return notifyAfterCommit(message, options.notify(options_))
|
|
475
489
|
} else if (!duplicate && Option.isSome(options_.address)) {
|
|
476
490
|
return Effect.catch(
|
|
477
491
|
options.send({
|
|
@@ -499,7 +513,7 @@ export const make: (
|
|
|
499
513
|
}
|
|
500
514
|
return notifyWith(message, (message) => {
|
|
501
515
|
if (options.discard || message._tag === "OutgoingEnvelope") {
|
|
502
|
-
return notifyEntity(message)
|
|
516
|
+
return notifyAfterCommit(message, notifyEntity(message))
|
|
503
517
|
}
|
|
504
518
|
return Effect.andThen(
|
|
505
519
|
notifyEntity(message),
|
package/src/cluster/Sharding.ts
CHANGED
|
@@ -143,7 +143,20 @@ export class Sharding extends Context.Service<Sharding, {
|
|
|
143
143
|
readonly concurrency?: number | "unbounded" | undefined
|
|
144
144
|
readonly mailboxCapacity?: number | "unbounded" | undefined
|
|
145
145
|
readonly mailboxMetrics?: boolean | undefined
|
|
146
|
+
/**
|
|
147
|
+
* When `true`, a handler defect fails only its request instead of
|
|
148
|
+
* restarting the entity and replaying its in-flight requests.
|
|
149
|
+
*/
|
|
146
150
|
readonly disableFatalDefects?: boolean | undefined
|
|
151
|
+
/**
|
|
152
|
+
* Schedule for restarting an entity after a defect and for retrying failed
|
|
153
|
+
* handler construction.
|
|
154
|
+
*
|
|
155
|
+
* Backoff is tracked per entity and resets once a request completes.
|
|
156
|
+
* When the policy ends, the default (500 ms growing by 1.5x, capped at 10
|
|
157
|
+
* seconds) continues, so restarts never stop; use `disableFatalDefects` to
|
|
158
|
+
* avoid them.
|
|
159
|
+
*/
|
|
147
160
|
readonly defectRetryPolicy?: Schedule.Schedule<any, unknown> | undefined
|
|
148
161
|
readonly spanAttributes?: Record<string, string> | undefined
|
|
149
162
|
}
|
|
@@ -1697,7 +1710,10 @@ const make = Effect.gen(function*() {
|
|
|
1697
1710
|
}
|
|
1698
1711
|
clientRequests.set(id, entry)
|
|
1699
1712
|
respond = makeClientRespond(entry, client.write)
|
|
1700
|
-
|
|
1713
|
+
// A failed send leaves no reply or interrupt to release the entry.
|
|
1714
|
+
// Only drop the local bookkeeping, as the request may have been
|
|
1715
|
+
// persisted.
|
|
1716
|
+
return Effect.tapError(sendOutgoing(message, false), () => Effect.sync(() => clientRequests.delete(id)))
|
|
1701
1717
|
}
|
|
1702
1718
|
case "Ack": {
|
|
1703
1719
|
const requestId = Snowflake.Snowflake(options.message.requestId)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type * as Cause from "../../Cause.ts"
|
|
2
2
|
import * as Effect from "../../Effect.ts"
|
|
3
|
-
import * as Fiber from "../../Fiber.ts"
|
|
4
3
|
import { Abandon } from "../ClusterSchema.ts"
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
)
|
|
5
|
+
// Annotate before opening the interruptible region. An interrupt already
|
|
6
|
+
// pending on an uninterruptible fiber fires as soon as the region opens, and
|
|
7
|
+
// the annotation is merged into that pending cause instead of being lost.
|
|
8
|
+
export const interrupt: Effect.Effect<never> = Effect.withFiber((fiber) => {
|
|
9
|
+
fiber.interruptUnsafe(fiber.id, Abandon.annotation)
|
|
10
|
+
return Effect.interruptible(Effect.never)
|
|
11
|
+
})
|
|
12
12
|
|
|
13
13
|
export const isCause = (cause: Cause.Cause<unknown>): boolean =>
|
|
14
14
|
cause.reasons.some((reason) => reason._tag === "Interrupt" && reason.annotations.has(Abandon.key))
|
|
@@ -116,6 +116,10 @@ export type EntityState = {
|
|
|
116
116
|
/** Set when the request should not outlive its caller. */
|
|
117
117
|
callerScope?: Scope.Scope | undefined
|
|
118
118
|
transaction?: RequestTransaction | undefined
|
|
119
|
+
/** Set when an interrupt arrives while no handlers are ready. */
|
|
120
|
+
interrupted?: boolean | undefined
|
|
121
|
+
/** The handler generation the remembered interrupt was last sent to. */
|
|
122
|
+
interruptSentTo?: EntityState["write"] | undefined
|
|
119
123
|
}>
|
|
120
124
|
lastActiveCheck: number
|
|
121
125
|
write: RpcServer.RpcServer<any>["write"]
|
|
@@ -172,7 +176,7 @@ export const make = Effect.fnUntraced(function*<
|
|
|
172
176
|
const defectRetryPolicy = options.defectRetryPolicy
|
|
173
177
|
? Schedule.concat(options.defectRetryPolicy, defaultRetryPolicy)
|
|
174
178
|
: defaultRetryPolicy
|
|
175
|
-
const
|
|
179
|
+
const newRestartStep = Schedule.toStepWithSleep(defectRetryPolicy)
|
|
176
180
|
const entityRpcs = new Map(entity.protocol.requests)
|
|
177
181
|
|
|
178
182
|
// The series reads the mailbox size on snapshot, so delivery does no extra work.
|
|
@@ -294,13 +298,38 @@ export const make = Effect.fnUntraced(function*<
|
|
|
294
298
|
const retired = Latch.makeUnsafe()
|
|
295
299
|
const isActive = () => !retired.isOpen()
|
|
296
300
|
|
|
301
|
+
// Per-activation restart backoff, reset when a request completes.
|
|
302
|
+
let restartStep: Effect.Success<typeof newRestartStep> | undefined
|
|
303
|
+
const restartDelay = Effect.gen(function*() {
|
|
304
|
+
restartStep ??= yield* newRestartStep
|
|
305
|
+
yield* restartStep(void 0)
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
// An interrupted request is not run again. The server answers the
|
|
309
|
+
// interrupt as it would for a request without a running handler. Each
|
|
310
|
+
// generation receives it at most once, and the flag stays so a later
|
|
311
|
+
// generation still applies it if this one fails first.
|
|
312
|
+
const writeInterrupt = (
|
|
313
|
+
request: {
|
|
314
|
+
readonly message: Message.IncomingRequestLocal<any>
|
|
315
|
+
interruptSentTo?: EntityState["write"] | undefined
|
|
316
|
+
},
|
|
317
|
+
write: EntityState["write"]
|
|
318
|
+
): Effect.Effect<void> => {
|
|
319
|
+
if (request.interruptSentTo === write) return Effect.void
|
|
320
|
+
request.interruptSentTo = write
|
|
321
|
+
return write(0, interruptEnvelope(request))
|
|
322
|
+
}
|
|
323
|
+
|
|
297
324
|
// Replay previously dispatched requests before admitting new work.
|
|
298
325
|
const replay = Effect.fnUntraced(function*(write: EntityState["write"]) {
|
|
299
326
|
if (!isActive()) return
|
|
300
327
|
for (const request of activeRequests.values()) {
|
|
301
328
|
if (!request.delivered) continue
|
|
302
329
|
request.sentExit = false
|
|
303
|
-
yield*
|
|
330
|
+
yield* request.interrupted
|
|
331
|
+
? writeInterrupt(request, write)
|
|
332
|
+
: write(0, requestEnvelope(request), requestWriteOptions(request))
|
|
304
333
|
}
|
|
305
334
|
})
|
|
306
335
|
|
|
@@ -369,8 +398,11 @@ export const make = Effect.fnUntraced(function*<
|
|
|
369
398
|
)
|
|
370
399
|
}
|
|
371
400
|
}
|
|
401
|
+
// A failed save can abort the request transaction, so a retry
|
|
402
|
+
// could store a success outside it. Save once and let the
|
|
403
|
+
// failed transaction replay the request.
|
|
372
404
|
const write = retryRespond(
|
|
373
|
-
4,
|
|
405
|
+
persisted && request.transaction && Exit.isSuccess(response.exit) ? 0 : 4,
|
|
374
406
|
Effect.suspend(() =>
|
|
375
407
|
request.message.respond(
|
|
376
408
|
new Reply.WithExit({
|
|
@@ -402,13 +434,31 @@ export const make = Effect.fnUntraced(function*<
|
|
|
402
434
|
)
|
|
403
435
|
})
|
|
404
436
|
const complete = Effect.sync(() => {
|
|
437
|
+
restartStep = undefined
|
|
405
438
|
if (storageEnabled) {
|
|
406
439
|
processedRequestIds.add(request.message.envelope.requestId)
|
|
407
440
|
}
|
|
408
441
|
removeActiveRequest(Snowflake.Snowflake(response.requestId))
|
|
409
442
|
})
|
|
443
|
+
// Let callers read the saved reply instead of waiting on a
|
|
444
|
+
// handler that will never be resumed.
|
|
445
|
+
const completeFromStorage = Effect.andThen(
|
|
446
|
+
complete,
|
|
447
|
+
options.storage.unregisterReplyHandler(request.message.envelope.requestId)
|
|
448
|
+
)
|
|
410
449
|
const respond = Effect.andThen(save, complete).pipe(
|
|
411
450
|
Effect.catchTag("EntityNotAssignedToRunner", () => abandonFenced),
|
|
451
|
+
// A save can commit and still fail, e.g. when the COMMIT
|
|
452
|
+
// acknowledgement is lost. Volatile requests skip the lookup:
|
|
453
|
+
// their replies are never stored, and a storage read could
|
|
454
|
+
// stall a custom responder's failure.
|
|
455
|
+
Effect.catchTag("PersistenceError", (error) =>
|
|
456
|
+
persisted
|
|
457
|
+
? Effect.flatMap(
|
|
458
|
+
hasStoredExit(request.message.envelope.requestId),
|
|
459
|
+
(committed) => committed ? completeFromStorage : Effect.fail(error)
|
|
460
|
+
)
|
|
461
|
+
: Effect.fail(error)),
|
|
412
462
|
Effect.orDie
|
|
413
463
|
)
|
|
414
464
|
const transaction = request.transaction
|
|
@@ -427,16 +477,10 @@ export const make = Effect.fnUntraced(function*<
|
|
|
427
477
|
// A rejected save failed the transaction, rolling back the
|
|
428
478
|
// handler's writes; the request is left for the owner.
|
|
429
479
|
if (fenced) return abandonFenced
|
|
480
|
+
// The commit can succeed despite the error.
|
|
430
481
|
return Effect.flatMap(
|
|
431
482
|
hasStoredExit(request.message.envelope.requestId),
|
|
432
|
-
(committed) =>
|
|
433
|
-
if (!committed) return restartFrom(outcome.cause)
|
|
434
|
-
// Commit succeeded despite the error; let callers read the saved reply.
|
|
435
|
-
return Effect.andThen(
|
|
436
|
-
complete,
|
|
437
|
-
options.storage.unregisterReplyHandler(request.message.envelope.requestId)
|
|
438
|
-
)
|
|
439
|
-
}
|
|
483
|
+
(committed) => committed ? completeFromStorage : restartFrom(outcome.cause)
|
|
440
484
|
)
|
|
441
485
|
}
|
|
442
486
|
return Effect.orDie(save)
|
|
@@ -513,10 +557,22 @@ export const make = Effect.fnUntraced(function*<
|
|
|
513
557
|
address
|
|
514
558
|
)
|
|
515
559
|
|
|
560
|
+
// Forward interrupts remembered after their request was replayed, which
|
|
561
|
+
// the replacement handlers have not seen yet.
|
|
562
|
+
const forwardInterrupts = Effect.suspend(() => {
|
|
563
|
+
const write = writeRef.getUnsafe()
|
|
564
|
+
if (write === undefined) return Effect.void
|
|
565
|
+
const interrupts: Array<Effect.Effect<void>> = []
|
|
566
|
+
for (const request of activeRequests.values()) {
|
|
567
|
+
if (request.interrupted) interrupts.push(writeInterrupt(request, write))
|
|
568
|
+
}
|
|
569
|
+
return Effect.all(interrupts, { discard: true })
|
|
570
|
+
})
|
|
571
|
+
|
|
516
572
|
function restart(cause: Cause.Cause<unknown>, rebuild: Effect.Effect<void>): Effect.Effect<void> {
|
|
517
573
|
return Effect.logError("Defect in entity, restarting", cause).pipe(
|
|
518
|
-
Effect.andThen(Effect.ignore(
|
|
519
|
-
Effect.flatMap(() => isActive() ? rebuild : endLatch.open),
|
|
574
|
+
Effect.andThen(Effect.ignore(restartDelay)),
|
|
575
|
+
Effect.flatMap(() => isActive() ? Effect.andThen(rebuild, forwardInterrupts) : endLatch.open),
|
|
520
576
|
Effect.annotateLogs({
|
|
521
577
|
module: "EntityManager",
|
|
522
578
|
address,
|
|
@@ -538,6 +594,16 @@ export const make = Effect.fnUntraced(function*<
|
|
|
538
594
|
if (message._tag !== "Request") {
|
|
539
595
|
// Interrupts, acks and EOF reach the handlers even during shutdown.
|
|
540
596
|
const write = writeRef.getUnsafe()
|
|
597
|
+
if (write === undefined && message._tag === "Interrupt") {
|
|
598
|
+
// Waiting could stall the sender indefinitely if every rebuild
|
|
599
|
+
// fails, so remember the interrupt for the next generation.
|
|
600
|
+
// Uninterruptible requests ignore it.
|
|
601
|
+
const request = activeRequests.get(Snowflake.Snowflake(message.requestId))
|
|
602
|
+
if (request && !isUninterruptibleForServer(request.message.annotations)) {
|
|
603
|
+
request.interrupted = true
|
|
604
|
+
}
|
|
605
|
+
return Effect.void
|
|
606
|
+
}
|
|
541
607
|
return write
|
|
542
608
|
? write(clientId, message, writeOptions)
|
|
543
609
|
: Effect.flatMap(writeRef.await, (write) => write(clientId, message, writeOptions))
|
|
@@ -553,7 +619,7 @@ export const make = Effect.fnUntraced(function*<
|
|
|
553
619
|
const request = activeRequests.get(Snowflake.Snowflake(message.id))
|
|
554
620
|
if (!request) return Effect.void
|
|
555
621
|
request.delivered = true
|
|
556
|
-
return write(clientId, message, writeOptions)
|
|
622
|
+
return request.interrupted ? writeInterrupt(request, write) : write(clientId, message, writeOptions)
|
|
557
623
|
})
|
|
558
624
|
},
|
|
559
625
|
activeRequests,
|
|
@@ -977,7 +1043,7 @@ const makeMessageDecode = <Rpcs extends Rpc.Any>(entityRpcs: Map<string, Rpcs>)
|
|
|
977
1043
|
)
|
|
978
1044
|
)
|
|
979
1045
|
}
|
|
980
|
-
return decodeRequest(message, rpc) as Effect.Effect<
|
|
1046
|
+
return decodeRequest(message, rpc) as any as Effect.Effect<
|
|
981
1047
|
{
|
|
982
1048
|
readonly _tag: "IncomingRequest"
|
|
983
1049
|
readonly envelope: Envelope.Request.Any
|
|
@@ -1002,6 +1068,14 @@ const requestEnvelope = (entry: {
|
|
|
1002
1068
|
} as any) as any
|
|
1003
1069
|
})
|
|
1004
1070
|
|
|
1071
|
+
const interruptEnvelope = (entry: {
|
|
1072
|
+
readonly message: Message.IncomingRequestLocal<any>
|
|
1073
|
+
}): Parameters<EntityState["write"]>[1] => ({
|
|
1074
|
+
_tag: "Interrupt",
|
|
1075
|
+
requestId: entry.message.envelope.requestId as any,
|
|
1076
|
+
interruptors: []
|
|
1077
|
+
})
|
|
1078
|
+
|
|
1005
1079
|
const retryRespond = <A, E, R>(times: number, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
|
|
1006
1080
|
times === 0 ?
|
|
1007
1081
|
effect :
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as Context from "../../Context.ts"
|
|
2
|
+
import type * as Effect from "../../Effect.ts"
|
|
3
|
+
import type { MalformedMessage, PersistenceError } from "../ClusterError.ts"
|
|
4
|
+
|
|
5
|
+
export const TransactionNotifications = Context.Reference<
|
|
6
|
+
Array<Effect.Effect<void, PersistenceError | MalformedMessage>> | undefined
|
|
7
|
+
>("effect/cluster/MessageStorage/TransactionNotifications", { defaultValue: () => undefined })
|
package/src/crypto/Aead.ts
CHANGED
|
@@ -37,7 +37,7 @@ import * as Chacha from "./internal/chacha.ts"
|
|
|
37
37
|
import * as KeyModel from "./internal/key.ts"
|
|
38
38
|
import * as internal from "./internal/webCrypto.ts"
|
|
39
39
|
import * as SecureRandom from "./SecureRandom.ts"
|
|
40
|
-
import
|
|
40
|
+
import * as WebCrypto from "./WebCrypto.ts"
|
|
41
41
|
|
|
42
42
|
const TypeId = "~effect/crypto/Aead/Key" as const
|
|
43
43
|
|
|
@@ -374,7 +374,7 @@ export const layerWebCryptoWith = (options: {
|
|
|
374
374
|
Aead,
|
|
375
375
|
Effect.gen(function*() {
|
|
376
376
|
const random = yield* SecureRandom.SecureRandom
|
|
377
|
-
const crypto = yield* WebCrypto
|
|
377
|
+
const crypto = yield* WebCrypto.WebCrypto
|
|
378
378
|
const cryptoKeyFor = KeyModel.makeCache((subtle, bytes) =>
|
|
379
379
|
subtle.importKey("raw", bytes as BufferSource, "AES-GCM", false, ["encrypt", "decrypt"])
|
|
380
380
|
)
|
|
@@ -488,7 +488,7 @@ export const key = <A extends Algorithm>(
|
|
|
488
488
|
*/
|
|
489
489
|
export const fromCryptoKey = <A extends AesGcm>(
|
|
490
490
|
algorithm: A,
|
|
491
|
-
cryptoKey: CryptoKey
|
|
491
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
492
492
|
): Effect.Effect<Key<A>, CryptoError.CryptoError> =>
|
|
493
493
|
algorithm.implementation !== undefined
|
|
494
494
|
? internal.invalidKey("Aead", "fromCryptoKey", `${algorithm.name} keys cannot be CryptoKeys`)
|
package/src/crypto/Cipher.ts
CHANGED
|
@@ -35,7 +35,7 @@ import * as CryptoError from "./CryptoError.ts"
|
|
|
35
35
|
import * as KeyModel from "./internal/key.ts"
|
|
36
36
|
import * as internal from "./internal/webCrypto.ts"
|
|
37
37
|
import * as SecureRandom from "./SecureRandom.ts"
|
|
38
|
-
import
|
|
38
|
+
import * as WebCrypto from "./WebCrypto.ts"
|
|
39
39
|
|
|
40
40
|
const TypeId = "~effect/crypto/Cipher/Key" as const
|
|
41
41
|
|
|
@@ -217,7 +217,7 @@ export const layerWebCrypto: Layer.Layer<Cipher, never, SecureRandom.SecureRando
|
|
|
217
217
|
Cipher,
|
|
218
218
|
Effect.gen(function*() {
|
|
219
219
|
const random = yield* SecureRandom.SecureRandom
|
|
220
|
-
const crypto = yield* WebCrypto
|
|
220
|
+
const crypto = yield* WebCrypto.WebCrypto
|
|
221
221
|
const cryptoKeyFor = KeyModel.makeCache((subtle, bytes, algorithm: Algorithm) =>
|
|
222
222
|
subtle.importKey("raw", bytes as BufferSource, algorithm.mode, false, ["encrypt", "decrypt"])
|
|
223
223
|
)
|
|
@@ -299,7 +299,7 @@ export const key = <A extends Algorithm>(
|
|
|
299
299
|
*/
|
|
300
300
|
export const fromCryptoKey = <A extends Algorithm>(
|
|
301
301
|
algorithm: A,
|
|
302
|
-
cryptoKey: CryptoKey
|
|
302
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
303
303
|
): Effect.Effect<Key<A>, CryptoError.CryptoError> =>
|
|
304
304
|
KeyModel.fromCryptoKey("Cipher", "fromCryptoKey", KeyProto, algorithm, cryptoKey, {
|
|
305
305
|
type: "secret",
|
|
@@ -43,7 +43,7 @@ import * as Asymmetric from "./internal/asymmetric.ts"
|
|
|
43
43
|
import * as KeyModel from "./internal/key.ts"
|
|
44
44
|
import * as internal from "./internal/webCrypto.ts"
|
|
45
45
|
import * as SecureRandom from "./SecureRandom.ts"
|
|
46
|
-
import
|
|
46
|
+
import * as WebCrypto from "./WebCrypto.ts"
|
|
47
47
|
|
|
48
48
|
const PrivateKeyTypeId = "~effect/crypto/KeyAgreement/PrivateKey" as const
|
|
49
49
|
const PublicKeyTypeId = "~effect/crypto/KeyAgreement/PublicKey" as const
|
|
@@ -307,7 +307,7 @@ export const layerWebCrypto: Layer.Layer<KeyAgreement, never, SecureRandom.Secur
|
|
|
307
307
|
KeyAgreement,
|
|
308
308
|
Effect.gen(function*() {
|
|
309
309
|
const random = yield* SecureRandom.SecureRandom
|
|
310
|
-
const crypto = yield* WebCrypto
|
|
310
|
+
const crypto = yield* WebCrypto.WebCrypto
|
|
311
311
|
const caches = Asymmetric.makeCaches(family)
|
|
312
312
|
return KeyAgreement.of({
|
|
313
313
|
generateKeyPair: <A extends Algorithm>(algorithm: A) =>
|
|
@@ -447,7 +447,7 @@ export const publicKey = <A extends Algorithm>(
|
|
|
447
447
|
*/
|
|
448
448
|
export const privateKeyFromCryptoKey = <A extends Algorithm>(
|
|
449
449
|
algorithm: A,
|
|
450
|
-
cryptoKey: CryptoKey
|
|
450
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
451
451
|
): Effect.Effect<PrivateKey<A>, CryptoError.CryptoError> =>
|
|
452
452
|
Asymmetric.fromCryptoKey(family, "privateKeyFromCryptoKey", algorithm, "private", cryptoKey)
|
|
453
453
|
|
|
@@ -467,7 +467,7 @@ export const privateKeyFromCryptoKey = <A extends Algorithm>(
|
|
|
467
467
|
*/
|
|
468
468
|
export const publicKeyFromCryptoKey = <A extends Algorithm>(
|
|
469
469
|
algorithm: A,
|
|
470
|
-
cryptoKey: CryptoKey
|
|
470
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
471
471
|
): Effect.Effect<PublicKey<A>, CryptoError.CryptoError> =>
|
|
472
472
|
Asymmetric.fromCryptoKey(family, "publicKeyFromCryptoKey", algorithm, "public", cryptoKey)
|
|
473
473
|
|
package/src/crypto/KeyFormat.ts
CHANGED
|
@@ -76,6 +76,35 @@ export type Role = "public" | "private" | "secret"
|
|
|
76
76
|
*/
|
|
77
77
|
export type Direction = "decode" | "encode"
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* A JSON Web Key (RFC 7517) with the native Web Crypto field types and
|
|
81
|
+
* mutability, usable without DOM declarations.
|
|
82
|
+
*
|
|
83
|
+
* @stability unstable
|
|
84
|
+
* @category models
|
|
85
|
+
* @since 4.1.1
|
|
86
|
+
*/
|
|
87
|
+
export interface JsonWebKey {
|
|
88
|
+
alg?: string
|
|
89
|
+
crv?: string
|
|
90
|
+
d?: string
|
|
91
|
+
dp?: string
|
|
92
|
+
dq?: string
|
|
93
|
+
e?: string
|
|
94
|
+
ext?: boolean
|
|
95
|
+
k?: string
|
|
96
|
+
key_ops?: Array<string>
|
|
97
|
+
kty?: string
|
|
98
|
+
n?: string
|
|
99
|
+
oth?: Array<{ d?: string; r?: string; t?: string }>
|
|
100
|
+
p?: string
|
|
101
|
+
q?: string
|
|
102
|
+
qi?: string
|
|
103
|
+
use?: string
|
|
104
|
+
x?: string
|
|
105
|
+
y?: string
|
|
106
|
+
}
|
|
107
|
+
|
|
79
108
|
/**
|
|
80
109
|
* A key format, such as {@link spki} or `pem(pkcs8)`.
|
|
81
110
|
*
|
|
@@ -83,7 +112,7 @@ export type Direction = "decode" | "encode"
|
|
|
83
112
|
*
|
|
84
113
|
* `~tags` exists only in the types. It records the roles the format holds,
|
|
85
114
|
* whether it can be read and written, and the type of its data: `Uint8Array`
|
|
86
|
-
* for DER, `string` for PEM, and
|
|
115
|
+
* for DER, `string` for PEM, and {@link JsonWebKey} for JWK.
|
|
87
116
|
*
|
|
88
117
|
* @stability unstable
|
|
89
118
|
* @category models
|
package/src/crypto/KeyWrap.ts
CHANGED
|
@@ -44,7 +44,7 @@ import * as internal from "./internal/webCrypto.ts"
|
|
|
44
44
|
import type * as KeyFormat from "./KeyFormat.ts"
|
|
45
45
|
import * as Mac from "./Mac.ts"
|
|
46
46
|
import * as SecureRandom from "./SecureRandom.ts"
|
|
47
|
-
import
|
|
47
|
+
import * as WebCrypto from "./WebCrypto.ts"
|
|
48
48
|
|
|
49
49
|
const KeyTypeId = "~effect/crypto/KeyWrap/Key" as const
|
|
50
50
|
const PrivateKeyTypeId = "~effect/crypto/KeyWrap/PrivateKey" as const
|
|
@@ -417,7 +417,7 @@ export const layerWebCrypto: Layer.Layer<KeyWrap, never, SecureRandom.SecureRand
|
|
|
417
417
|
KeyWrap,
|
|
418
418
|
Effect.gen(function*() {
|
|
419
419
|
const random = yield* SecureRandom.SecureRandom
|
|
420
|
-
const crypto = yield* WebCrypto
|
|
420
|
+
const crypto = yield* WebCrypto.WebCrypto
|
|
421
421
|
const kwCryptoKey = KeyModel.makeCache((subtle, bytes) =>
|
|
422
422
|
subtle.importKey("raw", bytes as BufferSource, "AES-KW", false, ["wrapKey", "unwrapKey"])
|
|
423
423
|
)
|
|
@@ -553,7 +553,7 @@ export const key = <A extends AesKw>(
|
|
|
553
553
|
*/
|
|
554
554
|
export const fromCryptoKey = <A extends AesKw>(
|
|
555
555
|
algorithm: A,
|
|
556
|
-
cryptoKey: CryptoKey
|
|
556
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
557
557
|
): Effect.Effect<Key<A>, CryptoError.CryptoError> =>
|
|
558
558
|
KeyModel.fromCryptoKey("KeyWrap", "fromCryptoKey", KeyProto, algorithm, cryptoKey, {
|
|
559
559
|
type: "secret",
|
|
@@ -570,7 +570,7 @@ const rsaFromCryptoKey = <K>(
|
|
|
570
570
|
proto: object,
|
|
571
571
|
algorithm: RsaOaep,
|
|
572
572
|
role: Asymmetric.Role,
|
|
573
|
-
cryptoKey: CryptoKey
|
|
573
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
574
574
|
): Effect.Effect<K, CryptoError.CryptoError> =>
|
|
575
575
|
KeyModel.fromCryptoKey("KeyWrap", method, proto, algorithm, cryptoKey, {
|
|
576
576
|
type: role,
|
|
@@ -597,7 +597,7 @@ const rsaFromCryptoKey = <K>(
|
|
|
597
597
|
*/
|
|
598
598
|
export const privateKeyFromCryptoKey = <A extends RsaOaep>(
|
|
599
599
|
algorithm: A,
|
|
600
|
-
cryptoKey: CryptoKey
|
|
600
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
601
601
|
): Effect.Effect<PrivateKey<A>, CryptoError.CryptoError> =>
|
|
602
602
|
rsaFromCryptoKey("privateKeyFromCryptoKey", PrivateKeyProto, algorithm, "private", cryptoKey)
|
|
603
603
|
|
|
@@ -617,7 +617,7 @@ export const privateKeyFromCryptoKey = <A extends RsaOaep>(
|
|
|
617
617
|
*/
|
|
618
618
|
export const publicKeyFromCryptoKey = <A extends RsaOaep>(
|
|
619
619
|
algorithm: A,
|
|
620
|
-
cryptoKey: CryptoKey
|
|
620
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
621
621
|
): Effect.Effect<PublicKey<A>, CryptoError.CryptoError> =>
|
|
622
622
|
rsaFromCryptoKey("publicKeyFromCryptoKey", PublicKeyProto, algorithm, "public", cryptoKey)
|
|
623
623
|
|
package/src/crypto/Mac.ts
CHANGED
|
@@ -23,7 +23,7 @@ import * as Digest from "./Digest.ts"
|
|
|
23
23
|
import * as KeyModel from "./internal/key.ts"
|
|
24
24
|
import * as internal from "./internal/webCrypto.ts"
|
|
25
25
|
import * as SecureRandom from "./SecureRandom.ts"
|
|
26
|
-
import
|
|
26
|
+
import * as WebCrypto from "./WebCrypto.ts"
|
|
27
27
|
|
|
28
28
|
const TypeId = "~effect/crypto/Mac/Key" as const
|
|
29
29
|
|
|
@@ -215,7 +215,7 @@ export const layerWebCryptoWith = (options: {
|
|
|
215
215
|
Mac,
|
|
216
216
|
Effect.gen(function*() {
|
|
217
217
|
const random = yield* SecureRandom.SecureRandom
|
|
218
|
-
const crypto = yield* WebCrypto
|
|
218
|
+
const crypto = yield* WebCrypto.WebCrypto
|
|
219
219
|
const cryptoKeyFor = KeyModel.makeCache((subtle, bytes, algorithm: Algorithm) =>
|
|
220
220
|
subtle.importKey("raw", bytes as BufferSource, importParams(algorithm), false, ["sign", "verify"])
|
|
221
221
|
)
|
|
@@ -321,7 +321,7 @@ export const key = <A extends Algorithm>(
|
|
|
321
321
|
*/
|
|
322
322
|
export const fromCryptoKey = <A extends Algorithm>(
|
|
323
323
|
algorithm: A,
|
|
324
|
-
cryptoKey: CryptoKey
|
|
324
|
+
cryptoKey: WebCrypto.CryptoKey
|
|
325
325
|
): Effect.Effect<Key<A>, CryptoError.CryptoError> =>
|
|
326
326
|
KeyModel.fromCryptoKey("Mac", "fromCryptoKey", KeyProto, algorithm, cryptoKey, {
|
|
327
327
|
type: "secret",
|