@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,1054 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R2PageVFS - R2 Page-based Virtual File System
|
|
3
|
+
*
|
|
4
|
+
* Provides page-level access to R2-backed storage with SWR caching integration.
|
|
5
|
+
* Optimized for PGLite database pages stored in R2 with efficient caching
|
|
6
|
+
* through Cloudflare's Cache API.
|
|
7
|
+
*
|
|
8
|
+
* Page Storage Format:
|
|
9
|
+
* - Pages stored at: {prefix}/v{version}/pages/{8-digit-padded-page-number}
|
|
10
|
+
* - Example: db/v1/pages/00000001, db/v1/pages/00000042
|
|
11
|
+
* - Default page size: 8192 bytes (8KB, PostgreSQL default)
|
|
12
|
+
*
|
|
13
|
+
* Key Features:
|
|
14
|
+
* - Page-granularity reads with 8-digit padded page numbers
|
|
15
|
+
* - SWR caching with primary (fresh) and stale cache tiers
|
|
16
|
+
* - Version-based cache invalidation for safe schema updates
|
|
17
|
+
* - Batch operations with configurable concurrency
|
|
18
|
+
* - Comprehensive statistics for monitoring
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { createR2PageVFS } from './r2-page-vfs'
|
|
23
|
+
* import { createSWRCacheLayer } from './swr-cache'
|
|
24
|
+
*
|
|
25
|
+
* const swrCache = await createSWRCacheLayer({
|
|
26
|
+
* baseUrl: 'https://pglite.cache.local',
|
|
27
|
+
* primaryTtlSeconds: 60,
|
|
28
|
+
* staleTtlSeconds: 3600,
|
|
29
|
+
* })
|
|
30
|
+
*
|
|
31
|
+
* const vfs = createR2PageVFS({
|
|
32
|
+
* bucket: env.R2_BUCKET,
|
|
33
|
+
* prefix: 'mydb',
|
|
34
|
+
* version: '1',
|
|
35
|
+
* swrCache,
|
|
36
|
+
* })
|
|
37
|
+
*
|
|
38
|
+
* // Read single page
|
|
39
|
+
* const result = await vfs.readPage(42, ctx)
|
|
40
|
+
* if (result.data) {
|
|
41
|
+
* console.log(`Page 42: ${result.data.length} bytes, stale: ${result.stale}`)
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* // Batch read
|
|
45
|
+
* const pages = await vfs.readPages([1, 2, 3, 4, 5], ctx)
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @module storage/r2-page-vfs
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
import type { SWRCacheLayer, ExecutionContext } from './swr-cache'
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Circuit breaker configuration
|
|
55
|
+
*/
|
|
56
|
+
export interface CircuitBreakerConfig {
|
|
57
|
+
/** Number of failures before opening the circuit */
|
|
58
|
+
failureThreshold: number
|
|
59
|
+
/** Time in ms to wait before attempting to close the circuit */
|
|
60
|
+
resetTimeoutMs: number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Configuration for R2PageVFS
|
|
65
|
+
*/
|
|
66
|
+
export interface R2PageVFSConfig {
|
|
67
|
+
/** The R2 bucket binding */
|
|
68
|
+
bucket: R2Bucket
|
|
69
|
+
/** Prefix for all keys in the bucket (without trailing slash) */
|
|
70
|
+
prefix: string
|
|
71
|
+
/** Version string for cache key namespacing and busting */
|
|
72
|
+
version: string
|
|
73
|
+
/** Page size in bytes (default: 8192 for PostgreSQL) */
|
|
74
|
+
pageSize?: number
|
|
75
|
+
/** SWR cache layer for tiered caching */
|
|
76
|
+
swrCache: SWRCacheLayer
|
|
77
|
+
/** Maximum concurrent R2 operations for batch reads (default: 10) */
|
|
78
|
+
concurrencyLimit?: number
|
|
79
|
+
/** Timeout for R2 operations in milliseconds (default: 30000) */
|
|
80
|
+
timeoutMs?: number
|
|
81
|
+
/** Number of retries for transient errors (default: 3) */
|
|
82
|
+
retryCount?: number
|
|
83
|
+
/** Circuit breaker configuration for R2 failure protection */
|
|
84
|
+
circuitBreaker?: CircuitBreakerConfig
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Result from a single page read operation
|
|
89
|
+
*/
|
|
90
|
+
export interface PageReadResult {
|
|
91
|
+
/** The page data (null if page doesn't exist) */
|
|
92
|
+
data: Uint8Array | null
|
|
93
|
+
/** Whether this was a cache hit */
|
|
94
|
+
hit: boolean
|
|
95
|
+
/** Whether the data is stale (from stale cache) */
|
|
96
|
+
stale: boolean
|
|
97
|
+
/** Source of the data */
|
|
98
|
+
source: 'primary-cache' | 'stale-cache' | 'r2' | 'miss'
|
|
99
|
+
/** Latency of the operation in milliseconds */
|
|
100
|
+
latencyMs: number
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Result from batch page read operation
|
|
105
|
+
*/
|
|
106
|
+
export interface BatchPageResult {
|
|
107
|
+
/** Map of page number to read result */
|
|
108
|
+
pages: Map<number, PageReadResult>
|
|
109
|
+
/** Total latency for the batch operation */
|
|
110
|
+
totalLatencyMs: number
|
|
111
|
+
/** Number of cache hits in the batch */
|
|
112
|
+
cacheHits: number
|
|
113
|
+
/** Number of R2 reads in the batch */
|
|
114
|
+
r2Reads: number
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Statistics for R2PageVFS operations
|
|
119
|
+
*/
|
|
120
|
+
export interface R2PageVFSStats {
|
|
121
|
+
/** Number of primary cache hits */
|
|
122
|
+
primaryCacheHits: number
|
|
123
|
+
/** Number of stale cache hits */
|
|
124
|
+
staleCacheHits: number
|
|
125
|
+
/** Number of complete cache misses */
|
|
126
|
+
cacheMisses: number
|
|
127
|
+
/** Number of R2 read operations */
|
|
128
|
+
r2Reads: number
|
|
129
|
+
/** Number of R2 errors */
|
|
130
|
+
r2Errors: number
|
|
131
|
+
/** Total bytes read */
|
|
132
|
+
bytesRead: number
|
|
133
|
+
/** Bytes served from cache */
|
|
134
|
+
bytesFromCache: number
|
|
135
|
+
/** Bytes fetched from R2 */
|
|
136
|
+
bytesFromR2: number
|
|
137
|
+
/** Number of batch operations */
|
|
138
|
+
batchOperations: number
|
|
139
|
+
/** Number of background revalidations triggered */
|
|
140
|
+
backgroundRevalidations: number
|
|
141
|
+
/** Number of requests deduplicated via singleflight pattern */
|
|
142
|
+
deduplicatedRequests: number
|
|
143
|
+
/** Cache hit ratio (0-1) */
|
|
144
|
+
cacheHitRatio: number
|
|
145
|
+
/** Average cache read latency in ms */
|
|
146
|
+
avgCacheLatencyMs: number
|
|
147
|
+
/** Average R2 read latency in ms */
|
|
148
|
+
avgR2LatencyMs: number
|
|
149
|
+
/** Total errors */
|
|
150
|
+
errors: number
|
|
151
|
+
/** Current circuit breaker state */
|
|
152
|
+
circuitBreakerState: 'closed' | 'open' | 'half-open'
|
|
153
|
+
/** Number of times the circuit breaker has tripped (opened) */
|
|
154
|
+
circuitBreakerTrips: number
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* R2PageVFS interface for page-based R2 access with SWR caching
|
|
159
|
+
*/
|
|
160
|
+
export interface R2PageVFS {
|
|
161
|
+
/**
|
|
162
|
+
* Read a single page by page number
|
|
163
|
+
*
|
|
164
|
+
* @param pageNumber - The page number to read (0-indexed)
|
|
165
|
+
* @param ctx - Optional execution context for background revalidation
|
|
166
|
+
* @returns Page read result with data and metadata
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const result = await vfs.readPage(42, ctx)
|
|
171
|
+
*
|
|
172
|
+
* if (result.data) {
|
|
173
|
+
* console.log(`Page 42: ${result.data.length} bytes`)
|
|
174
|
+
* console.log(`Source: ${result.source}`) // 'primary-cache', 'stale-cache', 'r2', or 'miss'
|
|
175
|
+
* console.log(`Latency: ${result.latencyMs}ms`)
|
|
176
|
+
*
|
|
177
|
+
* if (result.stale) {
|
|
178
|
+
* console.log('Serving stale data while revalidating in background')
|
|
179
|
+
* }
|
|
180
|
+
* } else {
|
|
181
|
+
* console.log('Page not found')
|
|
182
|
+
* }
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
readPage(pageNumber: number, ctx?: ExecutionContext): Promise<PageReadResult>
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Read multiple pages in parallel with concurrency control
|
|
189
|
+
*
|
|
190
|
+
* @param pageNumbers - Array of page numbers to read
|
|
191
|
+
* @param ctx - Optional execution context for background revalidation
|
|
192
|
+
* @returns Batch result with all pages and aggregate stats
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const result = await vfs.readPages([1, 2, 3, 4, 5], ctx)
|
|
197
|
+
*
|
|
198
|
+
* console.log(`Total time: ${result.totalLatencyMs}ms`)
|
|
199
|
+
* console.log(`Cache hits: ${result.cacheHits}`)
|
|
200
|
+
* console.log(`R2 reads: ${result.r2Reads}`)
|
|
201
|
+
*
|
|
202
|
+
* for (const [pageNum, pageResult] of result.pages) {
|
|
203
|
+
* if (pageResult.data) {
|
|
204
|
+
* console.log(`Page ${pageNum}: ${pageResult.data.length} bytes`)
|
|
205
|
+
* }
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
readPages(pageNumbers: number[], ctx?: ExecutionContext): Promise<BatchPageResult>
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get the latest version string from R2 metadata
|
|
213
|
+
*
|
|
214
|
+
* @returns The current version string stored in R2
|
|
215
|
+
*/
|
|
216
|
+
getLatestVersion(): Promise<string>
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Check if the current version matches the latest in R2
|
|
220
|
+
*
|
|
221
|
+
* @returns True if version is current, false if stale
|
|
222
|
+
*/
|
|
223
|
+
isVersionCurrent(): Promise<boolean>
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Invalidate all cached pages for the current version
|
|
227
|
+
*/
|
|
228
|
+
invalidateCache(): Promise<void>
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Invalidate a specific page from cache
|
|
232
|
+
*
|
|
233
|
+
* @param pageNumber - The page number to invalidate
|
|
234
|
+
*/
|
|
235
|
+
invalidatePage(pageNumber: number): Promise<void>
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Invalidate a range of pages from cache
|
|
239
|
+
*
|
|
240
|
+
* @param startPage - First page number in range (inclusive)
|
|
241
|
+
* @param endPage - Last page number in range (inclusive)
|
|
242
|
+
*/
|
|
243
|
+
invalidatePages(startPage: number, endPage: number): Promise<void>
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get current statistics
|
|
247
|
+
*
|
|
248
|
+
* @returns Statistics object with all counters and metrics
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```typescript
|
|
252
|
+
* const stats = vfs.getStats()
|
|
253
|
+
*
|
|
254
|
+
* console.log(`Cache hit ratio: ${(stats.cacheHitRatio * 100).toFixed(1)}%`)
|
|
255
|
+
* console.log(`Primary cache hits: ${stats.primaryCacheHits}`)
|
|
256
|
+
* console.log(`Stale cache hits: ${stats.staleCacheHits}`)
|
|
257
|
+
* console.log(`R2 reads: ${stats.r2Reads}`)
|
|
258
|
+
* console.log(`Avg cache latency: ${stats.avgCacheLatencyMs.toFixed(2)}ms`)
|
|
259
|
+
* console.log(`Avg R2 latency: ${stats.avgR2LatencyMs.toFixed(2)}ms`)
|
|
260
|
+
* console.log(`Circuit breaker: ${stats.circuitBreakerState}`)
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
getStats(): R2PageVFSStats
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Reset all statistics counters
|
|
267
|
+
*/
|
|
268
|
+
resetStats(): void
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get the current configuration
|
|
272
|
+
*
|
|
273
|
+
* @returns The resolved configuration with defaults applied
|
|
274
|
+
*/
|
|
275
|
+
getConfig(): Required<R2PageVFSConfig>
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Utility: Format page number as 8-digit padded string
|
|
280
|
+
*
|
|
281
|
+
* @param pageNumber - The page number to format
|
|
282
|
+
* @returns 8-character padded string (e.g., 1 -> '00000001')
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* formatPageKey(1) // '00000001'
|
|
287
|
+
* formatPageKey(42) // '00000042'
|
|
288
|
+
* formatPageKey(1234) // '00001234'
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
export function formatPageKey(pageNumber: number): string {
|
|
292
|
+
if (!Number.isInteger(pageNumber) || pageNumber < 0) {
|
|
293
|
+
throw new Error(`Invalid page number: ${pageNumber}. Must be non-negative integer.`)
|
|
294
|
+
}
|
|
295
|
+
if (pageNumber > 99999999) {
|
|
296
|
+
throw new Error(`Page number ${pageNumber} exceeds maximum of 99999999`)
|
|
297
|
+
}
|
|
298
|
+
return pageNumber.toString().padStart(8, '0')
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Utility: Build full R2 key for a page
|
|
303
|
+
*
|
|
304
|
+
* @param prefix - The bucket prefix
|
|
305
|
+
* @param version - The version string
|
|
306
|
+
* @param pageNumber - The page number
|
|
307
|
+
* @returns Full R2 key path
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* buildR2Key('mydb', '1', 42)
|
|
312
|
+
* // Returns: 'mydb/v1/pages/00000042'
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
export function buildR2Key(prefix: string, version: string, pageNumber: number): string {
|
|
316
|
+
return `${prefix}/v${version}/pages/${formatPageKey(pageNumber)}`
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Utility: Build cache key for SWR layer
|
|
321
|
+
*
|
|
322
|
+
* @param version - The version string
|
|
323
|
+
* @param pageNumber - The page number
|
|
324
|
+
* @returns Cache key string
|
|
325
|
+
*/
|
|
326
|
+
export function buildCacheKey(version: string, pageNumber: number): string {
|
|
327
|
+
return `page-v${version}-${formatPageKey(pageNumber)}`
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Utility: Parse page number from R2 key
|
|
332
|
+
*
|
|
333
|
+
* @param r2Key - The full R2 key
|
|
334
|
+
* @returns The page number, or null if key format is invalid
|
|
335
|
+
*/
|
|
336
|
+
export function parsePageNumber(r2Key: string): number | null {
|
|
337
|
+
const match = r2Key.match(/\/pages\/(\d{8})$/)
|
|
338
|
+
const pageStr = match?.[1]
|
|
339
|
+
if (!pageStr) {
|
|
340
|
+
return null
|
|
341
|
+
}
|
|
342
|
+
return parseInt(pageStr, 10)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Create initial empty stats object
|
|
347
|
+
*/
|
|
348
|
+
export function createEmptyStats(): R2PageVFSStats {
|
|
349
|
+
return {
|
|
350
|
+
primaryCacheHits: 0,
|
|
351
|
+
staleCacheHits: 0,
|
|
352
|
+
cacheMisses: 0,
|
|
353
|
+
r2Reads: 0,
|
|
354
|
+
r2Errors: 0,
|
|
355
|
+
bytesRead: 0,
|
|
356
|
+
bytesFromCache: 0,
|
|
357
|
+
bytesFromR2: 0,
|
|
358
|
+
batchOperations: 0,
|
|
359
|
+
backgroundRevalidations: 0,
|
|
360
|
+
deduplicatedRequests: 0,
|
|
361
|
+
cacheHitRatio: 0,
|
|
362
|
+
avgCacheLatencyMs: 0,
|
|
363
|
+
avgR2LatencyMs: 0,
|
|
364
|
+
errors: 0,
|
|
365
|
+
circuitBreakerState: 'closed',
|
|
366
|
+
circuitBreakerTrips: 0,
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Default configuration values
|
|
372
|
+
*/
|
|
373
|
+
export const R2_PAGE_VFS_DEFAULTS = {
|
|
374
|
+
/** PostgreSQL default page size */
|
|
375
|
+
pageSize: 8192,
|
|
376
|
+
/** Maximum concurrent R2 operations */
|
|
377
|
+
concurrencyLimit: 10,
|
|
378
|
+
/** R2 operation timeout */
|
|
379
|
+
timeoutMs: 30000,
|
|
380
|
+
/** Retry count for transient errors */
|
|
381
|
+
retryCount: 3,
|
|
382
|
+
/** Default circuit breaker configuration */
|
|
383
|
+
circuitBreaker: {
|
|
384
|
+
failureThreshold: 5,
|
|
385
|
+
resetTimeoutMs: 30000,
|
|
386
|
+
} as CircuitBreakerConfig,
|
|
387
|
+
} as const
|
|
388
|
+
|
|
389
|
+
// =============================================================================
|
|
390
|
+
// IMPLEMENTATION
|
|
391
|
+
// =============================================================================
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Simple circuit breaker implementation
|
|
395
|
+
*
|
|
396
|
+
* Protects against cascading failures by tracking R2 failures and temporarily
|
|
397
|
+
* blocking requests when the failure rate exceeds a threshold.
|
|
398
|
+
*
|
|
399
|
+
* States:
|
|
400
|
+
* - closed: Normal operation, all requests pass through
|
|
401
|
+
* - open: Circuit is tripped, requests fail fast without hitting R2
|
|
402
|
+
* - half-open: After reset timeout, allows one request through to test recovery
|
|
403
|
+
*/
|
|
404
|
+
class CircuitBreaker {
|
|
405
|
+
private failures = 0
|
|
406
|
+
private lastFailureTime = 0
|
|
407
|
+
private state: 'closed' | 'open' | 'half-open' = 'closed'
|
|
408
|
+
private trips = 0
|
|
409
|
+
|
|
410
|
+
constructor(
|
|
411
|
+
private readonly failureThreshold: number,
|
|
412
|
+
private readonly resetTimeoutMs: number
|
|
413
|
+
) {}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Check if a request can be executed
|
|
417
|
+
* @returns true if the circuit allows the request, false if open
|
|
418
|
+
*/
|
|
419
|
+
canExecute(): boolean {
|
|
420
|
+
if (this.state === 'closed') return true
|
|
421
|
+
if (this.state === 'open') {
|
|
422
|
+
if (Date.now() - this.lastFailureTime >= this.resetTimeoutMs) {
|
|
423
|
+
this.state = 'half-open'
|
|
424
|
+
return true
|
|
425
|
+
}
|
|
426
|
+
return false
|
|
427
|
+
}
|
|
428
|
+
// half-open: allow one request through to test recovery
|
|
429
|
+
return true
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Record a successful operation, resetting the circuit if needed
|
|
434
|
+
*/
|
|
435
|
+
recordSuccess(): void {
|
|
436
|
+
this.failures = 0
|
|
437
|
+
this.state = 'closed'
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Record a failed operation, potentially tripping the circuit
|
|
442
|
+
*/
|
|
443
|
+
recordFailure(): void {
|
|
444
|
+
this.failures++
|
|
445
|
+
this.lastFailureTime = Date.now()
|
|
446
|
+
if (this.failures >= this.failureThreshold) {
|
|
447
|
+
if (this.state !== 'open') {
|
|
448
|
+
this.trips++
|
|
449
|
+
}
|
|
450
|
+
this.state = 'open'
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Get the current circuit state
|
|
456
|
+
*/
|
|
457
|
+
getState(): 'closed' | 'open' | 'half-open' {
|
|
458
|
+
// Re-check if we should transition to half-open when queried
|
|
459
|
+
if (this.state === 'open' && Date.now() - this.lastFailureTime >= this.resetTimeoutMs) {
|
|
460
|
+
this.state = 'half-open'
|
|
461
|
+
}
|
|
462
|
+
return this.state
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Get the number of times the circuit has tripped
|
|
467
|
+
*/
|
|
468
|
+
getTrips(): number {
|
|
469
|
+
return this.trips
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Reset the circuit breaker to initial state
|
|
474
|
+
*/
|
|
475
|
+
reset(): void {
|
|
476
|
+
this.failures = 0
|
|
477
|
+
this.lastFailureTime = 0
|
|
478
|
+
this.state = 'closed'
|
|
479
|
+
this.trips = 0
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Internal stats tracking for latency averaging
|
|
485
|
+
*/
|
|
486
|
+
interface InternalStats extends R2PageVFSStats {
|
|
487
|
+
/** Total cache latency for averaging */
|
|
488
|
+
totalCacheLatencyMs: number
|
|
489
|
+
/** Number of cache operations for averaging */
|
|
490
|
+
cacheOperationCount: number
|
|
491
|
+
/** Total R2 latency for averaging */
|
|
492
|
+
totalR2LatencyMs: number
|
|
493
|
+
/** R2 operation count for averaging */
|
|
494
|
+
r2OperationCount: number
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Create initial internal stats object
|
|
499
|
+
*/
|
|
500
|
+
function createInternalStats(): InternalStats {
|
|
501
|
+
return {
|
|
502
|
+
...createEmptyStats(),
|
|
503
|
+
totalCacheLatencyMs: 0,
|
|
504
|
+
cacheOperationCount: 0,
|
|
505
|
+
totalR2LatencyMs: 0,
|
|
506
|
+
r2OperationCount: 0,
|
|
507
|
+
circuitBreakerState: 'closed',
|
|
508
|
+
circuitBreakerTrips: 0,
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Create an R2PageVFS instance
|
|
514
|
+
*
|
|
515
|
+
* @param config - Configuration for the VFS
|
|
516
|
+
* @returns Configured R2PageVFS instance
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```typescript
|
|
520
|
+
* import { createR2PageVFS } from './r2-page-vfs'
|
|
521
|
+
* import { createSWRCacheLayer } from './swr-cache'
|
|
522
|
+
*
|
|
523
|
+
* const swrCache = await createSWRCacheLayer({
|
|
524
|
+
* baseUrl: 'https://pglite.cache.local',
|
|
525
|
+
* primaryTtlSeconds: 60,
|
|
526
|
+
* staleTtlSeconds: 3600,
|
|
527
|
+
* })
|
|
528
|
+
*
|
|
529
|
+
* const vfs = createR2PageVFS({
|
|
530
|
+
* bucket: env.R2_BUCKET,
|
|
531
|
+
* prefix: 'mydb',
|
|
532
|
+
* version: '1',
|
|
533
|
+
* swrCache,
|
|
534
|
+
* pageSize: 8192,
|
|
535
|
+
* concurrencyLimit: 10,
|
|
536
|
+
* })
|
|
537
|
+
*
|
|
538
|
+
* // Read a database page
|
|
539
|
+
* const result = await vfs.readPage(42, ctx)
|
|
540
|
+
* if (result.data) {
|
|
541
|
+
* console.log(`Page 42: ${result.data.length} bytes`)
|
|
542
|
+
* console.log(`Cache hit: ${result.hit}, Stale: ${result.stale}`)
|
|
543
|
+
* }
|
|
544
|
+
* ```
|
|
545
|
+
*
|
|
546
|
+
* @example
|
|
547
|
+
* ```typescript
|
|
548
|
+
* // With circuit breaker configuration
|
|
549
|
+
* const vfs = createR2PageVFS({
|
|
550
|
+
* bucket: env.R2_BUCKET,
|
|
551
|
+
* prefix: 'mydb',
|
|
552
|
+
* version: '1',
|
|
553
|
+
* swrCache,
|
|
554
|
+
* circuitBreaker: {
|
|
555
|
+
* failureThreshold: 5,
|
|
556
|
+
* resetTimeoutMs: 30000,
|
|
557
|
+
* },
|
|
558
|
+
* })
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
export function createR2PageVFS(config: R2PageVFSConfig): R2PageVFS {
|
|
562
|
+
// Validate configuration
|
|
563
|
+
if (config.prefix.endsWith('/')) {
|
|
564
|
+
throw new Error('Prefix must not end with a slash')
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Apply defaults
|
|
568
|
+
const resolvedConfig: Required<R2PageVFSConfig> = {
|
|
569
|
+
bucket: config.bucket,
|
|
570
|
+
prefix: config.prefix,
|
|
571
|
+
version: config.version,
|
|
572
|
+
pageSize: config.pageSize ?? R2_PAGE_VFS_DEFAULTS.pageSize,
|
|
573
|
+
swrCache: config.swrCache,
|
|
574
|
+
concurrencyLimit: config.concurrencyLimit ?? R2_PAGE_VFS_DEFAULTS.concurrencyLimit,
|
|
575
|
+
timeoutMs: config.timeoutMs ?? R2_PAGE_VFS_DEFAULTS.timeoutMs,
|
|
576
|
+
retryCount: config.retryCount ?? R2_PAGE_VFS_DEFAULTS.retryCount,
|
|
577
|
+
circuitBreaker: config.circuitBreaker ?? R2_PAGE_VFS_DEFAULTS.circuitBreaker,
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Internal state
|
|
581
|
+
let stats = createInternalStats()
|
|
582
|
+
|
|
583
|
+
// Circuit breaker for R2 failure protection
|
|
584
|
+
let circuitBreaker = new CircuitBreaker(
|
|
585
|
+
resolvedConfig.circuitBreaker.failureThreshold,
|
|
586
|
+
resolvedConfig.circuitBreaker.resetTimeoutMs
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
// Singleflight: track in-flight R2 requests to deduplicate concurrent fetches
|
|
590
|
+
const inFlight = new Map<number, Promise<Uint8Array | null>>()
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Wire the origin fetcher to the SWR cache layer
|
|
594
|
+
* This allows SWR to call back to R2 for background revalidation
|
|
595
|
+
*/
|
|
596
|
+
config.swrCache.setOriginFetcher(async (cacheKey: string) => {
|
|
597
|
+
// Parse page number from cache key: page-v{version}-{pageNumber}
|
|
598
|
+
const match = cacheKey.match(/^page-v[^-]+-(\d{8})$/)
|
|
599
|
+
const pageStr = match?.[1]
|
|
600
|
+
if (!pageStr) {
|
|
601
|
+
return null
|
|
602
|
+
}
|
|
603
|
+
const pageNumber = parseInt(pageStr, 10)
|
|
604
|
+
const r2Key = buildR2Key(resolvedConfig.prefix, resolvedConfig.version, pageNumber)
|
|
605
|
+
|
|
606
|
+
try {
|
|
607
|
+
const r2Object = await resolvedConfig.bucket.get(r2Key)
|
|
608
|
+
if (!r2Object) {
|
|
609
|
+
return null
|
|
610
|
+
}
|
|
611
|
+
const buffer = await r2Object.arrayBuffer()
|
|
612
|
+
return new Uint8Array(buffer)
|
|
613
|
+
} catch {
|
|
614
|
+
return null
|
|
615
|
+
}
|
|
616
|
+
})
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Fetch a page from R2 with retry logic and circuit breaker protection
|
|
620
|
+
*/
|
|
621
|
+
async function fetchFromR2WithRetry(pageNumber: number): Promise<Uint8Array | null> {
|
|
622
|
+
const r2Key = buildR2Key(resolvedConfig.prefix, resolvedConfig.version, pageNumber)
|
|
623
|
+
|
|
624
|
+
// Check circuit breaker before attempting R2 fetch
|
|
625
|
+
if (!circuitBreaker.canExecute()) {
|
|
626
|
+
stats.r2Errors++
|
|
627
|
+
stats.errors++
|
|
628
|
+
throw new Error('Circuit breaker is open - R2 requests are blocked')
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
let lastError: Error | null = null
|
|
632
|
+
for (let attempt = 0; attempt < resolvedConfig.retryCount; attempt++) {
|
|
633
|
+
let timeoutId: ReturnType<typeof setTimeout> | undefined
|
|
634
|
+
try {
|
|
635
|
+
const r2Object = await Promise.race([
|
|
636
|
+
resolvedConfig.bucket.get(r2Key),
|
|
637
|
+
new Promise<never>((_, reject) => {
|
|
638
|
+
timeoutId = setTimeout(() => reject(new Error('R2 operation timed out')), resolvedConfig.timeoutMs)
|
|
639
|
+
}),
|
|
640
|
+
])
|
|
641
|
+
clearTimeout(timeoutId)
|
|
642
|
+
|
|
643
|
+
if (!r2Object) {
|
|
644
|
+
// Not finding an object is not a failure - circuit breaker records success
|
|
645
|
+
circuitBreaker.recordSuccess()
|
|
646
|
+
return null
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
const buffer = await r2Object.arrayBuffer()
|
|
650
|
+
const data = new Uint8Array(buffer)
|
|
651
|
+
|
|
652
|
+
// Validate page size - partial pages are an error
|
|
653
|
+
if (data.length !== resolvedConfig.pageSize && data.length > 0) {
|
|
654
|
+
throw new Error(`Invalid page size: expected ${resolvedConfig.pageSize}, got ${data.length}`)
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Success - record with circuit breaker
|
|
658
|
+
circuitBreaker.recordSuccess()
|
|
659
|
+
return data
|
|
660
|
+
} catch (error) {
|
|
661
|
+
clearTimeout(timeoutId)
|
|
662
|
+
lastError = error instanceof Error ? error : new Error(String(error))
|
|
663
|
+
// Don't retry on timeout or non-retryable errors
|
|
664
|
+
if (lastError.message.includes('timed out') || lastError.message.includes('Invalid page size')) {
|
|
665
|
+
break
|
|
666
|
+
}
|
|
667
|
+
// Exponential backoff for retries
|
|
668
|
+
if (attempt < resolvedConfig.retryCount - 1) {
|
|
669
|
+
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 100))
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Record failure with circuit breaker
|
|
675
|
+
circuitBreaker.recordFailure()
|
|
676
|
+
stats.r2Errors++
|
|
677
|
+
stats.errors++
|
|
678
|
+
if (lastError) {
|
|
679
|
+
throw lastError
|
|
680
|
+
}
|
|
681
|
+
return null
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Read a single page with caching
|
|
686
|
+
*/
|
|
687
|
+
async function readPage(pageNumber: number, ctx?: ExecutionContext): Promise<PageReadResult> {
|
|
688
|
+
// Validate page number
|
|
689
|
+
if (!Number.isInteger(pageNumber) || pageNumber < 0) {
|
|
690
|
+
throw new Error(`Invalid page number: ${pageNumber}. Must be non-negative integer.`)
|
|
691
|
+
}
|
|
692
|
+
if (pageNumber > 99999999) {
|
|
693
|
+
throw new Error(`Page number ${pageNumber} exceeds maximum of 99999999`)
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const startTime = performance.now()
|
|
697
|
+
const cacheKey = buildCacheKey(resolvedConfig.version, pageNumber)
|
|
698
|
+
|
|
699
|
+
// Try cache first
|
|
700
|
+
try {
|
|
701
|
+
const cacheResult = await config.swrCache.get(cacheKey, ctx)
|
|
702
|
+
|
|
703
|
+
if (cacheResult.hit && cacheResult.data) {
|
|
704
|
+
const latencyMs = performance.now() - startTime
|
|
705
|
+
const dataLength = cacheResult.data.length
|
|
706
|
+
|
|
707
|
+
// Update stats
|
|
708
|
+
stats.bytesRead += dataLength
|
|
709
|
+
stats.bytesFromCache += dataLength
|
|
710
|
+
stats.totalCacheLatencyMs += latencyMs
|
|
711
|
+
stats.cacheOperationCount++
|
|
712
|
+
|
|
713
|
+
if (cacheResult.stale) {
|
|
714
|
+
stats.staleCacheHits++
|
|
715
|
+
if (cacheResult.revalidating) {
|
|
716
|
+
stats.backgroundRevalidations++
|
|
717
|
+
}
|
|
718
|
+
return {
|
|
719
|
+
data: cacheResult.data,
|
|
720
|
+
hit: true,
|
|
721
|
+
stale: true,
|
|
722
|
+
source: 'stale-cache',
|
|
723
|
+
latencyMs,
|
|
724
|
+
}
|
|
725
|
+
} else {
|
|
726
|
+
stats.primaryCacheHits++
|
|
727
|
+
return {
|
|
728
|
+
data: cacheResult.data,
|
|
729
|
+
hit: true,
|
|
730
|
+
stale: false,
|
|
731
|
+
source: 'primary-cache',
|
|
732
|
+
latencyMs,
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
} catch {
|
|
737
|
+
// Cache error - fall through to R2
|
|
738
|
+
stats.errors++
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Cache miss - fetch from R2
|
|
742
|
+
stats.cacheMisses++
|
|
743
|
+
|
|
744
|
+
// Singleflight: check if there's already an in-flight request for this page
|
|
745
|
+
const existingRequest = inFlight.get(pageNumber)
|
|
746
|
+
if (existingRequest) {
|
|
747
|
+
stats.deduplicatedRequests++
|
|
748
|
+
try {
|
|
749
|
+
const data = await existingRequest
|
|
750
|
+
const totalLatencyMs = performance.now() - startTime
|
|
751
|
+
if (data) {
|
|
752
|
+
stats.bytesRead += data.length
|
|
753
|
+
// Note: bytesFromR2 not incremented since another request fetched it
|
|
754
|
+
return {
|
|
755
|
+
data,
|
|
756
|
+
hit: false,
|
|
757
|
+
stale: false,
|
|
758
|
+
source: 'r2', // Was fetched by another request
|
|
759
|
+
latencyMs: totalLatencyMs,
|
|
760
|
+
}
|
|
761
|
+
} else {
|
|
762
|
+
return {
|
|
763
|
+
data: null,
|
|
764
|
+
hit: false,
|
|
765
|
+
stale: false,
|
|
766
|
+
source: 'miss',
|
|
767
|
+
latencyMs: totalLatencyMs,
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
} catch {
|
|
771
|
+
// Original request failed, we'll try our own fetch below
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const r2StartTime = performance.now()
|
|
776
|
+
|
|
777
|
+
// Start our own fetch and register it in the singleflight map
|
|
778
|
+
const fetchPromise = fetchFromR2WithRetry(pageNumber)
|
|
779
|
+
inFlight.set(pageNumber, fetchPromise)
|
|
780
|
+
|
|
781
|
+
try {
|
|
782
|
+
stats.r2Reads++
|
|
783
|
+
const data = await fetchPromise
|
|
784
|
+
const r2LatencyMs = performance.now() - r2StartTime
|
|
785
|
+
const totalLatencyMs = performance.now() - startTime
|
|
786
|
+
|
|
787
|
+
stats.totalR2LatencyMs += r2LatencyMs
|
|
788
|
+
stats.r2OperationCount++
|
|
789
|
+
|
|
790
|
+
if (data) {
|
|
791
|
+
stats.bytesRead += data.length
|
|
792
|
+
stats.bytesFromR2 += data.length
|
|
793
|
+
|
|
794
|
+
// Populate cache with fetched data
|
|
795
|
+
try {
|
|
796
|
+
await config.swrCache.put(cacheKey, data)
|
|
797
|
+
} catch {
|
|
798
|
+
// Cache write error - non-fatal
|
|
799
|
+
stats.errors++
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
return {
|
|
803
|
+
data,
|
|
804
|
+
hit: false,
|
|
805
|
+
stale: false,
|
|
806
|
+
source: 'r2',
|
|
807
|
+
latencyMs: totalLatencyMs,
|
|
808
|
+
}
|
|
809
|
+
} else {
|
|
810
|
+
return {
|
|
811
|
+
data: null,
|
|
812
|
+
hit: false,
|
|
813
|
+
stale: false,
|
|
814
|
+
source: 'miss',
|
|
815
|
+
latencyMs: totalLatencyMs,
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
} catch (error) {
|
|
819
|
+
const totalLatencyMs = performance.now() - startTime
|
|
820
|
+
// R2 error already counted in fetchFromR2WithRetry
|
|
821
|
+
// Propagate fatal errors
|
|
822
|
+
if (error instanceof Error &&
|
|
823
|
+
(error.message.includes('timed out') || error.message.includes('Invalid page size'))) {
|
|
824
|
+
throw error
|
|
825
|
+
}
|
|
826
|
+
// Return null for network errors
|
|
827
|
+
return {
|
|
828
|
+
data: null,
|
|
829
|
+
hit: false,
|
|
830
|
+
stale: false,
|
|
831
|
+
source: 'miss',
|
|
832
|
+
latencyMs: totalLatencyMs,
|
|
833
|
+
}
|
|
834
|
+
} finally {
|
|
835
|
+
// Clean up the in-flight map
|
|
836
|
+
inFlight.delete(pageNumber)
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Read multiple pages with concurrency control
|
|
842
|
+
*/
|
|
843
|
+
async function readPages(pageNumbers: number[], ctx?: ExecutionContext): Promise<BatchPageResult> {
|
|
844
|
+
const startTime = performance.now()
|
|
845
|
+
stats.batchOperations++
|
|
846
|
+
|
|
847
|
+
// Deduplicate page numbers while preserving order
|
|
848
|
+
const uniquePages = [...new Set(pageNumbers)]
|
|
849
|
+
const pages = new Map<number, PageReadResult>()
|
|
850
|
+
|
|
851
|
+
let cacheHits = 0
|
|
852
|
+
let r2Reads = 0
|
|
853
|
+
|
|
854
|
+
// Process pages with concurrency control
|
|
855
|
+
const results: Array<{ pageNumber: number; result: PageReadResult }> = []
|
|
856
|
+
|
|
857
|
+
// Process in batches based on concurrency limit
|
|
858
|
+
for (let i = 0; i < uniquePages.length; i += resolvedConfig.concurrencyLimit) {
|
|
859
|
+
const batch = uniquePages.slice(i, i + resolvedConfig.concurrencyLimit)
|
|
860
|
+
const batchResults = await Promise.all(
|
|
861
|
+
batch.map(async (pageNumber) => {
|
|
862
|
+
const result = await readPage(pageNumber, ctx)
|
|
863
|
+
return { pageNumber, result }
|
|
864
|
+
})
|
|
865
|
+
)
|
|
866
|
+
results.push(...batchResults)
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// Build the result map in original request order
|
|
870
|
+
for (const { pageNumber, result } of results) {
|
|
871
|
+
pages.set(pageNumber, result)
|
|
872
|
+
if (result.hit) {
|
|
873
|
+
cacheHits++
|
|
874
|
+
}
|
|
875
|
+
if (result.source === 'r2') {
|
|
876
|
+
r2Reads++
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
const totalLatencyMs = performance.now() - startTime
|
|
881
|
+
|
|
882
|
+
return {
|
|
883
|
+
pages,
|
|
884
|
+
totalLatencyMs,
|
|
885
|
+
cacheHits,
|
|
886
|
+
r2Reads,
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Get the latest version from R2 metadata
|
|
892
|
+
*/
|
|
893
|
+
async function getLatestVersion(): Promise<string> {
|
|
894
|
+
const versionKey = `${resolvedConfig.prefix}/version`
|
|
895
|
+
|
|
896
|
+
try {
|
|
897
|
+
const r2Object = await resolvedConfig.bucket.get(versionKey)
|
|
898
|
+
if (!r2Object) {
|
|
899
|
+
throw new Error('Version file not found in R2')
|
|
900
|
+
}
|
|
901
|
+
const text = await r2Object.text()
|
|
902
|
+
return text.trim()
|
|
903
|
+
} catch (error) {
|
|
904
|
+
stats.r2Errors++
|
|
905
|
+
stats.errors++
|
|
906
|
+
throw error
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Check if current version matches latest
|
|
912
|
+
*/
|
|
913
|
+
async function isVersionCurrent(): Promise<boolean> {
|
|
914
|
+
try {
|
|
915
|
+
const latestVersion = await getLatestVersion()
|
|
916
|
+
return latestVersion === resolvedConfig.version
|
|
917
|
+
} catch {
|
|
918
|
+
// If we can't get the latest version, assume current is not current
|
|
919
|
+
return false
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* Invalidate all cached pages for the current version
|
|
925
|
+
*/
|
|
926
|
+
async function invalidateCache(): Promise<void> {
|
|
927
|
+
// List all pages in R2 for this version and invalidate their cache entries
|
|
928
|
+
const prefix = `${resolvedConfig.prefix}/v${resolvedConfig.version}/pages/`
|
|
929
|
+
|
|
930
|
+
try {
|
|
931
|
+
let cursor: string | undefined
|
|
932
|
+
do {
|
|
933
|
+
// Build list options without undefined values for exactOptionalPropertyTypes
|
|
934
|
+
const listOptions: { prefix: string; cursor?: string } = { prefix }
|
|
935
|
+
if (cursor !== undefined) {
|
|
936
|
+
listOptions.cursor = cursor
|
|
937
|
+
}
|
|
938
|
+
const listResult = await resolvedConfig.bucket.list(listOptions)
|
|
939
|
+
|
|
940
|
+
// Invalidate each page's cache entry
|
|
941
|
+
await Promise.all(
|
|
942
|
+
listResult.objects.map(async (obj) => {
|
|
943
|
+
const pageNumber = parsePageNumber(obj.key)
|
|
944
|
+
if (pageNumber !== null) {
|
|
945
|
+
const cacheKey = buildCacheKey(resolvedConfig.version, pageNumber)
|
|
946
|
+
await config.swrCache.invalidate(cacheKey)
|
|
947
|
+
}
|
|
948
|
+
})
|
|
949
|
+
)
|
|
950
|
+
|
|
951
|
+
cursor = listResult.truncated ? listResult.cursor : undefined
|
|
952
|
+
} while (cursor)
|
|
953
|
+
} catch {
|
|
954
|
+
stats.errors++
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Invalidate a specific page from cache
|
|
960
|
+
*/
|
|
961
|
+
async function invalidatePage(pageNumber: number): Promise<void> {
|
|
962
|
+
const cacheKey = buildCacheKey(resolvedConfig.version, pageNumber)
|
|
963
|
+
try {
|
|
964
|
+
await config.swrCache.invalidate(cacheKey)
|
|
965
|
+
} catch {
|
|
966
|
+
stats.errors++
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Invalidate a range of pages from cache
|
|
972
|
+
* Includes safeguards against unbounded memory growth from large ranges
|
|
973
|
+
*/
|
|
974
|
+
async function invalidatePages(startPage: number, endPage: number): Promise<void> {
|
|
975
|
+
const MAX_RANGE = 100000
|
|
976
|
+
const BATCH_SIZE = 1000
|
|
977
|
+
const pageCount = endPage - startPage + 1
|
|
978
|
+
|
|
979
|
+
if (pageCount > MAX_RANGE) {
|
|
980
|
+
throw new Error(`Page range too large: ${pageCount}. Maximum allowed: ${MAX_RANGE}`)
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// Process in batches to avoid creating too many promises at once
|
|
984
|
+
for (let i = startPage; i <= endPage; i += BATCH_SIZE) {
|
|
985
|
+
const batchEnd = Math.min(i + BATCH_SIZE - 1, endPage)
|
|
986
|
+
const promises: Promise<void>[] = []
|
|
987
|
+
for (let pageNumber = i; pageNumber <= batchEnd; pageNumber++) {
|
|
988
|
+
promises.push(invalidatePage(pageNumber))
|
|
989
|
+
}
|
|
990
|
+
await Promise.all(promises)
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Get current statistics
|
|
996
|
+
*/
|
|
997
|
+
function getStats(): R2PageVFSStats {
|
|
998
|
+
const totalReads = stats.primaryCacheHits + stats.staleCacheHits + stats.cacheMisses
|
|
999
|
+
|
|
1000
|
+
return {
|
|
1001
|
+
primaryCacheHits: stats.primaryCacheHits,
|
|
1002
|
+
staleCacheHits: stats.staleCacheHits,
|
|
1003
|
+
cacheMisses: stats.cacheMisses,
|
|
1004
|
+
r2Reads: stats.r2Reads,
|
|
1005
|
+
r2Errors: stats.r2Errors,
|
|
1006
|
+
bytesRead: stats.bytesRead,
|
|
1007
|
+
bytesFromCache: stats.bytesFromCache,
|
|
1008
|
+
bytesFromR2: stats.bytesFromR2,
|
|
1009
|
+
batchOperations: stats.batchOperations,
|
|
1010
|
+
backgroundRevalidations: stats.backgroundRevalidations,
|
|
1011
|
+
deduplicatedRequests: stats.deduplicatedRequests,
|
|
1012
|
+
cacheHitRatio: totalReads > 0
|
|
1013
|
+
? (stats.primaryCacheHits + stats.staleCacheHits) / totalReads
|
|
1014
|
+
: 0,
|
|
1015
|
+
avgCacheLatencyMs: stats.cacheOperationCount > 0
|
|
1016
|
+
? stats.totalCacheLatencyMs / stats.cacheOperationCount
|
|
1017
|
+
: 0,
|
|
1018
|
+
avgR2LatencyMs: stats.r2OperationCount > 0
|
|
1019
|
+
? stats.totalR2LatencyMs / stats.r2OperationCount
|
|
1020
|
+
: 0,
|
|
1021
|
+
errors: stats.errors,
|
|
1022
|
+
circuitBreakerState: circuitBreaker.getState(),
|
|
1023
|
+
circuitBreakerTrips: circuitBreaker.getTrips(),
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Reset all statistics
|
|
1029
|
+
*/
|
|
1030
|
+
function resetStats(): void {
|
|
1031
|
+
stats = createInternalStats()
|
|
1032
|
+
circuitBreaker.reset()
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* Get current configuration
|
|
1037
|
+
*/
|
|
1038
|
+
function getConfig(): Required<R2PageVFSConfig> {
|
|
1039
|
+
return { ...resolvedConfig }
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
return {
|
|
1043
|
+
readPage,
|
|
1044
|
+
readPages,
|
|
1045
|
+
getLatestVersion,
|
|
1046
|
+
isVersionCurrent,
|
|
1047
|
+
invalidateCache,
|
|
1048
|
+
invalidatePage,
|
|
1049
|
+
invalidatePages,
|
|
1050
|
+
getStats,
|
|
1051
|
+
resetStats,
|
|
1052
|
+
getConfig,
|
|
1053
|
+
}
|
|
1054
|
+
}
|