effect 4.0.5 → 4.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai-docs/package.json +1 -1
- package/ai-docs/src/06_schedule/10_schedules.ts +5 -4
- package/ai-docs/tsconfig.json +3 -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/Array.d.ts +117 -52
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +41 -20
- package/dist/Array.js.map +1 -1
- package/dist/Bytes.d.ts +79 -0
- package/dist/Bytes.d.ts.map +1 -0
- package/dist/Bytes.js +109 -0
- package/dist/Bytes.js.map +1 -0
- package/dist/Channel.d.ts +181 -13
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +144 -34
- package/dist/Channel.js.map +1 -1
- package/dist/ChannelSchema.d.ts.map +1 -1
- package/dist/ChannelSchema.js.map +1 -1
- package/dist/Chunk.d.ts +39 -21
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Chunk.js +26 -17
- package/dist/Chunk.js.map +1 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js +8 -3
- package/dist/Config.js.map +1 -1
- package/dist/ConfigProvider.d.ts.map +1 -1
- package/dist/ConfigProvider.js +2 -1
- package/dist/ConfigProvider.js.map +1 -1
- package/dist/Cron.d.ts +2 -2
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +6 -3
- 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.map +1 -1
- package/dist/Duration.js +56 -16
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +488 -164
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +204 -38
- 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/Equivalence.d.ts +2 -1
- package/dist/Equivalence.d.ts.map +1 -1
- package/dist/Equivalence.js +12 -8
- package/dist/Equivalence.js.map +1 -1
- package/dist/Exit.d.ts +27 -12
- package/dist/Exit.d.ts.map +1 -1
- package/dist/Exit.js +8 -3
- package/dist/Exit.js.map +1 -1
- package/dist/FiberHandle.d.ts +2 -0
- package/dist/FiberHandle.d.ts.map +1 -1
- package/dist/FiberHandle.js +9 -4
- package/dist/FiberHandle.js.map +1 -1
- package/dist/FiberMap.d.ts +2 -0
- package/dist/FiberMap.d.ts.map +1 -1
- package/dist/FiberMap.js +5 -2
- package/dist/FiberMap.js.map +1 -1
- package/dist/FileSystem.d.ts +5 -0
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +3 -0
- 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/Graph.d.ts.map +1 -1
- package/dist/Graph.js.map +1 -1
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +4 -1
- package/dist/Hash.js.map +1 -1
- package/dist/HashSet.d.ts.map +1 -1
- package/dist/HashSet.js.map +1 -1
- package/dist/Iterable.d.ts.map +1 -1
- package/dist/Iterable.js +18 -17
- package/dist/Iterable.js.map +1 -1
- package/dist/JsonPatch.js +4 -0
- package/dist/JsonPatch.js.map +1 -1
- package/dist/JsonSchema.d.ts +9 -3
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +32 -43
- package/dist/JsonSchema.js.map +1 -1
- package/dist/Layer.d.ts.map +1 -1
- package/dist/Layer.js +2 -2
- package/dist/Layer.js.map +1 -1
- package/dist/ManagedRuntime.d.ts +19 -1
- package/dist/ManagedRuntime.d.ts.map +1 -1
- package/dist/ManagedRuntime.js +62 -6
- package/dist/ManagedRuntime.js.map +1 -1
- package/dist/Metric.d.ts +135 -3
- package/dist/Metric.d.ts.map +1 -1
- package/dist/Metric.js +197 -25
- package/dist/Metric.js.map +1 -1
- package/dist/MutableHashMap.d.ts.map +1 -1
- package/dist/MutableHashMap.js.map +1 -1
- 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/Number.js +2 -2
- package/dist/Number.js.map +1 -1
- package/dist/Optic.d.ts.map +1 -1
- package/dist/Optic.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/Path.d.ts.map +1 -1
- package/dist/Path.js +8 -1
- package/dist/Path.js.map +1 -1
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +77 -27
- package/dist/Pool.js.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/PubSub.js +17 -13
- package/dist/PubSub.js.map +1 -1
- package/dist/Queue.d.ts +4 -1
- package/dist/Queue.d.ts.map +1 -1
- package/dist/Queue.js +4 -1
- package/dist/Queue.js.map +1 -1
- package/dist/Random.d.ts.map +1 -1
- package/dist/Random.js +1 -1
- package/dist/Random.js.map +1 -1
- package/dist/RcMap.d.ts +12 -7
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/RcMap.js +9 -6
- package/dist/RcMap.js.map +1 -1
- package/dist/Record.d.ts +51 -0
- package/dist/Record.d.ts.map +1 -1
- package/dist/Record.js +17 -0
- package/dist/Record.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/References.d.ts +5 -4
- package/dist/References.d.ts.map +1 -1
- package/dist/References.js +5 -4
- package/dist/References.js.map +1 -1
- package/dist/RequestResolver.d.ts +31 -1
- package/dist/RequestResolver.d.ts.map +1 -1
- package/dist/RequestResolver.js +39 -4
- package/dist/RequestResolver.js.map +1 -1
- package/dist/Resource.js +1 -1
- package/dist/Resource.js.map +1 -1
- package/dist/Runtime.d.ts +3 -3
- package/dist/Runtime.d.ts.map +1 -1
- package/dist/Runtime.js +18 -15
- package/dist/Runtime.js.map +1 -1
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +1 -1
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +408 -340
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +370 -47
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +9 -7
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +38 -25
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaGetter.d.ts +8 -3
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +15 -5
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/SchemaIssue.d.ts +4 -4
- package/dist/SchemaIssue.d.ts.map +1 -1
- package/dist/SchemaIssue.js +29 -51
- package/dist/SchemaIssue.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 +75 -11
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +41 -13
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +5 -2
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +10 -3
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/Scope.d.ts +12 -2
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +5 -0
- package/dist/Scope.js.map +1 -1
- package/dist/ScopedCache.d.ts +10 -7
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedCache.js +9 -5
- package/dist/ScopedCache.js.map +1 -1
- package/dist/SemVer.d.ts +1196 -0
- package/dist/SemVer.d.ts.map +1 -0
- package/dist/SemVer.js +756 -0
- package/dist/SemVer.js.map +1 -0
- package/dist/SemVerRange.d.ts +559 -0
- package/dist/SemVerRange.d.ts.map +1 -0
- package/dist/SemVerRange.js +551 -0
- package/dist/SemVerRange.js.map +1 -0
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Semaphore.js +54 -35
- package/dist/Semaphore.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +13 -4
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts +235 -8
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +167 -70
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +7 -2
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +11 -6
- package/dist/String.js.map +1 -1
- package/dist/TextDiff.d.ts +399 -0
- package/dist/TextDiff.d.ts.map +1 -0
- package/dist/TextDiff.js +634 -0
- package/dist/TextDiff.js.map +1 -0
- 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/TxHashMap.d.ts.map +1 -1
- package/dist/TxHashMap.js.map +1 -1
- package/dist/TxHashSet.d.ts.map +1 -1
- package/dist/TxHashSet.js.map +1 -1
- package/dist/ai/AiError.d.ts +68 -4
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +50 -2
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Chat.d.ts +1 -2
- package/dist/ai/Chat.d.ts.map +1 -1
- package/dist/ai/Chat.js +6 -3
- package/dist/ai/Chat.js.map +1 -1
- package/dist/ai/Decision.d.ts +46 -1
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.d.ts +129 -11
- package/dist/ai/DecisionModel.d.ts.map +1 -1
- package/dist/ai/DecisionModel.js +182 -94
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/EmbeddingModel.d.ts +10 -0
- package/dist/ai/EmbeddingModel.d.ts.map +1 -1
- package/dist/ai/EmbeddingModel.js +21 -7
- package/dist/ai/EmbeddingModel.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/McpClient.d.ts +289 -0
- package/dist/ai/McpClient.d.ts.map +1 -0
- package/dist/ai/McpClient.js +819 -0
- package/dist/ai/McpClient.js.map +1 -0
- package/dist/ai/McpClientError.d.ts +254 -0
- package/dist/ai/McpClientError.d.ts.map +1 -0
- package/dist/ai/McpClientError.js +260 -0
- package/dist/ai/McpClientError.js.map +1 -0
- package/dist/ai/McpProtocol.d.ts +2 -2
- package/dist/ai/McpProtocol.d.ts.map +1 -1
- package/dist/ai/McpSchema.d.ts +258 -125
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpSchema.js +94 -24
- package/dist/ai/McpSchema.js.map +1 -1
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +46 -37
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts +74 -20
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +61 -1
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +160 -3
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +39 -37
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +36 -4
- 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 +48 -1
- package/dist/ai/Toolkit.d.ts.map +1 -1
- package/dist/ai/Toolkit.js +73 -13
- package/dist/ai/Toolkit.js.map +1 -1
- package/dist/ai/index.d.ts +10 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +10 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/internal/mcpCore.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +2 -2
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +2 -2
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +4 -7
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js +16 -2
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +3 -4
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2024_11_05.js +19 -13
- package/dist/ai/internal/mcpSchema/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2025_03_26.js +3 -2
- package/dist/ai/internal/mcpSchema/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2025_06_18.js +7 -7
- package/dist/ai/internal/mcpSchema/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2025_11_25.js +8 -8
- package/dist/ai/internal/mcpSchema/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpSchema/v2026_07_28.js +43 -42
- package/dist/ai/internal/mcpSchema/v2026_07_28.js.map +1 -1
- package/dist/cli/Argument.d.ts +15 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +5 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliError.d.ts +120 -2
- package/dist/cli/CliError.d.ts.map +1 -1
- package/dist/cli/CliError.js +106 -5
- package/dist/cli/CliError.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +155 -6
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +62 -6
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +310 -18
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +164 -33
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +63 -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 +130 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +61 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +14 -6
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/Param.d.ts +116 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +77 -2
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/TerminalCapabilities.d.ts +85 -0
- package/dist/cli/TerminalCapabilities.d.ts.map +1 -0
- package/dist/cli/TerminalCapabilities.js +124 -0
- package/dist/cli/TerminalCapabilities.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/internal/command.d.ts +2 -1
- package/dist/cli/internal/command.d.ts.map +1 -1
- package/dist/cli/internal/command.js +5 -2
- package/dist/cli/internal/command.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +77 -30
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cli/internal/completions/descriptor.js +9 -1
- package/dist/cli/internal/completions/descriptor.js.map +1 -1
- package/dist/cli/internal/completions/fish.js +10 -8
- package/dist/cli/internal/completions/fish.js.map +1 -1
- package/dist/cli/internal/completions/powershell.js +18 -9
- package/dist/cli/internal/completions/powershell.js.map +1 -1
- package/dist/cli/internal/completions/zsh.js +8 -5
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/formatter.d.ts +2 -0
- package/dist/cli/internal/formatter.d.ts.map +1 -0
- package/dist/cli/internal/formatter.js +15 -0
- package/dist/cli/internal/formatter.js.map +1 -0
- package/dist/cli/internal/lexer.js +24 -10
- package/dist/cli/internal/lexer.js.map +1 -1
- package/dist/cli/internal/parser.js +24 -12
- package/dist/cli/internal/parser.js.map +1 -1
- package/dist/cluster/ClusterCron.d.ts +29 -1
- package/dist/cluster/ClusterCron.d.ts.map +1 -1
- package/dist/cluster/ClusterCron.js +64 -32
- package/dist/cluster/ClusterCron.js.map +1 -1
- package/dist/cluster/ClusterMetrics.d.ts +143 -7
- package/dist/cluster/ClusterMetrics.d.ts.map +1 -1
- package/dist/cluster/ClusterMetrics.js +151 -7
- package/dist/cluster/ClusterMetrics.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +82 -21
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/Entity.d.ts +2 -0
- package/dist/cluster/Entity.d.ts.map +1 -1
- package/dist/cluster/Entity.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +44 -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/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +54 -15
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts +1 -0
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +155 -52
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +30 -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/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.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +40 -50
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts +2 -2
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +97 -43
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +119 -28
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/devtools/DevTools.d.ts +3 -2
- package/dist/devtools/DevTools.d.ts.map +1 -1
- package/dist/devtools/DevTools.js +3 -2
- package/dist/devtools/DevTools.js.map +1 -1
- package/dist/devtools/DevToolsClient.d.ts +11 -0
- package/dist/devtools/DevToolsClient.d.ts.map +1 -1
- package/dist/devtools/DevToolsClient.js +33 -4
- 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 +29 -0
- package/dist/encoding/Base64Url.d.ts.map +1 -1
- package/dist/encoding/Base64Url.js +29 -0
- package/dist/encoding/Base64Url.js.map +1 -1
- package/dist/encoding/Ini.d.ts.map +1 -1
- package/dist/encoding/Ini.js +3 -0
- package/dist/encoding/Ini.js.map +1 -1
- package/dist/encoding/JsonArray.d.ts +270 -0
- package/dist/encoding/JsonArray.d.ts.map +1 -0
- package/dist/encoding/JsonArray.js +691 -0
- package/dist/encoding/JsonArray.js.map +1 -0
- package/dist/encoding/Ndjson.d.ts +43 -4
- package/dist/encoding/Ndjson.d.ts.map +1 -1
- package/dist/encoding/Ndjson.js +169 -18
- package/dist/encoding/Ndjson.js.map +1 -1
- package/dist/encoding/SchemaBinary.d.ts +9 -1
- package/dist/encoding/SchemaBinary.d.ts.map +1 -1
- package/dist/encoding/SchemaBinary.js +12 -19
- 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/Tar.d.ts +309 -0
- package/dist/encoding/Tar.d.ts.map +1 -0
- package/dist/encoding/Tar.js +1182 -0
- package/dist/encoding/Tar.js.map +1 -0
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +24 -19
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/encoding/Xml.d.ts +464 -0
- package/dist/encoding/Xml.d.ts.map +1 -0
- package/dist/encoding/Xml.js +1619 -0
- package/dist/encoding/Xml.js.map +1 -0
- package/dist/encoding/Yaml.d.ts +6 -2
- package/dist/encoding/Yaml.d.ts.map +1 -1
- package/dist/encoding/Yaml.js +97 -34
- package/dist/encoding/Yaml.js.map +1 -1
- package/dist/encoding/Zip.d.ts +413 -0
- package/dist/encoding/Zip.d.ts.map +1 -0
- package/dist/encoding/Zip.js +1255 -0
- package/dist/encoding/Zip.js.map +1 -0
- package/dist/encoding/index.d.ts +20 -0
- package/dist/encoding/index.d.ts.map +1 -1
- package/dist/encoding/index.js +20 -0
- package/dist/encoding/index.js.map +1 -1
- package/dist/eventlog/EventJournal.d.ts +90 -5
- package/dist/eventlog/EventJournal.d.ts.map +1 -1
- package/dist/eventlog/EventJournal.js +488 -228
- package/dist/eventlog/EventJournal.js.map +1 -1
- package/dist/eventlog/EventLog.d.ts +180 -12
- package/dist/eventlog/EventLog.d.ts.map +1 -1
- package/dist/eventlog/EventLog.js +394 -146
- package/dist/eventlog/EventLog.js.map +1 -1
- package/dist/eventlog/EventLogEncryption.d.ts +36 -30
- package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
- package/dist/eventlog/EventLogEncryption.js +97 -38
- package/dist/eventlog/EventLogEncryption.js.map +1 -1
- package/dist/eventlog/EventLogMessage.d.ts +74 -34
- package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
- package/dist/eventlog/EventLogMessage.js +45 -11
- package/dist/eventlog/EventLogMessage.js.map +1 -1
- package/dist/eventlog/EventLogRemote.d.ts +45 -8
- package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
- package/dist/eventlog/EventLogRemote.js +51 -14
- package/dist/eventlog/EventLogRemote.js.map +1 -1
- package/dist/eventlog/EventLogServer.d.ts +46 -3
- package/dist/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/eventlog/EventLogServer.js +119 -19
- package/dist/eventlog/EventLogServer.js.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.d.ts +23 -33
- package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.js +97 -70
- package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/EventLogServerUnencrypted.d.ts +39 -5
- package/dist/eventlog/EventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerUnencrypted.js +151 -69
- package/dist/eventlog/EventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/EventRow.d.ts +288 -0
- package/dist/eventlog/EventRow.d.ts.map +1 -0
- package/dist/eventlog/EventRow.js +435 -0
- package/dist/eventlog/EventRow.js.map +1 -0
- package/dist/eventlog/SqlEventJournal.d.ts +18 -18
- package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +417 -169
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +10 -18
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.js +179 -69
- package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.d.ts +23 -3
- package/dist/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.js +102 -51
- package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/index.d.ts +5 -0
- package/dist/eventlog/index.d.ts.map +1 -1
- package/dist/eventlog/index.js +5 -0
- package/dist/eventlog/index.js.map +1 -1
- package/dist/eventlog/internal/conflicts.d.ts +46 -0
- package/dist/eventlog/internal/conflicts.d.ts.map +1 -0
- package/dist/eventlog/internal/conflicts.js +89 -0
- package/dist/eventlog/internal/conflicts.js.map +1 -0
- package/dist/graphql/GraphQLClientError.d.ts +2 -2
- package/dist/graphql/GraphQLClientError.d.ts.map +1 -1
- package/dist/graphql/GraphQLClientError.js +4 -18
- package/dist/graphql/GraphQLClientError.js.map +1 -1
- package/dist/graphql/GraphQLProtocol.d.ts +12 -9
- package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
- package/dist/graphql/GraphQLProtocol.js +4 -3
- package/dist/graphql/GraphQLProtocol.js.map +1 -1
- package/dist/graphql/GraphQLResolver.d.ts +2 -0
- package/dist/graphql/GraphQLResolver.d.ts.map +1 -1
- package/dist/graphql/GraphQLResolver.js +74 -32
- package/dist/graphql/GraphQLResolver.js.map +1 -1
- package/dist/http/Cookies.d.ts.map +1 -1
- package/dist/http/Cookies.js +10 -9
- package/dist/http/Cookies.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +8 -1
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +51 -4
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +10 -0
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/Headers.d.ts +227 -0
- package/dist/http/Headers.d.ts.map +1 -1
- package/dist/http/Headers.js +261 -0
- package/dist/http/Headers.js.map +1 -1
- package/dist/http/HttpClient.d.ts +516 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +286 -23
- 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 +127 -3
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +45 -3
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpClientResponse.d.ts +53 -0
- package/dist/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/http/HttpClientResponse.js +47 -0
- package/dist/http/HttpClientResponse.js.map +1 -1
- package/dist/http/HttpEffect.d.ts +6 -2
- package/dist/http/HttpEffect.d.ts.map +1 -1
- package/dist/http/HttpEffect.js +21 -17
- package/dist/http/HttpEffect.js.map +1 -1
- package/dist/http/HttpIncomingMessage.d.ts +2 -1
- package/dist/http/HttpIncomingMessage.d.ts.map +1 -1
- package/dist/http/HttpIncomingMessage.js +3 -23
- package/dist/http/HttpIncomingMessage.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +119 -2
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +173 -29
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +9 -3
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.d.ts +5 -2
- package/dist/http/HttpServerError.d.ts.map +1 -1
- package/dist/http/HttpServerError.js +7 -5
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +30 -5
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +109 -20
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts +17 -8
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +37 -21
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts +0 -12
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +65 -24
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.d.ts +15 -1
- package/dist/http/MultipartParser/internal/contentType.d.ts.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.js +89 -7
- package/dist/http/MultipartParser/internal/contentType.js.map +1 -1
- package/dist/http/MultipartParser/internal/headers.d.ts.map +1 -1
- package/dist/http/MultipartParser/internal/headers.js +4 -12
- package/dist/http/MultipartParser/internal/headers.js.map +1 -1
- package/dist/http/MultipartParser/internal/multipart.d.ts.map +1 -1
- package/dist/http/MultipartParser/internal/multipart.js +6 -27
- package/dist/http/MultipartParser/internal/multipart.js.map +1 -1
- package/dist/http/Url.d.ts.map +1 -1
- package/dist/http/Url.js +6 -1
- package/dist/http/Url.js.map +1 -1
- package/dist/http/UrlParams.d.ts +3 -1
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +4 -2
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.js +4 -5
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/decompression.js +20 -11
- 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/lazyStream.d.ts +2 -0
- package/dist/http/internal/lazyStream.d.ts.map +1 -0
- package/dist/http/internal/lazyStream.js +18 -0
- package/dist/http/internal/lazyStream.js.map +1 -0
- package/dist/http/internal/requestState.d.ts +2 -0
- package/dist/http/internal/requestState.d.ts.map +1 -0
- package/dist/http/internal/requestState.js +28 -0
- package/dist/http/internal/requestState.js.map +1 -0
- package/dist/http/internal/urlParams.js +25 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http/internal/webResponse.d.ts +2 -0
- package/dist/http/internal/webResponse.d.ts.map +1 -0
- package/dist/http/internal/webResponse.js +12 -0
- package/dist/http/internal/webResponse.js.map +1 -0
- 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 +4 -7
- 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 +142 -23
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +99 -4
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +218 -60
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts +72 -29
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +140 -14
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiError.d.ts +58 -0
- package/dist/http-api/HttpApiError.d.ts.map +1 -1
- package/dist/http-api/HttpApiError.js +38 -12
- package/dist/http-api/HttpApiError.js.map +1 -1
- package/dist/http-api/HttpApiScalar.d.ts +2 -1
- package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
- package/dist/http-api/HttpApiScalar.js +6 -3
- package/dist/http-api/HttpApiScalar.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +242 -13
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +149 -5
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/http-api/HttpApiSwagger.d.ts +5 -0
- package/dist/http-api/HttpApiSwagger.d.ts.map +1 -1
- package/dist/http-api/HttpApiSwagger.js +14 -4
- package/dist/http-api/HttpApiSwagger.js.map +1 -1
- package/dist/http-api/HttpApiTest.d.ts +13 -2
- package/dist/http-api/HttpApiTest.d.ts.map +1 -1
- package/dist/http-api/HttpApiTest.js +33 -11
- package/dist/http-api/HttpApiTest.js.map +1 -1
- package/dist/http-api/OpenApi.d.ts +17 -3
- package/dist/http-api/OpenApi.d.ts.map +1 -1
- package/dist/http-api/OpenApi.js +81 -47
- package/dist/http-api/OpenApi.js.map +1 -1
- package/dist/http-api/internal/path.js +35 -10
- package/dist/http-api/internal/path.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 +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- 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 +3 -1
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/dateTime.js +19 -7
- package/dist/internal/dateTime.js.map +1 -1
- package/dist/internal/effect.js +106 -87
- 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/hashMap.js +2 -2
- package/dist/internal/hashMap.js.map +1 -1
- package/dist/internal/hydration.d.ts +2 -0
- package/dist/internal/hydration.d.ts.map +1 -0
- package/dist/internal/hydration.js +15 -0
- package/dist/internal/hydration.js.map +1 -0
- package/dist/internal/inflate.d.ts +2 -0
- package/dist/internal/inflate.d.ts.map +1 -0
- package/dist/internal/inflate.js +680 -0
- package/dist/internal/inflate.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 +1 -1
- package/dist/internal/matcher.js.map +1 -1
- package/dist/internal/record.js +6 -0
- package/dist/internal/record.js.map +1 -1
- package/dist/internal/request.js +20 -7
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/schedule.js +17 -22
- package/dist/internal/schedule.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 +253 -255
- 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/interpreter.js +51 -36
- package/dist/internal/schema/interpreter.js.map +1 -1
- package/dist/internal/schema/standardSchema.js +42 -35
- package/dist/internal/schema/standardSchema.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +10 -5
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +99 -17
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toFormatter.js +5 -5
- package/dist/internal/schema/toFormatter.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +257 -170
- 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 +1 -3
- package/dist/internal/trie.js.map +1 -1
- package/dist/internal/uuid.js +7 -3
- package/dist/internal/uuid.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/net/NetAddress.d.ts.map +1 -1
- package/dist/net/NetAddress.js +2 -8
- package/dist/net/NetAddress.js.map +1 -1
- package/dist/observability/OtlpExporter.d.ts.map +1 -1
- package/dist/observability/OtlpExporter.js +5 -12
- package/dist/observability/OtlpExporter.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +5 -3
- package/dist/observability/OtlpMetrics.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 +3 -1
- package/dist/observability/OtlpResource.d.ts.map +1 -1
- package/dist/observability/OtlpResource.js +11 -4
- package/dist/observability/OtlpResource.js.map +1 -1
- package/dist/observability/OtlpSerialization.d.ts +5 -0
- package/dist/observability/OtlpSerialization.d.ts.map +1 -1
- package/dist/observability/OtlpSerialization.js +14 -3
- package/dist/observability/OtlpSerialization.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/observability/internal/protobuf.d.ts +0 -9
- package/dist/observability/internal/protobuf.d.ts.map +1 -1
- package/dist/observability/internal/protobuf.js +2 -10
- package/dist/observability/internal/protobuf.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/PersistedCache.d.ts.map +1 -1
- package/dist/persistence/PersistedCache.js +1 -1
- package/dist/persistence/PersistedCache.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +6 -2
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +162 -84
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/persistence/Persistence.d.ts +28 -0
- package/dist/persistence/Persistence.d.ts.map +1 -1
- package/dist/persistence/Persistence.js +36 -8
- package/dist/persistence/Persistence.js.map +1 -1
- package/dist/persistence/RateLimiter.d.ts.map +1 -1
- package/dist/persistence/RateLimiter.js +8 -12
- package/dist/persistence/RateLimiter.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/UserDirectories.d.ts +129 -0
- package/dist/persistence/UserDirectories.d.ts.map +1 -0
- package/dist/persistence/UserDirectories.js +178 -0
- package/dist/persistence/UserDirectories.js.map +1 -0
- package/dist/persistence/index.d.ts +10 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +10 -0
- package/dist/persistence/index.js.map +1 -1
- package/dist/process/ChildProcess.d.ts +32 -5
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/process/ChildProcessSpawner.d.ts +30 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/process/ChildProcessSpawner.js +5 -2
- package/dist/process/ChildProcessSpawner.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +1 -1
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/reactivity/AsyncResult.js +1 -1
- package/dist/reactivity/AsyncResult.js.map +1 -1
- package/dist/reactivity/Atom.d.ts +69 -30
- package/dist/reactivity/Atom.d.ts.map +1 -1
- package/dist/reactivity/Atom.js +40 -15
- package/dist/reactivity/Atom.js.map +1 -1
- package/dist/reactivity/AtomHttpApi.d.ts +5 -5
- package/dist/reactivity/AtomHttpApi.d.ts.map +1 -1
- package/dist/reactivity/AtomHttpApi.js +1 -1
- package/dist/reactivity/AtomHttpApi.js.map +1 -1
- package/dist/reactivity/AtomRegistry.d.ts +2 -2
- package/dist/reactivity/AtomRegistry.d.ts.map +1 -1
- package/dist/reactivity/AtomRegistry.js +44 -9
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/reactivity/AtomRpc.d.ts +3 -3
- package/dist/reactivity/AtomRpc.d.ts.map +1 -1
- package/dist/reactivity/AtomRpc.js +1 -1
- package/dist/reactivity/AtomRpc.js.map +1 -1
- package/dist/reactivity/Hydration.d.ts.map +1 -1
- package/dist/reactivity/Hydration.js +46 -12
- package/dist/reactivity/Hydration.js.map +1 -1
- package/dist/reactivity/Reactivity.d.ts +71 -7
- package/dist/reactivity/Reactivity.d.ts.map +1 -1
- package/dist/reactivity/Reactivity.js +21 -12
- package/dist/reactivity/Reactivity.js.map +1 -1
- package/dist/rpc/Rpc.d.ts +18 -0
- package/dist/rpc/Rpc.d.ts.map +1 -1
- package/dist/rpc/Rpc.js +20 -0
- package/dist/rpc/Rpc.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +26 -2
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +198 -61
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts +29 -0
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +41 -13
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +20 -19
- 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 +1 -1
- package/dist/schema/VariantSchema.d.ts +22 -3
- package/dist/schema/VariantSchema.d.ts.map +1 -1
- package/dist/schema/VariantSchema.js +32 -18
- package/dist/schema/VariantSchema.js.map +1 -1
- package/dist/socket/Socket.d.ts +23 -1
- package/dist/socket/Socket.d.ts.map +1 -1
- package/dist/socket/Socket.js +36 -3
- package/dist/socket/Socket.js.map +1 -1
- package/dist/sql/Migrator.d.ts +2 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +21 -6
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +148 -5
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +155 -27
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/SqlResolver.d.ts +13 -0
- package/dist/sql/SqlResolver.d.ts.map +1 -1
- package/dist/sql/SqlResolver.js +27 -4
- package/dist/sql/SqlResolver.js.map +1 -1
- package/dist/sql/Statement.d.ts +10 -1
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +45 -7
- package/dist/sql/Statement.js.map +1 -1
- package/dist/testing/TestClock.d.ts.map +1 -1
- package/dist/testing/TestClock.js +4 -2
- package/dist/testing/TestClock.js.map +1 -1
- package/dist/testing/TestSchema.d.ts +7 -1
- package/dist/testing/TestSchema.d.ts.map +1 -1
- package/dist/testing/TestSchema.js +9 -3
- package/dist/testing/TestSchema.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/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +18 -4
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +13 -3
- package/src/Arbitrary.ts +10 -2
- package/src/Array.ts +128 -55
- package/src/Bytes.ts +111 -0
- package/src/Channel.ts +308 -452
- package/src/ChannelSchema.ts +1 -49
- package/src/Chunk.ts +55 -61
- package/src/Config.ts +12 -86
- package/src/ConfigProvider.ts +2 -1
- package/src/Cron.ts +6 -3
- package/src/Data.ts +60 -265
- package/src/Duration.ts +66 -16
- package/src/Effect.ts +503 -168
- package/src/Equal.ts +8 -1
- package/src/Equivalence.ts +7 -4
- package/src/Exit.ts +27 -12
- package/src/FiberHandle.ts +10 -9
- package/src/FiberMap.ts +13 -66
- package/src/FileSystem.ts +10 -0
- package/src/Formatter.ts +28 -13
- package/src/Graph.ts +171 -1263
- package/src/Hash.ts +4 -1
- package/src/HashSet.ts +0 -60
- package/src/Iterable.ts +15 -14
- package/src/JsonPatch.ts +4 -0
- package/src/JsonSchema.ts +40 -43
- package/src/Layer.ts +2 -2
- package/src/ManagedRuntime.ts +72 -6
- package/src/Metric.ts +252 -510
- package/src/MutableHashMap.ts +4 -473
- package/src/MutableList.ts +7 -5
- package/src/MutableRef.ts +8 -1
- package/src/Number.ts +2 -2
- package/src/Optic.ts +17 -332
- package/src/PartitionedSemaphore.ts +24 -13
- package/src/Path.ts +9 -1
- package/src/Pool.ts +109 -37
- package/src/PubSub.ts +17 -13
- package/src/Queue.ts +5 -37
- package/src/Random.ts +1 -1
- package/src/RcMap.ts +14 -8
- package/src/Record.ts +51 -0
- package/src/Ref.ts +15 -104
- package/src/References.ts +5 -4
- package/src/RequestResolver.ts +46 -87
- package/src/Resource.ts +1 -1
- package/src/Runtime.ts +19 -18
- package/src/Schedule.ts +3 -95
- package/src/Schema.ts +639 -381
- package/src/SchemaAST.ts +40 -29
- package/src/SchemaGetter.ts +22 -5
- package/src/SchemaIssue.ts +44 -53
- package/src/SchemaParser.ts +51 -18
- package/src/SchemaRepresentation.ts +95 -35
- package/src/SchemaTransformation.ts +10 -3
- package/src/Scope.ts +12 -2
- package/src/ScopedCache.ts +17 -142
- package/src/SemVer.ts +1528 -0
- package/src/SemVerRange.ts +883 -0
- package/src/Semaphore.ts +67 -40
- package/src/Sink.ts +21 -4
- package/src/Stream.ts +367 -1027
- package/src/String.ts +11 -8
- package/src/TextDiff.ts +766 -0
- package/src/Tracer.ts +15 -1
- package/src/TxHashMap.ts +1 -103
- package/src/TxHashSet.ts +48 -753
- package/src/ai/AiError.ts +66 -4
- package/src/ai/Chat.ts +10 -5
- package/src/ai/Decision.ts +49 -1
- package/src/ai/DecisionModel.ts +264 -108
- package/src/ai/EmbeddingModel.ts +25 -13
- package/src/ai/LanguageModel.ts +9 -0
- package/src/ai/McpClient.ts +1211 -0
- package/src/ai/McpClientError.ts +329 -0
- package/src/ai/McpProtocol.ts +2 -2
- package/src/ai/McpSchema.ts +153 -35
- package/src/ai/McpServer.ts +231 -233
- package/src/ai/Prompt.ts +114 -35
- package/src/ai/Response.ts +220 -65
- package/src/ai/Tool.ts +50 -6
- package/src/ai/Toolkit.ts +82 -11
- package/src/ai/index.ts +12 -0
- package/src/ai/internal/mcpCore.ts +13 -14
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +1 -1
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +1 -1
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +3 -3
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +3 -3
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +12 -14
- package/src/ai/internal/mcpProtocol.ts +22 -2
- package/src/ai/internal/mcpRuntime.ts +3 -4
- package/src/ai/internal/mcpSchema/v2024_11_05.ts +20 -13
- package/src/ai/internal/mcpSchema/v2025_03_26.ts +4 -2
- package/src/ai/internal/mcpSchema/v2025_06_18.ts +7 -7
- package/src/ai/internal/mcpSchema/v2025_11_25.ts +8 -8
- package/src/ai/internal/mcpSchema/v2026_07_28.ts +44 -42
- package/src/cli/Argument.ts +15 -0
- package/src/cli/CliError.ts +136 -4
- package/src/cli/CliOutput.ts +183 -6
- package/src/cli/Command.ts +367 -48
- package/src/cli/Completions.ts +56 -0
- package/src/cli/Flag.ts +132 -0
- package/src/cli/GlobalFlag.ts +5 -6
- package/src/cli/Param.ts +151 -6
- package/src/cli/TerminalCapabilities.ts +159 -0
- package/src/cli/index.ts +6 -0
- package/src/cli/internal/command.ts +8 -3
- package/src/cli/internal/completions/bash.ts +83 -32
- package/src/cli/internal/completions/descriptor.ts +11 -1
- package/src/cli/internal/completions/fish.ts +10 -8
- package/src/cli/internal/completions/powershell.ts +23 -14
- package/src/cli/internal/completions/zsh.ts +8 -5
- package/src/cli/internal/formatter.ts +18 -0
- package/src/cli/internal/lexer.ts +12 -5
- package/src/cli/internal/parser.ts +31 -11
- package/src/cluster/ClusterCron.ts +94 -35
- package/src/cluster/ClusterMetrics.ts +149 -7
- package/src/cluster/ClusterWorkflowEngine.ts +130 -57
- package/src/cluster/Entity.ts +4 -0
- package/src/cluster/MessageStorage.ts +26 -14
- package/src/cluster/Runners.ts +76 -25
- package/src/cluster/Sharding.ts +200 -58
- package/src/cluster/ShardingConfig.ts +20 -0
- package/src/cluster/Snowflake.ts +3 -7
- package/src/cluster/SqlMessageStorage.ts +58 -55
- package/src/cluster/SqlRunnerStorage.ts +120 -51
- package/src/cluster/internal/entityManager.ts +155 -32
- package/src/devtools/DevTools.ts +3 -2
- package/src/devtools/DevToolsClient.ts +29 -10
- package/src/encoding/Base64.ts +38 -0
- package/src/encoding/Base64Url.ts +31 -0
- package/src/encoding/Ini.ts +3 -0
- package/src/encoding/JsonArray.ts +849 -0
- package/src/encoding/Ndjson.ts +211 -20
- package/src/encoding/SchemaBinary.ts +14 -48
- package/src/encoding/Sse.ts +4 -3
- package/src/encoding/Tar.ts +1417 -0
- package/src/encoding/Toml.ts +36 -19
- package/src/encoding/Xml.ts +2037 -0
- package/src/encoding/Yaml.ts +108 -36
- package/src/encoding/Zip.ts +1558 -0
- package/src/encoding/index.ts +24 -0
- package/src/eventlog/EventJournal.ts +611 -227
- package/src/eventlog/EventLog.ts +496 -196
- package/src/eventlog/EventLogEncryption.ts +128 -43
- package/src/eventlog/EventLogMessage.ts +62 -11
- package/src/eventlog/EventLogRemote.ts +77 -21
- package/src/eventlog/EventLogServer.ts +162 -20
- package/src/eventlog/EventLogServerEncrypted.ts +121 -80
- package/src/eventlog/EventLogServerUnencrypted.ts +180 -77
- package/src/eventlog/EventRow.ts +706 -0
- package/src/eventlog/SqlEventJournal.ts +496 -193
- package/src/eventlog/SqlEventLogServerEncrypted.ts +212 -83
- package/src/eventlog/SqlEventLogServerUnencrypted.ts +141 -62
- package/src/eventlog/index.ts +6 -0
- package/src/eventlog/internal/conflicts.ts +119 -0
- package/src/graphql/GraphQLClientError.ts +5 -12
- package/src/graphql/GraphQLProtocol.ts +12 -9
- package/src/graphql/GraphQLResolver.ts +90 -239
- package/src/http/Cookies.ts +10 -11
- package/src/http/FetchHttpClient.ts +56 -6
- package/src/http/FindMyWay/internal/router.ts +11 -0
- package/src/http/Headers.ts +337 -154
- package/src/http/HttpClient.ts +673 -142
- package/src/http/HttpClientError.ts +35 -1
- package/src/http/HttpClientRequest.ts +151 -5
- package/src/http/HttpClientResponse.ts +71 -0
- package/src/http/HttpEffect.ts +25 -33
- package/src/http/HttpIncomingMessage.ts +3 -23
- package/src/http/HttpMiddleware.ts +194 -40
- package/src/http/HttpRouter.ts +10 -3
- package/src/http/HttpServerError.ts +8 -5
- package/src/http/HttpServerRequest.ts +172 -27
- package/src/http/HttpServerResponse.ts +49 -23
- package/src/http/HttpStaticServer.ts +71 -26
- package/src/http/MultipartParser/internal/contentType.ts +109 -8
- package/src/http/MultipartParser/internal/headers.ts +4 -16
- package/src/http/MultipartParser/internal/multipart.ts +10 -32
- package/src/http/Url.ts +6 -1
- package/src/http/UrlParams.ts +6 -1
- package/src/http/internal/compression.ts +4 -5
- package/src/http/internal/decompression.ts +32 -17
- package/src/http/internal/httpBody.ts +10 -2
- package/src/http/internal/lazyStream.ts +25 -0
- package/src/http/internal/requestState.ts +33 -0
- package/src/http/internal/urlParams.ts +29 -0
- package/src/http/internal/webResponse.ts +20 -0
- package/src/http-api/HttpApi.ts +4 -7
- package/src/http-api/HttpApiBuilder.ts +190 -32
- package/src/http-api/HttpApiClient.ts +364 -90
- package/src/http-api/HttpApiEndpoint.ts +248 -46
- package/src/http-api/HttpApiError.ts +55 -0
- package/src/http-api/HttpApiScalar.ts +4 -3
- package/src/http-api/HttpApiSchema.ts +373 -18
- package/src/http-api/HttpApiSwagger.ts +11 -4
- package/src/http-api/HttpApiTest.ts +36 -11
- package/src/http-api/OpenApi.ts +103 -58
- package/src/http-api/internal/path.ts +40 -12
- package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
- package/src/index.ts +24 -0
- package/src/internal/arbitrary/runner.ts +133 -36
- package/src/internal/core.ts +3 -1
- package/src/internal/dateTime.ts +20 -7
- package/src/internal/effect.ts +144 -100
- package/src/internal/equal.ts +17 -0
- package/src/internal/hashMap.ts +2 -2
- package/src/internal/hydration.ts +15 -0
- package/src/internal/inflate.ts +710 -0
- package/src/internal/jsonSchema.ts +27 -0
- package/src/internal/matcher.ts +1 -1
- package/src/internal/record.ts +6 -0
- package/src/internal/request.ts +21 -6
- package/src/internal/schedule.ts +20 -39
- package/src/internal/schema/compilerRegistry.ts +6 -1
- package/src/internal/schema/content.ts +18 -0
- package/src/internal/schema/fromJsonSchemaDocument.ts +458 -351
- package/src/internal/schema/fromRepresentation.ts +2 -1
- package/src/internal/schema/interpreter.ts +58 -45
- package/src/internal/schema/standardSchema.ts +34 -32
- package/src/internal/schema/toCodeDocument.ts +12 -7
- package/src/internal/schema/toCodec.ts +134 -15
- package/src/internal/schema/toFormatter.ts +6 -6
- package/src/internal/schema/toJsonSchemaDocument.ts +246 -194
- package/src/internal/schema/toRepresentation.ts +122 -140
- package/src/internal/sql.ts +14 -0
- package/src/internal/trie.ts +1 -3
- package/src/internal/uuid.ts +15 -10
- package/src/internal/version.ts +1 -1
- package/src/net/NetAddress.ts +2 -9
- package/src/observability/OtlpExporter.ts +5 -12
- package/src/observability/OtlpMetrics.ts +5 -3
- package/src/observability/OtlpProxy.ts +314 -0
- package/src/observability/OtlpResource.ts +16 -6
- package/src/observability/OtlpSerialization.ts +17 -3
- package/src/observability/OtlpTracer.ts +4 -0
- package/src/observability/index.ts +6 -0
- package/src/observability/internal/protobuf.ts +2 -10
- package/src/persistence/CircuitBreaker.ts +1678 -0
- package/src/persistence/PersistedCache.ts +3 -1
- package/src/persistence/PersistedQueue.ts +223 -153
- package/src/persistence/Persistence.ts +64 -30
- package/src/persistence/RateLimiter.ts +18 -21
- package/src/persistence/Redis.ts +129 -8
- package/src/persistence/UserDirectories.ts +273 -0
- package/src/persistence/index.ts +12 -0
- package/src/process/ChildProcess.ts +32 -5
- package/src/process/ChildProcessSpawner.ts +41 -2
- package/src/reactivity/AsyncResult.ts +5 -39
- package/src/reactivity/Atom.ts +134 -166
- package/src/reactivity/AtomHttpApi.ts +10 -16
- package/src/reactivity/AtomRegistry.ts +50 -29
- package/src/reactivity/AtomRpc.ts +6 -22
- package/src/reactivity/Hydration.ts +53 -12
- package/src/reactivity/Reactivity.ts +97 -39
- package/src/rpc/Rpc.ts +21 -0
- package/src/rpc/RpcClient.ts +283 -104
- package/src/rpc/RpcSerialization.ts +53 -14
- package/src/rpc/RpcServer.ts +27 -21
- package/src/rpc/RpcTest.ts +3 -0
- package/src/schema/VariantSchema.ts +86 -22
- package/src/socket/Socket.ts +45 -20
- package/src/sql/Migrator.ts +26 -11
- package/src/sql/SqlClient.ts +273 -29
- package/src/sql/SqlResolver.ts +32 -9
- package/src/sql/Statement.ts +65 -10
- package/src/testing/TestClock.ts +4 -1
- package/src/testing/TestSchema.ts +9 -3
- package/src/workflow/DurableDeferred.ts +23 -6
- package/src/workflow/WorkflowEngine.ts +34 -10
- package/dist/http/internal/preResponseHandler.d.ts +0 -2
- package/dist/http/internal/preResponseHandler.d.ts.map +0 -1
- package/dist/http/internal/preResponseHandler.js +0 -14
- package/dist/http/internal/preResponseHandler.js.map +0 -1
- package/src/http/internal/preResponseHandler.ts +0 -19
|
@@ -14,20 +14,24 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import * as Arr from "../Array.ts"
|
|
16
16
|
import type { Brand } from "../Brand.ts"
|
|
17
|
+
import * as Clock from "../Clock.ts"
|
|
17
18
|
import * as Context from "../Context.ts"
|
|
18
19
|
import * as Data from "../Data.ts"
|
|
19
20
|
import * as DateTime from "../DateTime.ts"
|
|
20
21
|
import * as Effect from "../Effect.ts"
|
|
21
22
|
import * as SchemaBinary from "../encoding/SchemaBinary.ts"
|
|
23
|
+
import { constVoid } from "../Function.ts"
|
|
22
24
|
import * as Uuid from "../internal/uuid.ts"
|
|
23
25
|
import * as Layer from "../Layer.ts"
|
|
24
26
|
import type { Option } from "../Option.ts"
|
|
25
27
|
import * as Order from "../Order.ts"
|
|
26
28
|
import * as PubSub from "../PubSub.ts"
|
|
27
29
|
import * as Schema from "../Schema.ts"
|
|
30
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
28
31
|
import type { Scope } from "../Scope.ts"
|
|
29
32
|
import * as Semaphore from "../Semaphore.ts"
|
|
30
33
|
import type { StoreId } from "./EventLogMessage.ts"
|
|
34
|
+
import { ConflictIndex, entryIdOrder } from "./internal/conflicts.ts"
|
|
31
35
|
|
|
32
36
|
/**
|
|
33
37
|
* Context service for storing and replaying event journal entries.
|
|
@@ -37,6 +41,9 @@ import type { StoreId } from "./EventLogMessage.ts"
|
|
|
37
41
|
* The service writes local entries, imports entries from remote journals, exposes
|
|
38
42
|
* a stream of local changes, and provides per-store locking.
|
|
39
43
|
*
|
|
44
|
+
* Entries written by `EventLog` carry payloads encoded with their event's
|
|
45
|
+
* `payloadSchemaBinary`; see {@link Entry} for how to decode them.
|
|
46
|
+
*
|
|
40
47
|
* @stability unstable
|
|
41
48
|
* @category services
|
|
42
49
|
* @since 4.0.0
|
|
@@ -47,6 +54,14 @@ export class EventJournal extends Context.Service<EventJournal, {
|
|
|
47
54
|
*/
|
|
48
55
|
readonly entries: Effect.Effect<ReadonlyArray<Entry>, EventJournalError>
|
|
49
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Read the stored entries with the given ids. The result is aligned with
|
|
59
|
+
* `ids`, with `undefined` for ids that are not in the journal.
|
|
60
|
+
*/
|
|
61
|
+
readonly entriesById: (
|
|
62
|
+
ids: ReadonlyArray<EntryId>
|
|
63
|
+
) => Effect.Effect<ReadonlyArray<Entry | undefined>, EventJournalError>
|
|
64
|
+
|
|
50
65
|
/**
|
|
51
66
|
* Write an event to the journal, performing an effect before committing the
|
|
52
67
|
* event.
|
|
@@ -58,12 +73,42 @@ export class EventJournal extends Context.Service<EventJournal, {
|
|
|
58
73
|
readonly effect: (entry: Entry) => Effect.Effect<A, E, R>
|
|
59
74
|
}) => Effect.Effect<A, EventJournalError | E, R>
|
|
60
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Write several events to the journal, performing an effect before
|
|
78
|
+
* committing them.
|
|
79
|
+
*
|
|
80
|
+
* **Details**
|
|
81
|
+
*
|
|
82
|
+
* `effect` runs once with every entry, in input order and with ascending
|
|
83
|
+
* ids. The entries are committed together and then published to `changes`
|
|
84
|
+
* only after it succeeds. If it fails, nothing is committed or published.
|
|
85
|
+
*/
|
|
86
|
+
readonly writeMany: <A, E, R>(options: {
|
|
87
|
+
readonly entries: Arr.NonEmptyReadonlyArray<{
|
|
88
|
+
readonly event: string
|
|
89
|
+
readonly primaryKey: string
|
|
90
|
+
readonly payload: Uint8Array
|
|
91
|
+
}>
|
|
92
|
+
readonly effect: (entries: Arr.NonEmptyReadonlyArray<Entry>) => Effect.Effect<A, E, R>
|
|
93
|
+
}) => Effect.Effect<A, EventJournalError | E, R>
|
|
94
|
+
|
|
61
95
|
/**
|
|
62
96
|
* Write events from a remote source to the journal.
|
|
63
97
|
*
|
|
64
98
|
* **Details**
|
|
65
99
|
*
|
|
66
|
-
*
|
|
100
|
+
* `effect` runs once with every new entry after compaction, sorted by
|
|
101
|
+
* `Entry.Order`. Each entry is paired with the stored entries for the same
|
|
102
|
+
* event and primary key whose id is strictly greater, in id order. Entries
|
|
103
|
+
* in the batch never conflict with each other: applying them in id order
|
|
104
|
+
* gives the same result as delivering them one at a time. A compaction
|
|
105
|
+
* replacement written by `EventLog` takes the place and conflicts of the
|
|
106
|
+
* source entry it is anchored to, not of its own id.
|
|
107
|
+
*
|
|
108
|
+
* All conflicts are read before `effect` runs and the batch is committed
|
|
109
|
+
* after it succeeds, with no journal I/O while it runs. It is not called
|
|
110
|
+
* when the batch has no new entries. If `effect` fails, no entry from the
|
|
111
|
+
* batch is committed.
|
|
67
112
|
*/
|
|
68
113
|
readonly writeFromRemote: (
|
|
69
114
|
options: {
|
|
@@ -72,10 +117,12 @@ export class EventJournal extends Context.Service<EventJournal, {
|
|
|
72
117
|
readonly compact?:
|
|
73
118
|
| ((uncommitted: ReadonlyArray<RemoteEntry>) => Effect.Effect<ReadonlyArray<Entry>, EventJournalError>)
|
|
74
119
|
| undefined
|
|
75
|
-
readonly effect: (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
120
|
+
readonly effect: (
|
|
121
|
+
entries: ReadonlyArray<{
|
|
122
|
+
readonly entry: Entry
|
|
123
|
+
readonly conflicts: ReadonlyArray<Entry>
|
|
124
|
+
}>
|
|
125
|
+
) => Effect.Effect<void, EventJournalError>
|
|
79
126
|
}
|
|
80
127
|
) => Effect.Effect<{
|
|
81
128
|
readonly duplicateEntries: ReadonlyArray<Entry>
|
|
@@ -93,6 +140,16 @@ export class EventJournal extends Context.Service<EventJournal, {
|
|
|
93
140
|
f: (entries: Arr.NonEmptyReadonlyArray<Entry>) => Effect.Effect<A, E, R>
|
|
94
141
|
) => Effect.Effect<Option<A>, EventJournalError | E, R>
|
|
95
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Records upload acknowledgements, advancing `nextRemoteSequence` only across
|
|
145
|
+
* contiguous sequences from the current cursor or `firstSequence`.
|
|
146
|
+
*/
|
|
147
|
+
readonly writeRemoteAcks: (options: {
|
|
148
|
+
readonly remoteId: RemoteId
|
|
149
|
+
readonly acks: ReadonlyArray<RemoteAck>
|
|
150
|
+
readonly firstSequence?: number | undefined
|
|
151
|
+
}) => Effect.Effect<void, EventJournalError>
|
|
152
|
+
|
|
96
153
|
/**
|
|
97
154
|
* Retrieve the first unused sequence number for a remote source.
|
|
98
155
|
*/
|
|
@@ -240,14 +297,57 @@ export const EntryId = (Schema.Uint8Array as Schema.instanceOf<Uint8Array<ArrayB
|
|
|
240
297
|
* @category ordering
|
|
241
298
|
* @since 4.0.0
|
|
242
299
|
*/
|
|
243
|
-
export const EntryIdOrder
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
300
|
+
export const EntryIdOrder: Order.Order<EntryId> = entryIdOrder
|
|
301
|
+
|
|
302
|
+
const maxEntryIdMillis = 2 ** 48 - 1
|
|
303
|
+
|
|
304
|
+
// The millisecond and 12-bit counter of the last id in a sequence of local ids.
|
|
305
|
+
interface EntryIdSequence {
|
|
306
|
+
millis: number
|
|
307
|
+
counter: number
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const processEntryIds: EntryIdSequence = { millis: 0, counter: 0 }
|
|
311
|
+
|
|
312
|
+
const nextEntryId = (sequence: EntryIdSequence, now: number): EntryId => {
|
|
313
|
+
if (now > sequence.millis) {
|
|
314
|
+
sequence.millis = now
|
|
315
|
+
sequence.counter = 0
|
|
316
|
+
} else if (++sequence.counter > 0xfff) {
|
|
317
|
+
sequence.millis++
|
|
318
|
+
sequence.counter = 0
|
|
248
319
|
}
|
|
249
|
-
|
|
250
|
-
|
|
320
|
+
// The sequence only moves forward, so once exhausted it stays exhausted.
|
|
321
|
+
if (sequence.millis > maxEntryIdMillis) {
|
|
322
|
+
throw new RangeError("The entry id sequence has passed the last UUID v7 millisecond")
|
|
323
|
+
}
|
|
324
|
+
const bytes = Uuid.v7Bytes(sequence.millis)
|
|
325
|
+
// The counter replaces the 12 random `rand_a` bits after the version.
|
|
326
|
+
bytes[6] = 0x70 | (sequence.counter >> 8)
|
|
327
|
+
bytes[7] = sequence.counter & 0xff
|
|
328
|
+
return bytes as EntryId
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// The process sequence, or a copy advanced to `floor` when that is later. The
|
|
332
|
+
// copy is never written back, so a floor read from uncommitted rows leaves the
|
|
333
|
+
// process sequence alone.
|
|
334
|
+
const sequenceAfter = (floor: EntryId | undefined): EntryIdSequence => {
|
|
335
|
+
if (floor === undefined) return processEntryIds
|
|
336
|
+
const millis = entryIdMillis(floor)
|
|
337
|
+
// Continuing from the floor's `rand_a` sorts the next id after it.
|
|
338
|
+
const counter = ((floor[6] & 0x0f) << 8) | floor[7]
|
|
339
|
+
return millis > processEntryIds.millis || (millis === processEntryIds.millis && counter > processEntryIds.counter)
|
|
340
|
+
? { millis, counter }
|
|
341
|
+
: processEntryIds
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const maxEntryId = (ids: Iterable<EntryId>): EntryId | undefined => {
|
|
345
|
+
let latest: EntryId | undefined
|
|
346
|
+
for (const id of ids) {
|
|
347
|
+
if (latest === undefined || EntryIdOrder(id, latest) === 1) latest = id
|
|
348
|
+
}
|
|
349
|
+
return latest
|
|
350
|
+
}
|
|
251
351
|
|
|
252
352
|
/**
|
|
253
353
|
* Generates a UUID v7 `EntryId`, optionally using the supplied millisecond
|
|
@@ -258,17 +358,58 @@ export const EntryIdOrder = Order.make<EntryId>((a, b) => {
|
|
|
258
358
|
* Use when generating an event-log entry id internally and the UUID v7 bytes
|
|
259
359
|
* are trusted to satisfy the brand.
|
|
260
360
|
*
|
|
361
|
+
* **Details**
|
|
362
|
+
*
|
|
363
|
+
* Ids taken from the clock are strictly ascending within the current process.
|
|
364
|
+
* Ids created in the same millisecond carry an incrementing 12-bit counter. If
|
|
365
|
+
* the clock stalls or moves backwards, ids keep the last millisecond, and
|
|
366
|
+
* after 4096 ids in one millisecond they move to the next one.
|
|
367
|
+
*
|
|
368
|
+
* The journals generate local ids from this sequence, or from a copy of it
|
|
369
|
+
* advanced past the latest id in their store, so a local id sorts after every
|
|
370
|
+
* entry committed to that store, even when the local clock is behind.
|
|
371
|
+
*
|
|
261
372
|
* **Gotchas**
|
|
262
373
|
*
|
|
263
374
|
* This is unsafe because the generated UUID bytes are cast to the brand without
|
|
264
375
|
* schema validation.
|
|
265
376
|
*
|
|
377
|
+
* Throws a `RangeError` once the sequence passes the last UUID v7 millisecond.
|
|
378
|
+
* Every later call throws too, because any id it could return would sort before
|
|
379
|
+
* one already generated.
|
|
380
|
+
*
|
|
381
|
+
* Ids created with an explicit `msecs` are not part of the sequence, and clamp
|
|
382
|
+
* to the UUID v7 range.
|
|
383
|
+
*
|
|
266
384
|
* @stability unstable
|
|
267
385
|
* @category unsafe
|
|
268
386
|
* @since 4.0.0
|
|
269
387
|
*/
|
|
270
388
|
export const makeEntryIdUnsafe = (options: { msecs?: number } = {}): EntryId =>
|
|
271
|
-
|
|
389
|
+
options.msecs !== undefined
|
|
390
|
+
? Uuid.v7Bytes(options.msecs) as EntryId
|
|
391
|
+
: nextEntryId(processEntryIds, Date.now())
|
|
392
|
+
|
|
393
|
+
// Imported ids further ahead of the local clock than this are logged.
|
|
394
|
+
const maxClockSkewMillis = 24 * 60 * 60 * 1000
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Logs a warning when the latest of the imported `ids` is more than 24 hours
|
|
398
|
+
* ahead of the supplied `clock`. Memory and IndexedDB journals call this after
|
|
399
|
+
* commit; SQL calls it at the end of its transaction body, so a later rollback
|
|
400
|
+
* (including an enclosing transaction rollback) can still leave a warning.
|
|
401
|
+
*
|
|
402
|
+
* @internal
|
|
403
|
+
*/
|
|
404
|
+
export const warnIfAhead = (clock: Clock.Clock, ids: Iterable<EntryId>): Effect.Effect<void> => {
|
|
405
|
+
const latest = maxEntryId(ids)
|
|
406
|
+
if (latest === undefined) return Effect.void
|
|
407
|
+
const ahead = entryIdMillis(latest) - clock.currentTimeMillisUnsafe()
|
|
408
|
+
if (ahead <= maxClockSkewMillis) return Effect.void
|
|
409
|
+
return Effect.logWarning(
|
|
410
|
+
`Imported an entry id ${Math.round(ahead / 3_600_000)} hours ahead of the local clock`
|
|
411
|
+
).pipe(Effect.annotateLogs({ service: "EventJournal", entryId: Uuid.stringify(latest) }))
|
|
412
|
+
}
|
|
272
413
|
|
|
273
414
|
/**
|
|
274
415
|
* Extracts the millisecond timestamp encoded in a UUID v7 `EntryId`.
|
|
@@ -277,11 +418,10 @@ export const makeEntryIdUnsafe = (options: { msecs?: number } = {}): EntryId =>
|
|
|
277
418
|
* @category getters
|
|
278
419
|
* @since 4.0.0
|
|
279
420
|
*/
|
|
280
|
-
export const entryIdMillis = (entryId: EntryId): number =>
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
421
|
+
export const entryIdMillis = (entryId: EntryId): number =>
|
|
422
|
+
// Multiply instead of shifting: bitwise operators are signed 32-bit.
|
|
423
|
+
((((entryId[0] * 256 + entryId[1]) * 256 + entryId[2]) * 256 + entryId[3]) * 256 + entryId[4]) * 256 +
|
|
424
|
+
entryId[5]
|
|
285
425
|
|
|
286
426
|
/**
|
|
287
427
|
* Schema for a committed event journal entry.
|
|
@@ -291,6 +431,14 @@ export const entryIdMillis = (entryId: EntryId): number => {
|
|
|
291
431
|
* An entry records its ID, event tag, primary key, and SchemaBinary-encoded
|
|
292
432
|
* payload, with helpers for array SchemaBinary encoding and creation timestamps.
|
|
293
433
|
*
|
|
434
|
+
* **Gotchas**
|
|
435
|
+
*
|
|
436
|
+
* `EventLog` encodes `payload` with the `payloadSchemaBinary` of the event whose
|
|
437
|
+
* tag is `entry.event`, so decode it with that event's codec. A codec with an
|
|
438
|
+
* incompatible wire layout, such as a union of a group's tagged payload schemas,
|
|
439
|
+
* cannot read it. Entries from remote journals can carry tags the local schema
|
|
440
|
+
* does not define.
|
|
441
|
+
*
|
|
294
442
|
* @stability unstable
|
|
295
443
|
* @category schemas
|
|
296
444
|
* @since 4.0.0
|
|
@@ -323,7 +471,11 @@ export class Entry extends Schema.Class<Entry>("effect/eventlog/EventJournal/Ent
|
|
|
323
471
|
* @stability unstable
|
|
324
472
|
* @since 4.0.0
|
|
325
473
|
*/
|
|
326
|
-
static decodeArray =
|
|
474
|
+
static decodeArray = (
|
|
475
|
+
input: unknown,
|
|
476
|
+
options?: SchemaAST.ParseOptions
|
|
477
|
+
): Effect.Effect<Array<Entry>, Schema.SchemaError> =>
|
|
478
|
+
Effect.map(decodeEntryFieldsArray(input, options), Arr.map(entryFromFields))
|
|
327
479
|
|
|
328
480
|
/**
|
|
329
481
|
* Ordering for committed entries by their event journal entry id.
|
|
@@ -333,6 +485,8 @@ export class Entry extends Schema.Class<Entry>("effect/eventlog/EventJournal/Ent
|
|
|
333
485
|
*/
|
|
334
486
|
static Order = Order.make<Entry>((a, b) => EntryIdOrder(a.id, b.id))
|
|
335
487
|
|
|
488
|
+
#idString: string | undefined
|
|
489
|
+
|
|
336
490
|
/**
|
|
337
491
|
* String representation of the entry id.
|
|
338
492
|
*
|
|
@@ -340,7 +494,7 @@ export class Entry extends Schema.Class<Entry>("effect/eventlog/EventJournal/Ent
|
|
|
340
494
|
* @since 4.0.0
|
|
341
495
|
*/
|
|
342
496
|
get idString(): string {
|
|
343
|
-
return Uuid.stringify(this.id)
|
|
497
|
+
return this.#idString ??= Uuid.stringify(this.id)
|
|
344
498
|
}
|
|
345
499
|
|
|
346
500
|
/**
|
|
@@ -364,6 +518,18 @@ export class Entry extends Schema.Class<Entry>("effect/eventlog/EventJournal/Ent
|
|
|
364
518
|
}
|
|
365
519
|
}
|
|
366
520
|
|
|
521
|
+
/**
|
|
522
|
+
* A local entry's remote-assigned sequence.
|
|
523
|
+
*
|
|
524
|
+
* @stability unstable
|
|
525
|
+
* @category models
|
|
526
|
+
* @since 4.0.6
|
|
527
|
+
*/
|
|
528
|
+
export interface RemoteAck {
|
|
529
|
+
readonly entryId: EntryId
|
|
530
|
+
readonly sequence: number
|
|
531
|
+
}
|
|
532
|
+
|
|
367
533
|
/**
|
|
368
534
|
* Schema for an event journal entry received from a remote source.
|
|
369
535
|
*
|
|
@@ -380,6 +546,44 @@ export class RemoteEntry extends Schema.Class<RemoteEntry>("effect/eventlog/Even
|
|
|
380
546
|
entry: Entry
|
|
381
547
|
}) {}
|
|
382
548
|
|
|
549
|
+
// Decoding frames into the plain field structs and then constructing the
|
|
550
|
+
// classes from the already validated fields skips the per-instance class
|
|
551
|
+
// decode, which costs more than reading the frame. The wire format is the same.
|
|
552
|
+
|
|
553
|
+
/** @internal */
|
|
554
|
+
export const EntryFields = Schema.Struct(Entry.fields)
|
|
555
|
+
|
|
556
|
+
/** @internal */
|
|
557
|
+
export const entryFromFields = (fields: typeof EntryFields.Type): Entry => Schema.makeClassTrusted(Entry, fields)
|
|
558
|
+
|
|
559
|
+
const decodeEntryFieldsArray = Schema.decodeUnknownEffect(Schema.Array(SchemaBinary.toCodec(EntryFields)))
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Creates local entries with ids after every id in `after`, normally the
|
|
563
|
+
* latest id in the journal's store.
|
|
564
|
+
*
|
|
565
|
+
* @internal
|
|
566
|
+
*/
|
|
567
|
+
export const makeEntries = (
|
|
568
|
+
entries: Arr.NonEmptyReadonlyArray<
|
|
569
|
+
{ readonly event: string; readonly primaryKey: string; readonly payload: Uint8Array }
|
|
570
|
+
>,
|
|
571
|
+
after: Iterable<EntryId>
|
|
572
|
+
): Effect.Effect<Arr.NonEmptyArray<Entry>, EventJournalError> =>
|
|
573
|
+
Effect.try({
|
|
574
|
+
try: () => {
|
|
575
|
+
const sequence = sequenceAfter(maxEntryId(after))
|
|
576
|
+
return Arr.map(entries, ({ event, payload, primaryKey }) =>
|
|
577
|
+
new Entry({
|
|
578
|
+
id: nextEntryId(sequence, Date.now()),
|
|
579
|
+
event,
|
|
580
|
+
primaryKey,
|
|
581
|
+
payload
|
|
582
|
+
}, { disableChecks: true }))
|
|
583
|
+
},
|
|
584
|
+
catch: (cause) => new EventJournalError({ method: "writeMany", cause })
|
|
585
|
+
})
|
|
586
|
+
|
|
383
587
|
/**
|
|
384
588
|
* Creates an in-memory `EventJournal` service.
|
|
385
589
|
*
|
|
@@ -394,6 +598,17 @@ export class RemoteEntry extends Schema.Class<RemoteEntry>("effect/eventlog/Even
|
|
|
394
598
|
*/
|
|
395
599
|
export const makeMemory: Effect.Effect<EventJournal["Service"]> = Effect.gen(function*() {
|
|
396
600
|
const journal: Array<Entry> = []
|
|
601
|
+
// Local writes append in commit order, which unserialized direct callers can
|
|
602
|
+
// make differ from id order, leaving the journal unordered until the next
|
|
603
|
+
// import re-sorts it. Remote backlogs are subsequences of the journal, so one
|
|
604
|
+
// flag covers them too.
|
|
605
|
+
let journalSorted = true
|
|
606
|
+
// The latest committed id, the floor for local ids.
|
|
607
|
+
let latestId: EntryId | undefined
|
|
608
|
+
const commitLatest = (ids: Iterable<EntryId>) => {
|
|
609
|
+
latestId = maxEntryId(latestId === undefined ? ids : [latestId, ...ids])
|
|
610
|
+
}
|
|
611
|
+
const clock = yield* Clock.Clock
|
|
397
612
|
const byId = new Map<string, Entry>()
|
|
398
613
|
const remotes = new Map<string, { sequence: number; missing: Array<Entry> }>()
|
|
399
614
|
const pubsub = yield* PubSub.unbounded<Entry>()
|
|
@@ -416,86 +631,82 @@ export const makeMemory: Effect.Effect<EventJournal["Service"]> = Effect.gen(fun
|
|
|
416
631
|
return created
|
|
417
632
|
}
|
|
418
633
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
effect,
|
|
432
|
-
(entry, exit) =>
|
|
433
|
-
Effect.suspend(() => {
|
|
434
|
-
if (exit._tag === "Failure" || byId.has(entry.idString)) return Effect.void
|
|
634
|
+
const writeMany: EventJournal["Service"]["writeMany"] = ({ effect, entries }) =>
|
|
635
|
+
Effect.acquireUseRelease(
|
|
636
|
+
Effect.suspend(() => makeEntries(entries, latestId === undefined ? [] : [latestId])),
|
|
637
|
+
effect,
|
|
638
|
+
(entries, exit) =>
|
|
639
|
+
Effect.suspend(() => {
|
|
640
|
+
if (exit._tag === "Failure") return Effect.void
|
|
641
|
+
for (const entry of entries) {
|
|
642
|
+
const last = journal[journal.length - 1]
|
|
643
|
+
if (last !== undefined && Entry.Order(last, entry) > 0) {
|
|
644
|
+
journalSorted = false
|
|
645
|
+
}
|
|
435
646
|
journal.push(entry)
|
|
436
647
|
byId.set(entry.idString, entry)
|
|
437
648
|
remotes.forEach((remote) => {
|
|
438
649
|
remote.missing.push(entry)
|
|
439
650
|
})
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
651
|
+
}
|
|
652
|
+
commitLatest(entries.map((entry) => entry.id))
|
|
653
|
+
return PubSub.publishAll(pubsub, entries)
|
|
654
|
+
})
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
return EventJournal.of({
|
|
658
|
+
entries: Effect.sync(() => journal.slice()),
|
|
659
|
+
write: ({ effect, ...entry }) => writeMany({ entries: [entry], effect: (entries) => effect(entries[0]) }),
|
|
660
|
+
writeMany,
|
|
444
661
|
writeFromRemote: Effect.fnUntraced(function*(options) {
|
|
445
662
|
const remote = ensureRemote(options.remoteId)
|
|
446
663
|
const uncommittedRemotes: Array<RemoteEntry> = []
|
|
447
|
-
const uncommitted: Array<Entry> = []
|
|
448
664
|
const duplicateEntries: Array<Entry> = []
|
|
665
|
+
// Overlapping batches can repeat an entry; the first copy wins.
|
|
666
|
+
const incomingIds = new Set<string>()
|
|
449
667
|
for (const remoteEntry of options.entries) {
|
|
450
|
-
|
|
668
|
+
const idString = remoteEntry.entry.idString
|
|
669
|
+
if (byId.has(idString)) {
|
|
451
670
|
duplicateEntries.push(remoteEntry.entry)
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
continue
|
|
671
|
+
} else if (!incomingIds.has(idString)) {
|
|
672
|
+
incomingIds.add(idString)
|
|
673
|
+
uncommittedRemotes.push(remoteEntry)
|
|
456
674
|
}
|
|
457
|
-
uncommittedRemotes.push(remoteEntry)
|
|
458
|
-
uncommitted.push(remoteEntry.entry)
|
|
459
675
|
}
|
|
460
676
|
|
|
461
677
|
const compacted = options.compact
|
|
462
678
|
? yield* options.compact(uncommittedRemotes)
|
|
463
|
-
:
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
const scannedEntry = journal[j]!
|
|
475
|
-
if (scannedEntry.event === originEntry.event && scannedEntry.primaryKey === originEntry.primaryKey) {
|
|
476
|
-
conflicts.push(scannedEntry)
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
yield* options.effect({ entry: originEntry, conflicts })
|
|
480
|
-
break
|
|
679
|
+
: uncommittedRemotes.map((remoteEntry) => remoteEntry.entry)
|
|
680
|
+
|
|
681
|
+
if (Arr.isReadonlyArrayNonEmpty(compacted)) {
|
|
682
|
+
const index = new ConflictIndex(compacted)
|
|
683
|
+
const oldest = index.oldest
|
|
684
|
+
// Only the suffix with greater ids can conflict, unless local writes
|
|
685
|
+
// left the journal unordered.
|
|
686
|
+
let i = journalSorted ? journal.length : 0
|
|
687
|
+
while (i > 0 && Entry.Order(journal[i - 1], oldest) > 0) i--
|
|
688
|
+
for (; i < journal.length; i++) {
|
|
689
|
+
index.add(journal[i])
|
|
481
690
|
}
|
|
691
|
+
yield* options.effect(index.toBatch())
|
|
482
692
|
}
|
|
483
693
|
for (const remoteEntry of uncommittedRemotes) {
|
|
484
|
-
journal.push(remoteEntry.entry)
|
|
485
694
|
byId.set(remoteEntry.entry.idString, remoteEntry.entry)
|
|
486
|
-
remotes.forEach((target) => {
|
|
487
|
-
if (target !== remote) {
|
|
488
|
-
target.missing.push(remoteEntry.entry)
|
|
489
|
-
}
|
|
490
|
-
})
|
|
491
|
-
if (remoteEntry.remoteSequence >= remote.sequence) {
|
|
492
|
-
remote.sequence = remoteEntry.remoteSequence + 1
|
|
493
|
-
}
|
|
494
695
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
696
|
+
// Sequences advance with the commit, so a failed batch is redelivered.
|
|
697
|
+
remote.sequence = nextSequenceAfter(options.entries, remote.sequence)
|
|
698
|
+
const imported = uncommittedRemotes.map((remoteEntry) => remoteEntry.entry).sort(Entry.Order)
|
|
699
|
+
insertOrdered(journal, journalSorted, imported)
|
|
700
|
+
remotes.forEach((target) => {
|
|
701
|
+
if (target !== remote) {
|
|
702
|
+
insertOrdered(target.missing, journalSorted, imported)
|
|
703
|
+
} else if (!journalSorted) {
|
|
704
|
+
target.missing.sort(Entry.Order)
|
|
705
|
+
}
|
|
498
706
|
})
|
|
707
|
+
journalSorted = true
|
|
708
|
+
commitLatest(imported.map((entry) => entry.id))
|
|
709
|
+
yield* warnIfAhead(clock, imported.map((entry) => entry.id))
|
|
499
710
|
return {
|
|
500
711
|
duplicateEntries
|
|
501
712
|
}
|
|
@@ -518,10 +729,18 @@ export const makeMemory: Effect.Effect<EventJournal["Service"]> = Effect.gen(fun
|
|
|
518
729
|
}
|
|
519
730
|
})
|
|
520
731
|
),
|
|
732
|
+
writeRemoteAcks: ({ acks, firstSequence, remoteId }) =>
|
|
733
|
+
Effect.sync(() => {
|
|
734
|
+
const remote = ensureRemote(remoteId)
|
|
735
|
+
remote.sequence = advanceSequence(remote.sequence, acks, firstSequence)
|
|
736
|
+
}),
|
|
521
737
|
nextRemoteSequence: (remoteId) => Effect.sync(() => ensureRemote(remoteId).sequence),
|
|
738
|
+
entriesById: (ids) => Effect.sync(() => ids.map((id) => byId.get(Uuid.stringify(id)))),
|
|
522
739
|
changes: PubSub.subscribe(pubsub),
|
|
523
740
|
destroy: Effect.sync(() => {
|
|
524
741
|
journal.length = 0
|
|
742
|
+
journalSorted = true
|
|
743
|
+
latestId = undefined
|
|
525
744
|
byId.clear()
|
|
526
745
|
remotes.clear()
|
|
527
746
|
}),
|
|
@@ -529,6 +748,28 @@ export const makeMemory: Effect.Effect<EventJournal["Service"]> = Effect.gen(fun
|
|
|
529
748
|
})
|
|
530
749
|
})
|
|
531
750
|
|
|
751
|
+
// Same result as appending `additions` and sorting by id.
|
|
752
|
+
const insertOrdered = (entries: Array<Entry>, sorted: boolean, additions: ReadonlyArray<Entry>): void => {
|
|
753
|
+
let i = entries.length - 1
|
|
754
|
+
for (let n = 0; n < additions.length; n++) {
|
|
755
|
+
entries.push(additions[n])
|
|
756
|
+
}
|
|
757
|
+
if (!sorted) {
|
|
758
|
+
entries.sort(Entry.Order)
|
|
759
|
+
return
|
|
760
|
+
}
|
|
761
|
+
// Merge from the back, so additions sorting after the whole array cost O(additions).
|
|
762
|
+
let j = additions.length - 1
|
|
763
|
+
let k = entries.length - 1
|
|
764
|
+
while (j >= 0) {
|
|
765
|
+
if (i >= 0 && Entry.Order(entries[i], additions[j]) > 0) {
|
|
766
|
+
entries[k--] = entries[i--]
|
|
767
|
+
} else {
|
|
768
|
+
entries[k--] = additions[j--]
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
532
773
|
/**
|
|
533
774
|
* Layer that provides an in-memory `EventJournal`.
|
|
534
775
|
*
|
|
@@ -561,20 +802,55 @@ export const makeIndexedDb = (options?: {
|
|
|
561
802
|
}): Effect.Effect<EventJournal["Service"], EventJournalError, Scope> =>
|
|
562
803
|
Effect.gen(function*() {
|
|
563
804
|
const database = options?.database ?? "effect_event_journal"
|
|
564
|
-
const openRequest = indexedDB.open(database,
|
|
565
|
-
openRequest.onupgradeneeded = () => {
|
|
805
|
+
const openRequest = indexedDB.open(database, 2)
|
|
806
|
+
openRequest.onupgradeneeded = (event) => {
|
|
566
807
|
const db = openRequest.result
|
|
808
|
+
const tx = openRequest.transaction!
|
|
809
|
+
|
|
810
|
+
if (event.oldVersion < 1) {
|
|
811
|
+
const entries = db.createObjectStore("entries", { keyPath: "id" })
|
|
812
|
+
entries.createIndex("id", "id", { unique: true })
|
|
813
|
+
entries.createIndex("event", "event")
|
|
814
|
+
db.createObjectStore("remoteEntryId", { keyPath: ["remoteId"] }).createIndex("id", "remoteId", { unique: true })
|
|
815
|
+
}
|
|
567
816
|
|
|
568
|
-
const entries =
|
|
569
|
-
|
|
570
|
-
entries.createIndex("
|
|
817
|
+
const entries = tx.objectStore("entries")
|
|
818
|
+
// Bounds conflict reads to one event and primary key.
|
|
819
|
+
entries.createIndex("conflict", ["event", "primaryKey", "id"])
|
|
820
|
+
// Entry ids order creation, not insertion, so uploads checkpoint an
|
|
821
|
+
// insertion sequence instead.
|
|
822
|
+
const sequence = db.createObjectStore("entrySequence", { autoIncrement: true })
|
|
823
|
+
// The remote each imported entry came from, so uploads skip it.
|
|
824
|
+
const sources = db.createObjectStore("entrySource")
|
|
825
|
+
if (event.oldVersion < 1) return
|
|
571
826
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
827
|
+
// Number the existing entries in creation order.
|
|
828
|
+
const entryIds = entries.openKeyCursor()
|
|
829
|
+
entryIds.onsuccess = () => {
|
|
830
|
+
const cursor = entryIds.result
|
|
831
|
+
if (!cursor) return
|
|
832
|
+
sequence.add(cursor.primaryKey)
|
|
833
|
+
cursor.continue()
|
|
834
|
+
}
|
|
575
835
|
|
|
576
|
-
|
|
577
|
-
|
|
836
|
+
// Version 1 kept a `remotes` row per entry per remote and recorded upload
|
|
837
|
+
// progress as an entry id, which cannot become a checkpoint. Keep one
|
|
838
|
+
// source per entry and, walking each remote's rows in sequence order, its
|
|
839
|
+
// download cursor; then drop the store.
|
|
840
|
+
const progress = tx.objectStore("remoteEntryId")
|
|
841
|
+
progress.clear()
|
|
842
|
+
const remotes = tx.objectStore("remotes").index("sequence").openCursor()
|
|
843
|
+
remotes.onsuccess = () => {
|
|
844
|
+
const cursor = remotes.result
|
|
845
|
+
if (!cursor) {
|
|
846
|
+
db.deleteObjectStore("remotes")
|
|
847
|
+
return
|
|
848
|
+
}
|
|
849
|
+
const row = cursor.value as { remoteId: IDBValidKey; entryId: IDBValidKey; sequence: number }
|
|
850
|
+
sources.put(row.remoteId, row.entryId)
|
|
851
|
+
progress.put({ remoteId: row.remoteId, nextSequence: row.sequence + 1 })
|
|
852
|
+
cursor.continue()
|
|
853
|
+
}
|
|
578
854
|
}
|
|
579
855
|
|
|
580
856
|
const db = yield* Effect.acquireRelease(
|
|
@@ -583,6 +859,45 @@ export const makeIndexedDb = (options?: {
|
|
|
583
859
|
)
|
|
584
860
|
|
|
585
861
|
const pubsub = yield* PubSub.unbounded<Entry>()
|
|
862
|
+
const clock = yield* Clock.Clock
|
|
863
|
+
|
|
864
|
+
// Other tabs share the database but not the entry id sequence.
|
|
865
|
+
const latestEntryId = Effect.callback<ReadonlyArray<EntryId>, EventJournalError>((resume) => {
|
|
866
|
+
const tx = db.transaction("entries", "readonly")
|
|
867
|
+
const request = tx.objectStore("entries").openKeyCursor(null, "prev")
|
|
868
|
+
onTransactionDone(tx, "writeMany", resume, () => {
|
|
869
|
+
const key = request.result?.primaryKey as ArrayBuffer | ArrayBufferView | undefined
|
|
870
|
+
if (key === undefined) return []
|
|
871
|
+
return [
|
|
872
|
+
(ArrayBuffer.isView(key)
|
|
873
|
+
? new Uint8Array(key.buffer, key.byteOffset, key.byteLength)
|
|
874
|
+
: new Uint8Array(key)) as EntryId
|
|
875
|
+
]
|
|
876
|
+
})
|
|
877
|
+
return Effect.sync(() => tx.abort())
|
|
878
|
+
})
|
|
879
|
+
|
|
880
|
+
const writeMany: EventJournal["Service"]["writeMany"] = ({ effect, entries }) =>
|
|
881
|
+
Effect.uninterruptibleMask((restore) =>
|
|
882
|
+
latestEntryId.pipe(
|
|
883
|
+
Effect.flatMap((latest) => makeEntries(entries, latest)),
|
|
884
|
+
Effect.flatMap((committed) =>
|
|
885
|
+
restore(effect(committed)).pipe(
|
|
886
|
+
Effect.tap(Effect.callback<void, EventJournalError>((resume) => {
|
|
887
|
+
const tx = db.transaction(["entries", "entrySequence"], "readwrite")
|
|
888
|
+
const store = tx.objectStore("entries")
|
|
889
|
+
const sequence = tx.objectStore("entrySequence")
|
|
890
|
+
for (const entry of committed) {
|
|
891
|
+
store.put(encodeEntryIdb(entry))
|
|
892
|
+
sequence.add(entry.id as IDBValidKey)
|
|
893
|
+
}
|
|
894
|
+
onTransactionDone(tx, "writeMany", resume, constVoid)
|
|
895
|
+
})),
|
|
896
|
+
Effect.tap(PubSub.publishAll(pubsub, committed))
|
|
897
|
+
)
|
|
898
|
+
)
|
|
899
|
+
)
|
|
900
|
+
)
|
|
586
901
|
|
|
587
902
|
return EventJournal.of({
|
|
588
903
|
entries: idbReq("entries", () =>
|
|
@@ -590,188 +905,174 @@ export const makeIndexedDb = (options?: {
|
|
|
590
905
|
.objectStore("entries")
|
|
591
906
|
.index("id")
|
|
592
907
|
.getAll()).pipe(
|
|
593
|
-
Effect.
|
|
594
|
-
decodeEntryIdbArray(_).pipe(
|
|
595
|
-
Effect.mapError((cause) => new EventJournalError({ method: "entries", cause }))
|
|
596
|
-
)
|
|
597
|
-
)
|
|
908
|
+
Effect.map((rows) => rows.map(entryFromIdb))
|
|
598
909
|
),
|
|
599
|
-
|
|
600
|
-
Effect.
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
.put(encodeEntryIdb(entry)))
|
|
613
|
-
),
|
|
614
|
-
Effect.tap(PubSub.publish(pubsub, entry))
|
|
615
|
-
)
|
|
910
|
+
entriesById: (ids) =>
|
|
911
|
+
Effect.callback<Array<Entry | undefined>, EventJournalError>((resume) => {
|
|
912
|
+
const entries: Array<Entry | undefined> = ids.map(() => undefined)
|
|
913
|
+
const tx = db.transaction("entries", "readonly")
|
|
914
|
+
const store = tx.objectStore("entries")
|
|
915
|
+
for (let i = 0; i < ids.length; i++) {
|
|
916
|
+
const request = store.get(ids[i] as IDBValidKey)
|
|
917
|
+
request.onsuccess = () => {
|
|
918
|
+
if (request.result !== undefined) entries[i] = entryFromIdb(request.result)
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
onTransactionDone(tx, "entriesById", resume, () => entries)
|
|
922
|
+
return Effect.sync(() => tx.abort())
|
|
616
923
|
}),
|
|
924
|
+
write: ({ effect, ...entry }) => writeMany({ entries: [entry], effect: (entries) => effect(entries[0]) }),
|
|
925
|
+
writeMany,
|
|
617
926
|
writeFromRemote: Effect.fnUntraced(function*(options) {
|
|
618
|
-
const uncommitted: Array<Entry> = []
|
|
619
927
|
const uncommittedRemotes: Array<RemoteEntry> = []
|
|
620
928
|
const duplicateEntries: Array<Entry> = []
|
|
929
|
+
// Overlapping batches can repeat an entry; the first copy wins.
|
|
930
|
+
const incomingIds = new Set<string>()
|
|
621
931
|
|
|
622
932
|
yield* Effect.callback<void, EventJournalError>((resume) => {
|
|
623
|
-
const tx = db.transaction(
|
|
933
|
+
const tx = db.transaction("entries", "readonly")
|
|
624
934
|
const entries = tx.objectStore("entries")
|
|
625
|
-
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
remotes.put({
|
|
636
|
-
remoteId: options.remoteId,
|
|
637
|
-
entryId: entry.id,
|
|
638
|
-
sequence: remoteEntry.remoteSequence
|
|
639
|
-
})
|
|
640
|
-
handleNext(iterator.next())
|
|
641
|
-
return
|
|
935
|
+
// Requests in a transaction complete in the order they were issued.
|
|
936
|
+
for (const remoteEntry of options.entries) {
|
|
937
|
+
const request = entries.getKey(remoteEntry.entry.id as IDBValidKey)
|
|
938
|
+
request.onsuccess = () => {
|
|
939
|
+
const idString = remoteEntry.entry.idString
|
|
940
|
+
if (request.result !== undefined) {
|
|
941
|
+
duplicateEntries.push(remoteEntry.entry)
|
|
942
|
+
} else if (!incomingIds.has(idString)) {
|
|
943
|
+
incomingIds.add(idString)
|
|
944
|
+
uncommittedRemotes.push(remoteEntry)
|
|
642
945
|
}
|
|
643
|
-
uncommitted.push(entry)
|
|
644
|
-
uncommittedRemotes.push(remoteEntry)
|
|
645
|
-
handleNext(iterator.next())
|
|
646
946
|
}
|
|
647
947
|
}
|
|
648
|
-
|
|
649
|
-
tx.oncomplete = () => resume(Effect.void)
|
|
650
|
-
tx.onerror = () => resume(Effect.fail(new EventJournalError({ method: "writeFromRemote", cause: tx.error })))
|
|
948
|
+
onTransactionDone(tx, "writeFromRemote", resume, constVoid)
|
|
651
949
|
return Effect.sync(() => tx.abort())
|
|
652
950
|
})
|
|
653
951
|
|
|
654
952
|
const compacted = options.compact
|
|
655
953
|
? yield* options.compact(uncommittedRemotes)
|
|
656
|
-
:
|
|
954
|
+
: uncommittedRemotes.map((remoteEntry) => remoteEntry.entry)
|
|
657
955
|
|
|
658
|
-
|
|
659
|
-
const
|
|
956
|
+
if (Arr.isReadonlyArrayNonEmpty(compacted)) {
|
|
957
|
+
const index = new ConflictIndex(compacted)
|
|
660
958
|
yield* Effect.callback<void, EventJournalError>((resume) => {
|
|
661
959
|
const tx = db.transaction("entries", "readonly")
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
decodedEntry.primaryKey === originEntry.primaryKey
|
|
674
|
-
) {
|
|
675
|
-
conflicts.push(decodedEntry)
|
|
960
|
+
const conflicts = tx.objectStore("entries").index("conflict")
|
|
961
|
+
// One read per group of the entries with a greater id than its
|
|
962
|
+
// oldest, in id order.
|
|
963
|
+
for (const group of index.groups()) {
|
|
964
|
+
const request = conflicts.getAll(IDBKeyRange.bound(
|
|
965
|
+
[group.event, group.primaryKey, group.oldest.id as IDBValidKey],
|
|
966
|
+
[group.event, group.primaryKey, entryIdUpperBound],
|
|
967
|
+
true
|
|
968
|
+
))
|
|
969
|
+
request.onsuccess = () => {
|
|
970
|
+
for (const row of request.result) index.add(entryFromIdb(row))
|
|
676
971
|
}
|
|
677
|
-
cursor.continue()
|
|
678
972
|
}
|
|
679
|
-
tx
|
|
680
|
-
tx.onerror = () =>
|
|
681
|
-
resume(Effect.fail(new EventJournalError({ method: "writeFromRemote", cause: tx.error })))
|
|
973
|
+
onTransactionDone(tx, "writeFromRemote", resume, constVoid)
|
|
682
974
|
return Effect.sync(() => tx.abort())
|
|
683
975
|
})
|
|
684
|
-
|
|
685
|
-
yield* options.effect({ entry: originEntry, conflicts })
|
|
976
|
+
yield* options.effect(index.toBatch())
|
|
686
977
|
}
|
|
687
978
|
|
|
688
979
|
yield* Effect.callback<void, EventJournalError>((resume) => {
|
|
689
|
-
const tx = db.transaction(["entries", "
|
|
980
|
+
const tx = db.transaction(["entries", "entrySource", "entrySequence", "remoteEntryId"], "readwrite")
|
|
690
981
|
const entries = tx.objectStore("entries")
|
|
691
|
-
const
|
|
982
|
+
const sources = tx.objectStore("entrySource")
|
|
983
|
+
const sequence = tx.objectStore("entrySequence")
|
|
692
984
|
for (const remoteEntry of uncommittedRemotes) {
|
|
693
985
|
entries.add(encodeEntryIdb(remoteEntry.entry))
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
entryId: remoteEntry.entry.id,
|
|
697
|
-
sequence: remoteEntry.remoteSequence
|
|
698
|
-
})
|
|
986
|
+
sequence.add(remoteEntry.entry.id as IDBValidKey)
|
|
987
|
+
sources.put(options.remoteId, remoteEntry.entry.id as IDBValidKey)
|
|
699
988
|
}
|
|
700
|
-
|
|
701
|
-
|
|
989
|
+
// Sequences advance with the commit, so a failed batch is redelivered.
|
|
990
|
+
advanceProgress(
|
|
991
|
+
tx.objectStore("remoteEntryId"),
|
|
992
|
+
options.remoteId,
|
|
993
|
+
"nextSequence",
|
|
994
|
+
() => nextSequenceAfter(options.entries)
|
|
995
|
+
)
|
|
996
|
+
onTransactionDone(tx, "writeFromRemote", resume, constVoid)
|
|
702
997
|
return Effect.sync(() => tx.abort())
|
|
703
998
|
})
|
|
999
|
+
yield* warnIfAhead(clock, uncommittedRemotes.map((remoteEntry) => remoteEntry.entry.id))
|
|
704
1000
|
return {
|
|
705
1001
|
duplicateEntries
|
|
706
1002
|
}
|
|
707
1003
|
}),
|
|
708
|
-
withRemoteUncommited: (remoteId, f) =>
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
1004
|
+
withRemoteUncommited: (remoteId, f) => {
|
|
1005
|
+
const remoteIdKey = remoteId as IDBValidKey
|
|
1006
|
+
return Effect.callback<{ readonly entries: Array<Entry>; readonly sequence: number }, EventJournalError>(
|
|
1007
|
+
(resume) => {
|
|
1008
|
+
const entries: Array<Entry> = []
|
|
1009
|
+
// The last insertion sequence visited, or 0 when nothing follows the checkpoint.
|
|
1010
|
+
let sequence = 0
|
|
1011
|
+
const tx = db.transaction(["entries", "entrySource", "remoteEntryId", "entrySequence"], "readonly")
|
|
1012
|
+
const entriesStore = tx.objectStore("entries")
|
|
1013
|
+
const sourcesStore = tx.objectStore("entrySource")
|
|
1014
|
+
const checkpoint = tx.objectStore("remoteEntryId").get([remoteIdKey]) as IDBRequest<
|
|
1015
|
+
RemoteProgress | undefined
|
|
1016
|
+
>
|
|
1017
|
+
checkpoint.onsuccess = () => {
|
|
1018
|
+
const cursorRequest = tx.objectStore("entrySequence").openCursor(
|
|
1019
|
+
IDBKeyRange.lowerBound(checkpoint.result?.sequence ?? 0, true)
|
|
1020
|
+
)
|
|
1021
|
+
cursorRequest.onsuccess = () => {
|
|
1022
|
+
const cursor = cursorRequest.result
|
|
1023
|
+
if (!cursor) return
|
|
1024
|
+
sequence = cursor.key as number
|
|
1025
|
+
const entryId = cursor.value as IDBValidKey
|
|
1026
|
+
const source = sourcesStore.get(entryId)
|
|
1027
|
+
source.onsuccess = () => {
|
|
1028
|
+
if (source.result !== undefined && indexedDB.cmp(source.result, remoteIdKey) === 0) return
|
|
1029
|
+
const entry = entriesStore.get(entryId)
|
|
1030
|
+
entry.onsuccess = () => {
|
|
1031
|
+
entries.push(entryFromIdb(entry.result))
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
731
1034
|
cursor.continue()
|
|
732
1035
|
}
|
|
733
1036
|
}
|
|
1037
|
+
onTransactionDone(tx, "withRemoteUncommited", resume, () => ({ entries, sequence }))
|
|
1038
|
+
return Effect.sync(() => tx.abort())
|
|
734
1039
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
return Effect.sync(() => tx.abort())
|
|
740
|
-
}).pipe(
|
|
741
|
-
Effect.flatMap((entries) => {
|
|
742
|
-
if (!Arr.isReadonlyArrayNonEmpty(entries)) return Effect.succeedNone
|
|
743
|
-
const entryId = entries[entries.length - 1].id
|
|
1040
|
+
).pipe(
|
|
1041
|
+
Effect.flatMap(({ entries, sequence }) => {
|
|
1042
|
+
if (sequence === 0) return Effect.succeedNone
|
|
1043
|
+
entries.sort(byEntryId)
|
|
744
1044
|
return Effect.uninterruptibleMask((restore) =>
|
|
745
|
-
restore(f(entries)).pipe(
|
|
746
|
-
Effect.tap(
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
),
|
|
753
|
-
Effect.asSome
|
|
1045
|
+
restore(Arr.isReadonlyArrayNonEmpty(entries) ? Effect.asSome(f(entries)) : Effect.succeedNone).pipe(
|
|
1046
|
+
Effect.tap(Effect.callback<void, EventJournalError>((resume) => {
|
|
1047
|
+
// Uploads can complete out of order; the checkpoint only moves forward.
|
|
1048
|
+
const tx = db.transaction("remoteEntryId", "readwrite")
|
|
1049
|
+
advanceProgress(tx.objectStore("remoteEntryId"), remoteId, "sequence", () => sequence)
|
|
1050
|
+
onTransactionDone(tx, "withRemoteUncommited", resume, constVoid)
|
|
1051
|
+
}))
|
|
754
1052
|
)
|
|
755
1053
|
)
|
|
756
1054
|
})
|
|
757
|
-
)
|
|
1055
|
+
)
|
|
1056
|
+
},
|
|
1057
|
+
writeRemoteAcks: ({ acks, firstSequence, remoteId }) =>
|
|
1058
|
+
Effect.callback<void, EventJournalError>((resume) => {
|
|
1059
|
+
const tx = db.transaction("remoteEntryId", "readwrite")
|
|
1060
|
+
advanceProgress(
|
|
1061
|
+
tx.objectStore("remoteEntryId"),
|
|
1062
|
+
remoteId,
|
|
1063
|
+
"nextSequence",
|
|
1064
|
+
(next) => advanceSequence(next, acks, firstSequence)
|
|
1065
|
+
)
|
|
1066
|
+
onTransactionDone(tx, "writeRemoteAcks", resume, constVoid)
|
|
1067
|
+
return Effect.sync(() => tx.abort())
|
|
1068
|
+
}),
|
|
758
1069
|
nextRemoteSequence: (remoteId) =>
|
|
759
1070
|
Effect.callback<number, EventJournalError>((resume) => {
|
|
760
|
-
const tx = db.transaction("
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
"prev"
|
|
766
|
-
)
|
|
767
|
-
cursorRequest.onsuccess = () => {
|
|
768
|
-
const cursor = cursorRequest.result
|
|
769
|
-
if (!cursor) return
|
|
770
|
-
sequence = cursor.value.sequence + 1
|
|
771
|
-
}
|
|
772
|
-
tx.oncomplete = () => resume(Effect.succeed(sequence))
|
|
773
|
-
tx.onerror = () =>
|
|
774
|
-
resume(Effect.fail(new EventJournalError({ method: "nextRemoteSequence", cause: tx.error })))
|
|
1071
|
+
const tx = db.transaction("remoteEntryId", "readonly")
|
|
1072
|
+
const progress = tx.objectStore("remoteEntryId").get([remoteId as IDBValidKey]) as IDBRequest<
|
|
1073
|
+
RemoteProgress | undefined
|
|
1074
|
+
>
|
|
1075
|
+
onTransactionDone(tx, "nextRemoteSequence", resume, () => progress.result?.nextSequence ?? 0)
|
|
775
1076
|
return Effect.sync(() => tx.abort())
|
|
776
1077
|
}),
|
|
777
1078
|
changes: PubSub.subscribe(pubsub),
|
|
@@ -782,6 +1083,37 @@ export const makeIndexedDb = (options?: {
|
|
|
782
1083
|
})
|
|
783
1084
|
})
|
|
784
1085
|
|
|
1086
|
+
/**
|
|
1087
|
+
* The sequence following every entry in a delivered batch.
|
|
1088
|
+
*
|
|
1089
|
+
* @internal
|
|
1090
|
+
*/
|
|
1091
|
+
export const nextSequenceAfter = (entries: ReadonlyArray<RemoteEntry>, next = 0): number => {
|
|
1092
|
+
for (const remoteEntry of entries) {
|
|
1093
|
+
if (remoteEntry.remoteSequence >= next) next = remoteEntry.remoteSequence + 1
|
|
1094
|
+
}
|
|
1095
|
+
return next
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* Advances across contiguous acknowledgements without skipping unseen entries.
|
|
1100
|
+
*
|
|
1101
|
+
* @internal
|
|
1102
|
+
*/
|
|
1103
|
+
export const advanceSequence = (
|
|
1104
|
+
next: number,
|
|
1105
|
+
acks: ReadonlyArray<RemoteAck>,
|
|
1106
|
+
firstSequence = 0
|
|
1107
|
+
): number => {
|
|
1108
|
+
next = Math.max(next, firstSequence)
|
|
1109
|
+
const sequences = acks.map((ack) => ack.sequence).sort((a, b) => a - b)
|
|
1110
|
+
for (const sequence of sequences) {
|
|
1111
|
+
if (sequence === next) next++
|
|
1112
|
+
else if (sequence > next) break
|
|
1113
|
+
}
|
|
1114
|
+
return next
|
|
1115
|
+
}
|
|
1116
|
+
|
|
785
1117
|
const makeBrowserWithLock = Effect.fnUntraced(function*(key: string) {
|
|
786
1118
|
if (typeof navigator !== "undefined" && "locks" in navigator) {
|
|
787
1119
|
return (storeId: StoreId) => <A, E, R>(self: Effect.Effect<A, E, R>) =>
|
|
@@ -806,10 +1138,50 @@ const makeBrowserWithLock = Effect.fnUntraced(function*(key: string) {
|
|
|
806
1138
|
}
|
|
807
1139
|
})
|
|
808
1140
|
|
|
809
|
-
|
|
1141
|
+
// Progress for a remote: `sequence` is the upload checkpoint and `nextSequence`
|
|
1142
|
+
// the download cursor.
|
|
1143
|
+
interface RemoteProgress {
|
|
1144
|
+
readonly sequence?: number
|
|
1145
|
+
readonly nextSequence?: number
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// Raises one progress field within the store's transaction; progress only moves forward.
|
|
1149
|
+
const advanceProgress = (
|
|
1150
|
+
store: IDBObjectStore,
|
|
1151
|
+
remoteId: RemoteId,
|
|
1152
|
+
field: keyof RemoteProgress,
|
|
1153
|
+
next: (current: number) => number
|
|
1154
|
+
): void => {
|
|
1155
|
+
const request = store.get([remoteId as IDBValidKey]) as IDBRequest<RemoteProgress | undefined>
|
|
1156
|
+
request.onsuccess = () => {
|
|
1157
|
+
const current = request.result?.[field] ?? 0
|
|
1158
|
+
const value = next(current)
|
|
1159
|
+
if (value > current) store.put({ ...request.result, remoteId, [field]: value })
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
const byEntryId = (a: Entry, b: Entry) => indexedDB.cmp(a.id as IDBValidKey, b.id as IDBValidKey)
|
|
1164
|
+
|
|
1165
|
+
// Greater than or equal to every entry id.
|
|
1166
|
+
const entryIdUpperBound = new Uint8Array(16).fill(0xff)
|
|
1167
|
+
|
|
1168
|
+
interface EntryIdb {
|
|
1169
|
+
readonly id: EntryId
|
|
1170
|
+
readonly event: string
|
|
1171
|
+
readonly primaryKey: string
|
|
1172
|
+
readonly payload: Uint8Array
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// Rows are written by `encodeEntryIdb`, so they are not validated again.
|
|
1176
|
+
const entryFromIdb = (row: EntryIdb): Entry =>
|
|
1177
|
+
new Entry({
|
|
1178
|
+
id: row.id,
|
|
1179
|
+
event: row.event,
|
|
1180
|
+
primaryKey: row.primaryKey,
|
|
1181
|
+
payload: row.payload
|
|
1182
|
+
}, { disableChecks: true })
|
|
1183
|
+
|
|
810
1184
|
const encodeEntryIdb = Schema.encodeSync(Entry)
|
|
811
|
-
const EntryIdbArray = Schema.Array(Entry)
|
|
812
|
-
const decodeEntryIdbArray = Schema.decodeUnknownEffect(EntryIdbArray)
|
|
813
1185
|
|
|
814
1186
|
/**
|
|
815
1187
|
* Provides `EventJournal` using the IndexedDB-backed implementation created by
|
|
@@ -827,6 +1199,18 @@ export const layerIndexedDb = (options?: {
|
|
|
827
1199
|
makeIndexedDb(options)
|
|
828
1200
|
)
|
|
829
1201
|
|
|
1202
|
+
// Resumes when the transaction commits, and fails if it errors or aborts. An
|
|
1203
|
+
// abort, such as a failed commit, does not always dispatch an error first.
|
|
1204
|
+
const onTransactionDone = <A>(
|
|
1205
|
+
tx: IDBTransaction,
|
|
1206
|
+
method: string,
|
|
1207
|
+
resume: (effect: Effect.Effect<A, EventJournalError>) => void,
|
|
1208
|
+
onComplete: () => A
|
|
1209
|
+
): void => {
|
|
1210
|
+
tx.oncomplete = () => resume(Effect.succeed(onComplete()))
|
|
1211
|
+
tx.onerror = tx.onabort = () => resume(Effect.fail(new EventJournalError({ method, cause: tx.error })))
|
|
1212
|
+
}
|
|
1213
|
+
|
|
830
1214
|
const idbReq = <T>(method: string, evaluate: () => IDBRequest<T>) =>
|
|
831
1215
|
Effect.callback<T, EventJournalError>((resume) => {
|
|
832
1216
|
const request = evaluate()
|