@dotdo/postgres 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +868 -0
- package/dist/cdc/change-stream.d.ts +44 -0
- package/dist/cdc/change-stream.d.ts.map +1 -0
- package/dist/cdc/change-stream.js +95 -0
- package/dist/cdc/change-stream.js.map +1 -0
- package/dist/cdc/filter.d.ts +58 -0
- package/dist/cdc/filter.d.ts.map +1 -0
- package/dist/cdc/filter.js +520 -0
- package/dist/cdc/filter.js.map +1 -0
- package/dist/cdc/index.d.ts +47 -0
- package/dist/cdc/index.d.ts.map +1 -0
- package/dist/cdc/index.js +50 -0
- package/dist/cdc/index.js.map +1 -0
- package/dist/cdc/resume-token.d.ts +60 -0
- package/dist/cdc/resume-token.d.ts.map +1 -0
- package/dist/cdc/resume-token.js +228 -0
- package/dist/cdc/resume-token.js.map +1 -0
- package/dist/cdc/transport/index.d.ts +7 -0
- package/dist/cdc/transport/index.d.ts.map +1 -0
- package/dist/cdc/transport/index.js +7 -0
- package/dist/cdc/transport/index.js.map +1 -0
- package/dist/cdc/transport/sse.d.ts +120 -0
- package/dist/cdc/transport/sse.d.ts.map +1 -0
- package/dist/cdc/transport/sse.js +590 -0
- package/dist/cdc/transport/sse.js.map +1 -0
- package/dist/cdc/transport/websocket.d.ts +130 -0
- package/dist/cdc/transport/websocket.d.ts.map +1 -0
- package/dist/cdc/transport/websocket.js +688 -0
- package/dist/cdc/transport/websocket.js.map +1 -0
- package/dist/cdc/types.d.ts +306 -0
- package/dist/cdc/types.d.ts.map +1 -0
- package/dist/cdc/types.js +8 -0
- package/dist/cdc/types.js.map +1 -0
- package/dist/config/index.d.ts +25 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +25 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/memory.d.ts +139 -0
- package/dist/config/memory.d.ts.map +1 -0
- package/dist/config/memory.js +157 -0
- package/dist/config/memory.js.map +1 -0
- package/dist/config/storage.d.ts +157 -0
- package/dist/config/storage.d.ts.map +1 -0
- package/dist/config/storage.js +178 -0
- package/dist/config/storage.js.map +1 -0
- package/dist/config/streaming.d.ts +117 -0
- package/dist/config/streaming.d.ts.map +1 -0
- package/dist/config/streaming.js +132 -0
- package/dist/config/streaming.js.map +1 -0
- package/dist/config/timeouts.d.ts +168 -0
- package/dist/config/timeouts.d.ts.map +1 -0
- package/dist/config/timeouts.js +192 -0
- package/dist/config/timeouts.js.map +1 -0
- package/dist/extensions/config.d.ts +89 -0
- package/dist/extensions/config.d.ts.map +1 -0
- package/dist/extensions/config.js +216 -0
- package/dist/extensions/config.js.map +1 -0
- package/dist/extensions/geo.d.ts +452 -0
- package/dist/extensions/geo.d.ts.map +1 -0
- package/dist/extensions/geo.js +583 -0
- package/dist/extensions/geo.js.map +1 -0
- package/dist/extensions/index.d.ts +167 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +99 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/loader.d.ts +226 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +456 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/pgmq-lite.d.ts +330 -0
- package/dist/extensions/pgmq-lite.d.ts.map +1 -0
- package/dist/extensions/pgmq-lite.js +648 -0
- package/dist/extensions/pgmq-lite.js.map +1 -0
- package/dist/extensions/plugins.d.ts +260 -0
- package/dist/extensions/plugins.d.ts.map +1 -0
- package/dist/extensions/plugins.js +535 -0
- package/dist/extensions/plugins.js.map +1 -0
- package/dist/extensions/registry.d.ts +93 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/registry.js +182 -0
- package/dist/extensions/registry.js.map +1 -0
- package/dist/extensions/vector.d.ts +106 -0
- package/dist/extensions/vector.d.ts.map +1 -0
- package/dist/extensions/vector.js +129 -0
- package/dist/extensions/vector.js.map +1 -0
- package/dist/iceberg/analytics.d.ts +279 -0
- package/dist/iceberg/analytics.d.ts.map +1 -0
- package/dist/iceberg/analytics.js +448 -0
- package/dist/iceberg/analytics.js.map +1 -0
- package/dist/iceberg/catalog-api.d.ts +39 -0
- package/dist/iceberg/catalog-api.d.ts.map +1 -0
- package/dist/iceberg/catalog-api.js +388 -0
- package/dist/iceberg/catalog-api.js.map +1 -0
- package/dist/iceberg/catalog.d.ts +401 -0
- package/dist/iceberg/catalog.d.ts.map +1 -0
- package/dist/iceberg/catalog.js +677 -0
- package/dist/iceberg/catalog.js.map +1 -0
- package/dist/iceberg/duckdb-wasm.d.ts +447 -0
- package/dist/iceberg/duckdb-wasm.d.ts.map +1 -0
- package/dist/iceberg/duckdb-wasm.js +600 -0
- package/dist/iceberg/duckdb-wasm.js.map +1 -0
- package/dist/iceberg/index.d.ts +92 -0
- package/dist/iceberg/index.d.ts.map +1 -0
- package/dist/iceberg/index.js +119 -0
- package/dist/iceberg/index.js.map +1 -0
- package/dist/iceberg/metadata.d.ts +214 -0
- package/dist/iceberg/metadata.d.ts.map +1 -0
- package/dist/iceberg/metadata.js +535 -0
- package/dist/iceberg/metadata.js.map +1 -0
- package/dist/iceberg/optimizer.d.ts +296 -0
- package/dist/iceberg/optimizer.d.ts.map +1 -0
- package/dist/iceberg/optimizer.js +889 -0
- package/dist/iceberg/optimizer.js.map +1 -0
- package/dist/iceberg/parquet.d.ts +447 -0
- package/dist/iceberg/parquet.d.ts.map +1 -0
- package/dist/iceberg/parquet.js +1225 -0
- package/dist/iceberg/parquet.js.map +1 -0
- package/dist/iceberg/r2-organization.d.ts +422 -0
- package/dist/iceberg/r2-organization.d.ts.map +1 -0
- package/dist/iceberg/r2-organization.js +672 -0
- package/dist/iceberg/r2-organization.js.map +1 -0
- package/dist/iceberg/scheduler-do-example.d.ts +158 -0
- package/dist/iceberg/scheduler-do-example.d.ts.map +1 -0
- package/dist/iceberg/scheduler-do-example.js +261 -0
- package/dist/iceberg/scheduler-do-example.js.map +1 -0
- package/dist/iceberg/scheduler.d.ts +434 -0
- package/dist/iceberg/scheduler.d.ts.map +1 -0
- package/dist/iceberg/scheduler.js +818 -0
- package/dist/iceberg/scheduler.js.map +1 -0
- package/dist/iceberg/schema.d.ts +149 -0
- package/dist/iceberg/schema.d.ts.map +1 -0
- package/dist/iceberg/schema.js +525 -0
- package/dist/iceberg/schema.js.map +1 -0
- package/dist/iceberg/snapshot-manager.d.ts +406 -0
- package/dist/iceberg/snapshot-manager.d.ts.map +1 -0
- package/dist/iceberg/snapshot-manager.js +934 -0
- package/dist/iceberg/snapshot-manager.js.map +1 -0
- package/dist/iceberg/sql-router.d.ts +194 -0
- package/dist/iceberg/sql-router.d.ts.map +1 -0
- package/dist/iceberg/sql-router.js +180 -0
- package/dist/iceberg/sql-router.js.map +1 -0
- package/dist/iceberg/test-fixtures.d.ts +151 -0
- package/dist/iceberg/test-fixtures.d.ts.map +1 -0
- package/dist/iceberg/test-fixtures.js +446 -0
- package/dist/iceberg/test-fixtures.js.map +1 -0
- package/dist/iceberg/time-travel-api.d.ts +102 -0
- package/dist/iceberg/time-travel-api.d.ts.map +1 -0
- package/dist/iceberg/time-travel-api.js +437 -0
- package/dist/iceberg/time-travel-api.js.map +1 -0
- package/dist/iceberg/time-travel.d.ts +293 -0
- package/dist/iceberg/time-travel.d.ts.map +1 -0
- package/dist/iceberg/time-travel.js +689 -0
- package/dist/iceberg/time-travel.js.map +1 -0
- package/dist/iceberg/transformer.d.ts +356 -0
- package/dist/iceberg/transformer.d.ts.map +1 -0
- package/dist/iceberg/transformer.js +770 -0
- package/dist/iceberg/transformer.js.map +1 -0
- package/dist/iceberg/types.d.ts +318 -0
- package/dist/iceberg/types.d.ts.map +1 -0
- package/dist/iceberg/types.js +9 -0
- package/dist/iceberg/types.js.map +1 -0
- package/dist/iceberg/writer.d.ts +144 -0
- package/dist/iceberg/writer.d.ts.map +1 -0
- package/dist/iceberg/writer.js +452 -0
- package/dist/iceberg/writer.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/lineage/index.d.ts +11 -0
- package/dist/lineage/index.d.ts.map +1 -0
- package/dist/lineage/index.js +11 -0
- package/dist/lineage/index.js.map +1 -0
- package/dist/lineage/integration.d.ts +134 -0
- package/dist/lineage/integration.d.ts.map +1 -0
- package/dist/lineage/integration.js +258 -0
- package/dist/lineage/integration.js.map +1 -0
- package/dist/lineage/tracker.d.ts +189 -0
- package/dist/lineage/tracker.d.ts.map +1 -0
- package/dist/lineage/tracker.js +1352 -0
- package/dist/lineage/tracker.js.map +1 -0
- package/dist/lineage/types.d.ts +318 -0
- package/dist/lineage/types.d.ts.map +1 -0
- package/dist/lineage/types.js +9 -0
- package/dist/lineage/types.js.map +1 -0
- package/dist/middleware/index.d.ts +11 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +16 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +397 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +507 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/migration-tooling/external-migration.d.ts +601 -0
- package/dist/migration-tooling/external-migration.d.ts.map +1 -0
- package/dist/migration-tooling/external-migration.js +1612 -0
- package/dist/migration-tooling/external-migration.js.map +1 -0
- package/dist/migration-tooling/index.d.ts +19 -0
- package/dist/migration-tooling/index.d.ts.map +1 -0
- package/dist/migration-tooling/index.js +19 -0
- package/dist/migration-tooling/index.js.map +1 -0
- package/dist/migrations/auto-migrator.d.ts +289 -0
- package/dist/migrations/auto-migrator.d.ts.map +1 -0
- package/dist/migrations/auto-migrator.js +396 -0
- package/dist/migrations/auto-migrator.js.map +1 -0
- package/dist/migrations/bulk-orchestrator.d.ts +403 -0
- package/dist/migrations/bulk-orchestrator.d.ts.map +1 -0
- package/dist/migrations/bulk-orchestrator.js +646 -0
- package/dist/migrations/bulk-orchestrator.js.map +1 -0
- package/dist/migrations/compatibility.d.ts +216 -0
- package/dist/migrations/compatibility.d.ts.map +1 -0
- package/dist/migrations/compatibility.js +651 -0
- package/dist/migrations/compatibility.js.map +1 -0
- package/dist/migrations/do-migrations.d.ts +101 -0
- package/dist/migrations/do-migrations.d.ts.map +1 -0
- package/dist/migrations/do-migrations.js +1060 -0
- package/dist/migrations/do-migrations.js.map +1 -0
- package/dist/migrations/do-migrations.types.d.ts +550 -0
- package/dist/migrations/do-migrations.types.d.ts.map +1 -0
- package/dist/migrations/do-migrations.types.js +15 -0
- package/dist/migrations/do-migrations.types.js.map +1 -0
- package/dist/migrations/drizzle-compat.d.ts +163 -0
- package/dist/migrations/drizzle-compat.d.ts.map +1 -0
- package/dist/migrations/drizzle-compat.js +273 -0
- package/dist/migrations/drizzle-compat.js.map +1 -0
- package/dist/migrations/index.d.ts +109 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +127 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/migration-api.d.ts +161 -0
- package/dist/migrations/migration-api.d.ts.map +1 -0
- package/dist/migrations/migration-api.js +499 -0
- package/dist/migrations/migration-api.js.map +1 -0
- package/dist/migrations/progress-tracker-do.d.ts +195 -0
- package/dist/migrations/progress-tracker-do.d.ts.map +1 -0
- package/dist/migrations/progress-tracker-do.js +339 -0
- package/dist/migrations/progress-tracker-do.js.map +1 -0
- package/dist/migrations/progress-tracker-kv.d.ts +103 -0
- package/dist/migrations/progress-tracker-kv.d.ts.map +1 -0
- package/dist/migrations/progress-tracker-kv.js +231 -0
- package/dist/migrations/progress-tracker-kv.js.map +1 -0
- package/dist/migrations/progress-tracker.d.ts +320 -0
- package/dist/migrations/progress-tracker.d.ts.map +1 -0
- package/dist/migrations/progress-tracker.js +443 -0
- package/dist/migrations/progress-tracker.js.map +1 -0
- package/dist/migrations/registry.d.ts +231 -0
- package/dist/migrations/registry.d.ts.map +1 -0
- package/dist/migrations/registry.js +376 -0
- package/dist/migrations/registry.js.map +1 -0
- package/dist/migrations/runner.d.ts +197 -0
- package/dist/migrations/runner.d.ts.map +1 -0
- package/dist/migrations/runner.js +1167 -0
- package/dist/migrations/runner.js.map +1 -0
- package/dist/migrations/schema-generator.d.ts +111 -0
- package/dist/migrations/schema-generator.d.ts.map +1 -0
- package/dist/migrations/schema-generator.js +335 -0
- package/dist/migrations/schema-generator.js.map +1 -0
- package/dist/migrations/testing.d.ts +321 -0
- package/dist/migrations/testing.d.ts.map +1 -0
- package/dist/migrations/testing.js +645 -0
- package/dist/migrations/testing.js.map +1 -0
- package/dist/migrations/types.d.ts +503 -0
- package/dist/migrations/types.d.ts.map +1 -0
- package/dist/migrations/types.js +11 -0
- package/dist/migrations/types.js.map +1 -0
- package/dist/migrations/validator.d.ts +215 -0
- package/dist/migrations/validator.d.ts.map +1 -0
- package/dist/migrations/validator.js +494 -0
- package/dist/migrations/validator.js.map +1 -0
- package/dist/observability/alerting.d.ts +116 -0
- package/dist/observability/alerting.d.ts.map +1 -0
- package/dist/observability/alerting.js +353 -0
- package/dist/observability/alerting.js.map +1 -0
- package/dist/observability/analytics-engine.d.ts +357 -0
- package/dist/observability/analytics-engine.d.ts.map +1 -0
- package/dist/observability/analytics-engine.js +430 -0
- package/dist/observability/analytics-engine.js.map +1 -0
- package/dist/observability/cost-metrics.d.ts +269 -0
- package/dist/observability/cost-metrics.d.ts.map +1 -0
- package/dist/observability/cost-metrics.js +560 -0
- package/dist/observability/cost-metrics.js.map +1 -0
- package/dist/observability/cross-do-tracing.d.ts +305 -0
- package/dist/observability/cross-do-tracing.d.ts.map +1 -0
- package/dist/observability/cross-do-tracing.js +431 -0
- package/dist/observability/cross-do-tracing.js.map +1 -0
- package/dist/observability/error-rate-collector.d.ts +163 -0
- package/dist/observability/error-rate-collector.d.ts.map +1 -0
- package/dist/observability/error-rate-collector.js +306 -0
- package/dist/observability/error-rate-collector.js.map +1 -0
- package/dist/observability/exporters.d.ts +231 -0
- package/dist/observability/exporters.d.ts.map +1 -0
- package/dist/observability/exporters.js +479 -0
- package/dist/observability/exporters.js.map +1 -0
- package/dist/observability/health-check.d.ts +106 -0
- package/dist/observability/health-check.d.ts.map +1 -0
- package/dist/observability/health-check.js +243 -0
- package/dist/observability/health-check.js.map +1 -0
- package/dist/observability/index.d.ts +297 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +455 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/instrumentation.d.ts +222 -0
- package/dist/observability/instrumentation.d.ts.map +1 -0
- package/dist/observability/instrumentation.js +532 -0
- package/dist/observability/instrumentation.js.map +1 -0
- package/dist/observability/memory-metrics.d.ts +227 -0
- package/dist/observability/memory-metrics.d.ts.map +1 -0
- package/dist/observability/memory-metrics.js +688 -0
- package/dist/observability/memory-metrics.js.map +1 -0
- package/dist/observability/metrics-endpoint.d.ts +91 -0
- package/dist/observability/metrics-endpoint.d.ts.map +1 -0
- package/dist/observability/metrics-endpoint.js +246 -0
- package/dist/observability/metrics-endpoint.js.map +1 -0
- package/dist/observability/metrics.d.ts +88 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +253 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/observability-features.d.ts +488 -0
- package/dist/observability/observability-features.d.ts.map +1 -0
- package/dist/observability/observability-features.js +773 -0
- package/dist/observability/observability-features.js.map +1 -0
- package/dist/observability/prometheus.d.ts +39 -0
- package/dist/observability/prometheus.d.ts.map +1 -0
- package/dist/observability/prometheus.js +120 -0
- package/dist/observability/prometheus.js.map +1 -0
- package/dist/observability/propagation.d.ts +126 -0
- package/dist/observability/propagation.d.ts.map +1 -0
- package/dist/observability/propagation.js +234 -0
- package/dist/observability/propagation.js.map +1 -0
- package/dist/observability/query-latency.d.ts +243 -0
- package/dist/observability/query-latency.d.ts.map +1 -0
- package/dist/observability/query-latency.js +292 -0
- package/dist/observability/query-latency.js.map +1 -0
- package/dist/observability/query-performance.d.ts +169 -0
- package/dist/observability/query-performance.d.ts.map +1 -0
- package/dist/observability/query-performance.js +290 -0
- package/dist/observability/query-performance.js.map +1 -0
- package/dist/observability/storage-tier-metrics.d.ts +174 -0
- package/dist/observability/storage-tier-metrics.d.ts.map +1 -0
- package/dist/observability/storage-tier-metrics.js +306 -0
- package/dist/observability/storage-tier-metrics.js.map +1 -0
- package/dist/observability/tier-cost-optimizer.d.ts +155 -0
- package/dist/observability/tier-cost-optimizer.d.ts.map +1 -0
- package/dist/observability/tier-cost-optimizer.js +536 -0
- package/dist/observability/tier-cost-optimizer.js.map +1 -0
- package/dist/observability/tracer.d.ts +149 -0
- package/dist/observability/tracer.d.ts.map +1 -0
- package/dist/observability/tracer.js +435 -0
- package/dist/observability/tracer.js.map +1 -0
- package/dist/observability/types.d.ts +402 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +103 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/pglite/workers-pglite.d.ts +138 -0
- package/dist/pglite/workers-pglite.d.ts.map +1 -0
- package/dist/pglite/workers-pglite.js +143 -0
- package/dist/pglite/workers-pglite.js.map +1 -0
- package/dist/pglite-assets/pglite.data +0 -0
- package/dist/pglite-assets/pglite.wasm +0 -0
- package/dist/playground/index.d.ts +52 -0
- package/dist/playground/index.d.ts.map +1 -0
- package/dist/playground/index.js +55 -0
- package/dist/playground/index.js.map +1 -0
- package/dist/playground/keyboard-shortcuts.d.ts +116 -0
- package/dist/playground/keyboard-shortcuts.d.ts.map +1 -0
- package/dist/playground/keyboard-shortcuts.js +588 -0
- package/dist/playground/keyboard-shortcuts.js.map +1 -0
- package/dist/playground/playground.d.ts +82 -0
- package/dist/playground/playground.d.ts.map +1 -0
- package/dist/playground/playground.js +271 -0
- package/dist/playground/playground.js.map +1 -0
- package/dist/playground/query-executor.d.ts +115 -0
- package/dist/playground/query-executor.d.ts.map +1 -0
- package/dist/playground/query-executor.js +558 -0
- package/dist/playground/query-executor.js.map +1 -0
- package/dist/playground/query-history.d.ts +92 -0
- package/dist/playground/query-history.d.ts.map +1 -0
- package/dist/playground/query-history.js +259 -0
- package/dist/playground/query-history.js.map +1 -0
- package/dist/playground/result-formatter.d.ts +59 -0
- package/dist/playground/result-formatter.d.ts.map +1 -0
- package/dist/playground/result-formatter.js +341 -0
- package/dist/playground/result-formatter.js.map +1 -0
- package/dist/playground/sample-datasets.d.ts +77 -0
- package/dist/playground/sample-datasets.d.ts.map +1 -0
- package/dist/playground/sample-datasets.js +641 -0
- package/dist/playground/sample-datasets.js.map +1 -0
- package/dist/playground/sample-queries.d.ts +73 -0
- package/dist/playground/sample-queries.d.ts.map +1 -0
- package/dist/playground/sample-queries.js +1095 -0
- package/dist/playground/sample-queries.js.map +1 -0
- package/dist/playground/schema-explorer.d.ts +55 -0
- package/dist/playground/schema-explorer.d.ts.map +1 -0
- package/dist/playground/schema-explorer.js +473 -0
- package/dist/playground/schema-explorer.js.map +1 -0
- package/dist/playground/types.d.ts +430 -0
- package/dist/playground/types.d.ts.map +1 -0
- package/dist/playground/types.js +10 -0
- package/dist/playground/types.js.map +1 -0
- package/dist/readonly/cache-reader.d.ts +145 -0
- package/dist/readonly/cache-reader.d.ts.map +1 -0
- package/dist/readonly/cache-reader.js +198 -0
- package/dist/readonly/cache-reader.js.map +1 -0
- package/dist/readonly/config.d.ts +74 -0
- package/dist/readonly/config.d.ts.map +1 -0
- package/dist/readonly/config.js +67 -0
- package/dist/readonly/config.js.map +1 -0
- package/dist/readonly/index.d.ts +22 -0
- package/dist/readonly/index.d.ts.map +1 -0
- package/dist/readonly/index.js +17 -0
- package/dist/readonly/index.js.map +1 -0
- package/dist/readonly/pglite-wrapper.d.ts +82 -0
- package/dist/readonly/pglite-wrapper.d.ts.map +1 -0
- package/dist/readonly/pglite-wrapper.js +123 -0
- package/dist/readonly/pglite-wrapper.js.map +1 -0
- package/dist/readonly/worker.d.ts +142 -0
- package/dist/readonly/worker.d.ts.map +1 -0
- package/dist/readonly/worker.js +187 -0
- package/dist/readonly/worker.js.map +1 -0
- package/dist/readonly/write-blocker.d.ts +47 -0
- package/dist/readonly/write-blocker.d.ts.map +1 -0
- package/dist/readonly/write-blocker.js +136 -0
- package/dist/readonly/write-blocker.js.map +1 -0
- package/dist/recovery/disaster-recovery.d.ts +326 -0
- package/dist/recovery/disaster-recovery.d.ts.map +1 -0
- package/dist/recovery/disaster-recovery.js +799 -0
- package/dist/recovery/disaster-recovery.js.map +1 -0
- package/dist/recovery/index.d.ts +12 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +12 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/recovery/parquet-parser.d.ts +321 -0
- package/dist/recovery/parquet-parser.d.ts.map +1 -0
- package/dist/recovery/parquet-parser.js +797 -0
- package/dist/recovery/parquet-parser.js.map +1 -0
- package/dist/retention/index.d.ts +50 -0
- package/dist/retention/index.d.ts.map +1 -0
- package/dist/retention/index.js +50 -0
- package/dist/retention/index.js.map +1 -0
- package/dist/retention/policy.d.ts +344 -0
- package/dist/retention/policy.d.ts.map +1 -0
- package/dist/retention/policy.js +472 -0
- package/dist/retention/policy.js.map +1 -0
- package/dist/retention/purger.d.ts +187 -0
- package/dist/retention/purger.d.ts.map +1 -0
- package/dist/retention/purger.js +411 -0
- package/dist/retention/purger.js.map +1 -0
- package/dist/rls/auth-integration.d.ts +280 -0
- package/dist/rls/auth-integration.d.ts.map +1 -0
- package/dist/rls/auth-integration.js +399 -0
- package/dist/rls/auth-integration.js.map +1 -0
- package/dist/rls/generator.d.ts +249 -0
- package/dist/rls/generator.d.ts.map +1 -0
- package/dist/rls/generator.js +495 -0
- package/dist/rls/generator.js.map +1 -0
- package/dist/rls/index.d.ts +26 -0
- package/dist/rls/index.d.ts.map +1 -0
- package/dist/rls/index.js +58 -0
- package/dist/rls/index.js.map +1 -0
- package/dist/rls/policy.d.ts +116 -0
- package/dist/rls/policy.d.ts.map +1 -0
- package/dist/rls/policy.js +77 -0
- package/dist/rls/policy.js.map +1 -0
- package/dist/rls/validator.d.ts +155 -0
- package/dist/rls/validator.d.ts.map +1 -0
- package/dist/rls/validator.js +792 -0
- package/dist/rls/validator.js.map +1 -0
- package/dist/routing/adaptive-router.d.ts +317 -0
- package/dist/routing/adaptive-router.d.ts.map +1 -0
- package/dist/routing/adaptive-router.js +554 -0
- package/dist/routing/adaptive-router.js.map +1 -0
- package/dist/routing/circuit-breaker.d.ts +339 -0
- package/dist/routing/circuit-breaker.d.ts.map +1 -0
- package/dist/routing/circuit-breaker.js +620 -0
- package/dist/routing/circuit-breaker.js.map +1 -0
- package/dist/routing/cost-metrics.d.ts +133 -0
- package/dist/routing/cost-metrics.d.ts.map +1 -0
- package/dist/routing/cost-metrics.js +259 -0
- package/dist/routing/cost-metrics.js.map +1 -0
- package/dist/routing/do-connection-pool.d.ts +243 -0
- package/dist/routing/do-connection-pool.d.ts.map +1 -0
- package/dist/routing/do-connection-pool.js +572 -0
- package/dist/routing/do-connection-pool.js.map +1 -0
- package/dist/routing/index.d.ts +59 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +59 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/query-complexity-estimator.d.ts +73 -0
- package/dist/routing/query-complexity-estimator.d.ts.map +1 -0
- package/dist/routing/query-complexity-estimator.js +327 -0
- package/dist/routing/query-complexity-estimator.js.map +1 -0
- package/dist/routing/request-coalescing.d.ts +178 -0
- package/dist/routing/request-coalescing.d.ts.map +1 -0
- package/dist/routing/request-coalescing.js +325 -0
- package/dist/routing/request-coalescing.js.map +1 -0
- package/dist/routing/runtime-router.d.ts +107 -0
- package/dist/routing/runtime-router.d.ts.map +1 -0
- package/dist/routing/runtime-router.js +246 -0
- package/dist/routing/runtime-router.js.map +1 -0
- package/dist/routing/tenant-router.d.ts +848 -0
- package/dist/routing/tenant-router.d.ts.map +1 -0
- package/dist/routing/tenant-router.js +1056 -0
- package/dist/routing/tenant-router.js.map +1 -0
- package/dist/routing/websocket-pool.d.ts +119 -0
- package/dist/routing/websocket-pool.d.ts.map +1 -0
- package/dist/routing/websocket-pool.js +436 -0
- package/dist/routing/websocket-pool.js.map +1 -0
- package/dist/storage/cache-layer.d.ts +159 -0
- package/dist/storage/cache-layer.d.ts.map +1 -0
- package/dist/storage/cache-layer.js +245 -0
- package/dist/storage/cache-layer.js.map +1 -0
- package/dist/storage/cost-aware-tiering.d.ts +258 -0
- package/dist/storage/cost-aware-tiering.d.ts.map +1 -0
- package/dist/storage/cost-aware-tiering.js +526 -0
- package/dist/storage/cost-aware-tiering.js.map +1 -0
- package/dist/storage/index.d.ts +87 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +78 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/interfaces.d.ts +856 -0
- package/dist/storage/interfaces.d.ts.map +1 -0
- package/dist/storage/interfaces.js +69 -0
- package/dist/storage/interfaces.js.map +1 -0
- package/dist/storage/r2-layer.d.ts +226 -0
- package/dist/storage/r2-layer.d.ts.map +1 -0
- package/dist/storage/r2-layer.js +307 -0
- package/dist/storage/r2-layer.js.map +1 -0
- package/dist/storage/r2-overflow.d.ts +344 -0
- package/dist/storage/r2-overflow.d.ts.map +1 -0
- package/dist/storage/r2-overflow.js +730 -0
- package/dist/storage/r2-overflow.js.map +1 -0
- package/dist/storage/r2-page-vfs.d.ts +374 -0
- package/dist/storage/r2-page-vfs.d.ts.map +1 -0
- package/dist/storage/r2-page-vfs.js +754 -0
- package/dist/storage/r2-page-vfs.js.map +1 -0
- package/dist/storage/swr-cache.d.ts +181 -0
- package/dist/storage/swr-cache.d.ts.map +1 -0
- package/dist/storage/swr-cache.js +295 -0
- package/dist/storage/swr-cache.js.map +1 -0
- package/dist/storage/tiered-orchestrator.d.ts +951 -0
- package/dist/storage/tiered-orchestrator.d.ts.map +1 -0
- package/dist/storage/tiered-orchestrator.js +1731 -0
- package/dist/storage/tiered-orchestrator.js.map +1 -0
- package/dist/storage/tiered-vfs-swr.d.ts +279 -0
- package/dist/storage/tiered-vfs-swr.d.ts.map +1 -0
- package/dist/storage/tiered-vfs-swr.js +584 -0
- package/dist/storage/tiered-vfs-swr.js.map +1 -0
- package/dist/storage/tiered-vfs.d.ts +405 -0
- package/dist/storage/tiered-vfs.d.ts.map +1 -0
- package/dist/storage/tiered-vfs.js +833 -0
- package/dist/storage/tiered-vfs.js.map +1 -0
- package/dist/streaming/backpressure-controller.d.ts +173 -0
- package/dist/streaming/backpressure-controller.d.ts.map +1 -0
- package/dist/streaming/backpressure-controller.js +344 -0
- package/dist/streaming/backpressure-controller.js.map +1 -0
- package/dist/streaming/buffer-pool.d.ts +241 -0
- package/dist/streaming/buffer-pool.d.ts.map +1 -0
- package/dist/streaming/buffer-pool.js +381 -0
- package/dist/streaming/buffer-pool.js.map +1 -0
- package/dist/streaming/cdc-iceberg-connector.d.ts +272 -0
- package/dist/streaming/cdc-iceberg-connector.d.ts.map +1 -0
- package/dist/streaming/cdc-iceberg-connector.js +408 -0
- package/dist/streaming/cdc-iceberg-connector.js.map +1 -0
- package/dist/streaming/index.d.ts +111 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +128 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/streaming/live-cdc-stream.d.ts +400 -0
- package/dist/streaming/live-cdc-stream.d.ts.map +1 -0
- package/dist/streaming/live-cdc-stream.js +703 -0
- package/dist/streaming/live-cdc-stream.js.map +1 -0
- package/dist/streaming/memory-bounded-stream.d.ts +207 -0
- package/dist/streaming/memory-bounded-stream.d.ts.map +1 -0
- package/dist/streaming/memory-bounded-stream.js +340 -0
- package/dist/streaming/memory-bounded-stream.js.map +1 -0
- package/dist/streaming/query-streamer.d.ts +379 -0
- package/dist/streaming/query-streamer.d.ts.map +1 -0
- package/dist/streaming/query-streamer.js +495 -0
- package/dist/streaming/query-streamer.js.map +1 -0
- package/dist/streaming/response-streaming.d.ts +203 -0
- package/dist/streaming/response-streaming.d.ts.map +1 -0
- package/dist/streaming/response-streaming.js +449 -0
- package/dist/streaming/response-streaming.js.map +1 -0
- package/dist/types/branded.d.ts +859 -0
- package/dist/types/branded.d.ts.map +1 -0
- package/dist/types/branded.js +891 -0
- package/dist/types/branded.js.map +1 -0
- package/dist/types/utilities.d.ts +757 -0
- package/dist/types/utilities.d.ts.map +1 -0
- package/dist/types/utilities.js +447 -0
- package/dist/types/utilities.js.map +1 -0
- package/dist/wal/replay-engine.d.ts +344 -0
- package/dist/wal/replay-engine.d.ts.map +1 -0
- package/dist/wal/replay-engine.js +975 -0
- package/dist/wal/replay-engine.js.map +1 -0
- package/dist/worker/__mocks__/capnweb.d.ts +13 -0
- package/dist/worker/__mocks__/capnweb.d.ts.map +1 -0
- package/dist/worker/__mocks__/capnweb.js +15 -0
- package/dist/worker/__mocks__/capnweb.js.map +1 -0
- package/dist/worker/__mocks__/cloudflare-workers.d.ts +31 -0
- package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +1 -0
- package/dist/worker/__mocks__/cloudflare-workers.js +33 -0
- package/dist/worker/__mocks__/cloudflare-workers.js.map +1 -0
- package/dist/worker/__mocks__/pglite.data.d.ts +3 -0
- package/dist/worker/__mocks__/pglite.data.d.ts.map +1 -0
- package/dist/worker/__mocks__/pglite.data.js +20 -0
- package/dist/worker/__mocks__/pglite.data.js.map +1 -0
- package/dist/worker/__mocks__/pglite.wasm.d.ts +3 -0
- package/dist/worker/__mocks__/pglite.wasm.d.ts.map +1 -0
- package/dist/worker/__mocks__/pglite.wasm.js +30 -0
- package/dist/worker/__mocks__/pglite.wasm.js.map +1 -0
- package/dist/worker/auth-rate-limiter.d.ts +270 -0
- package/dist/worker/auth-rate-limiter.d.ts.map +1 -0
- package/dist/worker/auth-rate-limiter.js +332 -0
- package/dist/worker/auth-rate-limiter.js.map +1 -0
- package/dist/worker/auth.d.ts +345 -0
- package/dist/worker/auth.d.ts.map +1 -0
- package/dist/worker/auth.js +837 -0
- package/dist/worker/auth.js.map +1 -0
- package/dist/worker/cdc-backpressure.d.ts +338 -0
- package/dist/worker/cdc-backpressure.d.ts.map +1 -0
- package/dist/worker/cdc-backpressure.js +619 -0
- package/dist/worker/cdc-backpressure.js.map +1 -0
- package/dist/worker/cdc-sse.d.ts +277 -0
- package/dist/worker/cdc-sse.d.ts.map +1 -0
- package/dist/worker/cdc-sse.js +528 -0
- package/dist/worker/cdc-sse.js.map +1 -0
- package/dist/worker/cdc-websocket.d.ts +252 -0
- package/dist/worker/cdc-websocket.d.ts.map +1 -0
- package/dist/worker/cdc-websocket.js +940 -0
- package/dist/worker/cdc-websocket.js.map +1 -0
- package/dist/worker/cdc.d.ts +95 -0
- package/dist/worker/cdc.d.ts.map +1 -0
- package/dist/worker/cdc.js +211 -0
- package/dist/worker/cdc.js.map +1 -0
- package/dist/worker/concerns/auth-concern.d.ts +50 -0
- package/dist/worker/concerns/auth-concern.d.ts.map +1 -0
- package/dist/worker/concerns/auth-concern.js +131 -0
- package/dist/worker/concerns/auth-concern.js.map +1 -0
- package/dist/worker/concerns/cdc-concern.d.ts +99 -0
- package/dist/worker/concerns/cdc-concern.d.ts.map +1 -0
- package/dist/worker/concerns/cdc-concern.js +137 -0
- package/dist/worker/concerns/cdc-concern.js.map +1 -0
- package/dist/worker/concerns/index.d.ts +22 -0
- package/dist/worker/concerns/index.d.ts.map +1 -0
- package/dist/worker/concerns/index.js +13 -0
- package/dist/worker/concerns/index.js.map +1 -0
- package/dist/worker/concerns/query-execution-concern.d.ts +104 -0
- package/dist/worker/concerns/query-execution-concern.d.ts.map +1 -0
- package/dist/worker/concerns/query-execution-concern.js +95 -0
- package/dist/worker/concerns/query-execution-concern.js.map +1 -0
- package/dist/worker/concerns/storage-orchestration-concern.d.ts +78 -0
- package/dist/worker/concerns/storage-orchestration-concern.d.ts.map +1 -0
- package/dist/worker/concerns/storage-orchestration-concern.js +240 -0
- package/dist/worker/concerns/storage-orchestration-concern.js.map +1 -0
- package/dist/worker/do-auth-manager.d.ts +108 -0
- package/dist/worker/do-auth-manager.d.ts.map +1 -0
- package/dist/worker/do-auth-manager.js +212 -0
- package/dist/worker/do-auth-manager.js.map +1 -0
- package/dist/worker/do-pglite-manager.d.ts +137 -0
- package/dist/worker/do-pglite-manager.d.ts.map +1 -0
- package/dist/worker/do-pglite-manager.js +228 -0
- package/dist/worker/do-pglite-manager.js.map +1 -0
- package/dist/worker/do.d.ts +556 -0
- package/dist/worker/do.d.ts.map +1 -0
- package/dist/worker/do.js +1441 -0
- package/dist/worker/do.js.map +1 -0
- package/dist/worker/entry.d.ts +23 -0
- package/dist/worker/entry.d.ts.map +1 -0
- package/dist/worker/entry.js +362 -0
- package/dist/worker/entry.js.map +1 -0
- package/dist/worker/errors.d.ts +106 -0
- package/dist/worker/errors.d.ts.map +1 -0
- package/dist/worker/errors.js +178 -0
- package/dist/worker/errors.js.map +1 -0
- package/dist/worker/health-check-manager.d.ts +141 -0
- package/dist/worker/health-check-manager.d.ts.map +1 -0
- package/dist/worker/health-check-manager.js +145 -0
- package/dist/worker/health-check-manager.js.map +1 -0
- package/dist/worker/index.d.ts +60 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +67 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/memory-pressure.d.ts +892 -0
- package/dist/worker/memory-pressure.d.ts.map +1 -0
- package/dist/worker/memory-pressure.js +1990 -0
- package/dist/worker/memory-pressure.js.map +1 -0
- package/dist/worker/migration-manager.d.ts +153 -0
- package/dist/worker/migration-manager.d.ts.map +1 -0
- package/dist/worker/migration-manager.js +461 -0
- package/dist/worker/migration-manager.js.map +1 -0
- package/dist/worker/plugin-manager.d.ts +147 -0
- package/dist/worker/plugin-manager.d.ts.map +1 -0
- package/dist/worker/plugin-manager.js +408 -0
- package/dist/worker/plugin-manager.js.map +1 -0
- package/dist/worker/proxy.d.ts +330 -0
- package/dist/worker/proxy.d.ts.map +1 -0
- package/dist/worker/proxy.js +504 -0
- package/dist/worker/proxy.js.map +1 -0
- package/dist/worker/query-execution-manager.d.ts +107 -0
- package/dist/worker/query-execution-manager.d.ts.map +1 -0
- package/dist/worker/query-execution-manager.js +155 -0
- package/dist/worker/query-execution-manager.js.map +1 -0
- package/dist/worker/query-executor.d.ts +163 -0
- package/dist/worker/query-executor.d.ts.map +1 -0
- package/dist/worker/query-executor.js +413 -0
- package/dist/worker/query-executor.js.map +1 -0
- package/dist/worker/query-stats-manager.d.ts +117 -0
- package/dist/worker/query-stats-manager.d.ts.map +1 -0
- package/dist/worker/query-stats-manager.js +162 -0
- package/dist/worker/query-stats-manager.js.map +1 -0
- package/dist/worker/result-handler.d.ts +192 -0
- package/dist/worker/result-handler.d.ts.map +1 -0
- package/dist/worker/result-handler.js +346 -0
- package/dist/worker/result-handler.js.map +1 -0
- package/dist/worker/routes.d.ts +135 -0
- package/dist/worker/routes.d.ts.map +1 -0
- package/dist/worker/routes.js +460 -0
- package/dist/worker/routes.js.map +1 -0
- package/dist/worker/rpc-methods-manager.d.ts +142 -0
- package/dist/worker/rpc-methods-manager.d.ts.map +1 -0
- package/dist/worker/rpc-methods-manager.js +195 -0
- package/dist/worker/rpc-methods-manager.js.map +1 -0
- package/dist/worker/rpc.d.ts +259 -0
- package/dist/worker/rpc.d.ts.map +1 -0
- package/dist/worker/rpc.js +398 -0
- package/dist/worker/rpc.js.map +1 -0
- package/dist/worker/schema-version.d.ts +209 -0
- package/dist/worker/schema-version.d.ts.map +1 -0
- package/dist/worker/schema-version.js +450 -0
- package/dist/worker/schema-version.js.map +1 -0
- package/dist/worker/session-manager.d.ts +282 -0
- package/dist/worker/session-manager.d.ts.map +1 -0
- package/dist/worker/session-manager.js +523 -0
- package/dist/worker/session-manager.js.map +1 -0
- package/dist/worker/shutdown-manager.d.ts +188 -0
- package/dist/worker/shutdown-manager.d.ts.map +1 -0
- package/dist/worker/shutdown-manager.js +347 -0
- package/dist/worker/shutdown-manager.js.map +1 -0
- package/dist/worker/sql-transform.d.ts +61 -0
- package/dist/worker/sql-transform.d.ts.map +1 -0
- package/dist/worker/sql-transform.js +312 -0
- package/dist/worker/sql-transform.js.map +1 -0
- package/dist/worker/types.d.ts +738 -0
- package/dist/worker/types.d.ts.map +1 -0
- package/dist/worker/types.js +6 -0
- package/dist/worker/types.js.map +1 -0
- package/dist/worker/user-routes.d.ts +76 -0
- package/dist/worker/user-routes.d.ts.map +1 -0
- package/dist/worker/user-routes.js +188 -0
- package/dist/worker/user-routes.js.map +1 -0
- package/dist/worker/wal-facade.d.ts +138 -0
- package/dist/worker/wal-facade.d.ts.map +1 -0
- package/dist/worker/wal-facade.js +184 -0
- package/dist/worker/wal-facade.js.map +1 -0
- package/dist/worker/wal-r2.d.ts +271 -0
- package/dist/worker/wal-r2.d.ts.map +1 -0
- package/dist/worker/wal-r2.js +689 -0
- package/dist/worker/wal-r2.js.map +1 -0
- package/dist/worker/wal-replay.d.ts +361 -0
- package/dist/worker/wal-replay.d.ts.map +1 -0
- package/dist/worker/wal-replay.js +628 -0
- package/dist/worker/wal-replay.js.map +1 -0
- package/dist/worker/wal-retention.d.ts +389 -0
- package/dist/worker/wal-retention.d.ts.map +1 -0
- package/dist/worker/wal-retention.js +763 -0
- package/dist/worker/wal-retention.js.map +1 -0
- package/dist/worker/wal.d.ts +278 -0
- package/dist/worker/wal.d.ts.map +1 -0
- package/dist/worker/wal.js +467 -0
- package/dist/worker/wal.js.map +1 -0
- package/dist/worker/websocket.d.ts +85 -0
- package/dist/worker/websocket.d.ts.map +1 -0
- package/dist/worker/websocket.js +227 -0
- package/dist/worker/websocket.js.map +1 -0
- package/package.json +108 -0
- package/src/cdc/change-stream.ts +137 -0
- package/src/cdc/filter.ts +646 -0
- package/src/cdc/index.ts +112 -0
- package/src/cdc/resume-token.ts +280 -0
- package/src/cdc/transport/index.ts +7 -0
- package/src/cdc/transport/sse.ts +723 -0
- package/src/cdc/transport/websocket.ts +873 -0
- package/src/cdc/types.ts +346 -0
- package/src/config/index.ts +25 -0
- package/src/config/memory.ts +177 -0
- package/src/config/storage.ts +204 -0
- package/src/config/streaming.ts +147 -0
- package/src/config/timeouts.ts +221 -0
- package/src/extensions/config.test.ts +187 -0
- package/src/extensions/config.ts +278 -0
- package/src/extensions/geo.test.ts +455 -0
- package/src/extensions/geo.ts +858 -0
- package/src/extensions/index.test.ts +259 -0
- package/src/extensions/index.ts +227 -0
- package/src/extensions/loader.test.ts +555 -0
- package/src/extensions/loader.ts +588 -0
- package/src/extensions/pgmq-lite.test.ts +727 -0
- package/src/extensions/pgmq-lite.ts +770 -0
- package/src/extensions/plugins.test.ts +528 -0
- package/src/extensions/plugins.ts +718 -0
- package/src/extensions/registry.test.ts +202 -0
- package/src/extensions/registry.ts +267 -0
- package/src/extensions/vector.test.ts +195 -0
- package/src/extensions/vector.ts +217 -0
- package/src/iceberg/SCHEDULER.md +580 -0
- package/src/iceberg/analytics.test.ts +703 -0
- package/src/iceberg/analytics.ts +727 -0
- package/src/iceberg/catalog-api.test.ts +838 -0
- package/src/iceberg/catalog-api.ts +520 -0
- package/src/iceberg/catalog.test.ts +680 -0
- package/src/iceberg/catalog.ts +1007 -0
- package/src/iceberg/iceberg.test.ts +705 -0
- package/src/iceberg/index.ts +406 -0
- package/src/iceberg/metadata.test.ts +632 -0
- package/src/iceberg/metadata.ts +649 -0
- package/src/iceberg/optimizer.test.ts +868 -0
- package/src/iceberg/optimizer.ts +1287 -0
- package/src/iceberg/parquet.test.ts +899 -0
- package/src/iceberg/parquet.ts +1640 -0
- package/src/iceberg/r2-organization.test.ts +615 -0
- package/src/iceberg/r2-organization.ts +951 -0
- package/src/iceberg/scheduler-do-example.ts +364 -0
- package/src/iceberg/scheduler.test.ts +861 -0
- package/src/iceberg/scheduler.ts +1201 -0
- package/src/iceberg/schema.test.ts +547 -0
- package/src/iceberg/schema.ts +616 -0
- package/src/iceberg/snapshot-manager.test.ts +919 -0
- package/src/iceberg/snapshot-manager.ts +1369 -0
- package/src/iceberg/sql-router.test.ts +334 -0
- package/src/iceberg/sql-router.ts +337 -0
- package/src/iceberg/test-fixtures.ts +605 -0
- package/src/iceberg/time-travel-api.test.ts +1029 -0
- package/src/iceberg/time-travel-api.ts +731 -0
- package/src/iceberg/time-travel.test.ts +1218 -0
- package/src/iceberg/time-travel.ts +1052 -0
- package/src/iceberg/transformer.test.ts +689 -0
- package/src/iceberg/transformer.ts +1029 -0
- package/src/iceberg/types.ts +373 -0
- package/src/iceberg/writer.test.ts +716 -0
- package/src/iceberg/writer.ts +590 -0
- package/src/index.ts +212 -0
- package/src/lineage/index.ts +42 -0
- package/src/lineage/integration.ts +334 -0
- package/src/lineage/tracker.ts +1618 -0
- package/src/lineage/types.ts +354 -0
- package/src/middleware/index.ts +36 -0
- package/src/middleware/rate-limit-concurrent.test.ts +794 -0
- package/src/middleware/rate-limit.test.ts +1568 -0
- package/src/middleware/rate-limit.ts +840 -0
- package/src/migration-tooling/external-migration.test.ts +1864 -0
- package/src/migration-tooling/external-migration.ts +2355 -0
- package/src/migration-tooling/index.ts +19 -0
- package/src/migrations/ARCHITECTURE.md +474 -0
- package/src/migrations/PROGRESS_TRACKING.md +485 -0
- package/src/migrations/auto-migrator.test.ts +732 -0
- package/src/migrations/auto-migrator.ts +531 -0
- package/src/migrations/bulk-orchestrator.test.ts +801 -0
- package/src/migrations/bulk-orchestrator.ts +1039 -0
- package/src/migrations/compatibility.test.ts +958 -0
- package/src/migrations/compatibility.ts +902 -0
- package/src/migrations/do-migrations.test.ts +2620 -0
- package/src/migrations/do-migrations.ts +1289 -0
- package/src/migrations/do-migrations.types.ts +715 -0
- package/src/migrations/drizzle-compat.test.ts +210 -0
- package/src/migrations/drizzle-compat.ts +337 -0
- package/src/migrations/index.ts +334 -0
- package/src/migrations/migration-api.test.ts +438 -0
- package/src/migrations/migration-api.ts +704 -0
- package/src/migrations/progress-tracker-do.ts +518 -0
- package/src/migrations/progress-tracker-kv.ts +305 -0
- package/src/migrations/progress-tracker.test.ts +937 -0
- package/src/migrations/progress-tracker.ts +665 -0
- package/src/migrations/registry.test.ts +331 -0
- package/src/migrations/registry.ts +468 -0
- package/src/migrations/rollback.test.ts +644 -0
- package/src/migrations/runner.test.ts +807 -0
- package/src/migrations/runner.test.ts.backup +759 -0
- package/src/migrations/runner.ts +1459 -0
- package/src/migrations/schema-generator.test.ts +649 -0
- package/src/migrations/schema-generator.ts +513 -0
- package/src/migrations/testing.ts +1037 -0
- package/src/migrations/types.ts +573 -0
- package/src/migrations/validator.test.ts +660 -0
- package/src/migrations/validator.ts +741 -0
- package/src/observability/alerting.test.ts +1133 -0
- package/src/observability/alerting.ts +455 -0
- package/src/observability/analytics-engine.ts +733 -0
- package/src/observability/cost-metrics.ts +804 -0
- package/src/observability/cross-do-tracing.test.ts +516 -0
- package/src/observability/cross-do-tracing.ts +588 -0
- package/src/observability/dashboards/postgres-do-overview.json +1656 -0
- package/src/observability/error-rate-collector.test.ts +977 -0
- package/src/observability/error-rate-collector.ts +518 -0
- package/src/observability/exporters.test.ts +365 -0
- package/src/observability/exporters.ts +650 -0
- package/src/observability/health-check.test.ts +353 -0
- package/src/observability/health-check.ts +341 -0
- package/src/observability/index.test.ts +298 -0
- package/src/observability/index.ts +885 -0
- package/src/observability/instrumentation.test.ts +428 -0
- package/src/observability/instrumentation.ts +788 -0
- package/src/observability/memory-metrics.test.ts +355 -0
- package/src/observability/memory-metrics.ts +990 -0
- package/src/observability/metrics-endpoint.test.ts +402 -0
- package/src/observability/metrics-endpoint.ts +374 -0
- package/src/observability/metrics.test.ts +291 -0
- package/src/observability/metrics.ts +315 -0
- package/src/observability/observability-features.ts +1296 -0
- package/src/observability/prometheus.test.ts +292 -0
- package/src/observability/prometheus.ts +170 -0
- package/src/observability/propagation.test.ts +417 -0
- package/src/observability/propagation.ts +294 -0
- package/src/observability/query-latency.ts +586 -0
- package/src/observability/query-performance.test.ts +406 -0
- package/src/observability/query-performance.ts +491 -0
- package/src/observability/storage-tier-metrics.test.ts +633 -0
- package/src/observability/storage-tier-metrics.ts +570 -0
- package/src/observability/tier-cost-optimizer.ts +740 -0
- package/src/observability/tracer.test.ts +346 -0
- package/src/observability/tracer.ts +585 -0
- package/src/observability/types.test.ts +726 -0
- package/src/observability/types.ts +434 -0
- package/src/pglite/auto-demotion.test.ts +477 -0
- package/src/pglite/auto-demotion.ts +385 -0
- package/src/pglite/auto-promotion.test.ts +824 -0
- package/src/pglite/auto-promotion.ts +547 -0
- package/src/pglite/cache-layer.test.ts +469 -0
- package/src/pglite/cache-layer.ts +271 -0
- package/src/pglite/cold-start-manager.ts +1260 -0
- package/src/pglite/cold-start-optimizer.test.ts +937 -0
- package/src/pglite/cold-start-optimizer.ts +1895 -0
- package/src/pglite/dovfs-adapter.ts +1122 -0
- package/src/pglite/dovfs.ts +1258 -0
- package/src/pglite/etag-cache.test.ts +844 -0
- package/src/pglite/etag-cache.ts +526 -0
- package/src/pglite/index.ts +442 -0
- package/src/pglite/init.test.ts +455 -0
- package/src/pglite/init.ts +574 -0
- package/src/pglite/lifecycle.test.ts +599 -0
- package/src/pglite/lifecycle.ts +704 -0
- package/src/pglite/parallel-loader.test.ts +586 -0
- package/src/pglite/parallel-loader.ts +481 -0
- package/src/pglite/production-pglite.test.ts +666 -0
- package/src/pglite/production-pglite.ts +537 -0
- package/src/pglite/query-executor.ts +614 -0
- package/src/pglite/r2-layer.test.ts +501 -0
- package/src/pglite/r2-layer.ts +322 -0
- package/src/pglite/tiered-init.test.ts +725 -0
- package/src/pglite/tiered-init.ts +556 -0
- package/src/pglite/tiered-vfs.test.ts +726 -0
- package/src/pglite/tiered-vfs.ts +33 -0
- package/src/pglite/tiering-stats.test.ts +531 -0
- package/src/pglite/tiering-stats.ts +407 -0
- package/src/pglite/transaction-hooks.ts +343 -0
- package/src/pglite/warm-loader.test.ts +1701 -0
- package/src/pglite/warm-loader.ts +528 -0
- package/src/pglite/workers-pglite.ts +224 -0
- package/src/pglite-assets/pglite.data +0 -0
- package/src/pglite-assets/pglite.wasm +0 -0
- package/src/pglite.d.ts +47 -0
- package/src/playground/index.ts +137 -0
- package/src/playground/keyboard-shortcuts.ts +677 -0
- package/src/playground/playground.ts +323 -0
- package/src/playground/query-executor.ts +669 -0
- package/src/playground/query-history.ts +328 -0
- package/src/playground/result-formatter.ts +420 -0
- package/src/playground/sample-datasets.ts +674 -0
- package/src/playground/sample-queries.ts +1168 -0
- package/src/playground/schema-explorer.ts +558 -0
- package/src/playground/types.ts +518 -0
- package/src/readonly/cache-reader.test.ts +460 -0
- package/src/readonly/cache-reader.ts +313 -0
- package/src/readonly/config.test.ts +187 -0
- package/src/readonly/config.ts +128 -0
- package/src/readonly/index.ts +50 -0
- package/src/readonly/pglite-wrapper.test.ts +278 -0
- package/src/readonly/pglite-wrapper.ts +184 -0
- package/src/readonly/worker.test.ts +533 -0
- package/src/readonly/worker.ts +341 -0
- package/src/readonly/write-blocker.test.ts +459 -0
- package/src/readonly/write-blocker.ts +175 -0
- package/src/recovery/disaster-recovery.test.ts +618 -0
- package/src/recovery/disaster-recovery.ts +1181 -0
- package/src/recovery/index.ts +43 -0
- package/src/recovery/parquet-parser.ts +974 -0
- package/src/retention/index.ts +74 -0
- package/src/retention/policy.test.ts +571 -0
- package/src/retention/policy.ts +774 -0
- package/src/retention/purger.test.ts +465 -0
- package/src/retention/purger.ts +558 -0
- package/src/rls/auth-integration.test.ts +752 -0
- package/src/rls/auth-integration.ts +533 -0
- package/src/rls/generator.test.ts +829 -0
- package/src/rls/generator.ts +573 -0
- package/src/rls/index.ts +128 -0
- package/src/rls/policy.ts +208 -0
- package/src/rls/rls.test.ts +1071 -0
- package/src/rls/validator.test.ts +930 -0
- package/src/rls/validator.ts +895 -0
- package/src/routing/adaptive-router.test.ts +884 -0
- package/src/routing/adaptive-router.ts +845 -0
- package/src/routing/circuit-breaker.test.ts +1505 -0
- package/src/routing/circuit-breaker.ts +852 -0
- package/src/routing/cost-metrics.test.ts +565 -0
- package/src/routing/cost-metrics.ts +408 -0
- package/src/routing/do-connection-pool.test.ts +1109 -0
- package/src/routing/do-connection-pool.ts +828 -0
- package/src/routing/index.ts +158 -0
- package/src/routing/query-complexity-estimator.test.ts +356 -0
- package/src/routing/query-complexity-estimator.ts +444 -0
- package/src/routing/request-coalescing.test.ts +738 -0
- package/src/routing/request-coalescing.ts +475 -0
- package/src/routing/runtime-router.test.ts +436 -0
- package/src/routing/runtime-router.ts +357 -0
- package/src/routing/tenant-router.test.ts +2493 -0
- package/src/routing/tenant-router.ts +1908 -0
- package/src/routing/websocket-pool.test.ts +551 -0
- package/src/routing/websocket-pool.ts +577 -0
- package/src/storage/access-pattern-tracker.test.ts +874 -0
- package/src/storage/cache-layer.test.ts +560 -0
- package/src/storage/cache-layer.ts +328 -0
- package/src/storage/cost-aware-tiering.test.ts +652 -0
- package/src/storage/cost-aware-tiering.ts +794 -0
- package/src/storage/do-sqlite-blobs.test.ts +937 -0
- package/src/storage/index.ts +272 -0
- package/src/storage/interfaces.ts +974 -0
- package/src/storage/r2-layer.test.ts +653 -0
- package/src/storage/r2-layer.ts +434 -0
- package/src/storage/r2-overflow.ts +920 -0
- package/src/storage/r2-page-vfs.test.ts +2348 -0
- package/src/storage/r2-page-vfs.ts +1054 -0
- package/src/storage/swr-cache.test.ts +832 -0
- package/src/storage/swr-cache.ts +398 -0
- package/src/storage/swr-tiered-integration.test.ts +617 -0
- package/src/storage/tiered-orchestrator.test.ts +2441 -0
- package/src/storage/tiered-orchestrator.ts +2081 -0
- package/src/storage/tiered-vfs-swr.test.ts +736 -0
- package/src/storage/tiered-vfs-swr.ts +735 -0
- package/src/storage/tiered-vfs.test.ts +793 -0
- package/src/storage/tiered-vfs.ts +1082 -0
- package/src/streaming/backpressure-controller.ts +452 -0
- package/src/streaming/buffer-pool.ts +484 -0
- package/src/streaming/cdc-iceberg-connector.ts +605 -0
- package/src/streaming/index.ts +225 -0
- package/src/streaming/live-cdc-stream.ts +985 -0
- package/src/streaming/memory-bounded-stream.ts +443 -0
- package/src/streaming/query-streamer.ts +662 -0
- package/src/streaming/response-streaming.ts +557 -0
- package/src/types/branded.ts +1075 -0
- package/src/types/branded.ts.backup +273 -0
- package/src/types/utilities.ts +1023 -0
- package/src/types/wasm.d.ts +30 -0
- package/src/validation/typed-errors.test.ts +420 -0
- package/src/wal/replay-engine.ts +1264 -0
- package/src/worker/__mocks__/capnweb.ts +15 -0
- package/src/worker/__mocks__/pglite.data.ts +22 -0
- package/src/worker/__mocks__/pglite.wasm.ts +33 -0
- package/src/worker/auth-rate-limiter.test.ts +272 -0
- package/src/worker/auth-rate-limiter.ts +448 -0
- package/src/worker/auth.security-red.test.ts +1236 -0
- package/src/worker/auth.security.test.ts +822 -0
- package/src/worker/auth.test.ts +469 -0
- package/src/worker/auth.ts +1104 -0
- package/src/worker/cdc-backpressure.test.ts +726 -0
- package/src/worker/cdc-backpressure.ts +866 -0
- package/src/worker/cdc-sse.test.ts +780 -0
- package/src/worker/cdc-sse.ts +728 -0
- package/src/worker/cdc-websocket.ts +1229 -0
- package/src/worker/cdc-ws.test.ts +1009 -0
- package/src/worker/cdc.test.ts +327 -0
- package/src/worker/cdc.ts +289 -0
- package/src/worker/concerns/auth-concern.ts +179 -0
- package/src/worker/concerns/cdc-concern.ts +247 -0
- package/src/worker/concerns/index.ts +58 -0
- package/src/worker/concerns/query-execution-concern.ts +194 -0
- package/src/worker/concerns/storage-orchestration-concern.ts +373 -0
- package/src/worker/discriminated-types.test.ts +280 -0
- package/src/worker/do-auth-manager.ts +257 -0
- package/src/worker/do-decomposition.test.ts +1236 -0
- package/src/worker/do-pglite-manager.ts +302 -0
- package/src/worker/do.test.ts +2254 -0
- package/src/worker/do.ts +1878 -0
- package/src/worker/entry.ts +417 -0
- package/src/worker/errors.ts +285 -0
- package/src/worker/health-check-manager.test.ts +261 -0
- package/src/worker/health-check-manager.ts +231 -0
- package/src/worker/index.ts +389 -0
- package/src/worker/memory-pressure.test.ts +1460 -0
- package/src/worker/memory-pressure.ts +2650 -0
- package/src/worker/migration-manager.ts +582 -0
- package/src/worker/neon-compat.test.ts +332 -0
- package/src/worker/plugin-manager.ts +485 -0
- package/src/worker/postgres.do-rpc.d.ts +76 -0
- package/src/worker/proxy.ts +694 -0
- package/src/worker/query-execution-manager.test.ts +303 -0
- package/src/worker/query-execution-manager.ts +219 -0
- package/src/worker/query-executor.test.ts +282 -0
- package/src/worker/query-executor.ts +560 -0
- package/src/worker/query-stats-manager.ts +229 -0
- package/src/worker/result-handler.test.ts +364 -0
- package/src/worker/result-handler.ts +510 -0
- package/src/worker/routes.test.ts +795 -0
- package/src/worker/routes.ts +650 -0
- package/src/worker/rpc-methods-manager.test.ts +326 -0
- package/src/worker/rpc-methods-manager.ts +276 -0
- package/src/worker/rpc.ts +524 -0
- package/src/worker/schema-version.ts +605 -0
- package/src/worker/session-manager.test.ts +506 -0
- package/src/worker/session-manager.ts +732 -0
- package/src/worker/shutdown-manager.ts +469 -0
- package/src/worker/sql-transform.test.ts +286 -0
- package/src/worker/sql-transform.ts +368 -0
- package/src/worker/supabase-compat.test.ts +621 -0
- package/src/worker/types.test.ts +292 -0
- package/src/worker/types.ts +873 -0
- package/src/worker/user-routes.test.ts +703 -0
- package/src/worker/user-routes.ts +303 -0
- package/src/worker/wal-facade.ts +235 -0
- package/src/worker/wal-r2.test.ts +570 -0
- package/src/worker/wal-r2.ts +930 -0
- package/src/worker/wal-replay.test.ts +845 -0
- package/src/worker/wal-replay.ts +897 -0
- package/src/worker/wal-retention.test.ts +758 -0
- package/src/worker/wal-retention.ts +1075 -0
- package/src/worker/wal.test.ts +618 -0
- package/src/worker/wal.ts +697 -0
- package/src/worker/websocket.test.ts +296 -0
- package/src/worker/websocket.ts +284 -0
|
@@ -0,0 +1,930 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R2 WAL Storage - Stream WAL entries to Cloudflare R2
|
|
3
|
+
* Task: postgres-54m - WAL streaming to R2 storage
|
|
4
|
+
*
|
|
5
|
+
* Implements durable WAL storage in R2 with:
|
|
6
|
+
* - Batched segment uploads organized by DO ID and time windows
|
|
7
|
+
* - zstd compression for storage efficiency
|
|
8
|
+
* - Checksum validation for data integrity
|
|
9
|
+
* - Retry logic for transient R2 failures
|
|
10
|
+
* - Configurable flush policies
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { WALStorage, SerializedWALEntry } from './wal'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* R2 WAL segment metadata stored alongside the segment
|
|
17
|
+
*/
|
|
18
|
+
export interface WALSegmentMetadata {
|
|
19
|
+
/** Durable Object ID that produced this segment */
|
|
20
|
+
doId: string
|
|
21
|
+
/** First LSN in the segment */
|
|
22
|
+
startLsn: string
|
|
23
|
+
/** Last LSN in the segment */
|
|
24
|
+
endLsn: string
|
|
25
|
+
/** Number of entries in the segment */
|
|
26
|
+
entryCount: number
|
|
27
|
+
/** Uncompressed size in bytes */
|
|
28
|
+
uncompressedSize: number
|
|
29
|
+
/** Compressed size in bytes */
|
|
30
|
+
compressedSize: number
|
|
31
|
+
/** Compression algorithm used */
|
|
32
|
+
compression: 'none' | 'gzip'
|
|
33
|
+
/** SHA-256 checksum of uncompressed data */
|
|
34
|
+
checksum: string
|
|
35
|
+
/** Timestamp when segment was created */
|
|
36
|
+
createdAt: number
|
|
37
|
+
/** Time window start (for organization) */
|
|
38
|
+
windowStart: number
|
|
39
|
+
/** Time window end (for organization) */
|
|
40
|
+
windowEnd: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Configuration for R2 WAL storage
|
|
45
|
+
*/
|
|
46
|
+
export interface R2WALStorageConfig {
|
|
47
|
+
/** The R2 bucket for WAL storage */
|
|
48
|
+
bucket: R2Bucket
|
|
49
|
+
/** Durable Object ID (used for organizing WAL files) */
|
|
50
|
+
doId: string
|
|
51
|
+
/** Prefix for all WAL keys in the bucket (default: 'wal/') */
|
|
52
|
+
prefix?: string
|
|
53
|
+
/** Enable compression (default: true) */
|
|
54
|
+
compression?: boolean
|
|
55
|
+
/** Time window size in milliseconds for segment organization (default: 1 hour) */
|
|
56
|
+
timeWindowMs?: number
|
|
57
|
+
/** Maximum entries per segment (default: 10000) */
|
|
58
|
+
maxEntriesPerSegment?: number
|
|
59
|
+
/** Maximum segment size in bytes before flush (default: 10MB) */
|
|
60
|
+
maxSegmentBytes?: number
|
|
61
|
+
/** Retry attempts for R2 operations (default: 3) */
|
|
62
|
+
retryAttempts?: number
|
|
63
|
+
/** Base delay for exponential backoff in ms (default: 100) */
|
|
64
|
+
retryBaseDelayMs?: number
|
|
65
|
+
/** Enable checksum validation (default: true) */
|
|
66
|
+
validateChecksums?: boolean
|
|
67
|
+
/** DO state for storing last flushed LSN */
|
|
68
|
+
state?: DurableObjectState
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Statistics for R2 WAL storage operations
|
|
73
|
+
*/
|
|
74
|
+
export interface R2WALStorageStats {
|
|
75
|
+
/** Number of segments uploaded */
|
|
76
|
+
segmentsUploaded: number
|
|
77
|
+
/** Number of entries stored */
|
|
78
|
+
entriesStored: number
|
|
79
|
+
/** Total bytes written (compressed) */
|
|
80
|
+
bytesWritten: number
|
|
81
|
+
/** Total bytes before compression */
|
|
82
|
+
bytesUncompressed: number
|
|
83
|
+
/** Number of failed uploads */
|
|
84
|
+
failedUploads: number
|
|
85
|
+
/** Number of retries */
|
|
86
|
+
retryCount: number
|
|
87
|
+
/** Last successful upload timestamp */
|
|
88
|
+
lastUploadAt: number | null
|
|
89
|
+
/** Last flushed LSN */
|
|
90
|
+
lastFlushedLsn: string | null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Result of a WAL segment upload
|
|
95
|
+
*/
|
|
96
|
+
export interface WALSegmentUploadResult {
|
|
97
|
+
/** Whether the upload was successful */
|
|
98
|
+
success: boolean
|
|
99
|
+
/** The segment key in R2 */
|
|
100
|
+
key?: string
|
|
101
|
+
/** Segment metadata */
|
|
102
|
+
metadata?: WALSegmentMetadata
|
|
103
|
+
/** Error message if failed */
|
|
104
|
+
error?: string
|
|
105
|
+
/** Number of retry attempts */
|
|
106
|
+
retryAttempts: number
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Default configuration values
|
|
111
|
+
*/
|
|
112
|
+
const DEFAULT_CONFIG = {
|
|
113
|
+
prefix: 'wal/',
|
|
114
|
+
compression: true,
|
|
115
|
+
timeWindowMs: 60 * 60 * 1000, // 1 hour
|
|
116
|
+
maxEntriesPerSegment: 10000,
|
|
117
|
+
maxSegmentBytes: 10 * 1024 * 1024, // 10MB
|
|
118
|
+
retryAttempts: 3,
|
|
119
|
+
retryBaseDelayMs: 100,
|
|
120
|
+
validateChecksums: true,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* DO storage key for tracking last flushed LSN
|
|
125
|
+
*/
|
|
126
|
+
const LAST_FLUSHED_LSN_KEY = '__wal_last_flushed_lsn__'
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Calculate SHA-256 checksum of data
|
|
130
|
+
*/
|
|
131
|
+
async function calculateChecksum(data: Uint8Array): Promise<string> {
|
|
132
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
|
|
133
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
|
134
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Compress data using gzip (available in Workers runtime)
|
|
139
|
+
*/
|
|
140
|
+
async function compressData(data: Uint8Array): Promise<Uint8Array> {
|
|
141
|
+
const stream = new CompressionStream('gzip')
|
|
142
|
+
const writer = stream.writable.getWriter()
|
|
143
|
+
const reader = stream.readable.getReader()
|
|
144
|
+
|
|
145
|
+
// Write data and close
|
|
146
|
+
writer.write(data)
|
|
147
|
+
writer.close()
|
|
148
|
+
|
|
149
|
+
// Read compressed result
|
|
150
|
+
const chunks: Uint8Array[] = []
|
|
151
|
+
while (true) {
|
|
152
|
+
const { done, value } = await reader.read()
|
|
153
|
+
if (done) break
|
|
154
|
+
chunks.push(value)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Combine chunks
|
|
158
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0)
|
|
159
|
+
const result = new Uint8Array(totalLength)
|
|
160
|
+
let offset = 0
|
|
161
|
+
for (const chunk of chunks) {
|
|
162
|
+
result.set(chunk, offset)
|
|
163
|
+
offset += chunk.length
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return result
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Decompress gzip data
|
|
171
|
+
*/
|
|
172
|
+
async function decompressData(data: Uint8Array): Promise<Uint8Array> {
|
|
173
|
+
const stream = new DecompressionStream('gzip')
|
|
174
|
+
const writer = stream.writable.getWriter()
|
|
175
|
+
const reader = stream.readable.getReader()
|
|
176
|
+
|
|
177
|
+
// Write data and close
|
|
178
|
+
writer.write(data)
|
|
179
|
+
writer.close()
|
|
180
|
+
|
|
181
|
+
// Read decompressed result
|
|
182
|
+
const chunks: Uint8Array[] = []
|
|
183
|
+
while (true) {
|
|
184
|
+
const { done, value } = await reader.read()
|
|
185
|
+
if (done) break
|
|
186
|
+
chunks.push(value)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Combine chunks
|
|
190
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0)
|
|
191
|
+
const result = new Uint8Array(totalLength)
|
|
192
|
+
let offset = 0
|
|
193
|
+
for (const chunk of chunks) {
|
|
194
|
+
result.set(chunk, offset)
|
|
195
|
+
offset += chunk.length
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return result
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Sleep for a given number of milliseconds
|
|
203
|
+
*/
|
|
204
|
+
function sleep(ms: number): Promise<void> {
|
|
205
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Generate a segment key based on DO ID and time window
|
|
210
|
+
*
|
|
211
|
+
* Format: {prefix}{doId}/{year}/{month}/{day}/{hour}/{startLsn}-{endLsn}.wal
|
|
212
|
+
*
|
|
213
|
+
* This organization allows efficient range queries by time and enables
|
|
214
|
+
* easy cleanup of old segments based on retention policies.
|
|
215
|
+
*/
|
|
216
|
+
function generateSegmentKey(
|
|
217
|
+
prefix: string,
|
|
218
|
+
doId: string,
|
|
219
|
+
windowStart: number,
|
|
220
|
+
startLsn: string,
|
|
221
|
+
endLsn: string
|
|
222
|
+
): string {
|
|
223
|
+
const date = new Date(windowStart)
|
|
224
|
+
const year = date.getUTCFullYear()
|
|
225
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0')
|
|
226
|
+
const day = String(date.getUTCDate()).padStart(2, '0')
|
|
227
|
+
const hour = String(date.getUTCHours()).padStart(2, '0')
|
|
228
|
+
|
|
229
|
+
// Pad LSNs for proper lexicographic ordering
|
|
230
|
+
const paddedStartLsn = startLsn.padStart(20, '0')
|
|
231
|
+
const paddedEndLsn = endLsn.padStart(20, '0')
|
|
232
|
+
|
|
233
|
+
return `${prefix}${doId}/${year}/${month}/${day}/${hour}/${paddedStartLsn}-${paddedEndLsn}.wal`
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* R2WALStorage - WAL storage implementation using Cloudflare R2
|
|
238
|
+
*
|
|
239
|
+
* Provides durable storage for WAL entries with:
|
|
240
|
+
* - Automatic batching into segments
|
|
241
|
+
* - Compression using gzip
|
|
242
|
+
* - Checksum validation
|
|
243
|
+
* - Retry logic for transient failures
|
|
244
|
+
* - Time-based organization for efficient queries
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* const storage = new R2WALStorage({
|
|
249
|
+
* bucket: env.WAL_BUCKET,
|
|
250
|
+
* doId: ctx.id.toString(),
|
|
251
|
+
* state: ctx.storage,
|
|
252
|
+
* })
|
|
253
|
+
*
|
|
254
|
+
* // Use with WALManager
|
|
255
|
+
* const walManager = new WALManager(walConfig, storage)
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
export class R2WALStorage implements WALStorage {
|
|
259
|
+
// Note: bucket is package-private to allow access from WALRetentionManager
|
|
260
|
+
protected bucket: R2Bucket
|
|
261
|
+
private doId: string
|
|
262
|
+
private prefix: string
|
|
263
|
+
private compression: boolean
|
|
264
|
+
private timeWindowMs: number
|
|
265
|
+
private maxEntriesPerSegment: number
|
|
266
|
+
private maxSegmentBytes: number
|
|
267
|
+
private retryAttempts: number
|
|
268
|
+
private retryBaseDelayMs: number
|
|
269
|
+
private validateChecksums: boolean
|
|
270
|
+
private state: DurableObjectState | null
|
|
271
|
+
|
|
272
|
+
private stats: R2WALStorageStats = {
|
|
273
|
+
segmentsUploaded: 0,
|
|
274
|
+
entriesStored: 0,
|
|
275
|
+
bytesWritten: 0,
|
|
276
|
+
bytesUncompressed: 0,
|
|
277
|
+
failedUploads: 0,
|
|
278
|
+
retryCount: 0,
|
|
279
|
+
lastUploadAt: null,
|
|
280
|
+
lastFlushedLsn: null,
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Internal buffer for batching entries before upload
|
|
284
|
+
private pendingEntries: SerializedWALEntry[] = []
|
|
285
|
+
private pendingBytes = 0
|
|
286
|
+
|
|
287
|
+
constructor(config: R2WALStorageConfig) {
|
|
288
|
+
this.bucket = config.bucket
|
|
289
|
+
this.doId = config.doId
|
|
290
|
+
this.prefix = config.prefix ?? DEFAULT_CONFIG.prefix
|
|
291
|
+
this.compression = config.compression ?? DEFAULT_CONFIG.compression
|
|
292
|
+
this.timeWindowMs = config.timeWindowMs ?? DEFAULT_CONFIG.timeWindowMs
|
|
293
|
+
this.maxEntriesPerSegment = config.maxEntriesPerSegment ?? DEFAULT_CONFIG.maxEntriesPerSegment
|
|
294
|
+
this.maxSegmentBytes = config.maxSegmentBytes ?? DEFAULT_CONFIG.maxSegmentBytes
|
|
295
|
+
this.retryAttempts = config.retryAttempts ?? DEFAULT_CONFIG.retryAttempts
|
|
296
|
+
this.retryBaseDelayMs = config.retryBaseDelayMs ?? DEFAULT_CONFIG.retryBaseDelayMs
|
|
297
|
+
this.validateChecksums = config.validateChecksums ?? DEFAULT_CONFIG.validateChecksums
|
|
298
|
+
this.state = config.state ?? null
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Store WAL entries to R2
|
|
303
|
+
*
|
|
304
|
+
* Entries are batched into segments and uploaded when:
|
|
305
|
+
* - The segment reaches maxEntriesPerSegment
|
|
306
|
+
* - The segment size reaches maxSegmentBytes
|
|
307
|
+
* - This method is called (ensures entries are persisted)
|
|
308
|
+
*/
|
|
309
|
+
async store(entries: SerializedWALEntry[]): Promise<void> {
|
|
310
|
+
if (entries.length === 0) {
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Add entries to pending buffer
|
|
315
|
+
for (const entry of entries) {
|
|
316
|
+
const entrySize = JSON.stringify(entry).length
|
|
317
|
+
this.pendingEntries.push(entry)
|
|
318
|
+
this.pendingBytes += entrySize
|
|
319
|
+
|
|
320
|
+
// Check if we should flush
|
|
321
|
+
if (
|
|
322
|
+
this.pendingEntries.length >= this.maxEntriesPerSegment ||
|
|
323
|
+
this.pendingBytes >= this.maxSegmentBytes
|
|
324
|
+
) {
|
|
325
|
+
await this.flushPendingEntries()
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Always flush remaining entries to ensure durability
|
|
330
|
+
if (this.pendingEntries.length > 0) {
|
|
331
|
+
await this.flushPendingEntries()
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Flush pending entries to R2 as a segment
|
|
337
|
+
*/
|
|
338
|
+
private async flushPendingEntries(): Promise<void> {
|
|
339
|
+
if (this.pendingEntries.length === 0) {
|
|
340
|
+
return
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const entries = this.pendingEntries
|
|
344
|
+
this.pendingEntries = []
|
|
345
|
+
this.pendingBytes = 0
|
|
346
|
+
|
|
347
|
+
const result = await this.uploadSegment(entries)
|
|
348
|
+
|
|
349
|
+
if (!result.success) {
|
|
350
|
+
// Re-add entries to pending buffer on failure
|
|
351
|
+
// They will be retried on next store() call
|
|
352
|
+
this.pendingEntries = entries.concat(this.pendingEntries)
|
|
353
|
+
this.pendingBytes = entries.reduce((sum, e) => sum + JSON.stringify(e).length, 0) + this.pendingBytes
|
|
354
|
+
throw new Error(`Failed to upload WAL segment: ${result.error}`)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Update last flushed LSN
|
|
358
|
+
if (result.metadata) {
|
|
359
|
+
this.stats.lastFlushedLsn = result.metadata.endLsn
|
|
360
|
+
await this.persistLastFlushedLsn(result.metadata.endLsn)
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Upload a segment of entries to R2
|
|
366
|
+
*/
|
|
367
|
+
private async uploadSegment(entries: SerializedWALEntry[]): Promise<WALSegmentUploadResult> {
|
|
368
|
+
const firstEntry = entries[0]
|
|
369
|
+
const lastEntry = entries[entries.length - 1]
|
|
370
|
+
|
|
371
|
+
if (!firstEntry || !lastEntry) {
|
|
372
|
+
return { success: true, retryAttempts: 0 }
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const now = Date.now()
|
|
376
|
+
const windowStart = Math.floor(now / this.timeWindowMs) * this.timeWindowMs
|
|
377
|
+
const windowEnd = windowStart + this.timeWindowMs
|
|
378
|
+
|
|
379
|
+
const startLsn = firstEntry.lsn
|
|
380
|
+
const endLsn = lastEntry.lsn
|
|
381
|
+
|
|
382
|
+
// Serialize entries as newline-delimited JSON (NDJSON)
|
|
383
|
+
const jsonData = entries.map((e) => JSON.stringify(e)).join('\n')
|
|
384
|
+
const uncompressedData = new TextEncoder().encode(jsonData)
|
|
385
|
+
const uncompressedSize = uncompressedData.length
|
|
386
|
+
|
|
387
|
+
// Calculate checksum before compression
|
|
388
|
+
const checksum = await calculateChecksum(uncompressedData)
|
|
389
|
+
|
|
390
|
+
// Compress if enabled
|
|
391
|
+
let finalData: Uint8Array
|
|
392
|
+
let compressionType: 'none' | 'gzip' = 'none'
|
|
393
|
+
|
|
394
|
+
if (this.compression) {
|
|
395
|
+
try {
|
|
396
|
+
finalData = await compressData(uncompressedData)
|
|
397
|
+
compressionType = 'gzip'
|
|
398
|
+
} catch (error) {
|
|
399
|
+
// Fall back to uncompressed on compression failure
|
|
400
|
+
console.warn('[R2WALStorage] Compression failed, storing uncompressed:', error)
|
|
401
|
+
finalData = uncompressedData
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
finalData = uncompressedData
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const compressedSize = finalData.length
|
|
408
|
+
|
|
409
|
+
// Build metadata
|
|
410
|
+
const metadata: WALSegmentMetadata = {
|
|
411
|
+
doId: this.doId,
|
|
412
|
+
startLsn,
|
|
413
|
+
endLsn,
|
|
414
|
+
entryCount: entries.length,
|
|
415
|
+
uncompressedSize,
|
|
416
|
+
compressedSize,
|
|
417
|
+
compression: compressionType,
|
|
418
|
+
checksum,
|
|
419
|
+
createdAt: now,
|
|
420
|
+
windowStart,
|
|
421
|
+
windowEnd,
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Generate key
|
|
425
|
+
const key = generateSegmentKey(this.prefix, this.doId, windowStart, startLsn, endLsn)
|
|
426
|
+
|
|
427
|
+
// Upload with retry
|
|
428
|
+
let lastError: Error | null = null
|
|
429
|
+
let retryCount = 0
|
|
430
|
+
|
|
431
|
+
for (let attempt = 0; attempt < this.retryAttempts; attempt++) {
|
|
432
|
+
try {
|
|
433
|
+
await this.bucket.put(key, finalData, {
|
|
434
|
+
customMetadata: {
|
|
435
|
+
...Object.fromEntries(
|
|
436
|
+
Object.entries(metadata).map(([k, v]) => [k, String(v)])
|
|
437
|
+
),
|
|
438
|
+
},
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
// Update stats
|
|
442
|
+
this.stats.segmentsUploaded++
|
|
443
|
+
this.stats.entriesStored += entries.length
|
|
444
|
+
this.stats.bytesWritten += compressedSize
|
|
445
|
+
this.stats.bytesUncompressed += uncompressedSize
|
|
446
|
+
this.stats.lastUploadAt = now
|
|
447
|
+
this.stats.retryCount += retryCount
|
|
448
|
+
|
|
449
|
+
return {
|
|
450
|
+
success: true,
|
|
451
|
+
key,
|
|
452
|
+
metadata,
|
|
453
|
+
retryAttempts: retryCount,
|
|
454
|
+
}
|
|
455
|
+
} catch (error) {
|
|
456
|
+
lastError = error instanceof Error ? error : new Error(String(error))
|
|
457
|
+
retryCount++
|
|
458
|
+
this.stats.retryCount++
|
|
459
|
+
|
|
460
|
+
if (attempt < this.retryAttempts - 1) {
|
|
461
|
+
// Exponential backoff
|
|
462
|
+
const delay = this.retryBaseDelayMs * Math.pow(2, attempt)
|
|
463
|
+
await sleep(delay)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// All retries failed
|
|
469
|
+
this.stats.failedUploads++
|
|
470
|
+
|
|
471
|
+
return {
|
|
472
|
+
success: false,
|
|
473
|
+
error: lastError?.message || 'Unknown error',
|
|
474
|
+
retryAttempts: retryCount,
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Get the last stored LSN
|
|
480
|
+
*
|
|
481
|
+
* This reads from DO storage for fast access, falling back to
|
|
482
|
+
* scanning R2 if DO storage is not available.
|
|
483
|
+
*/
|
|
484
|
+
async getLastLsn(): Promise<bigint | null> {
|
|
485
|
+
// Try DO storage first (fast path)
|
|
486
|
+
if (this.state) {
|
|
487
|
+
const stored = await this.state.storage.get<string>(LAST_FLUSHED_LSN_KEY)
|
|
488
|
+
if (stored) {
|
|
489
|
+
return BigInt(stored)
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Fall back to scanning R2 (slow path)
|
|
494
|
+
// List segments for this DO and find the latest
|
|
495
|
+
try {
|
|
496
|
+
const prefix = `${this.prefix}${this.doId}/`
|
|
497
|
+
let cursor: string | undefined
|
|
498
|
+
let latestLsn: bigint | null = null
|
|
499
|
+
|
|
500
|
+
do {
|
|
501
|
+
const listOptions: R2ListOptions = { prefix, limit: 1000 }
|
|
502
|
+
if (cursor) {
|
|
503
|
+
listOptions.cursor = cursor
|
|
504
|
+
}
|
|
505
|
+
const result = await this.bucket.list(listOptions)
|
|
506
|
+
|
|
507
|
+
for (const obj of result.objects) {
|
|
508
|
+
// Extract end LSN from key (format: .../startLsn-endLsn.wal)
|
|
509
|
+
const match = obj.key.match(/(\d+)-(\d+)\.wal$/)
|
|
510
|
+
if (match && match[2]) {
|
|
511
|
+
const endLsn = BigInt(match[2])
|
|
512
|
+
if (latestLsn === null || endLsn > latestLsn) {
|
|
513
|
+
latestLsn = endLsn
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
cursor = result.truncated ? result.cursor : undefined
|
|
519
|
+
} while (cursor)
|
|
520
|
+
|
|
521
|
+
// Cache in DO storage for next time
|
|
522
|
+
if (latestLsn !== null && this.state) {
|
|
523
|
+
await this.state.storage.put(LAST_FLUSHED_LSN_KEY, latestLsn.toString())
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return latestLsn
|
|
527
|
+
} catch (error) {
|
|
528
|
+
console.error('[R2WALStorage] Failed to get last LSN from R2:', error)
|
|
529
|
+
return null
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Persist the last flushed LSN to DO storage
|
|
535
|
+
*/
|
|
536
|
+
private async persistLastFlushedLsn(lsn: string): Promise<void> {
|
|
537
|
+
if (this.state) {
|
|
538
|
+
await this.state.storage.put(LAST_FLUSHED_LSN_KEY, lsn)
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Read entries from R2 storage starting from a given LSN
|
|
544
|
+
*
|
|
545
|
+
* This scans segments in order and returns entries from the specified LSN.
|
|
546
|
+
*/
|
|
547
|
+
async readEntries(fromLsn: bigint, limit = 1000): Promise<SerializedWALEntry[]> {
|
|
548
|
+
const entries: SerializedWALEntry[] = []
|
|
549
|
+
const prefix = `${this.prefix}${this.doId}/`
|
|
550
|
+
|
|
551
|
+
try {
|
|
552
|
+
let cursor: string | undefined
|
|
553
|
+
const segmentKeys: string[] = []
|
|
554
|
+
|
|
555
|
+
// First, list all segments for this DO
|
|
556
|
+
do {
|
|
557
|
+
const listOptions: R2ListOptions = { prefix, limit: 1000 }
|
|
558
|
+
if (cursor) {
|
|
559
|
+
listOptions.cursor = cursor
|
|
560
|
+
}
|
|
561
|
+
const result = await this.bucket.list(listOptions)
|
|
562
|
+
|
|
563
|
+
for (const obj of result.objects) {
|
|
564
|
+
// Check if this segment might contain entries >= fromLsn
|
|
565
|
+
const match = obj.key.match(/(\d+)-(\d+)\.wal$/)
|
|
566
|
+
if (match && match[2]) {
|
|
567
|
+
const endLsn = BigInt(match[2])
|
|
568
|
+
if (endLsn >= fromLsn) {
|
|
569
|
+
segmentKeys.push(obj.key)
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
cursor = result.truncated ? result.cursor : undefined
|
|
575
|
+
} while (cursor)
|
|
576
|
+
|
|
577
|
+
// Sort segments by their start LSN
|
|
578
|
+
segmentKeys.sort()
|
|
579
|
+
|
|
580
|
+
// Read segments until we have enough entries
|
|
581
|
+
for (const key of segmentKeys) {
|
|
582
|
+
if (entries.length >= limit) {
|
|
583
|
+
break
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const segmentEntries = await this.readSegment(key)
|
|
587
|
+
|
|
588
|
+
for (const entry of segmentEntries) {
|
|
589
|
+
if (BigInt(entry.lsn) >= fromLsn) {
|
|
590
|
+
entries.push(entry)
|
|
591
|
+
if (entries.length >= limit) {
|
|
592
|
+
break
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return entries
|
|
599
|
+
} catch (error) {
|
|
600
|
+
console.error('[R2WALStorage] Failed to read entries from R2:', error)
|
|
601
|
+
return []
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Read a single segment from R2
|
|
607
|
+
*/
|
|
608
|
+
private async readSegment(key: string): Promise<SerializedWALEntry[]> {
|
|
609
|
+
try {
|
|
610
|
+
const obj = await this.bucket.get(key)
|
|
611
|
+
if (!obj) {
|
|
612
|
+
return []
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const metadata = obj.customMetadata as Record<string, string> | undefined
|
|
616
|
+
const compression = metadata?.compression || 'none'
|
|
617
|
+
|
|
618
|
+
let data = await obj.bytes()
|
|
619
|
+
|
|
620
|
+
// Decompress if needed
|
|
621
|
+
if (compression === 'gzip') {
|
|
622
|
+
data = await decompressData(data)
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Validate checksum if enabled
|
|
626
|
+
if (this.validateChecksums && metadata?.checksum) {
|
|
627
|
+
const calculatedChecksum = await calculateChecksum(data)
|
|
628
|
+
if (calculatedChecksum !== metadata.checksum) {
|
|
629
|
+
throw new Error(`Checksum mismatch for segment ${key}`)
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Parse NDJSON
|
|
634
|
+
const jsonStr = new TextDecoder().decode(data)
|
|
635
|
+
const lines = jsonStr.split('\n').filter((line) => line.trim())
|
|
636
|
+
return lines.map((line) => JSON.parse(line) as SerializedWALEntry)
|
|
637
|
+
} catch (error) {
|
|
638
|
+
console.error(`[R2WALStorage] Failed to read segment ${key}:`, error)
|
|
639
|
+
return []
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Get storage statistics
|
|
645
|
+
*/
|
|
646
|
+
getStats(): R2WALStorageStats {
|
|
647
|
+
return { ...this.stats }
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* List all segment keys for this DO
|
|
652
|
+
*/
|
|
653
|
+
async listSegments(options?: {
|
|
654
|
+
fromTime?: number | undefined
|
|
655
|
+
toTime?: number | undefined
|
|
656
|
+
limit?: number | undefined
|
|
657
|
+
cursor?: string | undefined
|
|
658
|
+
}): Promise<{
|
|
659
|
+
keys: string[]
|
|
660
|
+
truncated: boolean
|
|
661
|
+
cursor?: string | undefined
|
|
662
|
+
}> {
|
|
663
|
+
const prefix = `${this.prefix}${this.doId}/`
|
|
664
|
+
|
|
665
|
+
try {
|
|
666
|
+
const listOptions: R2ListOptions = { prefix, limit: options?.limit || 1000 }
|
|
667
|
+
if (options?.cursor) {
|
|
668
|
+
listOptions.cursor = options.cursor
|
|
669
|
+
}
|
|
670
|
+
const result = await this.bucket.list(listOptions)
|
|
671
|
+
|
|
672
|
+
let keys = result.objects.map((obj) => obj.key)
|
|
673
|
+
|
|
674
|
+
// Filter by time if specified
|
|
675
|
+
if (options?.fromTime || options?.toTime) {
|
|
676
|
+
keys = keys.filter((key) => {
|
|
677
|
+
// Extract date from key path
|
|
678
|
+
const match = key.match(/\/(\d{4})\/(\d{2})\/(\d{2})\/(\d{2})\//)
|
|
679
|
+
if (!match) return true
|
|
680
|
+
|
|
681
|
+
const year = match[1]
|
|
682
|
+
const month = match[2]
|
|
683
|
+
const day = match[3]
|
|
684
|
+
const hour = match[4]
|
|
685
|
+
if (!year || !month || !day || !hour) return true
|
|
686
|
+
|
|
687
|
+
const segmentTime = new Date(
|
|
688
|
+
Date.UTC(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour))
|
|
689
|
+
).getTime()
|
|
690
|
+
|
|
691
|
+
if (options.fromTime && segmentTime < options.fromTime) return false
|
|
692
|
+
if (options.toTime && segmentTime > options.toTime) return false
|
|
693
|
+
return true
|
|
694
|
+
})
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const response: { keys: string[]; truncated: boolean; cursor?: string } = {
|
|
698
|
+
keys,
|
|
699
|
+
truncated: result.truncated,
|
|
700
|
+
}
|
|
701
|
+
if (result.truncated && result.cursor) {
|
|
702
|
+
response.cursor = result.cursor
|
|
703
|
+
}
|
|
704
|
+
return response
|
|
705
|
+
} catch (error) {
|
|
706
|
+
console.error('[R2WALStorage] Failed to list segments:', error)
|
|
707
|
+
return { keys: [], truncated: false }
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Delete segments older than a given timestamp
|
|
713
|
+
*
|
|
714
|
+
* Useful for implementing retention policies.
|
|
715
|
+
*/
|
|
716
|
+
async deleteSegmentsBefore(timestamp: number): Promise<number> {
|
|
717
|
+
let deletedCount = 0
|
|
718
|
+
const keysToDelete: string[] = []
|
|
719
|
+
|
|
720
|
+
// List all segments
|
|
721
|
+
let cursor: string | undefined
|
|
722
|
+
do {
|
|
723
|
+
const listOptions: { cursor?: string } = {}
|
|
724
|
+
if (cursor) {
|
|
725
|
+
listOptions.cursor = cursor
|
|
726
|
+
}
|
|
727
|
+
const result = await this.listSegments(Object.keys(listOptions).length > 0 ? listOptions : undefined)
|
|
728
|
+
|
|
729
|
+
for (const key of result.keys) {
|
|
730
|
+
// Extract date from key path
|
|
731
|
+
const match = key.match(/\/(\d{4})\/(\d{2})\/(\d{2})\/(\d{2})\//)
|
|
732
|
+
if (match) {
|
|
733
|
+
const year = match[1]
|
|
734
|
+
const month = match[2]
|
|
735
|
+
const day = match[3]
|
|
736
|
+
const hour = match[4]
|
|
737
|
+
if (year && month && day && hour) {
|
|
738
|
+
const segmentTime = new Date(
|
|
739
|
+
Date.UTC(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour))
|
|
740
|
+
).getTime()
|
|
741
|
+
|
|
742
|
+
if (segmentTime < timestamp) {
|
|
743
|
+
keysToDelete.push(key)
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
cursor = result.cursor
|
|
750
|
+
} while (cursor)
|
|
751
|
+
|
|
752
|
+
// Delete in batches
|
|
753
|
+
const batchSize = 100
|
|
754
|
+
for (let i = 0; i < keysToDelete.length; i += batchSize) {
|
|
755
|
+
const batch = keysToDelete.slice(i, i + batchSize)
|
|
756
|
+
try {
|
|
757
|
+
await this.bucket.delete(batch)
|
|
758
|
+
deletedCount += batch.length
|
|
759
|
+
} catch (error) {
|
|
760
|
+
console.error('[R2WALStorage] Failed to delete segments:', error)
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
return deletedCount
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Get the compression ratio (compressed/uncompressed)
|
|
769
|
+
*/
|
|
770
|
+
getCompressionRatio(): number {
|
|
771
|
+
if (this.stats.bytesUncompressed === 0) {
|
|
772
|
+
return 1
|
|
773
|
+
}
|
|
774
|
+
return this.stats.bytesWritten / this.stats.bytesUncompressed
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Get the R2 bucket (for use by retention manager)
|
|
779
|
+
*/
|
|
780
|
+
getBucket(): R2Bucket {
|
|
781
|
+
return this.bucket
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Get the DO ID
|
|
786
|
+
*/
|
|
787
|
+
getDoId(): string {
|
|
788
|
+
return this.doId
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Get the key prefix
|
|
793
|
+
*/
|
|
794
|
+
getPrefix(): string {
|
|
795
|
+
return this.prefix
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Delete multiple segments by key
|
|
800
|
+
* Used by retention manager for cleanup
|
|
801
|
+
*/
|
|
802
|
+
async deleteSegments(keys: string[]): Promise<number> {
|
|
803
|
+
if (keys.length === 0) {
|
|
804
|
+
return 0
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
let deletedCount = 0
|
|
808
|
+
const batchSize = 100
|
|
809
|
+
|
|
810
|
+
for (let i = 0; i < keys.length; i += batchSize) {
|
|
811
|
+
const batch = keys.slice(i, i + batchSize)
|
|
812
|
+
try {
|
|
813
|
+
await this.bucket.delete(batch)
|
|
814
|
+
deletedCount += batch.length
|
|
815
|
+
} catch (error) {
|
|
816
|
+
console.error('[R2WALStorage] Failed to delete segments:', error)
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return deletedCount
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Get detailed segment information including metadata
|
|
825
|
+
* Used by retention manager for cleanup decisions
|
|
826
|
+
*/
|
|
827
|
+
async getSegmentInfo(key: string): Promise<{
|
|
828
|
+
key: string
|
|
829
|
+
size: number
|
|
830
|
+
createdAt: number
|
|
831
|
+
startLsn: bigint
|
|
832
|
+
endLsn: bigint
|
|
833
|
+
entryCount: number
|
|
834
|
+
} | null> {
|
|
835
|
+
try {
|
|
836
|
+
const obj = await this.bucket.head(key)
|
|
837
|
+
if (!obj) {
|
|
838
|
+
return null
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
const metadata = obj.customMetadata as Record<string, string> | undefined
|
|
842
|
+
|
|
843
|
+
return {
|
|
844
|
+
key,
|
|
845
|
+
size: obj.size,
|
|
846
|
+
createdAt: metadata?.createdAt ? parseInt(metadata.createdAt) : obj.uploaded.getTime(),
|
|
847
|
+
startLsn: metadata?.startLsn ? BigInt(metadata.startLsn) : 0n,
|
|
848
|
+
endLsn: metadata?.endLsn ? BigInt(metadata.endLsn) : 0n,
|
|
849
|
+
entryCount: metadata?.entryCount ? parseInt(metadata.entryCount) : 0,
|
|
850
|
+
}
|
|
851
|
+
} catch (error) {
|
|
852
|
+
console.error(`[R2WALStorage] Failed to get segment info for ${key}:`, error)
|
|
853
|
+
return null
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* List segments with detailed metadata
|
|
859
|
+
* Used by retention manager for cleanup decisions
|
|
860
|
+
*/
|
|
861
|
+
async listSegmentsWithInfo(options?: {
|
|
862
|
+
fromTime?: number
|
|
863
|
+
toTime?: number
|
|
864
|
+
limit?: number
|
|
865
|
+
cursor?: string
|
|
866
|
+
}): Promise<{
|
|
867
|
+
segments: Array<{
|
|
868
|
+
key: string
|
|
869
|
+
size: number
|
|
870
|
+
createdAt: number
|
|
871
|
+
startLsn: bigint
|
|
872
|
+
endLsn: bigint
|
|
873
|
+
entryCount: number
|
|
874
|
+
}>
|
|
875
|
+
truncated: boolean
|
|
876
|
+
cursor?: string
|
|
877
|
+
totalSize: number
|
|
878
|
+
}> {
|
|
879
|
+
const result = await this.listSegments(options)
|
|
880
|
+
const segments: Array<{
|
|
881
|
+
key: string
|
|
882
|
+
size: number
|
|
883
|
+
createdAt: number
|
|
884
|
+
startLsn: bigint
|
|
885
|
+
endLsn: bigint
|
|
886
|
+
entryCount: number
|
|
887
|
+
}> = []
|
|
888
|
+
let totalSize = 0
|
|
889
|
+
|
|
890
|
+
// Get detailed info for each segment
|
|
891
|
+
for (const key of result.keys) {
|
|
892
|
+
const info = await this.getSegmentInfo(key)
|
|
893
|
+
if (info) {
|
|
894
|
+
segments.push(info)
|
|
895
|
+
totalSize += info.size
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const response: {
|
|
900
|
+
segments: typeof segments
|
|
901
|
+
truncated: boolean
|
|
902
|
+
cursor?: string
|
|
903
|
+
totalSize: number
|
|
904
|
+
} = {
|
|
905
|
+
segments,
|
|
906
|
+
truncated: result.truncated,
|
|
907
|
+
totalSize,
|
|
908
|
+
}
|
|
909
|
+
if (result.cursor !== undefined) {
|
|
910
|
+
response.cursor = result.cursor
|
|
911
|
+
}
|
|
912
|
+
return response
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* Create an R2WALStorage instance
|
|
918
|
+
*
|
|
919
|
+
* @example
|
|
920
|
+
* ```typescript
|
|
921
|
+
* const storage = createR2WALStorage({
|
|
922
|
+
* bucket: env.WAL_BUCKET,
|
|
923
|
+
* doId: ctx.id.toString(),
|
|
924
|
+
* state: ctx.storage,
|
|
925
|
+
* })
|
|
926
|
+
* ```
|
|
927
|
+
*/
|
|
928
|
+
export function createR2WALStorage(config: R2WALStorageConfig): R2WALStorage {
|
|
929
|
+
return new R2WALStorage(config)
|
|
930
|
+
}
|