effect 4.0.6 → 4.1.0
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 +1 -1
- package/dist/Arbitrary.d.ts +10 -2
- package/dist/Arbitrary.d.ts.map +1 -1
- package/dist/Arbitrary.js +2 -1
- package/dist/Arbitrary.js.map +1 -1
- package/dist/BigDecimal.d.ts.map +1 -1
- package/dist/BigDecimal.js +3 -0
- package/dist/BigDecimal.js.map +1 -1
- package/dist/Channel.d.ts +12 -6
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +30 -9
- package/dist/Channel.js.map +1 -1
- package/dist/Config.d.ts +7 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/Context.d.ts +18 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +27 -8
- package/dist/Context.js.map +1 -1
- package/dist/Cron.d.ts +81 -11
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +101 -26
- package/dist/Cron.js.map +1 -1
- package/dist/Data.d.ts +54 -235
- package/dist/Data.d.ts.map +1 -1
- package/dist/Data.js.map +1 -1
- package/dist/Duration.d.ts +78 -0
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +123 -0
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +165 -8
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +12 -2
- package/dist/Effect.js.map +1 -1
- package/dist/Equal.d.ts.map +1 -1
- package/dist/Equal.js +8 -1
- package/dist/Equal.js.map +1 -1
- package/dist/Exit.d.ts +3 -3
- package/dist/Exit.d.ts.map +1 -1
- package/dist/Exit.js.map +1 -1
- package/dist/FileSystem.d.ts +59 -4
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +9 -2
- package/dist/FileSystem.js.map +1 -1
- package/dist/Formatter.d.ts.map +1 -1
- package/dist/Formatter.js +27 -13
- package/dist/Formatter.js.map +1 -1
- package/dist/Glob.d.ts +165 -0
- package/dist/Glob.d.ts.map +1 -0
- package/dist/Glob.js +127 -0
- package/dist/Glob.js.map +1 -0
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +4 -1
- package/dist/Hash.js.map +1 -1
- package/dist/JsonPatch.js +4 -0
- package/dist/JsonPatch.js.map +1 -1
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +13 -40
- package/dist/JsonSchema.js.map +1 -1
- package/dist/Match.d.ts +86 -0
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +72 -0
- package/dist/Match.js.map +1 -1
- package/dist/Metric.d.ts +3 -3
- package/dist/MutableList.d.ts +5 -2
- package/dist/MutableList.d.ts.map +1 -1
- package/dist/MutableList.js +7 -5
- package/dist/MutableList.js.map +1 -1
- package/dist/MutableRef.d.ts.map +1 -1
- package/dist/MutableRef.js +7 -0
- package/dist/MutableRef.js.map +1 -1
- package/dist/PartitionedSemaphore.d.ts +2 -1
- package/dist/PartitionedSemaphore.d.ts.map +1 -1
- package/dist/PartitionedSemaphore.js +22 -12
- package/dist/PartitionedSemaphore.js.map +1 -1
- package/dist/Pool.d.ts +51 -0
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +136 -36
- package/dist/Pool.js.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/PubSub.js +5 -6
- package/dist/PubSub.js.map +1 -1
- package/dist/Random.d.ts.map +1 -1
- package/dist/Random.js +3 -3
- package/dist/Random.js.map +1 -1
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/RcMap.js +8 -2
- package/dist/RcMap.js.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +8 -0
- package/dist/Ref.js.map +1 -1
- package/dist/Schedule.d.ts +18 -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 +690 -49
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +687 -28
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +4 -2
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +14 -17
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaGetter.d.ts +6 -1
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +22 -11
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +48 -22
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +33 -10
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +39 -13
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +12 -4
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +15 -5
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedCache.js +5 -7
- package/dist/ScopedCache.js.map +1 -1
- package/dist/Semaphore.d.ts +130 -0
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Semaphore.js +94 -35
- package/dist/Semaphore.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +7 -2
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts +13 -4
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +31 -10
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +3 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +3 -0
- package/dist/String.js.map +1 -1
- package/dist/Terminal.d.ts +18 -1
- package/dist/Terminal.d.ts.map +1 -1
- package/dist/Terminal.js +1 -1
- package/dist/Terminal.js.map +1 -1
- package/dist/Tracer.d.ts +11 -1
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Tracer.js +6 -1
- package/dist/Tracer.js.map +1 -1
- package/dist/ai/AiError.d.ts +43 -116
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +53 -72
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Decision.d.ts +196 -15
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +130 -0
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.d.ts +54 -13
- package/dist/ai/DecisionModel.d.ts.map +1 -1
- package/dist/ai/DecisionModel.js +123 -12
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +9 -0
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpSchema.d.ts +110 -110
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpServer.d.ts +630 -29
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +583 -131
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/McpTest.d.ts +130 -0
- package/dist/ai/McpTest.d.ts.map +1 -0
- package/dist/ai/McpTest.js +237 -0
- package/dist/ai/McpTest.js.map +1 -0
- package/dist/ai/Prompt.d.ts +52 -0
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +38 -0
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +17 -28
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +5 -10
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +43 -1
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js +5 -2
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/Toolkit.d.ts.map +1 -1
- package/dist/ai/Toolkit.js +8 -1
- package/dist/ai/Toolkit.js.map +1 -1
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +5 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/internal/mcpCore.js +17 -12
- package/dist/ai/internal/mcpCore.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +18 -10
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js +13 -0
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +5 -3
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/ai/internal/mcpStatefulRuntime.js +6 -1
- package/dist/ai/internal/mcpStatefulRuntime.js.map +1 -1
- package/dist/cli/Argument.d.ts +21 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +7 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliError.d.ts +78 -0
- package/dist/cli/CliError.d.ts.map +1 -1
- package/dist/cli/CliError.js +65 -3
- package/dist/cli/CliError.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +220 -7
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +156 -43
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +47 -16
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +67 -29
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +58 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js +49 -9
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +122 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +42 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +15 -7
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/HelpDoc.d.ts +15 -1
- package/dist/cli/HelpDoc.d.ts.map +1 -1
- package/dist/cli/Param.d.ts +15 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +23 -2
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/Primitive.d.ts +14 -0
- package/dist/cli/Primitive.d.ts.map +1 -1
- package/dist/cli/Primitive.js +15 -1
- package/dist/cli/Primitive.js.map +1 -1
- package/dist/cli/Prompt.d.ts +1 -0
- package/dist/cli/Prompt.d.ts.map +1 -1
- package/dist/cli/Prompt.js +1 -0
- package/dist/cli/Prompt.js.map +1 -1
- package/dist/cli/TerminalCapabilities.d.ts +3 -2
- package/dist/cli/TerminalCapabilities.d.ts.map +1 -1
- package/dist/cli/TerminalCapabilities.js +3 -1
- package/dist/cli/TerminalCapabilities.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +73 -27
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/help.d.ts.map +1 -1
- package/dist/cli/internal/help.js +17 -10
- package/dist/cli/internal/help.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +45 -10
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +23 -45
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +6 -7
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +151 -49
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +76 -0
- package/dist/cluster/ShardingConfig.d.ts.map +1 -1
- package/dist/cluster/ShardingConfig.js +4 -0
- package/dist/cluster/ShardingConfig.js.map +1 -1
- package/dist/cluster/SingleRunner.d.ts +3 -3
- package/dist/cluster/SingleRunner.d.ts.map +1 -1
- package/dist/cluster/SingleRunner.js +1 -1
- package/dist/cluster/Snowflake.d.ts.map +1 -1
- package/dist/cluster/Snowflake.js +3 -7
- package/dist/cluster/Snowflake.js.map +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts +37 -6
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +34 -7
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +109 -46
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +54 -20
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/crypto/Aead.d.ts +322 -0
- package/dist/crypto/Aead.d.ts.map +1 -0
- package/dist/crypto/Aead.js +331 -0
- package/dist/crypto/Aead.js.map +1 -0
- package/dist/crypto/Cipher.d.ts +235 -0
- package/dist/crypto/Cipher.d.ts.map +1 -0
- package/dist/crypto/Cipher.js +233 -0
- package/dist/crypto/Cipher.js.map +1 -0
- package/dist/crypto/CryptoError.d.ts +212 -0
- package/dist/crypto/CryptoError.d.ts.map +1 -0
- package/dist/crypto/CryptoError.js +202 -0
- package/dist/crypto/CryptoError.js.map +1 -0
- package/dist/crypto/Digest.d.ts +143 -0
- package/dist/crypto/Digest.d.ts.map +1 -0
- package/dist/crypto/Digest.js +146 -0
- package/dist/crypto/Digest.js.map +1 -0
- package/dist/crypto/Kdf.d.ts +220 -0
- package/dist/crypto/Kdf.d.ts.map +1 -0
- package/dist/crypto/Kdf.js +212 -0
- package/dist/crypto/Kdf.js.map +1 -0
- package/dist/crypto/KeyAgreement.d.ts +323 -0
- package/dist/crypto/KeyAgreement.d.ts.map +1 -0
- package/dist/crypto/KeyAgreement.js +303 -0
- package/dist/crypto/KeyAgreement.js.map +1 -0
- package/dist/crypto/KeyFormat.d.ts +309 -0
- package/dist/crypto/KeyFormat.d.ts.map +1 -0
- package/dist/crypto/KeyFormat.js +556 -0
- package/dist/crypto/KeyFormat.js.map +1 -0
- package/dist/crypto/KeyWrap.d.ts +389 -0
- package/dist/crypto/KeyWrap.d.ts.map +1 -0
- package/dist/crypto/KeyWrap.js +381 -0
- package/dist/crypto/KeyWrap.js.map +1 -0
- package/dist/crypto/Mac.d.ts +277 -0
- package/dist/crypto/Mac.d.ts.map +1 -0
- package/dist/crypto/Mac.js +288 -0
- package/dist/crypto/Mac.js.map +1 -0
- package/dist/crypto/SecureRandom.d.ts +340 -0
- package/dist/crypto/SecureRandom.d.ts.map +1 -0
- package/dist/crypto/SecureRandom.js +257 -0
- package/dist/crypto/SecureRandom.js.map +1 -0
- package/dist/crypto/Signature.d.ts +448 -0
- package/dist/crypto/Signature.d.ts.map +1 -0
- package/dist/crypto/Signature.js +484 -0
- package/dist/crypto/Signature.js.map +1 -0
- package/dist/crypto/WebCrypto.d.ts +61 -0
- package/dist/crypto/WebCrypto.d.ts.map +1 -0
- package/dist/crypto/WebCrypto.js +63 -0
- package/dist/crypto/WebCrypto.js.map +1 -0
- package/dist/crypto/index.d.ts +65 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +66 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/internal/asymmetric.d.ts +2 -0
- package/dist/crypto/internal/asymmetric.d.ts.map +1 -0
- package/dist/crypto/internal/asymmetric.js +210 -0
- package/dist/crypto/internal/asymmetric.js.map +1 -0
- package/dist/crypto/internal/chacha.d.ts +46 -0
- package/dist/crypto/internal/chacha.d.ts.map +1 -0
- package/dist/crypto/internal/chacha.js +885 -0
- package/dist/crypto/internal/chacha.js.map +1 -0
- package/dist/crypto/internal/der.d.ts +6 -0
- package/dist/crypto/internal/der.d.ts.map +1 -0
- package/dist/crypto/internal/der.js +86 -0
- package/dist/crypto/internal/der.js.map +1 -0
- package/dist/crypto/internal/digest.d.ts +2 -0
- package/dist/crypto/internal/digest.d.ts.map +1 -0
- package/dist/crypto/internal/digest.js +15 -0
- package/dist/crypto/internal/digest.js.map +1 -0
- package/dist/crypto/internal/key.d.ts +2 -0
- package/dist/crypto/internal/key.d.ts.map +1 -0
- package/dist/crypto/internal/key.js +170 -0
- package/dist/crypto/internal/key.js.map +1 -0
- package/dist/crypto/internal/md5.d.ts +39 -0
- package/dist/crypto/internal/md5.d.ts.map +1 -0
- package/dist/crypto/internal/md5.js +179 -0
- package/dist/crypto/internal/md5.js.map +1 -0
- package/dist/crypto/internal/webCrypto.d.ts +2 -0
- package/dist/crypto/internal/webCrypto.d.ts.map +1 -0
- package/dist/crypto/internal/webCrypto.js +111 -0
- package/dist/crypto/internal/webCrypto.js.map +1 -0
- package/dist/devtools/DevToolsClient.d.ts.map +1 -1
- package/dist/devtools/DevToolsClient.js +2 -0
- package/dist/devtools/DevToolsClient.js.map +1 -1
- package/dist/encoding/Base64.js +36 -0
- package/dist/encoding/Base64.js.map +1 -1
- package/dist/encoding/Base64Url.d.ts.map +1 -1
- package/dist/encoding/Base64Url.js +3 -2
- package/dist/encoding/Base64Url.js.map +1 -1
- package/dist/encoding/Csv.d.ts +608 -0
- package/dist/encoding/Csv.d.ts.map +1 -0
- package/dist/encoding/Csv.js +718 -0
- package/dist/encoding/Csv.js.map +1 -0
- package/dist/encoding/Hex.d.ts +3 -2
- package/dist/encoding/Hex.d.ts.map +1 -1
- package/dist/encoding/Hex.js +3 -2
- package/dist/encoding/Hex.js.map +1 -1
- package/dist/encoding/SchemaBinary.d.ts.map +1 -1
- package/dist/encoding/SchemaBinary.js +42 -4
- package/dist/encoding/SchemaBinary.js.map +1 -1
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +3 -3
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/encoding/Toml.d.ts +17 -3
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +124 -31
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/encoding/Yaml.d.ts +8 -1
- package/dist/encoding/Yaml.d.ts.map +1 -1
- package/dist/encoding/Yaml.js +54 -18
- package/dist/encoding/Yaml.js.map +1 -1
- package/dist/encoding/index.d.ts +5 -0
- package/dist/encoding/index.d.ts.map +1 -1
- package/dist/encoding/index.js +5 -0
- package/dist/encoding/index.js.map +1 -1
- package/dist/eventlog/EventJournal.d.ts.map +1 -1
- package/dist/eventlog/EventJournal.js +6 -3
- package/dist/eventlog/EventJournal.js.map +1 -1
- package/dist/eventlog/EventLog.d.ts +119 -4
- package/dist/eventlog/EventLog.d.ts.map +1 -1
- package/dist/eventlog/EventLog.js +200 -12
- package/dist/eventlog/EventLog.js.map +1 -1
- package/dist/eventlog/EventLogEncryption.d.ts +41 -4
- package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
- package/dist/eventlog/EventLogEncryption.js +83 -64
- package/dist/eventlog/EventLogEncryption.js.map +1 -1
- package/dist/eventlog/EventLogMessage.d.ts +279 -0
- package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
- package/dist/eventlog/EventLogMessage.js +217 -1
- package/dist/eventlog/EventLogMessage.js.map +1 -1
- package/dist/eventlog/EventLogRemote.d.ts +200 -28
- package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
- package/dist/eventlog/EventLogRemote.js +186 -16
- package/dist/eventlog/EventLogRemote.js.map +1 -1
- package/dist/eventlog/EventLogServer.d.ts +3 -0
- package/dist/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/eventlog/EventLogServer.js +18 -10
- package/dist/eventlog/EventLogServer.js.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.d.ts +326 -5
- package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.js +769 -14
- package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.d.ts +5 -3
- package/dist/eventlog/EventLogSessionAuth.d.ts.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.js +41 -64
- package/dist/eventlog/EventLogSessionAuth.js.map +1 -1
- package/dist/eventlog/EventRow.d.ts +4 -0
- package/dist/eventlog/EventRow.d.ts.map +1 -1
- package/dist/eventlog/EventRow.js +12 -2
- package/dist/eventlog/EventRow.js.map +1 -1
- package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +47 -27
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +21 -5
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.js +1048 -113
- package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.js +2 -2
- package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/internal/batches.d.ts +12 -0
- package/dist/eventlog/internal/batches.d.ts.map +1 -0
- package/dist/eventlog/internal/batches.js +26 -0
- package/dist/eventlog/internal/batches.js.map +1 -0
- package/dist/eventlog/internal/compaction.d.ts +38 -0
- package/dist/eventlog/internal/compaction.d.ts.map +1 -0
- package/dist/eventlog/internal/compaction.js +33 -0
- package/dist/eventlog/internal/compaction.js.map +1 -0
- package/dist/eventlog/internal/conflicts.d.ts +0 -1
- package/dist/eventlog/internal/conflicts.d.ts.map +1 -1
- package/dist/eventlog/internal/conflicts.js +0 -3
- package/dist/eventlog/internal/conflicts.js.map +1 -1
- package/dist/eventlog/internal/identityRootSecretDerivation.js +66 -67
- package/dist/eventlog/internal/identityRootSecretDerivation.js.map +1 -1
- package/dist/eventlog/internal/remoteCompaction.d.ts +31 -0
- package/dist/eventlog/internal/remoteCompaction.d.ts.map +1 -0
- package/dist/eventlog/internal/remoteCompaction.js +76 -0
- package/dist/eventlog/internal/remoteCompaction.js.map +1 -0
- package/dist/http/Cookies.d.ts +172 -0
- package/dist/http/Cookies.d.ts.map +1 -1
- package/dist/http/Cookies.js +153 -10
- package/dist/http/Cookies.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +26 -2
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +78 -15
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/HttpClient.d.ts +502 -8
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +296 -12
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts +8 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +37 -1
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +9 -5
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +3 -4
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/http/HttpClientResponse.js +3 -2
- package/dist/http/HttpClientResponse.js.map +1 -1
- package/dist/http/HttpMethod.d.ts +7 -1
- package/dist/http/HttpMethod.d.ts.map +1 -1
- package/dist/http/HttpMethod.js +3 -8
- package/dist/http/HttpMethod.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +1 -1
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +14 -16
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +2 -1
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.js +2 -2
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +11 -3
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +77 -25
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +3 -2
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +48 -21
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/HttpTraceContext.d.ts +2 -1
- package/dist/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/http/HttpTraceContext.js +7 -5
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.js +3 -3
- package/dist/http/ProblemDetails.d.ts +96 -0
- package/dist/http/ProblemDetails.d.ts.map +1 -0
- package/dist/http/ProblemDetails.js +98 -0
- package/dist/http/ProblemDetails.js.map +1 -0
- package/dist/http/UrlParams.d.ts +3 -1
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +4 -2
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/index.d.ts +5 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +5 -0
- package/dist/http/index.js.map +1 -1
- package/dist/http/internal/compression.js +4 -5
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/decompression.js +6 -2
- package/dist/http/internal/decompression.js.map +1 -1
- package/dist/http/internal/httpBody.js +8 -1
- package/dist/http/internal/httpBody.js.map +1 -1
- package/dist/http/internal/urlParams.js +33 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http-api/HttpApi.d.ts +3 -6
- package/dist/http-api/HttpApi.d.ts.map +1 -1
- package/dist/http-api/HttpApi.js +3 -6
- package/dist/http-api/HttpApi.js.map +1 -1
- package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
- package/dist/http-api/HttpApiBuilder.js +43 -13
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +140 -7
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +193 -44
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts +24 -7
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +123 -32
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiError.d.ts +185 -13
- package/dist/http-api/HttpApiError.d.ts.map +1 -1
- package/dist/http-api/HttpApiError.js +128 -0
- package/dist/http-api/HttpApiError.js.map +1 -1
- package/dist/http-api/HttpApiMiddleware.d.ts +64 -17
- package/dist/http-api/HttpApiMiddleware.d.ts.map +1 -1
- package/dist/http-api/HttpApiMiddleware.js +85 -1
- package/dist/http-api/HttpApiMiddleware.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +142 -33
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +123 -59
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/http-api/HttpApiTest.d.ts.map +1 -1
- package/dist/http-api/HttpApiTest.js +3 -2
- package/dist/http-api/HttpApiTest.js.map +1 -1
- package/dist/http-api/OpenApi.d.ts.map +1 -1
- package/dist/http-api/OpenApi.js +25 -16
- package/dist/http-api/OpenApi.js.map +1 -1
- package/dist/http-api/internal/toCodecHttpProperties.d.ts +2 -0
- package/dist/http-api/internal/toCodecHttpProperties.d.ts.map +1 -0
- package/dist/http-api/internal/toCodecHttpProperties.js +38 -0
- package/dist/http-api/internal/toCodecHttpProperties.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/internal/arbitrary/runner.d.ts.map +1 -1
- package/dist/internal/arbitrary/runner.js +120 -44
- package/dist/internal/arbitrary/runner.js.map +1 -1
- package/dist/internal/core.js +2 -0
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/effect.js +46 -27
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/equal.js +14 -0
- package/dist/internal/equal.js.map +1 -1
- package/dist/internal/glob.d.ts +2 -0
- package/dist/internal/glob.d.ts.map +1 -0
- package/dist/internal/glob.js +630 -0
- package/dist/internal/glob.js.map +1 -0
- package/dist/internal/jsonSchema.d.ts +2 -0
- package/dist/internal/jsonSchema.d.ts.map +1 -0
- package/dist/internal/jsonSchema.js +28 -0
- package/dist/internal/jsonSchema.js.map +1 -0
- package/dist/internal/matcher.js +11 -1
- package/dist/internal/matcher.js.map +1 -1
- package/dist/internal/persistence.js +9 -0
- package/dist/internal/persistence.js.map +1 -1
- package/dist/internal/rcRef.js +4 -1
- package/dist/internal/rcRef.js.map +1 -1
- package/dist/internal/schema/compilerRegistry.js +4 -1
- package/dist/internal/schema/compilerRegistry.js.map +1 -1
- package/dist/internal/schema/content.d.ts +2 -0
- package/dist/internal/schema/content.d.ts.map +1 -0
- package/dist/internal/schema/content.js +13 -0
- package/dist/internal/schema/content.js.map +1 -0
- package/dist/internal/schema/fromJsonSchemaDocument.js +173 -185
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/fromRepresentation.js +2 -1
- package/dist/internal/schema/fromRepresentation.js.map +1 -1
- package/dist/internal/schema/standardSchema.js +8 -2
- package/dist/internal/schema/standardSchema.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +9 -6
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +21 -24
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +205 -140
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/toRepresentation.js +107 -129
- package/dist/internal/schema/toRepresentation.js.map +1 -1
- package/dist/internal/sql.d.ts +2 -0
- package/dist/internal/sql.d.ts.map +1 -0
- package/dist/internal/sql.js +13 -0
- package/dist/internal/sql.js.map +1 -0
- package/dist/internal/trie.js +42 -13
- package/dist/internal/trie.js.map +1 -1
- package/dist/internal/ulid.js +41 -0
- package/dist/internal/ulid.js.map +1 -1
- package/dist/internal/uuid.js +52 -8
- package/dist/internal/uuid.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/observability/Otlp.d.ts +15 -4
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +10 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpProxy.d.ts +154 -0
- package/dist/observability/OtlpProxy.d.ts.map +1 -0
- package/dist/observability/OtlpProxy.js +235 -0
- package/dist/observability/OtlpProxy.js.map +1 -0
- package/dist/observability/OtlpResource.d.ts +7 -0
- package/dist/observability/OtlpResource.d.ts.map +1 -1
- package/dist/observability/OtlpResource.js +11 -1
- package/dist/observability/OtlpResource.js.map +1 -1
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +4 -0
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/observability/index.d.ts +5 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +5 -0
- package/dist/observability/index.js.map +1 -1
- package/dist/persistence/CircuitBreaker.d.ts +897 -0
- package/dist/persistence/CircuitBreaker.d.ts.map +1 -0
- package/dist/persistence/CircuitBreaker.js +1165 -0
- package/dist/persistence/CircuitBreaker.js.map +1 -0
- package/dist/persistence/KeyValueStore.d.ts +47 -2
- package/dist/persistence/KeyValueStore.d.ts.map +1 -1
- package/dist/persistence/KeyValueStore.js +129 -18
- package/dist/persistence/KeyValueStore.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +9 -0
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +94 -52
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/persistence/Persistence.d.ts +10 -4
- package/dist/persistence/Persistence.d.ts.map +1 -1
- package/dist/persistence/Persistence.js +18 -11
- package/dist/persistence/Persistence.js.map +1 -1
- package/dist/persistence/Redis.d.ts +78 -2
- package/dist/persistence/Redis.d.ts.map +1 -1
- package/dist/persistence/Redis.js +62 -7
- package/dist/persistence/Redis.js.map +1 -1
- package/dist/persistence/index.d.ts +5 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +5 -0
- package/dist/persistence/index.js.map +1 -1
- package/dist/process/ChildProcess.d.ts +237 -71
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js +56 -158
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/process/ChildProcessSpawner.d.ts +35 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/process/ChildProcessSpawner.js +5 -2
- package/dist/process/ChildProcessSpawner.js.map +1 -1
- package/dist/process/CommandLine.d.ts +294 -0
- package/dist/process/CommandLine.d.ts.map +1 -0
- package/dist/process/CommandLine.js +481 -0
- package/dist/process/CommandLine.js.map +1 -0
- package/dist/process/index.d.ts +5 -0
- package/dist/process/index.d.ts.map +1 -1
- package/dist/process/index.js +5 -0
- package/dist/process/index.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +1 -1
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/Atom.d.ts +2 -1
- package/dist/reactivity/Atom.d.ts.map +1 -1
- package/dist/reactivity/Atom.js +3 -4
- package/dist/reactivity/Atom.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +16 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +59 -24
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcMessage.d.ts +10 -1
- package/dist/rpc/RpcMessage.d.ts.map +1 -1
- package/dist/rpc/RpcMessage.js +1 -0
- package/dist/rpc/RpcMessage.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts +14 -0
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +26 -8
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts +31 -0
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +139 -56
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/rpc/RpcTest.d.ts +1 -0
- package/dist/rpc/RpcTest.d.ts.map +1 -1
- package/dist/rpc/RpcTest.js +1 -0
- package/dist/rpc/RpcTest.js.map +1 -1
- package/dist/schema/Model.d.ts +14 -0
- package/dist/schema/Model.d.ts.map +1 -1
- package/dist/schema/Model.js +18 -3
- package/dist/schema/Model.js.map +1 -1
- package/dist/sql/Migrator.d.ts +2 -20
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +13 -55
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/MigratorFileSystem.d.ts +21 -0
- package/dist/sql/MigratorFileSystem.d.ts.map +1 -0
- package/dist/sql/MigratorFileSystem.js +57 -0
- package/dist/sql/MigratorFileSystem.js.map +1 -0
- package/dist/sql/SqlClient.d.ts +9 -4
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +13 -10
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/SqlResolver.d.ts +4 -0
- package/dist/sql/SqlResolver.d.ts.map +1 -1
- package/dist/sql/SqlResolver.js +18 -4
- package/dist/sql/SqlResolver.js.map +1 -1
- package/dist/sql/Statement.d.ts +27 -6
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +21 -15
- package/dist/sql/Statement.js.map +1 -1
- package/dist/sql/index.js +1 -1
- package/dist/testing/index.d.ts +0 -5
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +0 -5
- package/dist/testing/index.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +21 -2
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/internal/crypto.js +9 -8
- package/dist/workflow/internal/crypto.js.map +1 -1
- package/package.json +3 -1
- package/src/Arbitrary.ts +10 -2
- package/src/BigDecimal.ts +3 -0
- package/src/Channel.ts +64 -29
- package/src/Config.ts +7 -1
- package/src/Context.ts +34 -10
- package/src/Cron.ts +178 -29
- package/src/Data.ts +60 -265
- package/src/Duration.ts +140 -0
- package/src/Effect.ts +915 -86
- package/src/Equal.ts +8 -1
- package/src/Exit.ts +3 -3
- package/src/FileSystem.ts +65 -4
- package/src/Formatter.ts +28 -13
- package/src/Glob.ts +205 -0
- package/src/Hash.ts +4 -1
- package/src/JsonPatch.ts +4 -0
- package/src/JsonSchema.ts +12 -40
- package/src/Match.ts +127 -0
- package/src/Metric.ts +3 -3
- package/src/MutableList.ts +7 -5
- package/src/MutableRef.ts +8 -1
- package/src/PartitionedSemaphore.ts +24 -13
- package/src/Pool.ts +182 -52
- package/src/PubSub.ts +5 -6
- package/src/Random.ts +3 -3
- package/src/RcMap.ts +5 -1
- package/src/Ref.ts +8 -0
- package/src/Schedule.ts +27 -4
- package/src/Schema.ts +1237 -87
- package/src/SchemaAST.ts +20 -20
- package/src/SchemaGetter.ts +27 -11
- package/src/SchemaParser.ts +51 -18
- package/src/SchemaRepresentation.ts +50 -34
- package/src/SchemaTransformation.ts +17 -5
- package/src/ScopedCache.ts +5 -9
- package/src/Semaphore.ts +208 -40
- package/src/Sink.ts +15 -2
- package/src/Stream.ts +48 -22
- package/src/String.ts +3 -0
- package/src/Terminal.ts +19 -1
- package/src/Tracer.ts +15 -1
- package/src/ai/AiError.ts +56 -80
- package/src/ai/Decision.ts +257 -6
- package/src/ai/DecisionModel.ts +171 -28
- package/src/ai/LanguageModel.ts +9 -0
- package/src/ai/McpServer.ts +1283 -299
- package/src/ai/McpTest.ts +380 -0
- package/src/ai/Prompt.ts +65 -0
- package/src/ai/Response.ts +36 -31
- package/src/ai/Tool.ts +65 -10
- package/src/ai/Toolkit.ts +4 -1
- package/src/ai/index.ts +6 -0
- package/src/ai/internal/mcpCore.ts +78 -44
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +15 -10
- package/src/ai/internal/mcpProtocol.ts +29 -0
- package/src/ai/internal/mcpRuntime.ts +9 -5
- package/src/ai/internal/mcpStatefulRuntime.ts +14 -2
- package/src/cli/Argument.ts +21 -0
- package/src/cli/CliError.ts +90 -3
- package/src/cli/CliOutput.ts +300 -55
- package/src/cli/Command.ts +76 -41
- package/src/cli/Completions.ts +51 -0
- package/src/cli/Flag.ts +122 -0
- package/src/cli/GlobalFlag.ts +6 -7
- package/src/cli/HelpDoc.ts +18 -1
- package/src/cli/Param.ts +35 -6
- package/src/cli/Primitive.ts +16 -1
- package/src/cli/Prompt.ts +1 -0
- package/src/cli/TerminalCapabilities.ts +6 -3
- package/src/cli/internal/completions/bash.ts +79 -29
- package/src/cli/internal/help.ts +21 -9
- package/src/cluster/ClusterWorkflowEngine.ts +46 -16
- package/src/cluster/MessageStorage.ts +19 -14
- package/src/cluster/Sharding.ts +176 -47
- package/src/cluster/ShardingConfig.ts +43 -0
- package/src/cluster/SingleRunner.ts +3 -3
- package/src/cluster/Snowflake.ts +3 -7
- package/src/cluster/SqlMessageStorage.ts +49 -17
- package/src/cluster/SqlRunnerStorage.ts +143 -70
- package/src/cluster/internal/entityManager.ts +75 -22
- package/src/crypto/Aead.ts +517 -0
- package/src/crypto/Cipher.ts +326 -0
- package/src/crypto/CryptoError.ts +242 -0
- package/src/crypto/Digest.ts +167 -0
- package/src/crypto/Kdf.ts +315 -0
- package/src/crypto/KeyAgreement.ts +489 -0
- package/src/crypto/KeyFormat.ts +712 -0
- package/src/crypto/KeyWrap.ts +639 -0
- package/src/crypto/Mac.ts +386 -0
- package/src/crypto/SecureRandom.ts +459 -0
- package/src/crypto/Signature.ts +673 -0
- package/src/crypto/WebCrypto.ts +64 -0
- package/src/crypto/index.ts +78 -0
- package/src/crypto/internal/asymmetric.ts +329 -0
- package/src/crypto/internal/chacha.ts +1088 -0
- package/src/crypto/internal/der.ts +110 -0
- package/src/crypto/internal/digest.ts +16 -0
- package/src/crypto/internal/key.ts +235 -0
- package/src/crypto/internal/md5.ts +170 -0
- package/src/crypto/internal/webCrypto.ts +150 -0
- package/src/devtools/DevToolsClient.ts +2 -0
- package/src/encoding/Base64.ts +38 -0
- package/src/encoding/Base64Url.ts +5 -2
- package/src/encoding/Csv.ts +1298 -0
- package/src/encoding/Hex.ts +3 -2
- package/src/encoding/SchemaBinary.ts +40 -4
- package/src/encoding/Sse.ts +4 -3
- package/src/encoding/Toml.ts +117 -35
- package/src/encoding/Yaml.ts +61 -18
- package/src/encoding/index.ts +6 -0
- package/src/eventlog/EventJournal.ts +4 -3
- package/src/eventlog/EventLog.ts +340 -15
- package/src/eventlog/EventLogEncryption.ts +118 -110
- package/src/eventlog/EventLogMessage.ts +273 -1
- package/src/eventlog/EventLogRemote.ts +367 -23
- package/src/eventlog/EventLogServer.ts +23 -8
- package/src/eventlog/EventLogServerEncrypted.ts +1130 -67
- package/src/eventlog/EventLogSessionAuth.ts +56 -70
- package/src/eventlog/EventRow.ts +12 -3
- package/src/eventlog/SqlEventJournal.ts +68 -45
- package/src/eventlog/SqlEventLogServerEncrypted.ts +1244 -136
- package/src/eventlog/SqlEventLogServerUnencrypted.ts +2 -2
- package/src/eventlog/internal/batches.ts +30 -0
- package/src/eventlog/internal/compaction.ts +64 -0
- package/src/eventlog/internal/conflicts.ts +0 -4
- package/src/eventlog/internal/identityRootSecretDerivation.ts +93 -123
- package/src/eventlog/internal/remoteCompaction.ts +92 -0
- package/src/http/Cookies.ts +291 -12
- package/src/http/FetchHttpClient.ts +88 -16
- package/src/http/HttpClient.ts +636 -29
- package/src/http/HttpClientError.ts +35 -1
- package/src/http/HttpClientRequest.ts +21 -10
- package/src/http/HttpClientResponse.ts +3 -2
- package/src/http/HttpMethod.ts +10 -2
- package/src/http/HttpMiddleware.ts +15 -18
- package/src/http/HttpRouter.ts +2 -1
- package/src/http/HttpServerError.ts +2 -2
- package/src/http/HttpServerRequest.ts +101 -30
- package/src/http/HttpServerResponse.ts +3 -2
- package/src/http/HttpStaticServer.ts +51 -22
- package/src/http/HttpTraceContext.ts +7 -4
- package/src/http/MultipartParser/internal/contentType.ts +3 -3
- package/src/http/ProblemDetails.ts +149 -0
- package/src/http/UrlParams.ts +6 -1
- package/src/http/index.ts +6 -0
- package/src/http/internal/compression.ts +4 -5
- package/src/http/internal/decompression.ts +10 -4
- package/src/http/internal/httpBody.ts +10 -2
- package/src/http/internal/urlParams.ts +37 -0
- package/src/http-api/HttpApi.ts +3 -6
- package/src/http-api/HttpApiBuilder.ts +61 -19
- package/src/http-api/HttpApiClient.ts +284 -72
- package/src/http-api/HttpApiEndpoint.ts +135 -35
- package/src/http-api/HttpApiError.ts +250 -0
- package/src/http-api/HttpApiMiddleware.ts +95 -1
- package/src/http-api/HttpApiSchema.ts +236 -52
- package/src/http-api/HttpApiTest.ts +3 -2
- package/src/http-api/OpenApi.ts +20 -17
- package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
- package/src/index.ts +6 -6
- package/src/internal/arbitrary/runner.ts +133 -36
- package/src/internal/core.ts +2 -0
- package/src/internal/effect.ts +58 -34
- package/src/internal/equal.ts +17 -0
- package/src/internal/glob.ts +736 -0
- package/src/internal/jsonSchema.ts +27 -0
- package/src/internal/matcher.ts +18 -1
- package/src/internal/persistence.ts +11 -0
- package/src/internal/rcRef.ts +4 -1
- package/src/internal/schema/compilerRegistry.ts +6 -1
- package/src/internal/schema/content.ts +18 -0
- package/src/internal/schema/fromJsonSchemaDocument.ts +228 -190
- package/src/internal/schema/fromRepresentation.ts +2 -1
- package/src/internal/schema/standardSchema.ts +2 -2
- package/src/internal/schema/toCodeDocument.ts +11 -7
- package/src/internal/schema/toCodec.ts +26 -22
- package/src/internal/schema/toJsonSchemaDocument.ts +189 -167
- package/src/internal/schema/toRepresentation.ts +122 -140
- package/src/internal/sql.ts +14 -0
- package/src/internal/trie.ts +43 -14
- package/src/internal/ulid.ts +44 -0
- package/src/internal/uuid.ts +57 -16
- package/src/internal/version.ts +1 -1
- package/src/observability/Otlp.ts +21 -4
- package/src/observability/OtlpProxy.ts +314 -0
- package/src/observability/OtlpResource.ts +9 -1
- package/src/observability/OtlpTracer.ts +4 -0
- package/src/observability/index.ts +6 -0
- package/src/persistence/CircuitBreaker.ts +1678 -0
- package/src/persistence/KeyValueStore.ts +219 -22
- package/src/persistence/PersistedQueue.ts +128 -59
- package/src/persistence/Persistence.ts +20 -13
- package/src/persistence/Redis.ts +129 -8
- package/src/persistence/index.ts +6 -0
- package/src/process/ChildProcess.ts +285 -264
- package/src/process/ChildProcessSpawner.ts +46 -2
- package/src/process/CommandLine.ts +630 -0
- package/src/process/index.ts +6 -0
- package/src/reactivity/AsyncResult.ts +1 -1
- package/src/reactivity/Atom.ts +5 -5
- package/src/reactivity/AtomRegistry.ts +1 -1
- package/src/rpc/RpcClient.ts +75 -36
- package/src/rpc/RpcMessage.ts +10 -1
- package/src/rpc/RpcSerialization.ts +35 -9
- package/src/rpc/RpcServer.ts +176 -63
- package/src/rpc/RpcTest.ts +3 -0
- package/src/schema/Model.ts +26 -3
- package/src/sql/Migrator.ts +15 -69
- package/src/sql/MigratorFileSystem.ts +71 -0
- package/src/sql/SqlClient.ts +13 -20
- package/src/sql/SqlResolver.ts +23 -9
- package/src/sql/Statement.ts +38 -9
- package/src/sql/index.ts +1 -1
- package/src/testing/index.ts +0 -6
- package/src/workflow/DurableDeferred.ts +23 -6
- package/src/workflow/internal/crypto.ts +15 -11
- package/dist/Crypto.d.ts +0 -244
- package/dist/Crypto.d.ts.map +0 -1
- package/dist/Crypto.js +0 -139
- package/dist/Crypto.js.map +0 -1
- package/dist/testing/TestCrypto.d.ts +0 -73
- package/dist/testing/TestCrypto.d.ts.map +0 -1
- package/dist/testing/TestCrypto.js +0 -87
- package/dist/testing/TestCrypto.js.map +0 -1
- package/src/Crypto.ts +0 -347
- package/src/testing/TestCrypto.ts +0 -94
|
@@ -12,18 +12,26 @@
|
|
|
12
12
|
* @since 4.0.0
|
|
13
13
|
*/
|
|
14
14
|
import * as Arr from "../Array.js";
|
|
15
|
+
import * as Cause from "../Cause.js";
|
|
16
|
+
import * as Clock from "../Clock.js";
|
|
15
17
|
import * as Context from "../Context.js";
|
|
18
|
+
import * as SecureRandom from "../crypto/SecureRandom.js";
|
|
19
|
+
import * as Data from "../Data.js";
|
|
20
|
+
import * as Duration from "../Duration.js";
|
|
16
21
|
import * as Effect from "../Effect.js";
|
|
17
22
|
import * as Equal from "../Equal.js";
|
|
18
23
|
import * as Uuid from "../internal/uuid.js";
|
|
24
|
+
import * as Latch from "../Latch.js";
|
|
19
25
|
import * as Layer from "../Layer.js";
|
|
20
26
|
import * as PubSub from "../PubSub.js";
|
|
27
|
+
import * as Pull from "../Pull.js";
|
|
21
28
|
import * as RcMap from "../RcMap.js";
|
|
22
29
|
import * as RpcServer from "../rpc/RpcServer.js";
|
|
23
30
|
import * as Stream from "../Stream.js";
|
|
24
31
|
import { makeRemoteIdUnsafe } from "./EventJournal.js";
|
|
25
|
-
import { ChangesRpc, EventLogProtocolError, EventLogRemoteRpcs, WriteEntries } from "./EventLogMessage.js";
|
|
32
|
+
import { ChangesRpc, ChunkedMessage, CompactionInputRpc, CompactionPartRpc, CompactionStatus, EventLogCompactionRpcs, EventLogProtocolError, EventLogRemoteRpcs, WriteEntries } from "./EventLogMessage.js";
|
|
26
33
|
import * as EventLogServer from "./EventLogServer.js";
|
|
34
|
+
import { hourMillis, lagHour, logCommit, logNoOp, logRollback, maxSegments, positionsPerSegment } from "./internal/compaction.js";
|
|
27
35
|
/**
|
|
28
36
|
* Provides RPC handlers for the encrypted event-log server.
|
|
29
37
|
*
|
|
@@ -33,6 +41,10 @@ import * as EventLogServer from "./EventLogServer.js";
|
|
|
33
41
|
* sequences. Change streams encode stored batches, excluding this connection's
|
|
34
42
|
* writes.
|
|
35
43
|
*
|
|
44
|
+
* It also serves `EventLogCompactionRpcs`. If `Storage` provides `compaction`,
|
|
45
|
+
* it sets `HelloResponse.compaction` and applies the compaction policy;
|
|
46
|
+
* otherwise those handlers fail with `NotFound`.
|
|
47
|
+
*
|
|
36
48
|
* @stability unstable
|
|
37
49
|
* @category layers
|
|
38
50
|
* @since 4.0.0
|
|
@@ -40,9 +52,10 @@ import * as EventLogServer from "./EventLogServer.js";
|
|
|
40
52
|
export const layerRpcHandlers = /*#__PURE__*/Layer.unwrap(/*#__PURE__*/Effect.gen(function* () {
|
|
41
53
|
const storage = yield* Storage;
|
|
42
54
|
const remoteId = yield* storage.getId;
|
|
43
|
-
return EventLogServer.layerRpcHandlers({
|
|
55
|
+
return Layer.merge(EventLogServer.layerRpcHandlers({
|
|
44
56
|
remoteId,
|
|
45
57
|
firstSequence: storage.firstSequence,
|
|
58
|
+
compaction: storage.compaction !== undefined,
|
|
46
59
|
getOrCreateSessionAuthBinding: (publicKey, signingPublicKey) => storage.getOrCreateSessionAuthBinding(publicKey, signingPublicKey),
|
|
47
60
|
onWrite: Effect.fnUntraced(function* (data, authenticatedPublicKeys, writes) {
|
|
48
61
|
const request = yield* WriteEntries.decode(data).pipe(Effect.mapError(_ => new EventLogProtocolError({
|
|
@@ -83,10 +96,11 @@ export const layerRpcHandlers = /*#__PURE__*/Layer.unwrap(/*#__PURE__*/Effect.ge
|
|
|
83
96
|
entryIds: batch => batch.entryIds,
|
|
84
97
|
sequence: batch => batch.sequence + batch.entryIds.length - 1
|
|
85
98
|
}, storage.changes(publicKey, storeId, startSequence)).pipe(Stream.mapArrayEffect(batches => Effect.map(ChangesRpc.encodeEncrypted(batches), Arr.of)))
|
|
86
|
-
});
|
|
99
|
+
}), layerCompactionRpcHandlers(storage));
|
|
87
100
|
}));
|
|
88
101
|
// Acknowledges each entry occurrence in request order: at its position in the
|
|
89
|
-
// batch this write stored, or, for a skipped batch, where it was first stored
|
|
102
|
+
// batch this write stored, or, for a skipped batch, where it was first stored
|
|
103
|
+
// if that is above the active compaction base.
|
|
90
104
|
const toWriteAcks = /*#__PURE__*/Effect.fnUntraced(function* (storage, publicKey, storeId, batches, stored) {
|
|
91
105
|
// Stored batches keep request order, and each batch has its own random iv.
|
|
92
106
|
let next = 0;
|
|
@@ -97,8 +111,11 @@ const toWriteAcks = /*#__PURE__*/Effect.fnUntraced(function* (storage, publicKey
|
|
|
97
111
|
const skipped = batches.flatMap((batch, i) => storedAt[i] === undefined ? batch.entryIds : []);
|
|
98
112
|
const firstStored = new Map();
|
|
99
113
|
if (skipped.length > 0) {
|
|
114
|
+
// An id first stored at or below the active base may have been dropped, so
|
|
115
|
+
// acking it would move the client's cursor past kept entries.
|
|
116
|
+
const base = storage.compaction === undefined ? -Infinity : (yield* storage.compaction.status(publicKey, storeId)).base;
|
|
100
117
|
for (const ack of yield* storage.entrySequences(publicKey, storeId, skipped)) {
|
|
101
|
-
firstStored.set(Uuid.stringify(ack.entryId), ack.sequence);
|
|
118
|
+
if (ack.sequence > base) firstStored.set(Uuid.stringify(ack.entryId), ack.sequence);
|
|
102
119
|
}
|
|
103
120
|
}
|
|
104
121
|
const acks = [];
|
|
@@ -111,6 +128,213 @@ const toWriteAcks = /*#__PURE__*/Effect.fnUntraced(function* (storage, publicKey
|
|
|
111
128
|
}));
|
|
112
129
|
return acks;
|
|
113
130
|
});
|
|
131
|
+
const layerCompactionRpcHandlers = storage => EventLogCompactionRpcs.toLayer(Effect.sync(() => {
|
|
132
|
+
const compaction = storage.compaction;
|
|
133
|
+
const toFrames = EventLogServer.makeFramer();
|
|
134
|
+
const protocolError = (requestTag, request, code, message) => new EventLogProtocolError({
|
|
135
|
+
requestTag,
|
|
136
|
+
publicKey: request.publicKey,
|
|
137
|
+
storeId: request.storeId,
|
|
138
|
+
code,
|
|
139
|
+
message
|
|
140
|
+
});
|
|
141
|
+
const fromCompactionError = (requestTag, request) => error => error._tag === "CompactionNotFound" ? protocolError(requestTag, request, "NotFound", "Compaction stage not found") : protocolError(requestTag, request, "InvalidRequest", error.message);
|
|
142
|
+
const withCompaction = (requestTag, request, client, f) => {
|
|
143
|
+
if (!Context.getOrUndefined(client.annotations, EventLogServer.AuthenticatedIdentities)?.has(request.publicKey)) {
|
|
144
|
+
return Effect.fail(protocolError(requestTag, request, "Forbidden", "Identity is not authenticated"));
|
|
145
|
+
}
|
|
146
|
+
if (compaction === undefined) {
|
|
147
|
+
return Effect.fail(protocolError(requestTag, request, "NotFound", "Compaction is not supported"));
|
|
148
|
+
}
|
|
149
|
+
return Effect.mapError(f(compaction), fromCompactionError(requestTag, request));
|
|
150
|
+
};
|
|
151
|
+
const withCompactionStream = (requestTag, request, client, f) => Stream.unwrap(withCompaction(requestTag, request, client, compaction => Effect.succeed(Stream.mapError(f(compaction), fromCompactionError(requestTag, request)))));
|
|
152
|
+
const getStatus = Effect.fnUntraced(function* (compaction, publicKey, storeId) {
|
|
153
|
+
const status = yield* compaction.status(publicKey, storeId);
|
|
154
|
+
return {
|
|
155
|
+
status,
|
|
156
|
+
wanted: isCompactionWanted(status, compaction.config.thresholdFloor)
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
return EventLogCompactionRpcs.of({
|
|
160
|
+
"EventLog.CompactionStatus": (request, {
|
|
161
|
+
client
|
|
162
|
+
}) => withCompaction("CompactionStatus", request, client, compaction => Effect.map(getStatus(compaction, request.publicKey, request.storeId), ({
|
|
163
|
+
status,
|
|
164
|
+
wanted
|
|
165
|
+
}) => new CompactionStatus({
|
|
166
|
+
wanted,
|
|
167
|
+
head: status.head
|
|
168
|
+
}))),
|
|
169
|
+
"EventLog.CompactionBegin": (request, {
|
|
170
|
+
client
|
|
171
|
+
}) => withCompaction("CompactionBegin", request, client, compaction => Effect.gen(function* () {
|
|
172
|
+
const {
|
|
173
|
+
status,
|
|
174
|
+
wanted
|
|
175
|
+
} = yield* getStatus(compaction, request.publicKey, request.storeId);
|
|
176
|
+
if (!wanted) {
|
|
177
|
+
return {
|
|
178
|
+
_tag: "NotWanted"
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const result = yield* compaction.begin(request.publicKey, request.storeId, {
|
|
182
|
+
through: status.lagHead
|
|
183
|
+
});
|
|
184
|
+
return result._tag === "Busy" ? {
|
|
185
|
+
_tag: "Busy"
|
|
186
|
+
} : {
|
|
187
|
+
_tag: "Started",
|
|
188
|
+
stageId: result.stageId
|
|
189
|
+
};
|
|
190
|
+
})),
|
|
191
|
+
"EventLog.CompactionInput": (request, {
|
|
192
|
+
client
|
|
193
|
+
}) => withCompactionStream("CompactionInput", request, client, compaction => compaction.inputHeaders(request.publicKey, request.storeId, request.stageId).pipe(Stream.mapArrayEffect(headers => Effect.map(Effect.orDie(CompactionInputRpc.encodeHeaders(headers)), toFrames)))),
|
|
194
|
+
"EventLog.CompactionFetch": (request, {
|
|
195
|
+
client
|
|
196
|
+
}) => withCompactionStream("CompactionFetch", request, client, compaction => compaction.fetch(request.publicKey, request.storeId, request.stageId, request.batches).pipe(Stream.mapArrayEffect(batches => Effect.map(Effect.orDie(ChangesRpc.encodeEncrypted(batches)), toFrames)))),
|
|
197
|
+
"EventLog.CompactionPart": (request, {
|
|
198
|
+
client
|
|
199
|
+
}) => withCompaction("CompactionPart", request, client, compaction => Effect.gen(function* () {
|
|
200
|
+
const {
|
|
201
|
+
publicKey,
|
|
202
|
+
stageId,
|
|
203
|
+
storeId
|
|
204
|
+
} = request;
|
|
205
|
+
const data = ChunkedMessage.join(getPendingSegments(client, request), request.chunk);
|
|
206
|
+
if (data === undefined) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const batches = yield* CompactionPartRpc.decodeSegment(data).pipe(Effect.catch(() => Effect.andThen(compaction.abort(publicKey, storeId, stageId), Effect.fail(new CompactionInvalidRequest({
|
|
210
|
+
stageId,
|
|
211
|
+
message: "Invalid segment"
|
|
212
|
+
})))));
|
|
213
|
+
yield* compaction.stagePart(publicKey, storeId, stageId, request.chunk.id, batches);
|
|
214
|
+
})),
|
|
215
|
+
"EventLog.CompactionAbort": (request, {
|
|
216
|
+
client
|
|
217
|
+
}) => withCompaction("CompactionAbort", request, client, compaction => {
|
|
218
|
+
releasePendingSegments(client, request);
|
|
219
|
+
return compaction.abort(request.publicKey, request.storeId, request.stageId);
|
|
220
|
+
}),
|
|
221
|
+
"EventLog.CompactionCommit": (request, {
|
|
222
|
+
client
|
|
223
|
+
}) => withCompaction("CompactionCommit", request, client, compaction => {
|
|
224
|
+
const {
|
|
225
|
+
publicKey,
|
|
226
|
+
stageId,
|
|
227
|
+
storeId
|
|
228
|
+
} = request;
|
|
229
|
+
releasePendingSegments(client, request);
|
|
230
|
+
if (request.result._tag === "NoOp") {
|
|
231
|
+
return Effect.as(compaction.recordNoOp(publicKey, storeId, stageId), "Committed");
|
|
232
|
+
}
|
|
233
|
+
return checkSnapshot(compaction, publicKey, storeId, stageId, request.result.segmentCount).pipe(Effect.tapError(error => error._tag === "CompactionInvalidRequest" ? compaction.abort(publicKey, storeId, stageId) : Effect.void), Effect.flatMap(virtualSequences => compaction.commit(publicKey, storeId, stageId, virtualSequences)));
|
|
234
|
+
})
|
|
235
|
+
});
|
|
236
|
+
}));
|
|
237
|
+
// The input past the lag must reach the threshold. After `k` consecutive
|
|
238
|
+
// no-ops, the lag head must also have moved `threshold * 2^(k-1)` past the
|
|
239
|
+
// latest one.
|
|
240
|
+
const isCompactionWanted = (status, thresholdFloor) => {
|
|
241
|
+
const threshold = Math.max(status.activeKeptCount, thresholdFloor);
|
|
242
|
+
const pending = status.lagHead - status.base;
|
|
243
|
+
if (pending <= 0 || pending < threshold) return false;
|
|
244
|
+
if (status.noOp === undefined) return true;
|
|
245
|
+
return status.lagHead - status.noOp.at >= threshold * 2 ** (status.noOp.count - 1);
|
|
246
|
+
};
|
|
247
|
+
// Checks the staged batches against the stage's input in one pass over both
|
|
248
|
+
// and returns each batch's virtual start sequence. The kept ids, read in
|
|
249
|
+
// segments 0 to segmentCount - 1, must be a non-empty, repeat-free
|
|
250
|
+
// subsequence of the input's ids.
|
|
251
|
+
const checkSnapshot = /*#__PURE__*/Effect.fnUntraced(function* (compaction, publicKey, storeId, stageId, segmentCount) {
|
|
252
|
+
const invalid = message => Effect.fail(new CompactionInvalidRequest({
|
|
253
|
+
stageId,
|
|
254
|
+
message
|
|
255
|
+
}));
|
|
256
|
+
const pullInput = yield* Stream.toPull(compaction.inputHeaders(publicKey, storeId, stageId));
|
|
257
|
+
let headers = [];
|
|
258
|
+
let headerIndex = 0;
|
|
259
|
+
let entryIndex = 0;
|
|
260
|
+
let lastInputSequence = -1;
|
|
261
|
+
const nextInput = Effect.gen(function* () {
|
|
262
|
+
while (true) {
|
|
263
|
+
const header = headers[headerIndex];
|
|
264
|
+
if (header === undefined) {
|
|
265
|
+
const chunk = yield* Pull.catchDone(pullInput, () => Effect.succeed(undefined));
|
|
266
|
+
if (chunk === undefined) return undefined;
|
|
267
|
+
headers = chunk;
|
|
268
|
+
headerIndex = 0;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (entryIndex === header.entryIds.length) {
|
|
272
|
+
headerIndex++;
|
|
273
|
+
entryIndex = 0;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const sequence = header.sequence + entryIndex;
|
|
277
|
+
const id = Uuid.stringify(header.entryIds[entryIndex++]);
|
|
278
|
+
lastInputSequence = sequence;
|
|
279
|
+
return {
|
|
280
|
+
id,
|
|
281
|
+
sequence
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
// The input sequence of each batch's last kept entry, and its size.
|
|
286
|
+
const ends = [];
|
|
287
|
+
const sizes = [];
|
|
288
|
+
let segment = -1;
|
|
289
|
+
yield* Stream.runForEach(compaction.stagedHeaders(publicKey, storeId, stageId), header => Effect.gen(function* () {
|
|
290
|
+
const headerSegment = Math.floor(header.position / positionsPerSegment);
|
|
291
|
+
if (headerSegment !== segment) {
|
|
292
|
+
if (headerSegment !== segment + 1 || headerSegment >= segmentCount) {
|
|
293
|
+
return yield* invalid("Unexpected segment");
|
|
294
|
+
}
|
|
295
|
+
segment = headerSegment;
|
|
296
|
+
}
|
|
297
|
+
let last = -1;
|
|
298
|
+
for (const entryId of header.entryIds) {
|
|
299
|
+
const id = Uuid.stringify(entryId);
|
|
300
|
+
let input = yield* nextInput;
|
|
301
|
+
while (input !== undefined && input.id !== id) input = yield* nextInput;
|
|
302
|
+
if (input === undefined) return yield* invalid("Kept entry is not in the input, or is out of order");
|
|
303
|
+
last = input.sequence;
|
|
304
|
+
}
|
|
305
|
+
ends.push(last);
|
|
306
|
+
sizes.push(header.entryIds.length);
|
|
307
|
+
}));
|
|
308
|
+
if (ends.length === 0) return yield* invalid("Snapshot is empty");
|
|
309
|
+
if (segment !== segmentCount - 1) return yield* invalid("Missing segment");
|
|
310
|
+
while ((yield* nextInput) !== undefined) {
|
|
311
|
+
// Drain the input to learn its last sequence.
|
|
312
|
+
}
|
|
313
|
+
// Each batch ends at its last kept entry's input sequence, and the final one
|
|
314
|
+
// at the end of the input, so no batch starts below its entries' input.
|
|
315
|
+
return ends.map((end, i) => (i === ends.length - 1 ? lastInputSequence : end) - sizes[i] + 1);
|
|
316
|
+
}, Effect.scoped);
|
|
317
|
+
// One connection's unjoined segment pieces, keyed by identity, store and
|
|
318
|
+
// stage. The JSON tuple key keeps the components unambiguous.
|
|
319
|
+
class PendingSegments extends /*#__PURE__*/Context.Service()("effect/eventlog/EventLogServerEncrypted/PendingSegments") {}
|
|
320
|
+
const pendingSegmentsKey = request => JSON.stringify([request.publicKey, request.storeId, request.stageId]);
|
|
321
|
+
const getPendingSegments = (client, request) => {
|
|
322
|
+
let stages = Context.getOrUndefined(client.annotations, PendingSegments);
|
|
323
|
+
if (stages === undefined) {
|
|
324
|
+
stages = new Map();
|
|
325
|
+
client.annotate(PendingSegments, stages);
|
|
326
|
+
}
|
|
327
|
+
const key = pendingSegmentsKey(request);
|
|
328
|
+
let pending = stages.get(key);
|
|
329
|
+
if (pending === undefined) {
|
|
330
|
+
pending = ChunkedMessage.initialJoinState();
|
|
331
|
+
stages.set(key, pending);
|
|
332
|
+
}
|
|
333
|
+
return pending;
|
|
334
|
+
};
|
|
335
|
+
const releasePendingSegments = (client, request) => {
|
|
336
|
+
Context.getOrUndefined(client.annotations, PendingSegments)?.delete(pendingSegmentsKey(request));
|
|
337
|
+
};
|
|
114
338
|
/**
|
|
115
339
|
* Provides an encrypted event-log RPC server using `EventLogRemoteRpcs` and the
|
|
116
340
|
* encrypted server RPC handlers.
|
|
@@ -125,7 +349,8 @@ const toWriteAcks = /*#__PURE__*/Effect.fnUntraced(function* (storage, publicKey
|
|
|
125
349
|
* This layer installs `EventLogRemoteRpcs` on the provided RPC server protocol
|
|
126
350
|
* and wires those RPCs to `layerRpcHandlers`. Encrypted batches, session
|
|
127
351
|
* authentication bindings, remote ids, and change streams are delegated to
|
|
128
|
-
* `Storage`.
|
|
352
|
+
* `Storage`. It also installs `EventLogCompactionRpcs`, which clients call
|
|
353
|
+
* only when `Storage` provides `compaction`.
|
|
129
354
|
*
|
|
130
355
|
* @see {@link layerRpcHandlers} for the encrypted handler layer without installing an RPC server protocol
|
|
131
356
|
* @see {@link Storage} for the storage service required by this layer
|
|
@@ -135,7 +360,7 @@ const toWriteAcks = /*#__PURE__*/Effect.fnUntraced(function* (storage, publicKey
|
|
|
135
360
|
* @category layers
|
|
136
361
|
* @since 4.0.0
|
|
137
362
|
*/
|
|
138
|
-
export const layer = /*#__PURE__*/RpcServer.layer(EventLogRemoteRpcs).pipe(/*#__PURE__*/Layer.provide(layerRpcHandlers));
|
|
363
|
+
export const layer = /*#__PURE__*/RpcServer.layer(EventLogRemoteRpcs.merge(EventLogCompactionRpcs)).pipe(/*#__PURE__*/Layer.provide(layerRpcHandlers));
|
|
139
364
|
/**
|
|
140
365
|
* Defines the backing store service used by the encrypted event-log server.
|
|
141
366
|
*
|
|
@@ -158,34 +383,143 @@ export const layer = /*#__PURE__*/RpcServer.layer(EventLogRemoteRpcs).pipe(/*#__
|
|
|
158
383
|
* whose last sequence is at or after `startSequence`, followed by newly stored
|
|
159
384
|
* batches.
|
|
160
385
|
*
|
|
386
|
+
* Storages that support remote compaction provide `compaction`. With an active
|
|
387
|
+
* snapshot, `changes` serves snapshot batches by their virtual sequences for a
|
|
388
|
+
* start sequence at or below the snapshot base, then the originals above it.
|
|
389
|
+
*
|
|
161
390
|
* @stability unstable
|
|
162
391
|
* @category services
|
|
163
392
|
* @since 4.0.0
|
|
164
393
|
*/
|
|
165
394
|
export class Storage extends /*#__PURE__*/Context.Service()("effect/eventlog/EventLogServer/Storage") {}
|
|
166
395
|
/**
|
|
167
|
-
*
|
|
396
|
+
* Error raised when a compaction stage has expired, was aborted or committed,
|
|
397
|
+
* or is unknown to the store.
|
|
398
|
+
*
|
|
399
|
+
* @stability unstable
|
|
400
|
+
* @category errors
|
|
401
|
+
* @since 4.0.0
|
|
402
|
+
*/
|
|
403
|
+
export class CompactionNotFound extends /*#__PURE__*/Data.TaggedError("CompactionNotFound") {}
|
|
404
|
+
/**
|
|
405
|
+
* Error raised when a compaction Part fails validation.
|
|
406
|
+
*
|
|
407
|
+
* @stability unstable
|
|
408
|
+
* @category errors
|
|
409
|
+
* @since 4.0.0
|
|
410
|
+
*/
|
|
411
|
+
export class CompactionInvalidRequest extends /*#__PURE__*/Data.TaggedError("CompactionInvalidRequest") {}
|
|
412
|
+
/**
|
|
413
|
+
* Error raised when a rollback is refused.
|
|
414
|
+
*
|
|
415
|
+
* **Details**
|
|
416
|
+
*
|
|
417
|
+
* `NotActive` means the expected activation is not the active one,
|
|
418
|
+
* `NoPrevious` that there is no earlier generation, and `PruneStarted` that
|
|
419
|
+
* the previous generation has started to be pruned.
|
|
420
|
+
*
|
|
421
|
+
* @stability unstable
|
|
422
|
+
* @category errors
|
|
423
|
+
* @since 4.0.0
|
|
424
|
+
*/
|
|
425
|
+
export class CompactionRollbackError extends /*#__PURE__*/Data.TaggedError("CompactionRollbackError") {}
|
|
426
|
+
/**
|
|
427
|
+
* Resolves compaction options against their defaults.
|
|
428
|
+
*
|
|
429
|
+
* **Details**
|
|
430
|
+
*
|
|
431
|
+
* Dies with an `IllegalArgumentError` unless `grace` is longer than both `lag`
|
|
432
|
+
* and `stageTtl`, `stageTtl` and `sweepInterval` are positive, and
|
|
433
|
+
* `thresholdFloor` is a non-negative integer.
|
|
434
|
+
*
|
|
435
|
+
* @stability unstable
|
|
436
|
+
* @category constructors
|
|
437
|
+
* @since 4.0.0
|
|
438
|
+
*/
|
|
439
|
+
export const makeCompactionConfig = options => Effect.suspend(() => {
|
|
440
|
+
const config = {
|
|
441
|
+
grace: Duration.fromInputUnsafe(options?.grace ?? "30 days"),
|
|
442
|
+
lag: Duration.fromInputUnsafe(options?.lag ?? "24 hours"),
|
|
443
|
+
stageTtl: Duration.fromInputUnsafe(options?.stageTtl ?? "10 minutes"),
|
|
444
|
+
thresholdFloor: options?.thresholdFloor ?? 1000,
|
|
445
|
+
sweepInterval: Duration.fromInputUnsafe(options?.sweepInterval ?? "1 hour")
|
|
446
|
+
};
|
|
447
|
+
if (!Duration.isGreaterThan(config.grace, config.lag) || !Duration.isGreaterThan(config.grace, config.stageTtl)) {
|
|
448
|
+
return Effect.die(new Cause.IllegalArgumentError("Compaction grace must be longer than lag and stageTtl"));
|
|
449
|
+
}
|
|
450
|
+
if (!Duration.isGreaterThan(config.stageTtl, Duration.zero)) {
|
|
451
|
+
return Effect.die(new Cause.IllegalArgumentError("Compaction stageTtl must be positive"));
|
|
452
|
+
}
|
|
453
|
+
if (!Duration.isGreaterThan(config.sweepInterval, Duration.zero)) {
|
|
454
|
+
return Effect.die(new Cause.IllegalArgumentError("Compaction sweepInterval must be positive"));
|
|
455
|
+
}
|
|
456
|
+
if (!Number.isSafeInteger(config.thresholdFloor) || config.thresholdFloor < 0) {
|
|
457
|
+
return Effect.die(new Cause.IllegalArgumentError("Compaction thresholdFloor must be a non-negative integer"));
|
|
458
|
+
}
|
|
459
|
+
return Effect.succeed(config);
|
|
460
|
+
});
|
|
461
|
+
/**
|
|
462
|
+
* Creates an in-memory encrypted server `Storage` with default compaction
|
|
463
|
+
* tuning.
|
|
168
464
|
*
|
|
169
465
|
* **Details**
|
|
170
466
|
*
|
|
171
467
|
* Data, session authentication bindings, and streams are process-local and are
|
|
172
468
|
* released with the surrounding scope.
|
|
173
469
|
*
|
|
470
|
+
* @see {@link makeStorageMemoryWith} to configure compaction
|
|
471
|
+
*
|
|
472
|
+
* @stability unstable
|
|
473
|
+
* @category constructors
|
|
474
|
+
* @since 4.0.0
|
|
475
|
+
*/
|
|
476
|
+
export const makeStorageMemory = /*#__PURE__*/Effect.suspend(() => makeStorageMemoryWith({}));
|
|
477
|
+
/**
|
|
478
|
+
* Creates an in-memory encrypted server `Storage`.
|
|
479
|
+
*
|
|
480
|
+
* **Details**
|
|
481
|
+
*
|
|
482
|
+
* Data, session authentication bindings, and streams are process-local and are
|
|
483
|
+
* released with the surrounding scope. The storage always provides
|
|
484
|
+
* `compaction`. Its sweep runs on `Clock` only while some store has a
|
|
485
|
+
* generation to prune or a stage to expire.
|
|
486
|
+
*
|
|
487
|
+
* Dies when the compaction options are invalid (see {@link makeCompactionConfig}).
|
|
488
|
+
*
|
|
174
489
|
* @stability unstable
|
|
175
490
|
* @category constructors
|
|
176
491
|
* @since 4.0.0
|
|
177
492
|
*/
|
|
178
|
-
export const
|
|
493
|
+
export const makeStorageMemoryWith = /*#__PURE__*/Effect.fnUntraced(function* (options) {
|
|
494
|
+
const config = yield* makeCompactionConfig(options.compaction);
|
|
495
|
+
const graceMillis = Duration.toMillis(config.grace);
|
|
496
|
+
const lagMillis = Duration.toMillis(config.lag);
|
|
497
|
+
const stageTtlMillis = Duration.toMillis(config.stageTtl);
|
|
179
498
|
const journals = new Map();
|
|
180
499
|
const sessionAuthBindings = new Map();
|
|
181
500
|
const remoteId = makeRemoteIdUnsafe();
|
|
182
501
|
const ensureJournal = scopeKey => {
|
|
183
502
|
let journal = journals.get(scopeKey);
|
|
184
503
|
if (journal) return journal;
|
|
504
|
+
const originals = {
|
|
505
|
+
id: SecureRandom.uuidV4Unsafe(),
|
|
506
|
+
set: undefined,
|
|
507
|
+
base: -1,
|
|
508
|
+
keptCount: undefined,
|
|
509
|
+
previous: undefined,
|
|
510
|
+
supersededAt: undefined,
|
|
511
|
+
pruneStartedAt: undefined
|
|
512
|
+
};
|
|
185
513
|
journal = {
|
|
186
514
|
knownIds: new Map(),
|
|
187
515
|
batches: [],
|
|
188
|
-
nextSequence: 0
|
|
516
|
+
nextSequence: 0,
|
|
517
|
+
buckets: new Map(),
|
|
518
|
+
activations: [originals],
|
|
519
|
+
active: originals,
|
|
520
|
+
noOp: undefined,
|
|
521
|
+
openStage: undefined,
|
|
522
|
+
nextSweepAt: undefined
|
|
189
523
|
};
|
|
190
524
|
journals.set(scopeKey, journal);
|
|
191
525
|
return journal;
|
|
@@ -194,6 +528,386 @@ export const makeStorageMemory = /*#__PURE__*/Effect.gen(function* () {
|
|
|
194
528
|
lookup: _scopeKey => Effect.acquireRelease(PubSub.unbounded(), PubSub.shutdown),
|
|
195
529
|
idleTimeToLive: 60000
|
|
196
530
|
});
|
|
531
|
+
// Open while any store has something for the sweep to do, so an idle
|
|
532
|
+
// storage never sleeps on the clock.
|
|
533
|
+
const sweepPending = Latch.makeUnsafe(false);
|
|
534
|
+
const schedulePrune = (journal, at) => {
|
|
535
|
+
journal.nextSweepAt = journal.nextSweepAt === undefined ? at : Math.min(journal.nextSweepAt, at);
|
|
536
|
+
sweepPending.openUnsafe();
|
|
537
|
+
};
|
|
538
|
+
const closeStage = (journal, stage) => {
|
|
539
|
+
if (journal.openStage === stage) journal.openStage = undefined;
|
|
540
|
+
};
|
|
541
|
+
const sweep = now => {
|
|
542
|
+
let pending = false;
|
|
543
|
+
for (const journal of journals.values()) {
|
|
544
|
+
if (journal.openStage !== undefined && journal.openStage.expiresAt <= now) closeStage(journal, journal.openStage);
|
|
545
|
+
if (journal.nextSweepAt !== undefined && journal.nextSweepAt <= now) prune(journal, now);
|
|
546
|
+
pending ||= journal.openStage !== undefined || journal.nextSweepAt !== undefined;
|
|
547
|
+
}
|
|
548
|
+
if (!pending) sweepPending.closeUnsafe();
|
|
549
|
+
};
|
|
550
|
+
// Keeps what the active generation and every generation still within grace
|
|
551
|
+
// need, which is their batch sets and the originals above their bases.
|
|
552
|
+
const prune = (journal, now) => {
|
|
553
|
+
const kept = journal.activations.filter(activation => activation === journal.active || activation.pruneStartedAt === undefined && activation.supersededAt + graceMillis > now);
|
|
554
|
+
const keptSets = new Set(kept.map(activation => activation.set));
|
|
555
|
+
for (const activation of journal.activations) {
|
|
556
|
+
if (kept.includes(activation) || activation.pruneStartedAt !== undefined) continue;
|
|
557
|
+
activation.pruneStartedAt = now;
|
|
558
|
+
if (activation.set !== undefined && !keptSets.has(activation.set)) activation.set.batches = [];
|
|
559
|
+
}
|
|
560
|
+
const keptBase = Math.min(...kept.map(activation => activation.base));
|
|
561
|
+
const first = journal.batches.findIndex(batch => batch.sequence + batch.entryIds.length - 1 > keptBase);
|
|
562
|
+
journal.batches.splice(0, first === -1 ? journal.batches.length : first);
|
|
563
|
+
journal.nextSweepAt = undefined;
|
|
564
|
+
for (const activation of journal.activations) {
|
|
565
|
+
if (activation !== journal.active && activation.pruneStartedAt === undefined) {
|
|
566
|
+
schedulePrune(journal, activation.supersededAt + graceMillis);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
yield* Effect.forkScoped(Effect.forever(sweepPending.await.pipe(Effect.andThen(Effect.sleep(config.sweepInterval)), Effect.andThen(Clock.currentTimeMillis), Effect.flatMap(now => Effect.sync(() => sweep(now))))));
|
|
571
|
+
// The highest last sequence stored in an hour that ended before now - lag.
|
|
572
|
+
const lagHead = (journal, now) => {
|
|
573
|
+
const pastLag = lagHour(now, lagMillis);
|
|
574
|
+
let head = -1;
|
|
575
|
+
for (const [hour, lastSequence] of journal.buckets) {
|
|
576
|
+
if (hour <= pastLag) head = Math.max(head, lastSequence);
|
|
577
|
+
}
|
|
578
|
+
return head;
|
|
579
|
+
};
|
|
580
|
+
const recordBucket = (journal, now, lastSequence) => {
|
|
581
|
+
const hour = Math.floor(now / hourMillis);
|
|
582
|
+
const existing = journal.buckets.get(hour);
|
|
583
|
+
if (existing !== undefined) {
|
|
584
|
+
journal.buckets.set(hour, Math.max(existing, lastSequence));
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
journal.buckets.set(hour, lastSequence);
|
|
588
|
+
// Only the newest bucket past the lag matters for the lag head.
|
|
589
|
+
const pastLag = Array.from(journal.buckets.keys()).filter(bucket => bucket <= lagHour(now, lagMillis));
|
|
590
|
+
const newest = Math.max(...pastLag);
|
|
591
|
+
for (const bucket of pastLag) {
|
|
592
|
+
if (bucket < newest) journal.buckets.delete(bucket);
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
// The input of a stage: its pinned batch set, then originals in (base, through].
|
|
596
|
+
const inputBatches = (journal, stage) => [...(stage.pinned.set?.batches ?? []), ...journal.batches.filter(batch => batch.sequence > stage.pinned.base && batch.sequence + batch.entryIds.length - 1 <= stage.through)];
|
|
597
|
+
// A stage that Part, NoOp and Commit can act on.
|
|
598
|
+
const findOpenStage = (publicKey, storeId, stageId, now) => {
|
|
599
|
+
const journal = journals.get(makeEncryptedScopeKey({
|
|
600
|
+
publicKey,
|
|
601
|
+
storeId
|
|
602
|
+
}));
|
|
603
|
+
const stage = journal?.openStage;
|
|
604
|
+
if (journal === undefined || stage === undefined || stage.id !== stageId) return undefined;
|
|
605
|
+
if (stage.expiresAt <= now) {
|
|
606
|
+
closeStage(journal, stage);
|
|
607
|
+
return undefined;
|
|
608
|
+
}
|
|
609
|
+
return {
|
|
610
|
+
stage,
|
|
611
|
+
journal
|
|
612
|
+
};
|
|
613
|
+
};
|
|
614
|
+
// Call within the same execution-time block that captures the input rows.
|
|
615
|
+
const findInputStage = (publicKey, storeId, stageId, now) => {
|
|
616
|
+
const found = findOpenStage(publicKey, storeId, stageId, now);
|
|
617
|
+
return found?.stage.pinned.pruneStartedAt === undefined ? found : undefined;
|
|
618
|
+
};
|
|
619
|
+
const compaction = {
|
|
620
|
+
config,
|
|
621
|
+
status: (publicKey, storeId) => Effect.map(Clock.currentTimeMillis, now => {
|
|
622
|
+
const journal = ensureJournal(makeEncryptedScopeKey({
|
|
623
|
+
publicKey,
|
|
624
|
+
storeId
|
|
625
|
+
}));
|
|
626
|
+
return {
|
|
627
|
+
head: journal.nextSequence - 1,
|
|
628
|
+
base: journal.active.base,
|
|
629
|
+
activeKeptCount: journal.active.keptCount ?? 0,
|
|
630
|
+
lagHead: lagHead(journal, now),
|
|
631
|
+
noOp: journal.noOp
|
|
632
|
+
};
|
|
633
|
+
}),
|
|
634
|
+
begin: (publicKey, storeId, {
|
|
635
|
+
through
|
|
636
|
+
}) => Effect.map(Clock.currentTimeMillis, now => {
|
|
637
|
+
const scopeKey = makeEncryptedScopeKey({
|
|
638
|
+
publicKey,
|
|
639
|
+
storeId
|
|
640
|
+
});
|
|
641
|
+
const journal = ensureJournal(scopeKey);
|
|
642
|
+
const open = journal.openStage;
|
|
643
|
+
if (open !== undefined) {
|
|
644
|
+
if (open.expiresAt > now) return {
|
|
645
|
+
_tag: "Busy",
|
|
646
|
+
expiresAt: open.expiresAt
|
|
647
|
+
};
|
|
648
|
+
closeStage(journal, open);
|
|
649
|
+
}
|
|
650
|
+
const stage = {
|
|
651
|
+
id: SecureRandom.uuidV4Unsafe(),
|
|
652
|
+
pinned: journal.active,
|
|
653
|
+
through,
|
|
654
|
+
expiresAt: now + stageTtlMillis,
|
|
655
|
+
staged: new Map()
|
|
656
|
+
};
|
|
657
|
+
journal.openStage = stage;
|
|
658
|
+
sweepPending.openUnsafe();
|
|
659
|
+
return {
|
|
660
|
+
_tag: "Started",
|
|
661
|
+
stageId: stage.id
|
|
662
|
+
};
|
|
663
|
+
}),
|
|
664
|
+
inputHeaders: (publicKey, storeId, stageId) => Clock.currentTimeMillis.pipe(Effect.flatMap(now => {
|
|
665
|
+
const found = findInputStage(publicKey, storeId, stageId, now);
|
|
666
|
+
if (found === undefined) return Effect.fail(new CompactionNotFound({
|
|
667
|
+
stageId
|
|
668
|
+
}));
|
|
669
|
+
const {
|
|
670
|
+
journal,
|
|
671
|
+
stage
|
|
672
|
+
} = found;
|
|
673
|
+
return Effect.succeed(Stream.fromArray(inputBatches(journal, stage).map(batch => ({
|
|
674
|
+
sequence: batch.sequence,
|
|
675
|
+
entryIds: batch.entryIds
|
|
676
|
+
}))));
|
|
677
|
+
}), Stream.unwrap),
|
|
678
|
+
fetch: (publicKey, storeId, stageId, sequences) => Clock.currentTimeMillis.pipe(Effect.flatMap(now => {
|
|
679
|
+
const found = findInputStage(publicKey, storeId, stageId, now);
|
|
680
|
+
if (found === undefined) return Effect.fail(new CompactionNotFound({
|
|
681
|
+
stageId
|
|
682
|
+
}));
|
|
683
|
+
const {
|
|
684
|
+
journal,
|
|
685
|
+
stage
|
|
686
|
+
} = found;
|
|
687
|
+
const fetched = [];
|
|
688
|
+
for (const sequence of sequences) {
|
|
689
|
+
const batch = sequence <= stage.pinned.base ? findBatch(stage.pinned.set?.batches ?? [], sequence) : sequence <= stage.through ? findBatch(journal.batches, sequence) : undefined;
|
|
690
|
+
if (batch !== undefined) fetched.push(batch);
|
|
691
|
+
}
|
|
692
|
+
return Effect.succeed(Stream.fromArray(fetched));
|
|
693
|
+
}), Stream.unwrap),
|
|
694
|
+
stagePart: (publicKey, storeId, stageId, segment, batches) => Effect.flatMap(Clock.currentTimeMillis, now => {
|
|
695
|
+
const found = findOpenStage(publicKey, storeId, stageId, now);
|
|
696
|
+
if (found === undefined) return Effect.fail(new CompactionNotFound({
|
|
697
|
+
stageId
|
|
698
|
+
}));
|
|
699
|
+
const {
|
|
700
|
+
journal,
|
|
701
|
+
stage
|
|
702
|
+
} = found;
|
|
703
|
+
const reject = message => {
|
|
704
|
+
closeStage(journal, stage);
|
|
705
|
+
return Effect.fail(new CompactionInvalidRequest({
|
|
706
|
+
stageId,
|
|
707
|
+
message
|
|
708
|
+
}));
|
|
709
|
+
};
|
|
710
|
+
if (!Number.isSafeInteger(segment) || segment < 0 || segment >= maxSegments) {
|
|
711
|
+
return reject("Invalid segment index");
|
|
712
|
+
}
|
|
713
|
+
if (batches.length > positionsPerSegment) return reject("Too many batches in a segment");
|
|
714
|
+
// Positions are the staged rows' key, so a retried segment inserts nothing.
|
|
715
|
+
let inserted = 0;
|
|
716
|
+
batches.forEach((batch, i) => {
|
|
717
|
+
const position = segment * positionsPerSegment + i;
|
|
718
|
+
if (stage.staged.has(position)) return;
|
|
719
|
+
stage.staged.set(position, batch);
|
|
720
|
+
inserted++;
|
|
721
|
+
});
|
|
722
|
+
if (inserted === 0) return Effect.succeed("AlreadyStored");
|
|
723
|
+
stage.expiresAt = now + stageTtlMillis;
|
|
724
|
+
return Effect.succeed("Stored");
|
|
725
|
+
}),
|
|
726
|
+
stagedHeaders: (publicKey, storeId, stageId) => Effect.flatMap(Clock.currentTimeMillis, now => {
|
|
727
|
+
const found = findOpenStage(publicKey, storeId, stageId, now);
|
|
728
|
+
if (found === undefined) {
|
|
729
|
+
return Effect.fail(new CompactionNotFound({
|
|
730
|
+
stageId
|
|
731
|
+
}));
|
|
732
|
+
}
|
|
733
|
+
return Effect.succeed(Stream.fromArray(stagedBatches(found.stage).map(({
|
|
734
|
+
batch,
|
|
735
|
+
position
|
|
736
|
+
}) => ({
|
|
737
|
+
position,
|
|
738
|
+
entryIds: batch.entryIds
|
|
739
|
+
}))));
|
|
740
|
+
}).pipe(Stream.unwrap),
|
|
741
|
+
commit: (publicKey, storeId, stageId, virtualSequences) => Effect.flatMap(Clock.currentTimeMillis, now => {
|
|
742
|
+
const found = findOpenStage(publicKey, storeId, stageId, now);
|
|
743
|
+
if (found === undefined) return Effect.fail(new CompactionNotFound({
|
|
744
|
+
stageId
|
|
745
|
+
}));
|
|
746
|
+
const {
|
|
747
|
+
journal,
|
|
748
|
+
stage
|
|
749
|
+
} = found;
|
|
750
|
+
if (stage.pinned !== journal.active) {
|
|
751
|
+
const keptCount = stagedBatches(stage).reduce((count, {
|
|
752
|
+
batch
|
|
753
|
+
}) => count + batch.entryIds.length, 0);
|
|
754
|
+
closeStage(journal, stage);
|
|
755
|
+
return Effect.as(logCommit({
|
|
756
|
+
publicKey,
|
|
757
|
+
storeId,
|
|
758
|
+
result: "Superseded",
|
|
759
|
+
through: stage.through,
|
|
760
|
+
keptCount,
|
|
761
|
+
activationId: undefined
|
|
762
|
+
}), "Superseded");
|
|
763
|
+
}
|
|
764
|
+
const staged = stagedBatches(stage);
|
|
765
|
+
if (staged.length !== virtualSequences.length) {
|
|
766
|
+
return Effect.die(new Cause.IllegalArgumentError("Expected one virtual sequence per staged batch"));
|
|
767
|
+
}
|
|
768
|
+
const keptCount = staged.reduce((count, {
|
|
769
|
+
batch
|
|
770
|
+
}) => count + batch.entryIds.length, 0);
|
|
771
|
+
const activation = {
|
|
772
|
+
id: SecureRandom.uuidV4Unsafe(),
|
|
773
|
+
set: {
|
|
774
|
+
batches: staged.map(({
|
|
775
|
+
batch
|
|
776
|
+
}, i) => ({
|
|
777
|
+
...batch,
|
|
778
|
+
sequence: virtualSequences[i]
|
|
779
|
+
}))
|
|
780
|
+
},
|
|
781
|
+
base: stage.through,
|
|
782
|
+
keptCount,
|
|
783
|
+
previous: journal.active,
|
|
784
|
+
supersededAt: undefined,
|
|
785
|
+
pruneStartedAt: undefined
|
|
786
|
+
};
|
|
787
|
+
journal.active.supersededAt = now;
|
|
788
|
+
journal.activations.push(activation);
|
|
789
|
+
journal.active = activation;
|
|
790
|
+
journal.noOp = undefined;
|
|
791
|
+
schedulePrune(journal, now + graceMillis);
|
|
792
|
+
closeStage(journal, stage);
|
|
793
|
+
// Log this commit's activation id. A concurrent rollback could change
|
|
794
|
+
// the active one before the logger runs.
|
|
795
|
+
return Effect.as(logCommit({
|
|
796
|
+
publicKey,
|
|
797
|
+
storeId,
|
|
798
|
+
result: "Committed",
|
|
799
|
+
through: stage.through,
|
|
800
|
+
keptCount,
|
|
801
|
+
activationId: activation.id
|
|
802
|
+
}), "Committed");
|
|
803
|
+
}),
|
|
804
|
+
recordNoOp: (publicKey, storeId, stageId) => Effect.flatMap(Clock.currentTimeMillis, now => {
|
|
805
|
+
const found = findOpenStage(publicKey, storeId, stageId, now);
|
|
806
|
+
if (found === undefined) return Effect.fail(new CompactionNotFound({
|
|
807
|
+
stageId
|
|
808
|
+
}));
|
|
809
|
+
const {
|
|
810
|
+
journal,
|
|
811
|
+
stage
|
|
812
|
+
} = found;
|
|
813
|
+
// A rollback since begin cleared the no-op state, so a stale run leaves it.
|
|
814
|
+
if (stage.pinned === journal.active) {
|
|
815
|
+
journal.noOp = {
|
|
816
|
+
at: stage.through,
|
|
817
|
+
count: (journal.noOp?.count ?? 0) + 1
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
closeStage(journal, stage);
|
|
821
|
+
return logNoOp({
|
|
822
|
+
publicKey,
|
|
823
|
+
storeId,
|
|
824
|
+
stageId,
|
|
825
|
+
through: stage.through
|
|
826
|
+
});
|
|
827
|
+
}),
|
|
828
|
+
abort: (publicKey, storeId, stageId) => Effect.sync(() => {
|
|
829
|
+
const journal = journals.get(makeEncryptedScopeKey({
|
|
830
|
+
publicKey,
|
|
831
|
+
storeId
|
|
832
|
+
}));
|
|
833
|
+
if (journal?.openStage?.id === stageId) closeStage(journal, journal.openStage);
|
|
834
|
+
}),
|
|
835
|
+
rollback: Effect.fnUntraced(function* (publicKey, storeId, expectedActivationId) {
|
|
836
|
+
const scopeKey = makeEncryptedScopeKey({
|
|
837
|
+
publicKey,
|
|
838
|
+
storeId
|
|
839
|
+
});
|
|
840
|
+
const pubsub = yield* RcMap.get(pubsubs, scopeKey);
|
|
841
|
+
const now = yield* Clock.currentTimeMillis;
|
|
842
|
+
return yield* Effect.suspend(() => {
|
|
843
|
+
const journal = ensureJournal(scopeKey);
|
|
844
|
+
const withdrawn = journal.active;
|
|
845
|
+
if (withdrawn.id !== expectedActivationId) {
|
|
846
|
+
return Effect.fail(new CompactionRollbackError({
|
|
847
|
+
reason: "NotActive"
|
|
848
|
+
}));
|
|
849
|
+
}
|
|
850
|
+
const target = withdrawn.previous;
|
|
851
|
+
if (target === undefined) return Effect.fail(new CompactionRollbackError({
|
|
852
|
+
reason: "NoPrevious"
|
|
853
|
+
}));
|
|
854
|
+
if (target.pruneStartedAt !== undefined) {
|
|
855
|
+
return Effect.fail(new CompactionRollbackError({
|
|
856
|
+
reason: "PruneStarted"
|
|
857
|
+
}));
|
|
858
|
+
}
|
|
859
|
+
const activation = {
|
|
860
|
+
...target,
|
|
861
|
+
id: SecureRandom.uuidV4Unsafe(),
|
|
862
|
+
supersededAt: undefined,
|
|
863
|
+
pruneStartedAt: undefined
|
|
864
|
+
};
|
|
865
|
+
// The input of the stage that built the withdrawn generation.
|
|
866
|
+
const input = [...(target.set?.batches ?? []), ...journal.batches.filter(batch => batch.sequence > target.base && batch.sequence + batch.entryIds.length - 1 <= withdrawn.base)];
|
|
867
|
+
withdrawn.supersededAt = now;
|
|
868
|
+
journal.activations.push(activation);
|
|
869
|
+
journal.active = activation;
|
|
870
|
+
journal.noOp = undefined;
|
|
871
|
+
schedulePrune(journal, now + graceMillis);
|
|
872
|
+
for (const {
|
|
873
|
+
encryptedBatch,
|
|
874
|
+
entryIds,
|
|
875
|
+
iv
|
|
876
|
+
} of input) {
|
|
877
|
+
const batch = {
|
|
878
|
+
sequence: journal.nextSequence,
|
|
879
|
+
entryIds,
|
|
880
|
+
iv,
|
|
881
|
+
encryptedBatch
|
|
882
|
+
};
|
|
883
|
+
journal.nextSequence += entryIds.length;
|
|
884
|
+
journal.batches.push(batch);
|
|
885
|
+
PubSub.publishUnsafe(pubsub, batch);
|
|
886
|
+
}
|
|
887
|
+
if (input.length > 0) recordBucket(journal, now, journal.nextSequence - 1);
|
|
888
|
+
return Effect.as(logRollback({
|
|
889
|
+
publicKey,
|
|
890
|
+
storeId,
|
|
891
|
+
activation,
|
|
892
|
+
withdrawn
|
|
893
|
+
}), activation.id);
|
|
894
|
+
});
|
|
895
|
+
}, Effect.scoped),
|
|
896
|
+
history: (publicKey, storeId) => Effect.sync(() => {
|
|
897
|
+
const journal = ensureJournal(makeEncryptedScopeKey({
|
|
898
|
+
publicKey,
|
|
899
|
+
storeId
|
|
900
|
+
}));
|
|
901
|
+
return journal.activations.map(activation => ({
|
|
902
|
+
activationId: activation.id,
|
|
903
|
+
base: activation.base,
|
|
904
|
+
keptCount: activation.keptCount,
|
|
905
|
+
active: activation === journal.active,
|
|
906
|
+
supersededAt: activation === journal.active ? undefined : activation.supersededAt,
|
|
907
|
+
restorable: activation.pruneStartedAt === undefined
|
|
908
|
+
}));
|
|
909
|
+
})
|
|
910
|
+
};
|
|
197
911
|
return Storage.of({
|
|
198
912
|
getId: Effect.succeed(remoteId),
|
|
199
913
|
getOrCreateSessionAuthBinding: (publicKey, signingPublicKey) => Effect.sync(() => {
|
|
@@ -208,6 +922,7 @@ export const makeStorageMemory = /*#__PURE__*/Effect.gen(function* () {
|
|
|
208
922
|
storeId
|
|
209
923
|
});
|
|
210
924
|
const pubsub = yield* RcMap.get(pubsubs, scopeKey);
|
|
925
|
+
const now = yield* Clock.currentTimeMillis;
|
|
211
926
|
const journal = ensureJournal(scopeKey);
|
|
212
927
|
const stored = [];
|
|
213
928
|
for (const batch of batches) {
|
|
@@ -225,6 +940,7 @@ export const makeStorageMemory = /*#__PURE__*/Effect.gen(function* () {
|
|
|
225
940
|
stored.push(remoteBatch);
|
|
226
941
|
PubSub.publishUnsafe(pubsub, remoteBatch);
|
|
227
942
|
}
|
|
943
|
+
if (stored.length > 0) recordBucket(journal, now, journal.nextSequence - 1);
|
|
228
944
|
return stored;
|
|
229
945
|
}, Effect.scoped),
|
|
230
946
|
entrySequences: (publicKey, storeId, entryIds) => Effect.sync(() => {
|
|
@@ -249,20 +965,59 @@ export const makeStorageMemory = /*#__PURE__*/Effect.gen(function* () {
|
|
|
249
965
|
});
|
|
250
966
|
const pubsub = yield* RcMap.get(pubsubs, scopeKey);
|
|
251
967
|
const subscription = yield* PubSub.subscribe(pubsub);
|
|
252
|
-
const
|
|
968
|
+
const journal = ensureJournal(scopeKey);
|
|
969
|
+
const {
|
|
970
|
+
base,
|
|
971
|
+
set
|
|
972
|
+
} = journal.active;
|
|
973
|
+
const live = Stream.fromSubscription(subscription);
|
|
974
|
+
// Below the base an active snapshot replaces the originals.
|
|
975
|
+
if (set !== undefined && startSequence <= base) {
|
|
976
|
+
if (set.batches.length === 0) {
|
|
977
|
+
return Stream.die(new Error(`The active compaction snapshot of store ${storeId} has no batches`));
|
|
978
|
+
}
|
|
979
|
+
const tail = journal.batches.filter(batch => batch.sequence > base);
|
|
980
|
+
return Stream.fromArray([...set.batches.filter(batch => batch.sequence + batch.entryIds.length > startSequence), ...tail]).pipe(Stream.concat(live));
|
|
981
|
+
}
|
|
982
|
+
const batches = journal.batches;
|
|
253
983
|
const first = batches.findIndex(batch => batch.sequence + batch.entryIds.length > startSequence);
|
|
254
|
-
return Stream.fromArray(first === -1 ? [] : batches.slice(first)).pipe(Stream.concat(
|
|
255
|
-
}, Stream.unwrap)
|
|
984
|
+
return Stream.fromArray(first === -1 ? [] : batches.slice(first)).pipe(Stream.concat(live));
|
|
985
|
+
}, Stream.unwrap),
|
|
986
|
+
compaction
|
|
256
987
|
});
|
|
257
988
|
});
|
|
258
989
|
/**
|
|
259
|
-
* Provides encrypted server `Storage` using the in-memory implementation
|
|
990
|
+
* Provides encrypted server `Storage` using the in-memory implementation with
|
|
991
|
+
* default compaction tuning.
|
|
992
|
+
*
|
|
993
|
+
* @see {@link layerStorageMemoryWith} to configure compaction
|
|
260
994
|
*
|
|
261
995
|
* @stability unstable
|
|
262
996
|
* @category layers
|
|
263
997
|
* @since 4.0.0
|
|
264
998
|
*/
|
|
265
999
|
export const layerStorageMemory = /*#__PURE__*/Layer.effect(Storage)(makeStorageMemory);
|
|
1000
|
+
/**
|
|
1001
|
+
* Provides encrypted server `Storage` using the in-memory implementation.
|
|
1002
|
+
*
|
|
1003
|
+
* @stability unstable
|
|
1004
|
+
* @category layers
|
|
1005
|
+
* @since 4.0.0
|
|
1006
|
+
*/
|
|
1007
|
+
export const layerStorageMemoryWith = options => Layer.effect(Storage)(makeStorageMemoryWith(options));
|
|
1008
|
+
const stagedBatches = stage => Array.from(stage.staged, ([position, batch]) => ({
|
|
1009
|
+
batch,
|
|
1010
|
+
position
|
|
1011
|
+
})).sort((a, b) => a.position - b.position);
|
|
1012
|
+
const findBatch = (batches, sequence) => {
|
|
1013
|
+
let low = 0;
|
|
1014
|
+
let high = batches.length;
|
|
1015
|
+
while (low < high) {
|
|
1016
|
+
const mid = low + high >>> 1;
|
|
1017
|
+
if (batches[mid].sequence < sequence) low = mid + 1;else high = mid;
|
|
1018
|
+
}
|
|
1019
|
+
return batches[low]?.sequence === sequence ? batches[low] : undefined;
|
|
1020
|
+
};
|
|
266
1021
|
const makeEncryptedScopeKey = ({
|
|
267
1022
|
publicKey,
|
|
268
1023
|
storeId
|