@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.
Files changed (1129) hide show
  1. package/README.md +868 -0
  2. package/dist/cdc/change-stream.d.ts +44 -0
  3. package/dist/cdc/change-stream.d.ts.map +1 -0
  4. package/dist/cdc/change-stream.js +95 -0
  5. package/dist/cdc/change-stream.js.map +1 -0
  6. package/dist/cdc/filter.d.ts +58 -0
  7. package/dist/cdc/filter.d.ts.map +1 -0
  8. package/dist/cdc/filter.js +520 -0
  9. package/dist/cdc/filter.js.map +1 -0
  10. package/dist/cdc/index.d.ts +47 -0
  11. package/dist/cdc/index.d.ts.map +1 -0
  12. package/dist/cdc/index.js +50 -0
  13. package/dist/cdc/index.js.map +1 -0
  14. package/dist/cdc/resume-token.d.ts +60 -0
  15. package/dist/cdc/resume-token.d.ts.map +1 -0
  16. package/dist/cdc/resume-token.js +228 -0
  17. package/dist/cdc/resume-token.js.map +1 -0
  18. package/dist/cdc/transport/index.d.ts +7 -0
  19. package/dist/cdc/transport/index.d.ts.map +1 -0
  20. package/dist/cdc/transport/index.js +7 -0
  21. package/dist/cdc/transport/index.js.map +1 -0
  22. package/dist/cdc/transport/sse.d.ts +120 -0
  23. package/dist/cdc/transport/sse.d.ts.map +1 -0
  24. package/dist/cdc/transport/sse.js +590 -0
  25. package/dist/cdc/transport/sse.js.map +1 -0
  26. package/dist/cdc/transport/websocket.d.ts +130 -0
  27. package/dist/cdc/transport/websocket.d.ts.map +1 -0
  28. package/dist/cdc/transport/websocket.js +688 -0
  29. package/dist/cdc/transport/websocket.js.map +1 -0
  30. package/dist/cdc/types.d.ts +306 -0
  31. package/dist/cdc/types.d.ts.map +1 -0
  32. package/dist/cdc/types.js +8 -0
  33. package/dist/cdc/types.js.map +1 -0
  34. package/dist/config/index.d.ts +25 -0
  35. package/dist/config/index.d.ts.map +1 -0
  36. package/dist/config/index.js +25 -0
  37. package/dist/config/index.js.map +1 -0
  38. package/dist/config/memory.d.ts +139 -0
  39. package/dist/config/memory.d.ts.map +1 -0
  40. package/dist/config/memory.js +157 -0
  41. package/dist/config/memory.js.map +1 -0
  42. package/dist/config/storage.d.ts +157 -0
  43. package/dist/config/storage.d.ts.map +1 -0
  44. package/dist/config/storage.js +178 -0
  45. package/dist/config/storage.js.map +1 -0
  46. package/dist/config/streaming.d.ts +117 -0
  47. package/dist/config/streaming.d.ts.map +1 -0
  48. package/dist/config/streaming.js +132 -0
  49. package/dist/config/streaming.js.map +1 -0
  50. package/dist/config/timeouts.d.ts +168 -0
  51. package/dist/config/timeouts.d.ts.map +1 -0
  52. package/dist/config/timeouts.js +192 -0
  53. package/dist/config/timeouts.js.map +1 -0
  54. package/dist/extensions/config.d.ts +89 -0
  55. package/dist/extensions/config.d.ts.map +1 -0
  56. package/dist/extensions/config.js +216 -0
  57. package/dist/extensions/config.js.map +1 -0
  58. package/dist/extensions/geo.d.ts +452 -0
  59. package/dist/extensions/geo.d.ts.map +1 -0
  60. package/dist/extensions/geo.js +583 -0
  61. package/dist/extensions/geo.js.map +1 -0
  62. package/dist/extensions/index.d.ts +167 -0
  63. package/dist/extensions/index.d.ts.map +1 -0
  64. package/dist/extensions/index.js +99 -0
  65. package/dist/extensions/index.js.map +1 -0
  66. package/dist/extensions/loader.d.ts +226 -0
  67. package/dist/extensions/loader.d.ts.map +1 -0
  68. package/dist/extensions/loader.js +456 -0
  69. package/dist/extensions/loader.js.map +1 -0
  70. package/dist/extensions/pgmq-lite.d.ts +330 -0
  71. package/dist/extensions/pgmq-lite.d.ts.map +1 -0
  72. package/dist/extensions/pgmq-lite.js +648 -0
  73. package/dist/extensions/pgmq-lite.js.map +1 -0
  74. package/dist/extensions/plugins.d.ts +260 -0
  75. package/dist/extensions/plugins.d.ts.map +1 -0
  76. package/dist/extensions/plugins.js +535 -0
  77. package/dist/extensions/plugins.js.map +1 -0
  78. package/dist/extensions/registry.d.ts +93 -0
  79. package/dist/extensions/registry.d.ts.map +1 -0
  80. package/dist/extensions/registry.js +182 -0
  81. package/dist/extensions/registry.js.map +1 -0
  82. package/dist/extensions/vector.d.ts +106 -0
  83. package/dist/extensions/vector.d.ts.map +1 -0
  84. package/dist/extensions/vector.js +129 -0
  85. package/dist/extensions/vector.js.map +1 -0
  86. package/dist/iceberg/analytics.d.ts +279 -0
  87. package/dist/iceberg/analytics.d.ts.map +1 -0
  88. package/dist/iceberg/analytics.js +448 -0
  89. package/dist/iceberg/analytics.js.map +1 -0
  90. package/dist/iceberg/catalog-api.d.ts +39 -0
  91. package/dist/iceberg/catalog-api.d.ts.map +1 -0
  92. package/dist/iceberg/catalog-api.js +388 -0
  93. package/dist/iceberg/catalog-api.js.map +1 -0
  94. package/dist/iceberg/catalog.d.ts +401 -0
  95. package/dist/iceberg/catalog.d.ts.map +1 -0
  96. package/dist/iceberg/catalog.js +677 -0
  97. package/dist/iceberg/catalog.js.map +1 -0
  98. package/dist/iceberg/duckdb-wasm.d.ts +447 -0
  99. package/dist/iceberg/duckdb-wasm.d.ts.map +1 -0
  100. package/dist/iceberg/duckdb-wasm.js +600 -0
  101. package/dist/iceberg/duckdb-wasm.js.map +1 -0
  102. package/dist/iceberg/index.d.ts +92 -0
  103. package/dist/iceberg/index.d.ts.map +1 -0
  104. package/dist/iceberg/index.js +119 -0
  105. package/dist/iceberg/index.js.map +1 -0
  106. package/dist/iceberg/metadata.d.ts +214 -0
  107. package/dist/iceberg/metadata.d.ts.map +1 -0
  108. package/dist/iceberg/metadata.js +535 -0
  109. package/dist/iceberg/metadata.js.map +1 -0
  110. package/dist/iceberg/optimizer.d.ts +296 -0
  111. package/dist/iceberg/optimizer.d.ts.map +1 -0
  112. package/dist/iceberg/optimizer.js +889 -0
  113. package/dist/iceberg/optimizer.js.map +1 -0
  114. package/dist/iceberg/parquet.d.ts +447 -0
  115. package/dist/iceberg/parquet.d.ts.map +1 -0
  116. package/dist/iceberg/parquet.js +1225 -0
  117. package/dist/iceberg/parquet.js.map +1 -0
  118. package/dist/iceberg/r2-organization.d.ts +422 -0
  119. package/dist/iceberg/r2-organization.d.ts.map +1 -0
  120. package/dist/iceberg/r2-organization.js +672 -0
  121. package/dist/iceberg/r2-organization.js.map +1 -0
  122. package/dist/iceberg/scheduler-do-example.d.ts +158 -0
  123. package/dist/iceberg/scheduler-do-example.d.ts.map +1 -0
  124. package/dist/iceberg/scheduler-do-example.js +261 -0
  125. package/dist/iceberg/scheduler-do-example.js.map +1 -0
  126. package/dist/iceberg/scheduler.d.ts +434 -0
  127. package/dist/iceberg/scheduler.d.ts.map +1 -0
  128. package/dist/iceberg/scheduler.js +818 -0
  129. package/dist/iceberg/scheduler.js.map +1 -0
  130. package/dist/iceberg/schema.d.ts +149 -0
  131. package/dist/iceberg/schema.d.ts.map +1 -0
  132. package/dist/iceberg/schema.js +525 -0
  133. package/dist/iceberg/schema.js.map +1 -0
  134. package/dist/iceberg/snapshot-manager.d.ts +406 -0
  135. package/dist/iceberg/snapshot-manager.d.ts.map +1 -0
  136. package/dist/iceberg/snapshot-manager.js +934 -0
  137. package/dist/iceberg/snapshot-manager.js.map +1 -0
  138. package/dist/iceberg/sql-router.d.ts +194 -0
  139. package/dist/iceberg/sql-router.d.ts.map +1 -0
  140. package/dist/iceberg/sql-router.js +180 -0
  141. package/dist/iceberg/sql-router.js.map +1 -0
  142. package/dist/iceberg/test-fixtures.d.ts +151 -0
  143. package/dist/iceberg/test-fixtures.d.ts.map +1 -0
  144. package/dist/iceberg/test-fixtures.js +446 -0
  145. package/dist/iceberg/test-fixtures.js.map +1 -0
  146. package/dist/iceberg/time-travel-api.d.ts +102 -0
  147. package/dist/iceberg/time-travel-api.d.ts.map +1 -0
  148. package/dist/iceberg/time-travel-api.js +437 -0
  149. package/dist/iceberg/time-travel-api.js.map +1 -0
  150. package/dist/iceberg/time-travel.d.ts +293 -0
  151. package/dist/iceberg/time-travel.d.ts.map +1 -0
  152. package/dist/iceberg/time-travel.js +689 -0
  153. package/dist/iceberg/time-travel.js.map +1 -0
  154. package/dist/iceberg/transformer.d.ts +356 -0
  155. package/dist/iceberg/transformer.d.ts.map +1 -0
  156. package/dist/iceberg/transformer.js +770 -0
  157. package/dist/iceberg/transformer.js.map +1 -0
  158. package/dist/iceberg/types.d.ts +318 -0
  159. package/dist/iceberg/types.d.ts.map +1 -0
  160. package/dist/iceberg/types.js +9 -0
  161. package/dist/iceberg/types.js.map +1 -0
  162. package/dist/iceberg/writer.d.ts +144 -0
  163. package/dist/iceberg/writer.d.ts.map +1 -0
  164. package/dist/iceberg/writer.js +452 -0
  165. package/dist/iceberg/writer.js.map +1 -0
  166. package/dist/index.d.ts +50 -0
  167. package/dist/index.d.ts.map +1 -0
  168. package/dist/index.js +69 -0
  169. package/dist/index.js.map +1 -0
  170. package/dist/lineage/index.d.ts +11 -0
  171. package/dist/lineage/index.d.ts.map +1 -0
  172. package/dist/lineage/index.js +11 -0
  173. package/dist/lineage/index.js.map +1 -0
  174. package/dist/lineage/integration.d.ts +134 -0
  175. package/dist/lineage/integration.d.ts.map +1 -0
  176. package/dist/lineage/integration.js +258 -0
  177. package/dist/lineage/integration.js.map +1 -0
  178. package/dist/lineage/tracker.d.ts +189 -0
  179. package/dist/lineage/tracker.d.ts.map +1 -0
  180. package/dist/lineage/tracker.js +1352 -0
  181. package/dist/lineage/tracker.js.map +1 -0
  182. package/dist/lineage/types.d.ts +318 -0
  183. package/dist/lineage/types.d.ts.map +1 -0
  184. package/dist/lineage/types.js +9 -0
  185. package/dist/lineage/types.js.map +1 -0
  186. package/dist/middleware/index.d.ts +11 -0
  187. package/dist/middleware/index.d.ts.map +1 -0
  188. package/dist/middleware/index.js +16 -0
  189. package/dist/middleware/index.js.map +1 -0
  190. package/dist/middleware/rate-limit.d.ts +397 -0
  191. package/dist/middleware/rate-limit.d.ts.map +1 -0
  192. package/dist/middleware/rate-limit.js +507 -0
  193. package/dist/middleware/rate-limit.js.map +1 -0
  194. package/dist/migration-tooling/external-migration.d.ts +601 -0
  195. package/dist/migration-tooling/external-migration.d.ts.map +1 -0
  196. package/dist/migration-tooling/external-migration.js +1612 -0
  197. package/dist/migration-tooling/external-migration.js.map +1 -0
  198. package/dist/migration-tooling/index.d.ts +19 -0
  199. package/dist/migration-tooling/index.d.ts.map +1 -0
  200. package/dist/migration-tooling/index.js +19 -0
  201. package/dist/migration-tooling/index.js.map +1 -0
  202. package/dist/migrations/auto-migrator.d.ts +289 -0
  203. package/dist/migrations/auto-migrator.d.ts.map +1 -0
  204. package/dist/migrations/auto-migrator.js +396 -0
  205. package/dist/migrations/auto-migrator.js.map +1 -0
  206. package/dist/migrations/bulk-orchestrator.d.ts +403 -0
  207. package/dist/migrations/bulk-orchestrator.d.ts.map +1 -0
  208. package/dist/migrations/bulk-orchestrator.js +646 -0
  209. package/dist/migrations/bulk-orchestrator.js.map +1 -0
  210. package/dist/migrations/compatibility.d.ts +216 -0
  211. package/dist/migrations/compatibility.d.ts.map +1 -0
  212. package/dist/migrations/compatibility.js +651 -0
  213. package/dist/migrations/compatibility.js.map +1 -0
  214. package/dist/migrations/do-migrations.d.ts +101 -0
  215. package/dist/migrations/do-migrations.d.ts.map +1 -0
  216. package/dist/migrations/do-migrations.js +1060 -0
  217. package/dist/migrations/do-migrations.js.map +1 -0
  218. package/dist/migrations/do-migrations.types.d.ts +550 -0
  219. package/dist/migrations/do-migrations.types.d.ts.map +1 -0
  220. package/dist/migrations/do-migrations.types.js +15 -0
  221. package/dist/migrations/do-migrations.types.js.map +1 -0
  222. package/dist/migrations/drizzle-compat.d.ts +163 -0
  223. package/dist/migrations/drizzle-compat.d.ts.map +1 -0
  224. package/dist/migrations/drizzle-compat.js +273 -0
  225. package/dist/migrations/drizzle-compat.js.map +1 -0
  226. package/dist/migrations/index.d.ts +109 -0
  227. package/dist/migrations/index.d.ts.map +1 -0
  228. package/dist/migrations/index.js +127 -0
  229. package/dist/migrations/index.js.map +1 -0
  230. package/dist/migrations/migration-api.d.ts +161 -0
  231. package/dist/migrations/migration-api.d.ts.map +1 -0
  232. package/dist/migrations/migration-api.js +499 -0
  233. package/dist/migrations/migration-api.js.map +1 -0
  234. package/dist/migrations/progress-tracker-do.d.ts +195 -0
  235. package/dist/migrations/progress-tracker-do.d.ts.map +1 -0
  236. package/dist/migrations/progress-tracker-do.js +339 -0
  237. package/dist/migrations/progress-tracker-do.js.map +1 -0
  238. package/dist/migrations/progress-tracker-kv.d.ts +103 -0
  239. package/dist/migrations/progress-tracker-kv.d.ts.map +1 -0
  240. package/dist/migrations/progress-tracker-kv.js +231 -0
  241. package/dist/migrations/progress-tracker-kv.js.map +1 -0
  242. package/dist/migrations/progress-tracker.d.ts +320 -0
  243. package/dist/migrations/progress-tracker.d.ts.map +1 -0
  244. package/dist/migrations/progress-tracker.js +443 -0
  245. package/dist/migrations/progress-tracker.js.map +1 -0
  246. package/dist/migrations/registry.d.ts +231 -0
  247. package/dist/migrations/registry.d.ts.map +1 -0
  248. package/dist/migrations/registry.js +376 -0
  249. package/dist/migrations/registry.js.map +1 -0
  250. package/dist/migrations/runner.d.ts +197 -0
  251. package/dist/migrations/runner.d.ts.map +1 -0
  252. package/dist/migrations/runner.js +1167 -0
  253. package/dist/migrations/runner.js.map +1 -0
  254. package/dist/migrations/schema-generator.d.ts +111 -0
  255. package/dist/migrations/schema-generator.d.ts.map +1 -0
  256. package/dist/migrations/schema-generator.js +335 -0
  257. package/dist/migrations/schema-generator.js.map +1 -0
  258. package/dist/migrations/testing.d.ts +321 -0
  259. package/dist/migrations/testing.d.ts.map +1 -0
  260. package/dist/migrations/testing.js +645 -0
  261. package/dist/migrations/testing.js.map +1 -0
  262. package/dist/migrations/types.d.ts +503 -0
  263. package/dist/migrations/types.d.ts.map +1 -0
  264. package/dist/migrations/types.js +11 -0
  265. package/dist/migrations/types.js.map +1 -0
  266. package/dist/migrations/validator.d.ts +215 -0
  267. package/dist/migrations/validator.d.ts.map +1 -0
  268. package/dist/migrations/validator.js +494 -0
  269. package/dist/migrations/validator.js.map +1 -0
  270. package/dist/observability/alerting.d.ts +116 -0
  271. package/dist/observability/alerting.d.ts.map +1 -0
  272. package/dist/observability/alerting.js +353 -0
  273. package/dist/observability/alerting.js.map +1 -0
  274. package/dist/observability/analytics-engine.d.ts +357 -0
  275. package/dist/observability/analytics-engine.d.ts.map +1 -0
  276. package/dist/observability/analytics-engine.js +430 -0
  277. package/dist/observability/analytics-engine.js.map +1 -0
  278. package/dist/observability/cost-metrics.d.ts +269 -0
  279. package/dist/observability/cost-metrics.d.ts.map +1 -0
  280. package/dist/observability/cost-metrics.js +560 -0
  281. package/dist/observability/cost-metrics.js.map +1 -0
  282. package/dist/observability/cross-do-tracing.d.ts +305 -0
  283. package/dist/observability/cross-do-tracing.d.ts.map +1 -0
  284. package/dist/observability/cross-do-tracing.js +431 -0
  285. package/dist/observability/cross-do-tracing.js.map +1 -0
  286. package/dist/observability/error-rate-collector.d.ts +163 -0
  287. package/dist/observability/error-rate-collector.d.ts.map +1 -0
  288. package/dist/observability/error-rate-collector.js +306 -0
  289. package/dist/observability/error-rate-collector.js.map +1 -0
  290. package/dist/observability/exporters.d.ts +231 -0
  291. package/dist/observability/exporters.d.ts.map +1 -0
  292. package/dist/observability/exporters.js +479 -0
  293. package/dist/observability/exporters.js.map +1 -0
  294. package/dist/observability/health-check.d.ts +106 -0
  295. package/dist/observability/health-check.d.ts.map +1 -0
  296. package/dist/observability/health-check.js +243 -0
  297. package/dist/observability/health-check.js.map +1 -0
  298. package/dist/observability/index.d.ts +297 -0
  299. package/dist/observability/index.d.ts.map +1 -0
  300. package/dist/observability/index.js +455 -0
  301. package/dist/observability/index.js.map +1 -0
  302. package/dist/observability/instrumentation.d.ts +222 -0
  303. package/dist/observability/instrumentation.d.ts.map +1 -0
  304. package/dist/observability/instrumentation.js +532 -0
  305. package/dist/observability/instrumentation.js.map +1 -0
  306. package/dist/observability/memory-metrics.d.ts +227 -0
  307. package/dist/observability/memory-metrics.d.ts.map +1 -0
  308. package/dist/observability/memory-metrics.js +688 -0
  309. package/dist/observability/memory-metrics.js.map +1 -0
  310. package/dist/observability/metrics-endpoint.d.ts +91 -0
  311. package/dist/observability/metrics-endpoint.d.ts.map +1 -0
  312. package/dist/observability/metrics-endpoint.js +246 -0
  313. package/dist/observability/metrics-endpoint.js.map +1 -0
  314. package/dist/observability/metrics.d.ts +88 -0
  315. package/dist/observability/metrics.d.ts.map +1 -0
  316. package/dist/observability/metrics.js +253 -0
  317. package/dist/observability/metrics.js.map +1 -0
  318. package/dist/observability/observability-features.d.ts +488 -0
  319. package/dist/observability/observability-features.d.ts.map +1 -0
  320. package/dist/observability/observability-features.js +773 -0
  321. package/dist/observability/observability-features.js.map +1 -0
  322. package/dist/observability/prometheus.d.ts +39 -0
  323. package/dist/observability/prometheus.d.ts.map +1 -0
  324. package/dist/observability/prometheus.js +120 -0
  325. package/dist/observability/prometheus.js.map +1 -0
  326. package/dist/observability/propagation.d.ts +126 -0
  327. package/dist/observability/propagation.d.ts.map +1 -0
  328. package/dist/observability/propagation.js +234 -0
  329. package/dist/observability/propagation.js.map +1 -0
  330. package/dist/observability/query-latency.d.ts +243 -0
  331. package/dist/observability/query-latency.d.ts.map +1 -0
  332. package/dist/observability/query-latency.js +292 -0
  333. package/dist/observability/query-latency.js.map +1 -0
  334. package/dist/observability/query-performance.d.ts +169 -0
  335. package/dist/observability/query-performance.d.ts.map +1 -0
  336. package/dist/observability/query-performance.js +290 -0
  337. package/dist/observability/query-performance.js.map +1 -0
  338. package/dist/observability/storage-tier-metrics.d.ts +174 -0
  339. package/dist/observability/storage-tier-metrics.d.ts.map +1 -0
  340. package/dist/observability/storage-tier-metrics.js +306 -0
  341. package/dist/observability/storage-tier-metrics.js.map +1 -0
  342. package/dist/observability/tier-cost-optimizer.d.ts +155 -0
  343. package/dist/observability/tier-cost-optimizer.d.ts.map +1 -0
  344. package/dist/observability/tier-cost-optimizer.js +536 -0
  345. package/dist/observability/tier-cost-optimizer.js.map +1 -0
  346. package/dist/observability/tracer.d.ts +149 -0
  347. package/dist/observability/tracer.d.ts.map +1 -0
  348. package/dist/observability/tracer.js +435 -0
  349. package/dist/observability/tracer.js.map +1 -0
  350. package/dist/observability/types.d.ts +402 -0
  351. package/dist/observability/types.d.ts.map +1 -0
  352. package/dist/observability/types.js +103 -0
  353. package/dist/observability/types.js.map +1 -0
  354. package/dist/pglite/workers-pglite.d.ts +138 -0
  355. package/dist/pglite/workers-pglite.d.ts.map +1 -0
  356. package/dist/pglite/workers-pglite.js +143 -0
  357. package/dist/pglite/workers-pglite.js.map +1 -0
  358. package/dist/pglite-assets/pglite.data +0 -0
  359. package/dist/pglite-assets/pglite.wasm +0 -0
  360. package/dist/playground/index.d.ts +52 -0
  361. package/dist/playground/index.d.ts.map +1 -0
  362. package/dist/playground/index.js +55 -0
  363. package/dist/playground/index.js.map +1 -0
  364. package/dist/playground/keyboard-shortcuts.d.ts +116 -0
  365. package/dist/playground/keyboard-shortcuts.d.ts.map +1 -0
  366. package/dist/playground/keyboard-shortcuts.js +588 -0
  367. package/dist/playground/keyboard-shortcuts.js.map +1 -0
  368. package/dist/playground/playground.d.ts +82 -0
  369. package/dist/playground/playground.d.ts.map +1 -0
  370. package/dist/playground/playground.js +271 -0
  371. package/dist/playground/playground.js.map +1 -0
  372. package/dist/playground/query-executor.d.ts +115 -0
  373. package/dist/playground/query-executor.d.ts.map +1 -0
  374. package/dist/playground/query-executor.js +558 -0
  375. package/dist/playground/query-executor.js.map +1 -0
  376. package/dist/playground/query-history.d.ts +92 -0
  377. package/dist/playground/query-history.d.ts.map +1 -0
  378. package/dist/playground/query-history.js +259 -0
  379. package/dist/playground/query-history.js.map +1 -0
  380. package/dist/playground/result-formatter.d.ts +59 -0
  381. package/dist/playground/result-formatter.d.ts.map +1 -0
  382. package/dist/playground/result-formatter.js +341 -0
  383. package/dist/playground/result-formatter.js.map +1 -0
  384. package/dist/playground/sample-datasets.d.ts +77 -0
  385. package/dist/playground/sample-datasets.d.ts.map +1 -0
  386. package/dist/playground/sample-datasets.js +641 -0
  387. package/dist/playground/sample-datasets.js.map +1 -0
  388. package/dist/playground/sample-queries.d.ts +73 -0
  389. package/dist/playground/sample-queries.d.ts.map +1 -0
  390. package/dist/playground/sample-queries.js +1095 -0
  391. package/dist/playground/sample-queries.js.map +1 -0
  392. package/dist/playground/schema-explorer.d.ts +55 -0
  393. package/dist/playground/schema-explorer.d.ts.map +1 -0
  394. package/dist/playground/schema-explorer.js +473 -0
  395. package/dist/playground/schema-explorer.js.map +1 -0
  396. package/dist/playground/types.d.ts +430 -0
  397. package/dist/playground/types.d.ts.map +1 -0
  398. package/dist/playground/types.js +10 -0
  399. package/dist/playground/types.js.map +1 -0
  400. package/dist/readonly/cache-reader.d.ts +145 -0
  401. package/dist/readonly/cache-reader.d.ts.map +1 -0
  402. package/dist/readonly/cache-reader.js +198 -0
  403. package/dist/readonly/cache-reader.js.map +1 -0
  404. package/dist/readonly/config.d.ts +74 -0
  405. package/dist/readonly/config.d.ts.map +1 -0
  406. package/dist/readonly/config.js +67 -0
  407. package/dist/readonly/config.js.map +1 -0
  408. package/dist/readonly/index.d.ts +22 -0
  409. package/dist/readonly/index.d.ts.map +1 -0
  410. package/dist/readonly/index.js +17 -0
  411. package/dist/readonly/index.js.map +1 -0
  412. package/dist/readonly/pglite-wrapper.d.ts +82 -0
  413. package/dist/readonly/pglite-wrapper.d.ts.map +1 -0
  414. package/dist/readonly/pglite-wrapper.js +123 -0
  415. package/dist/readonly/pglite-wrapper.js.map +1 -0
  416. package/dist/readonly/worker.d.ts +142 -0
  417. package/dist/readonly/worker.d.ts.map +1 -0
  418. package/dist/readonly/worker.js +187 -0
  419. package/dist/readonly/worker.js.map +1 -0
  420. package/dist/readonly/write-blocker.d.ts +47 -0
  421. package/dist/readonly/write-blocker.d.ts.map +1 -0
  422. package/dist/readonly/write-blocker.js +136 -0
  423. package/dist/readonly/write-blocker.js.map +1 -0
  424. package/dist/recovery/disaster-recovery.d.ts +326 -0
  425. package/dist/recovery/disaster-recovery.d.ts.map +1 -0
  426. package/dist/recovery/disaster-recovery.js +799 -0
  427. package/dist/recovery/disaster-recovery.js.map +1 -0
  428. package/dist/recovery/index.d.ts +12 -0
  429. package/dist/recovery/index.d.ts.map +1 -0
  430. package/dist/recovery/index.js +12 -0
  431. package/dist/recovery/index.js.map +1 -0
  432. package/dist/recovery/parquet-parser.d.ts +321 -0
  433. package/dist/recovery/parquet-parser.d.ts.map +1 -0
  434. package/dist/recovery/parquet-parser.js +797 -0
  435. package/dist/recovery/parquet-parser.js.map +1 -0
  436. package/dist/retention/index.d.ts +50 -0
  437. package/dist/retention/index.d.ts.map +1 -0
  438. package/dist/retention/index.js +50 -0
  439. package/dist/retention/index.js.map +1 -0
  440. package/dist/retention/policy.d.ts +344 -0
  441. package/dist/retention/policy.d.ts.map +1 -0
  442. package/dist/retention/policy.js +472 -0
  443. package/dist/retention/policy.js.map +1 -0
  444. package/dist/retention/purger.d.ts +187 -0
  445. package/dist/retention/purger.d.ts.map +1 -0
  446. package/dist/retention/purger.js +411 -0
  447. package/dist/retention/purger.js.map +1 -0
  448. package/dist/rls/auth-integration.d.ts +280 -0
  449. package/dist/rls/auth-integration.d.ts.map +1 -0
  450. package/dist/rls/auth-integration.js +399 -0
  451. package/dist/rls/auth-integration.js.map +1 -0
  452. package/dist/rls/generator.d.ts +249 -0
  453. package/dist/rls/generator.d.ts.map +1 -0
  454. package/dist/rls/generator.js +495 -0
  455. package/dist/rls/generator.js.map +1 -0
  456. package/dist/rls/index.d.ts +26 -0
  457. package/dist/rls/index.d.ts.map +1 -0
  458. package/dist/rls/index.js +58 -0
  459. package/dist/rls/index.js.map +1 -0
  460. package/dist/rls/policy.d.ts +116 -0
  461. package/dist/rls/policy.d.ts.map +1 -0
  462. package/dist/rls/policy.js +77 -0
  463. package/dist/rls/policy.js.map +1 -0
  464. package/dist/rls/validator.d.ts +155 -0
  465. package/dist/rls/validator.d.ts.map +1 -0
  466. package/dist/rls/validator.js +792 -0
  467. package/dist/rls/validator.js.map +1 -0
  468. package/dist/routing/adaptive-router.d.ts +317 -0
  469. package/dist/routing/adaptive-router.d.ts.map +1 -0
  470. package/dist/routing/adaptive-router.js +554 -0
  471. package/dist/routing/adaptive-router.js.map +1 -0
  472. package/dist/routing/circuit-breaker.d.ts +339 -0
  473. package/dist/routing/circuit-breaker.d.ts.map +1 -0
  474. package/dist/routing/circuit-breaker.js +620 -0
  475. package/dist/routing/circuit-breaker.js.map +1 -0
  476. package/dist/routing/cost-metrics.d.ts +133 -0
  477. package/dist/routing/cost-metrics.d.ts.map +1 -0
  478. package/dist/routing/cost-metrics.js +259 -0
  479. package/dist/routing/cost-metrics.js.map +1 -0
  480. package/dist/routing/do-connection-pool.d.ts +243 -0
  481. package/dist/routing/do-connection-pool.d.ts.map +1 -0
  482. package/dist/routing/do-connection-pool.js +572 -0
  483. package/dist/routing/do-connection-pool.js.map +1 -0
  484. package/dist/routing/index.d.ts +59 -0
  485. package/dist/routing/index.d.ts.map +1 -0
  486. package/dist/routing/index.js +59 -0
  487. package/dist/routing/index.js.map +1 -0
  488. package/dist/routing/query-complexity-estimator.d.ts +73 -0
  489. package/dist/routing/query-complexity-estimator.d.ts.map +1 -0
  490. package/dist/routing/query-complexity-estimator.js +327 -0
  491. package/dist/routing/query-complexity-estimator.js.map +1 -0
  492. package/dist/routing/request-coalescing.d.ts +178 -0
  493. package/dist/routing/request-coalescing.d.ts.map +1 -0
  494. package/dist/routing/request-coalescing.js +325 -0
  495. package/dist/routing/request-coalescing.js.map +1 -0
  496. package/dist/routing/runtime-router.d.ts +107 -0
  497. package/dist/routing/runtime-router.d.ts.map +1 -0
  498. package/dist/routing/runtime-router.js +246 -0
  499. package/dist/routing/runtime-router.js.map +1 -0
  500. package/dist/routing/tenant-router.d.ts +848 -0
  501. package/dist/routing/tenant-router.d.ts.map +1 -0
  502. package/dist/routing/tenant-router.js +1056 -0
  503. package/dist/routing/tenant-router.js.map +1 -0
  504. package/dist/routing/websocket-pool.d.ts +119 -0
  505. package/dist/routing/websocket-pool.d.ts.map +1 -0
  506. package/dist/routing/websocket-pool.js +436 -0
  507. package/dist/routing/websocket-pool.js.map +1 -0
  508. package/dist/storage/cache-layer.d.ts +159 -0
  509. package/dist/storage/cache-layer.d.ts.map +1 -0
  510. package/dist/storage/cache-layer.js +245 -0
  511. package/dist/storage/cache-layer.js.map +1 -0
  512. package/dist/storage/cost-aware-tiering.d.ts +258 -0
  513. package/dist/storage/cost-aware-tiering.d.ts.map +1 -0
  514. package/dist/storage/cost-aware-tiering.js +526 -0
  515. package/dist/storage/cost-aware-tiering.js.map +1 -0
  516. package/dist/storage/index.d.ts +87 -0
  517. package/dist/storage/index.d.ts.map +1 -0
  518. package/dist/storage/index.js +78 -0
  519. package/dist/storage/index.js.map +1 -0
  520. package/dist/storage/interfaces.d.ts +856 -0
  521. package/dist/storage/interfaces.d.ts.map +1 -0
  522. package/dist/storage/interfaces.js +69 -0
  523. package/dist/storage/interfaces.js.map +1 -0
  524. package/dist/storage/r2-layer.d.ts +226 -0
  525. package/dist/storage/r2-layer.d.ts.map +1 -0
  526. package/dist/storage/r2-layer.js +307 -0
  527. package/dist/storage/r2-layer.js.map +1 -0
  528. package/dist/storage/r2-overflow.d.ts +344 -0
  529. package/dist/storage/r2-overflow.d.ts.map +1 -0
  530. package/dist/storage/r2-overflow.js +730 -0
  531. package/dist/storage/r2-overflow.js.map +1 -0
  532. package/dist/storage/r2-page-vfs.d.ts +374 -0
  533. package/dist/storage/r2-page-vfs.d.ts.map +1 -0
  534. package/dist/storage/r2-page-vfs.js +754 -0
  535. package/dist/storage/r2-page-vfs.js.map +1 -0
  536. package/dist/storage/swr-cache.d.ts +181 -0
  537. package/dist/storage/swr-cache.d.ts.map +1 -0
  538. package/dist/storage/swr-cache.js +295 -0
  539. package/dist/storage/swr-cache.js.map +1 -0
  540. package/dist/storage/tiered-orchestrator.d.ts +951 -0
  541. package/dist/storage/tiered-orchestrator.d.ts.map +1 -0
  542. package/dist/storage/tiered-orchestrator.js +1731 -0
  543. package/dist/storage/tiered-orchestrator.js.map +1 -0
  544. package/dist/storage/tiered-vfs-swr.d.ts +279 -0
  545. package/dist/storage/tiered-vfs-swr.d.ts.map +1 -0
  546. package/dist/storage/tiered-vfs-swr.js +584 -0
  547. package/dist/storage/tiered-vfs-swr.js.map +1 -0
  548. package/dist/storage/tiered-vfs.d.ts +405 -0
  549. package/dist/storage/tiered-vfs.d.ts.map +1 -0
  550. package/dist/storage/tiered-vfs.js +833 -0
  551. package/dist/storage/tiered-vfs.js.map +1 -0
  552. package/dist/streaming/backpressure-controller.d.ts +173 -0
  553. package/dist/streaming/backpressure-controller.d.ts.map +1 -0
  554. package/dist/streaming/backpressure-controller.js +344 -0
  555. package/dist/streaming/backpressure-controller.js.map +1 -0
  556. package/dist/streaming/buffer-pool.d.ts +241 -0
  557. package/dist/streaming/buffer-pool.d.ts.map +1 -0
  558. package/dist/streaming/buffer-pool.js +381 -0
  559. package/dist/streaming/buffer-pool.js.map +1 -0
  560. package/dist/streaming/cdc-iceberg-connector.d.ts +272 -0
  561. package/dist/streaming/cdc-iceberg-connector.d.ts.map +1 -0
  562. package/dist/streaming/cdc-iceberg-connector.js +408 -0
  563. package/dist/streaming/cdc-iceberg-connector.js.map +1 -0
  564. package/dist/streaming/index.d.ts +111 -0
  565. package/dist/streaming/index.d.ts.map +1 -0
  566. package/dist/streaming/index.js +128 -0
  567. package/dist/streaming/index.js.map +1 -0
  568. package/dist/streaming/live-cdc-stream.d.ts +400 -0
  569. package/dist/streaming/live-cdc-stream.d.ts.map +1 -0
  570. package/dist/streaming/live-cdc-stream.js +703 -0
  571. package/dist/streaming/live-cdc-stream.js.map +1 -0
  572. package/dist/streaming/memory-bounded-stream.d.ts +207 -0
  573. package/dist/streaming/memory-bounded-stream.d.ts.map +1 -0
  574. package/dist/streaming/memory-bounded-stream.js +340 -0
  575. package/dist/streaming/memory-bounded-stream.js.map +1 -0
  576. package/dist/streaming/query-streamer.d.ts +379 -0
  577. package/dist/streaming/query-streamer.d.ts.map +1 -0
  578. package/dist/streaming/query-streamer.js +495 -0
  579. package/dist/streaming/query-streamer.js.map +1 -0
  580. package/dist/streaming/response-streaming.d.ts +203 -0
  581. package/dist/streaming/response-streaming.d.ts.map +1 -0
  582. package/dist/streaming/response-streaming.js +449 -0
  583. package/dist/streaming/response-streaming.js.map +1 -0
  584. package/dist/types/branded.d.ts +859 -0
  585. package/dist/types/branded.d.ts.map +1 -0
  586. package/dist/types/branded.js +891 -0
  587. package/dist/types/branded.js.map +1 -0
  588. package/dist/types/utilities.d.ts +757 -0
  589. package/dist/types/utilities.d.ts.map +1 -0
  590. package/dist/types/utilities.js +447 -0
  591. package/dist/types/utilities.js.map +1 -0
  592. package/dist/wal/replay-engine.d.ts +344 -0
  593. package/dist/wal/replay-engine.d.ts.map +1 -0
  594. package/dist/wal/replay-engine.js +975 -0
  595. package/dist/wal/replay-engine.js.map +1 -0
  596. package/dist/worker/__mocks__/capnweb.d.ts +13 -0
  597. package/dist/worker/__mocks__/capnweb.d.ts.map +1 -0
  598. package/dist/worker/__mocks__/capnweb.js +15 -0
  599. package/dist/worker/__mocks__/capnweb.js.map +1 -0
  600. package/dist/worker/__mocks__/cloudflare-workers.d.ts +31 -0
  601. package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +1 -0
  602. package/dist/worker/__mocks__/cloudflare-workers.js +33 -0
  603. package/dist/worker/__mocks__/cloudflare-workers.js.map +1 -0
  604. package/dist/worker/__mocks__/pglite.data.d.ts +3 -0
  605. package/dist/worker/__mocks__/pglite.data.d.ts.map +1 -0
  606. package/dist/worker/__mocks__/pglite.data.js +20 -0
  607. package/dist/worker/__mocks__/pglite.data.js.map +1 -0
  608. package/dist/worker/__mocks__/pglite.wasm.d.ts +3 -0
  609. package/dist/worker/__mocks__/pglite.wasm.d.ts.map +1 -0
  610. package/dist/worker/__mocks__/pglite.wasm.js +30 -0
  611. package/dist/worker/__mocks__/pglite.wasm.js.map +1 -0
  612. package/dist/worker/auth-rate-limiter.d.ts +270 -0
  613. package/dist/worker/auth-rate-limiter.d.ts.map +1 -0
  614. package/dist/worker/auth-rate-limiter.js +332 -0
  615. package/dist/worker/auth-rate-limiter.js.map +1 -0
  616. package/dist/worker/auth.d.ts +345 -0
  617. package/dist/worker/auth.d.ts.map +1 -0
  618. package/dist/worker/auth.js +837 -0
  619. package/dist/worker/auth.js.map +1 -0
  620. package/dist/worker/cdc-backpressure.d.ts +338 -0
  621. package/dist/worker/cdc-backpressure.d.ts.map +1 -0
  622. package/dist/worker/cdc-backpressure.js +619 -0
  623. package/dist/worker/cdc-backpressure.js.map +1 -0
  624. package/dist/worker/cdc-sse.d.ts +277 -0
  625. package/dist/worker/cdc-sse.d.ts.map +1 -0
  626. package/dist/worker/cdc-sse.js +528 -0
  627. package/dist/worker/cdc-sse.js.map +1 -0
  628. package/dist/worker/cdc-websocket.d.ts +252 -0
  629. package/dist/worker/cdc-websocket.d.ts.map +1 -0
  630. package/dist/worker/cdc-websocket.js +940 -0
  631. package/dist/worker/cdc-websocket.js.map +1 -0
  632. package/dist/worker/cdc.d.ts +95 -0
  633. package/dist/worker/cdc.d.ts.map +1 -0
  634. package/dist/worker/cdc.js +211 -0
  635. package/dist/worker/cdc.js.map +1 -0
  636. package/dist/worker/concerns/auth-concern.d.ts +50 -0
  637. package/dist/worker/concerns/auth-concern.d.ts.map +1 -0
  638. package/dist/worker/concerns/auth-concern.js +131 -0
  639. package/dist/worker/concerns/auth-concern.js.map +1 -0
  640. package/dist/worker/concerns/cdc-concern.d.ts +99 -0
  641. package/dist/worker/concerns/cdc-concern.d.ts.map +1 -0
  642. package/dist/worker/concerns/cdc-concern.js +137 -0
  643. package/dist/worker/concerns/cdc-concern.js.map +1 -0
  644. package/dist/worker/concerns/index.d.ts +22 -0
  645. package/dist/worker/concerns/index.d.ts.map +1 -0
  646. package/dist/worker/concerns/index.js +13 -0
  647. package/dist/worker/concerns/index.js.map +1 -0
  648. package/dist/worker/concerns/query-execution-concern.d.ts +104 -0
  649. package/dist/worker/concerns/query-execution-concern.d.ts.map +1 -0
  650. package/dist/worker/concerns/query-execution-concern.js +95 -0
  651. package/dist/worker/concerns/query-execution-concern.js.map +1 -0
  652. package/dist/worker/concerns/storage-orchestration-concern.d.ts +78 -0
  653. package/dist/worker/concerns/storage-orchestration-concern.d.ts.map +1 -0
  654. package/dist/worker/concerns/storage-orchestration-concern.js +240 -0
  655. package/dist/worker/concerns/storage-orchestration-concern.js.map +1 -0
  656. package/dist/worker/do-auth-manager.d.ts +108 -0
  657. package/dist/worker/do-auth-manager.d.ts.map +1 -0
  658. package/dist/worker/do-auth-manager.js +212 -0
  659. package/dist/worker/do-auth-manager.js.map +1 -0
  660. package/dist/worker/do-pglite-manager.d.ts +137 -0
  661. package/dist/worker/do-pglite-manager.d.ts.map +1 -0
  662. package/dist/worker/do-pglite-manager.js +228 -0
  663. package/dist/worker/do-pglite-manager.js.map +1 -0
  664. package/dist/worker/do.d.ts +556 -0
  665. package/dist/worker/do.d.ts.map +1 -0
  666. package/dist/worker/do.js +1441 -0
  667. package/dist/worker/do.js.map +1 -0
  668. package/dist/worker/entry.d.ts +23 -0
  669. package/dist/worker/entry.d.ts.map +1 -0
  670. package/dist/worker/entry.js +362 -0
  671. package/dist/worker/entry.js.map +1 -0
  672. package/dist/worker/errors.d.ts +106 -0
  673. package/dist/worker/errors.d.ts.map +1 -0
  674. package/dist/worker/errors.js +178 -0
  675. package/dist/worker/errors.js.map +1 -0
  676. package/dist/worker/health-check-manager.d.ts +141 -0
  677. package/dist/worker/health-check-manager.d.ts.map +1 -0
  678. package/dist/worker/health-check-manager.js +145 -0
  679. package/dist/worker/health-check-manager.js.map +1 -0
  680. package/dist/worker/index.d.ts +60 -0
  681. package/dist/worker/index.d.ts.map +1 -0
  682. package/dist/worker/index.js +67 -0
  683. package/dist/worker/index.js.map +1 -0
  684. package/dist/worker/memory-pressure.d.ts +892 -0
  685. package/dist/worker/memory-pressure.d.ts.map +1 -0
  686. package/dist/worker/memory-pressure.js +1990 -0
  687. package/dist/worker/memory-pressure.js.map +1 -0
  688. package/dist/worker/migration-manager.d.ts +153 -0
  689. package/dist/worker/migration-manager.d.ts.map +1 -0
  690. package/dist/worker/migration-manager.js +461 -0
  691. package/dist/worker/migration-manager.js.map +1 -0
  692. package/dist/worker/plugin-manager.d.ts +147 -0
  693. package/dist/worker/plugin-manager.d.ts.map +1 -0
  694. package/dist/worker/plugin-manager.js +408 -0
  695. package/dist/worker/plugin-manager.js.map +1 -0
  696. package/dist/worker/proxy.d.ts +330 -0
  697. package/dist/worker/proxy.d.ts.map +1 -0
  698. package/dist/worker/proxy.js +504 -0
  699. package/dist/worker/proxy.js.map +1 -0
  700. package/dist/worker/query-execution-manager.d.ts +107 -0
  701. package/dist/worker/query-execution-manager.d.ts.map +1 -0
  702. package/dist/worker/query-execution-manager.js +155 -0
  703. package/dist/worker/query-execution-manager.js.map +1 -0
  704. package/dist/worker/query-executor.d.ts +163 -0
  705. package/dist/worker/query-executor.d.ts.map +1 -0
  706. package/dist/worker/query-executor.js +413 -0
  707. package/dist/worker/query-executor.js.map +1 -0
  708. package/dist/worker/query-stats-manager.d.ts +117 -0
  709. package/dist/worker/query-stats-manager.d.ts.map +1 -0
  710. package/dist/worker/query-stats-manager.js +162 -0
  711. package/dist/worker/query-stats-manager.js.map +1 -0
  712. package/dist/worker/result-handler.d.ts +192 -0
  713. package/dist/worker/result-handler.d.ts.map +1 -0
  714. package/dist/worker/result-handler.js +346 -0
  715. package/dist/worker/result-handler.js.map +1 -0
  716. package/dist/worker/routes.d.ts +135 -0
  717. package/dist/worker/routes.d.ts.map +1 -0
  718. package/dist/worker/routes.js +460 -0
  719. package/dist/worker/routes.js.map +1 -0
  720. package/dist/worker/rpc-methods-manager.d.ts +142 -0
  721. package/dist/worker/rpc-methods-manager.d.ts.map +1 -0
  722. package/dist/worker/rpc-methods-manager.js +195 -0
  723. package/dist/worker/rpc-methods-manager.js.map +1 -0
  724. package/dist/worker/rpc.d.ts +259 -0
  725. package/dist/worker/rpc.d.ts.map +1 -0
  726. package/dist/worker/rpc.js +398 -0
  727. package/dist/worker/rpc.js.map +1 -0
  728. package/dist/worker/schema-version.d.ts +209 -0
  729. package/dist/worker/schema-version.d.ts.map +1 -0
  730. package/dist/worker/schema-version.js +450 -0
  731. package/dist/worker/schema-version.js.map +1 -0
  732. package/dist/worker/session-manager.d.ts +282 -0
  733. package/dist/worker/session-manager.d.ts.map +1 -0
  734. package/dist/worker/session-manager.js +523 -0
  735. package/dist/worker/session-manager.js.map +1 -0
  736. package/dist/worker/shutdown-manager.d.ts +188 -0
  737. package/dist/worker/shutdown-manager.d.ts.map +1 -0
  738. package/dist/worker/shutdown-manager.js +347 -0
  739. package/dist/worker/shutdown-manager.js.map +1 -0
  740. package/dist/worker/sql-transform.d.ts +61 -0
  741. package/dist/worker/sql-transform.d.ts.map +1 -0
  742. package/dist/worker/sql-transform.js +312 -0
  743. package/dist/worker/sql-transform.js.map +1 -0
  744. package/dist/worker/types.d.ts +738 -0
  745. package/dist/worker/types.d.ts.map +1 -0
  746. package/dist/worker/types.js +6 -0
  747. package/dist/worker/types.js.map +1 -0
  748. package/dist/worker/user-routes.d.ts +76 -0
  749. package/dist/worker/user-routes.d.ts.map +1 -0
  750. package/dist/worker/user-routes.js +188 -0
  751. package/dist/worker/user-routes.js.map +1 -0
  752. package/dist/worker/wal-facade.d.ts +138 -0
  753. package/dist/worker/wal-facade.d.ts.map +1 -0
  754. package/dist/worker/wal-facade.js +184 -0
  755. package/dist/worker/wal-facade.js.map +1 -0
  756. package/dist/worker/wal-r2.d.ts +271 -0
  757. package/dist/worker/wal-r2.d.ts.map +1 -0
  758. package/dist/worker/wal-r2.js +689 -0
  759. package/dist/worker/wal-r2.js.map +1 -0
  760. package/dist/worker/wal-replay.d.ts +361 -0
  761. package/dist/worker/wal-replay.d.ts.map +1 -0
  762. package/dist/worker/wal-replay.js +628 -0
  763. package/dist/worker/wal-replay.js.map +1 -0
  764. package/dist/worker/wal-retention.d.ts +389 -0
  765. package/dist/worker/wal-retention.d.ts.map +1 -0
  766. package/dist/worker/wal-retention.js +763 -0
  767. package/dist/worker/wal-retention.js.map +1 -0
  768. package/dist/worker/wal.d.ts +278 -0
  769. package/dist/worker/wal.d.ts.map +1 -0
  770. package/dist/worker/wal.js +467 -0
  771. package/dist/worker/wal.js.map +1 -0
  772. package/dist/worker/websocket.d.ts +85 -0
  773. package/dist/worker/websocket.d.ts.map +1 -0
  774. package/dist/worker/websocket.js +227 -0
  775. package/dist/worker/websocket.js.map +1 -0
  776. package/package.json +108 -0
  777. package/src/cdc/change-stream.ts +137 -0
  778. package/src/cdc/filter.ts +646 -0
  779. package/src/cdc/index.ts +112 -0
  780. package/src/cdc/resume-token.ts +280 -0
  781. package/src/cdc/transport/index.ts +7 -0
  782. package/src/cdc/transport/sse.ts +723 -0
  783. package/src/cdc/transport/websocket.ts +873 -0
  784. package/src/cdc/types.ts +346 -0
  785. package/src/config/index.ts +25 -0
  786. package/src/config/memory.ts +177 -0
  787. package/src/config/storage.ts +204 -0
  788. package/src/config/streaming.ts +147 -0
  789. package/src/config/timeouts.ts +221 -0
  790. package/src/extensions/config.test.ts +187 -0
  791. package/src/extensions/config.ts +278 -0
  792. package/src/extensions/geo.test.ts +455 -0
  793. package/src/extensions/geo.ts +858 -0
  794. package/src/extensions/index.test.ts +259 -0
  795. package/src/extensions/index.ts +227 -0
  796. package/src/extensions/loader.test.ts +555 -0
  797. package/src/extensions/loader.ts +588 -0
  798. package/src/extensions/pgmq-lite.test.ts +727 -0
  799. package/src/extensions/pgmq-lite.ts +770 -0
  800. package/src/extensions/plugins.test.ts +528 -0
  801. package/src/extensions/plugins.ts +718 -0
  802. package/src/extensions/registry.test.ts +202 -0
  803. package/src/extensions/registry.ts +267 -0
  804. package/src/extensions/vector.test.ts +195 -0
  805. package/src/extensions/vector.ts +217 -0
  806. package/src/iceberg/SCHEDULER.md +580 -0
  807. package/src/iceberg/analytics.test.ts +703 -0
  808. package/src/iceberg/analytics.ts +727 -0
  809. package/src/iceberg/catalog-api.test.ts +838 -0
  810. package/src/iceberg/catalog-api.ts +520 -0
  811. package/src/iceberg/catalog.test.ts +680 -0
  812. package/src/iceberg/catalog.ts +1007 -0
  813. package/src/iceberg/iceberg.test.ts +705 -0
  814. package/src/iceberg/index.ts +406 -0
  815. package/src/iceberg/metadata.test.ts +632 -0
  816. package/src/iceberg/metadata.ts +649 -0
  817. package/src/iceberg/optimizer.test.ts +868 -0
  818. package/src/iceberg/optimizer.ts +1287 -0
  819. package/src/iceberg/parquet.test.ts +899 -0
  820. package/src/iceberg/parquet.ts +1640 -0
  821. package/src/iceberg/r2-organization.test.ts +615 -0
  822. package/src/iceberg/r2-organization.ts +951 -0
  823. package/src/iceberg/scheduler-do-example.ts +364 -0
  824. package/src/iceberg/scheduler.test.ts +861 -0
  825. package/src/iceberg/scheduler.ts +1201 -0
  826. package/src/iceberg/schema.test.ts +547 -0
  827. package/src/iceberg/schema.ts +616 -0
  828. package/src/iceberg/snapshot-manager.test.ts +919 -0
  829. package/src/iceberg/snapshot-manager.ts +1369 -0
  830. package/src/iceberg/sql-router.test.ts +334 -0
  831. package/src/iceberg/sql-router.ts +337 -0
  832. package/src/iceberg/test-fixtures.ts +605 -0
  833. package/src/iceberg/time-travel-api.test.ts +1029 -0
  834. package/src/iceberg/time-travel-api.ts +731 -0
  835. package/src/iceberg/time-travel.test.ts +1218 -0
  836. package/src/iceberg/time-travel.ts +1052 -0
  837. package/src/iceberg/transformer.test.ts +689 -0
  838. package/src/iceberg/transformer.ts +1029 -0
  839. package/src/iceberg/types.ts +373 -0
  840. package/src/iceberg/writer.test.ts +716 -0
  841. package/src/iceberg/writer.ts +590 -0
  842. package/src/index.ts +212 -0
  843. package/src/lineage/index.ts +42 -0
  844. package/src/lineage/integration.ts +334 -0
  845. package/src/lineage/tracker.ts +1618 -0
  846. package/src/lineage/types.ts +354 -0
  847. package/src/middleware/index.ts +36 -0
  848. package/src/middleware/rate-limit-concurrent.test.ts +794 -0
  849. package/src/middleware/rate-limit.test.ts +1568 -0
  850. package/src/middleware/rate-limit.ts +840 -0
  851. package/src/migration-tooling/external-migration.test.ts +1864 -0
  852. package/src/migration-tooling/external-migration.ts +2355 -0
  853. package/src/migration-tooling/index.ts +19 -0
  854. package/src/migrations/ARCHITECTURE.md +474 -0
  855. package/src/migrations/PROGRESS_TRACKING.md +485 -0
  856. package/src/migrations/auto-migrator.test.ts +732 -0
  857. package/src/migrations/auto-migrator.ts +531 -0
  858. package/src/migrations/bulk-orchestrator.test.ts +801 -0
  859. package/src/migrations/bulk-orchestrator.ts +1039 -0
  860. package/src/migrations/compatibility.test.ts +958 -0
  861. package/src/migrations/compatibility.ts +902 -0
  862. package/src/migrations/do-migrations.test.ts +2620 -0
  863. package/src/migrations/do-migrations.ts +1289 -0
  864. package/src/migrations/do-migrations.types.ts +715 -0
  865. package/src/migrations/drizzle-compat.test.ts +210 -0
  866. package/src/migrations/drizzle-compat.ts +337 -0
  867. package/src/migrations/index.ts +334 -0
  868. package/src/migrations/migration-api.test.ts +438 -0
  869. package/src/migrations/migration-api.ts +704 -0
  870. package/src/migrations/progress-tracker-do.ts +518 -0
  871. package/src/migrations/progress-tracker-kv.ts +305 -0
  872. package/src/migrations/progress-tracker.test.ts +937 -0
  873. package/src/migrations/progress-tracker.ts +665 -0
  874. package/src/migrations/registry.test.ts +331 -0
  875. package/src/migrations/registry.ts +468 -0
  876. package/src/migrations/rollback.test.ts +644 -0
  877. package/src/migrations/runner.test.ts +807 -0
  878. package/src/migrations/runner.test.ts.backup +759 -0
  879. package/src/migrations/runner.ts +1459 -0
  880. package/src/migrations/schema-generator.test.ts +649 -0
  881. package/src/migrations/schema-generator.ts +513 -0
  882. package/src/migrations/testing.ts +1037 -0
  883. package/src/migrations/types.ts +573 -0
  884. package/src/migrations/validator.test.ts +660 -0
  885. package/src/migrations/validator.ts +741 -0
  886. package/src/observability/alerting.test.ts +1133 -0
  887. package/src/observability/alerting.ts +455 -0
  888. package/src/observability/analytics-engine.ts +733 -0
  889. package/src/observability/cost-metrics.ts +804 -0
  890. package/src/observability/cross-do-tracing.test.ts +516 -0
  891. package/src/observability/cross-do-tracing.ts +588 -0
  892. package/src/observability/dashboards/postgres-do-overview.json +1656 -0
  893. package/src/observability/error-rate-collector.test.ts +977 -0
  894. package/src/observability/error-rate-collector.ts +518 -0
  895. package/src/observability/exporters.test.ts +365 -0
  896. package/src/observability/exporters.ts +650 -0
  897. package/src/observability/health-check.test.ts +353 -0
  898. package/src/observability/health-check.ts +341 -0
  899. package/src/observability/index.test.ts +298 -0
  900. package/src/observability/index.ts +885 -0
  901. package/src/observability/instrumentation.test.ts +428 -0
  902. package/src/observability/instrumentation.ts +788 -0
  903. package/src/observability/memory-metrics.test.ts +355 -0
  904. package/src/observability/memory-metrics.ts +990 -0
  905. package/src/observability/metrics-endpoint.test.ts +402 -0
  906. package/src/observability/metrics-endpoint.ts +374 -0
  907. package/src/observability/metrics.test.ts +291 -0
  908. package/src/observability/metrics.ts +315 -0
  909. package/src/observability/observability-features.ts +1296 -0
  910. package/src/observability/prometheus.test.ts +292 -0
  911. package/src/observability/prometheus.ts +170 -0
  912. package/src/observability/propagation.test.ts +417 -0
  913. package/src/observability/propagation.ts +294 -0
  914. package/src/observability/query-latency.ts +586 -0
  915. package/src/observability/query-performance.test.ts +406 -0
  916. package/src/observability/query-performance.ts +491 -0
  917. package/src/observability/storage-tier-metrics.test.ts +633 -0
  918. package/src/observability/storage-tier-metrics.ts +570 -0
  919. package/src/observability/tier-cost-optimizer.ts +740 -0
  920. package/src/observability/tracer.test.ts +346 -0
  921. package/src/observability/tracer.ts +585 -0
  922. package/src/observability/types.test.ts +726 -0
  923. package/src/observability/types.ts +434 -0
  924. package/src/pglite/auto-demotion.test.ts +477 -0
  925. package/src/pglite/auto-demotion.ts +385 -0
  926. package/src/pglite/auto-promotion.test.ts +824 -0
  927. package/src/pglite/auto-promotion.ts +547 -0
  928. package/src/pglite/cache-layer.test.ts +469 -0
  929. package/src/pglite/cache-layer.ts +271 -0
  930. package/src/pglite/cold-start-manager.ts +1260 -0
  931. package/src/pglite/cold-start-optimizer.test.ts +937 -0
  932. package/src/pglite/cold-start-optimizer.ts +1895 -0
  933. package/src/pglite/dovfs-adapter.ts +1122 -0
  934. package/src/pglite/dovfs.ts +1258 -0
  935. package/src/pglite/etag-cache.test.ts +844 -0
  936. package/src/pglite/etag-cache.ts +526 -0
  937. package/src/pglite/index.ts +442 -0
  938. package/src/pglite/init.test.ts +455 -0
  939. package/src/pglite/init.ts +574 -0
  940. package/src/pglite/lifecycle.test.ts +599 -0
  941. package/src/pglite/lifecycle.ts +704 -0
  942. package/src/pglite/parallel-loader.test.ts +586 -0
  943. package/src/pglite/parallel-loader.ts +481 -0
  944. package/src/pglite/production-pglite.test.ts +666 -0
  945. package/src/pglite/production-pglite.ts +537 -0
  946. package/src/pglite/query-executor.ts +614 -0
  947. package/src/pglite/r2-layer.test.ts +501 -0
  948. package/src/pglite/r2-layer.ts +322 -0
  949. package/src/pglite/tiered-init.test.ts +725 -0
  950. package/src/pglite/tiered-init.ts +556 -0
  951. package/src/pglite/tiered-vfs.test.ts +726 -0
  952. package/src/pglite/tiered-vfs.ts +33 -0
  953. package/src/pglite/tiering-stats.test.ts +531 -0
  954. package/src/pglite/tiering-stats.ts +407 -0
  955. package/src/pglite/transaction-hooks.ts +343 -0
  956. package/src/pglite/warm-loader.test.ts +1701 -0
  957. package/src/pglite/warm-loader.ts +528 -0
  958. package/src/pglite/workers-pglite.ts +224 -0
  959. package/src/pglite-assets/pglite.data +0 -0
  960. package/src/pglite-assets/pglite.wasm +0 -0
  961. package/src/pglite.d.ts +47 -0
  962. package/src/playground/index.ts +137 -0
  963. package/src/playground/keyboard-shortcuts.ts +677 -0
  964. package/src/playground/playground.ts +323 -0
  965. package/src/playground/query-executor.ts +669 -0
  966. package/src/playground/query-history.ts +328 -0
  967. package/src/playground/result-formatter.ts +420 -0
  968. package/src/playground/sample-datasets.ts +674 -0
  969. package/src/playground/sample-queries.ts +1168 -0
  970. package/src/playground/schema-explorer.ts +558 -0
  971. package/src/playground/types.ts +518 -0
  972. package/src/readonly/cache-reader.test.ts +460 -0
  973. package/src/readonly/cache-reader.ts +313 -0
  974. package/src/readonly/config.test.ts +187 -0
  975. package/src/readonly/config.ts +128 -0
  976. package/src/readonly/index.ts +50 -0
  977. package/src/readonly/pglite-wrapper.test.ts +278 -0
  978. package/src/readonly/pglite-wrapper.ts +184 -0
  979. package/src/readonly/worker.test.ts +533 -0
  980. package/src/readonly/worker.ts +341 -0
  981. package/src/readonly/write-blocker.test.ts +459 -0
  982. package/src/readonly/write-blocker.ts +175 -0
  983. package/src/recovery/disaster-recovery.test.ts +618 -0
  984. package/src/recovery/disaster-recovery.ts +1181 -0
  985. package/src/recovery/index.ts +43 -0
  986. package/src/recovery/parquet-parser.ts +974 -0
  987. package/src/retention/index.ts +74 -0
  988. package/src/retention/policy.test.ts +571 -0
  989. package/src/retention/policy.ts +774 -0
  990. package/src/retention/purger.test.ts +465 -0
  991. package/src/retention/purger.ts +558 -0
  992. package/src/rls/auth-integration.test.ts +752 -0
  993. package/src/rls/auth-integration.ts +533 -0
  994. package/src/rls/generator.test.ts +829 -0
  995. package/src/rls/generator.ts +573 -0
  996. package/src/rls/index.ts +128 -0
  997. package/src/rls/policy.ts +208 -0
  998. package/src/rls/rls.test.ts +1071 -0
  999. package/src/rls/validator.test.ts +930 -0
  1000. package/src/rls/validator.ts +895 -0
  1001. package/src/routing/adaptive-router.test.ts +884 -0
  1002. package/src/routing/adaptive-router.ts +845 -0
  1003. package/src/routing/circuit-breaker.test.ts +1505 -0
  1004. package/src/routing/circuit-breaker.ts +852 -0
  1005. package/src/routing/cost-metrics.test.ts +565 -0
  1006. package/src/routing/cost-metrics.ts +408 -0
  1007. package/src/routing/do-connection-pool.test.ts +1109 -0
  1008. package/src/routing/do-connection-pool.ts +828 -0
  1009. package/src/routing/index.ts +158 -0
  1010. package/src/routing/query-complexity-estimator.test.ts +356 -0
  1011. package/src/routing/query-complexity-estimator.ts +444 -0
  1012. package/src/routing/request-coalescing.test.ts +738 -0
  1013. package/src/routing/request-coalescing.ts +475 -0
  1014. package/src/routing/runtime-router.test.ts +436 -0
  1015. package/src/routing/runtime-router.ts +357 -0
  1016. package/src/routing/tenant-router.test.ts +2493 -0
  1017. package/src/routing/tenant-router.ts +1908 -0
  1018. package/src/routing/websocket-pool.test.ts +551 -0
  1019. package/src/routing/websocket-pool.ts +577 -0
  1020. package/src/storage/access-pattern-tracker.test.ts +874 -0
  1021. package/src/storage/cache-layer.test.ts +560 -0
  1022. package/src/storage/cache-layer.ts +328 -0
  1023. package/src/storage/cost-aware-tiering.test.ts +652 -0
  1024. package/src/storage/cost-aware-tiering.ts +794 -0
  1025. package/src/storage/do-sqlite-blobs.test.ts +937 -0
  1026. package/src/storage/index.ts +272 -0
  1027. package/src/storage/interfaces.ts +974 -0
  1028. package/src/storage/r2-layer.test.ts +653 -0
  1029. package/src/storage/r2-layer.ts +434 -0
  1030. package/src/storage/r2-overflow.ts +920 -0
  1031. package/src/storage/r2-page-vfs.test.ts +2348 -0
  1032. package/src/storage/r2-page-vfs.ts +1054 -0
  1033. package/src/storage/swr-cache.test.ts +832 -0
  1034. package/src/storage/swr-cache.ts +398 -0
  1035. package/src/storage/swr-tiered-integration.test.ts +617 -0
  1036. package/src/storage/tiered-orchestrator.test.ts +2441 -0
  1037. package/src/storage/tiered-orchestrator.ts +2081 -0
  1038. package/src/storage/tiered-vfs-swr.test.ts +736 -0
  1039. package/src/storage/tiered-vfs-swr.ts +735 -0
  1040. package/src/storage/tiered-vfs.test.ts +793 -0
  1041. package/src/storage/tiered-vfs.ts +1082 -0
  1042. package/src/streaming/backpressure-controller.ts +452 -0
  1043. package/src/streaming/buffer-pool.ts +484 -0
  1044. package/src/streaming/cdc-iceberg-connector.ts +605 -0
  1045. package/src/streaming/index.ts +225 -0
  1046. package/src/streaming/live-cdc-stream.ts +985 -0
  1047. package/src/streaming/memory-bounded-stream.ts +443 -0
  1048. package/src/streaming/query-streamer.ts +662 -0
  1049. package/src/streaming/response-streaming.ts +557 -0
  1050. package/src/types/branded.ts +1075 -0
  1051. package/src/types/branded.ts.backup +273 -0
  1052. package/src/types/utilities.ts +1023 -0
  1053. package/src/types/wasm.d.ts +30 -0
  1054. package/src/validation/typed-errors.test.ts +420 -0
  1055. package/src/wal/replay-engine.ts +1264 -0
  1056. package/src/worker/__mocks__/capnweb.ts +15 -0
  1057. package/src/worker/__mocks__/pglite.data.ts +22 -0
  1058. package/src/worker/__mocks__/pglite.wasm.ts +33 -0
  1059. package/src/worker/auth-rate-limiter.test.ts +272 -0
  1060. package/src/worker/auth-rate-limiter.ts +448 -0
  1061. package/src/worker/auth.security-red.test.ts +1236 -0
  1062. package/src/worker/auth.security.test.ts +822 -0
  1063. package/src/worker/auth.test.ts +469 -0
  1064. package/src/worker/auth.ts +1104 -0
  1065. package/src/worker/cdc-backpressure.test.ts +726 -0
  1066. package/src/worker/cdc-backpressure.ts +866 -0
  1067. package/src/worker/cdc-sse.test.ts +780 -0
  1068. package/src/worker/cdc-sse.ts +728 -0
  1069. package/src/worker/cdc-websocket.ts +1229 -0
  1070. package/src/worker/cdc-ws.test.ts +1009 -0
  1071. package/src/worker/cdc.test.ts +327 -0
  1072. package/src/worker/cdc.ts +289 -0
  1073. package/src/worker/concerns/auth-concern.ts +179 -0
  1074. package/src/worker/concerns/cdc-concern.ts +247 -0
  1075. package/src/worker/concerns/index.ts +58 -0
  1076. package/src/worker/concerns/query-execution-concern.ts +194 -0
  1077. package/src/worker/concerns/storage-orchestration-concern.ts +373 -0
  1078. package/src/worker/discriminated-types.test.ts +280 -0
  1079. package/src/worker/do-auth-manager.ts +257 -0
  1080. package/src/worker/do-decomposition.test.ts +1236 -0
  1081. package/src/worker/do-pglite-manager.ts +302 -0
  1082. package/src/worker/do.test.ts +2254 -0
  1083. package/src/worker/do.ts +1878 -0
  1084. package/src/worker/entry.ts +417 -0
  1085. package/src/worker/errors.ts +285 -0
  1086. package/src/worker/health-check-manager.test.ts +261 -0
  1087. package/src/worker/health-check-manager.ts +231 -0
  1088. package/src/worker/index.ts +389 -0
  1089. package/src/worker/memory-pressure.test.ts +1460 -0
  1090. package/src/worker/memory-pressure.ts +2650 -0
  1091. package/src/worker/migration-manager.ts +582 -0
  1092. package/src/worker/neon-compat.test.ts +332 -0
  1093. package/src/worker/plugin-manager.ts +485 -0
  1094. package/src/worker/postgres.do-rpc.d.ts +76 -0
  1095. package/src/worker/proxy.ts +694 -0
  1096. package/src/worker/query-execution-manager.test.ts +303 -0
  1097. package/src/worker/query-execution-manager.ts +219 -0
  1098. package/src/worker/query-executor.test.ts +282 -0
  1099. package/src/worker/query-executor.ts +560 -0
  1100. package/src/worker/query-stats-manager.ts +229 -0
  1101. package/src/worker/result-handler.test.ts +364 -0
  1102. package/src/worker/result-handler.ts +510 -0
  1103. package/src/worker/routes.test.ts +795 -0
  1104. package/src/worker/routes.ts +650 -0
  1105. package/src/worker/rpc-methods-manager.test.ts +326 -0
  1106. package/src/worker/rpc-methods-manager.ts +276 -0
  1107. package/src/worker/rpc.ts +524 -0
  1108. package/src/worker/schema-version.ts +605 -0
  1109. package/src/worker/session-manager.test.ts +506 -0
  1110. package/src/worker/session-manager.ts +732 -0
  1111. package/src/worker/shutdown-manager.ts +469 -0
  1112. package/src/worker/sql-transform.test.ts +286 -0
  1113. package/src/worker/sql-transform.ts +368 -0
  1114. package/src/worker/supabase-compat.test.ts +621 -0
  1115. package/src/worker/types.test.ts +292 -0
  1116. package/src/worker/types.ts +873 -0
  1117. package/src/worker/user-routes.test.ts +703 -0
  1118. package/src/worker/user-routes.ts +303 -0
  1119. package/src/worker/wal-facade.ts +235 -0
  1120. package/src/worker/wal-r2.test.ts +570 -0
  1121. package/src/worker/wal-r2.ts +930 -0
  1122. package/src/worker/wal-replay.test.ts +845 -0
  1123. package/src/worker/wal-replay.ts +897 -0
  1124. package/src/worker/wal-retention.test.ts +758 -0
  1125. package/src/worker/wal-retention.ts +1075 -0
  1126. package/src/worker/wal.test.ts +618 -0
  1127. package/src/worker/wal.ts +697 -0
  1128. package/src/worker/websocket.test.ts +296 -0
  1129. package/src/worker/websocket.ts +284 -0
@@ -0,0 +1,1895 @@
1
+ /**
2
+ * Cold Start Optimizer for PGLite in Cloudflare Workers
3
+ *
4
+ * This module provides optimized initialization strategies for PGLite instances
5
+ * running in Cloudflare Workers' Durable Objects environment, where cold starts
6
+ * can significantly impact user experience.
7
+ *
8
+ * ## Overview
9
+ *
10
+ * Cloudflare Workers have ephemeral execution contexts that can be evicted at any
11
+ * time. When a new request arrives after eviction, a "cold start" occurs requiring
12
+ * full re-initialization of PGLite. This module implements several strategies to
13
+ * minimize cold start latency:
14
+ *
15
+ * ### Optimization Strategies
16
+ *
17
+ * 1. **WASM Caching** - Module-level singleton caching allows warm starts within
18
+ * the same isolate by reusing already-initialized PGLite instances.
19
+ *
20
+ * 2. **Parallel Data Fetching** - While WASM prepares (near-instant for pre-compiled
21
+ * modules), data is fetched from storage tiers in parallel:
22
+ * - HOT tier: Synchronous DO SQLite (fastest)
23
+ * - WARM tier: Cloudflare Cache API (FREE!)
24
+ * - COLD tier: R2 object storage (durable)
25
+ *
26
+ * 3. **Lazy Initialization** - PGLite initialization is deferred until the first
27
+ * query, allowing the DO to respond quickly to health checks and metadata requests.
28
+ *
29
+ * 4. **Memory Optimization** - Buffer pooling reduces allocation overhead and helps
30
+ * stay within Workers' 128MB memory limit.
31
+ *
32
+ * 5. **Pre-warming** - After initialization, common queries are executed to warm
33
+ * PostgreSQL's query planner cache.
34
+ *
35
+ * ## Performance Targets
36
+ *
37
+ * | Metric | p50 Target | p95 Target | Notes |
38
+ * |--------|------------|------------|-------|
39
+ * | WASM module loading | < 300ms | < 500ms | Near-zero for pre-compiled static imports |
40
+ * | PGLite initialization | < 500ms | < 800ms | Includes filesystem setup |
41
+ * | First query latency | < 20ms | < 50ms | After prewarm queries |
42
+ * | **Total cold start** | **< 800ms** | **< 1500ms** | End-to-end including prewarm |
43
+ *
44
+ * ## Architecture
45
+ *
46
+ * ```
47
+ * ┌─────────────────────────────────────────────────────────────────┐
48
+ * │ Cold Start Optimizer │
49
+ * ├─────────────────────────────────────────────────────────────────┤
50
+ * │ │
51
+ * │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
52
+ * │ │ WASM Cache │ │ Parallel │ │ Lazy Init │ │
53
+ * │ │ (Isolate) │────│ Data Fetch │────│ Pattern │ │
54
+ * │ └─────────────┘ └─────────────┘ └─────────────┘ │
55
+ * │ │ │ │ │
56
+ * │ ▼ ▼ ▼ │
57
+ * │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
58
+ * │ │ Warm Start │ │ HOT/WARM/ │ │ First Query │ │
59
+ * │ │ Detection │ │ COLD Tiers │ │ Trigger │ │
60
+ * │ └─────────────┘ └─────────────┘ └─────────────┘ │
61
+ * │ │
62
+ * │ ┌─────────────┐ │
63
+ * │ │ Buffer Pool │ │
64
+ * │ │ (Memory) │ │
65
+ * │ └─────────────┘ │
66
+ * └─────────────────────────────────────────────────────────────────┘
67
+ * ```
68
+ *
69
+ * ## Usage
70
+ *
71
+ * ```typescript
72
+ * import pgliteWasm from './pglite.wasm'
73
+ * import { createColdStartOptimizer } from '@dotdo/postgres/pglite'
74
+ *
75
+ * // Create optimizer with tiered storage
76
+ * const optimizer = createColdStartOptimizer({
77
+ * wasmModule: pgliteWasm,
78
+ * cacheLayer: myCacheLayer,
79
+ * warmCacheKey: `db:${databaseId}`,
80
+ * r2Layer: myR2Layer,
81
+ * coldStorageKey: `databases/${databaseId}/data.tar`,
82
+ * lazy: true,
83
+ * prewarm: true,
84
+ * })
85
+ *
86
+ * // First query triggers initialization
87
+ * const result = await optimizer.query('SELECT * FROM users')
88
+ *
89
+ * // Check performance metrics
90
+ * const metrics = optimizer.getMetrics()
91
+ * console.log(`Cold start: ${metrics?.totalMs}ms from ${metrics?.dataSource}`)
92
+ * ```
93
+ *
94
+ * @module pglite/cold-start-optimizer
95
+ * @see {@link ColdStartManager} for DO lifecycle integration
96
+ * @see {@link TieredVFS} for the underlying storage system
97
+ * @issue postgres-w6l6
98
+ */
99
+
100
+ import type { PGlite, PGliteOptions } from '@dotdo/pglite'
101
+ import type { CacheLayer } from './cache-layer'
102
+ import type { R2StorageLayer } from './r2-layer'
103
+
104
+ // ============================================================================
105
+ // Types
106
+ // ============================================================================
107
+
108
+ /**
109
+ * Cold start initialization phases
110
+ *
111
+ * The optimizer progresses through these phases during initialization:
112
+ *
113
+ * ```
114
+ * not_started → wasm_loading → parallel_loading → pglite_init → ready
115
+ * ↓
116
+ * error
117
+ * ```
118
+ *
119
+ * - `not_started`: Initial state, no initialization attempted
120
+ * - `wasm_loading`: Preparing WASM module (near-instant for pre-compiled)
121
+ * - `data_fetching`: Fetching data from a single tier (deprecated, use parallel_loading)
122
+ * - `parallel_loading`: Fetching data from HOT/WARM/COLD tiers in parallel
123
+ * - `pglite_init`: Creating PGLite instance and running prewarm queries
124
+ * - `ready`: Initialization complete, ready for queries
125
+ * - `error`: Initialization failed
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * optimizer.onPhaseChange((phase, metrics) => {
130
+ * console.log(`Phase: ${phase}, elapsed: ${metrics.totalMs}ms`)
131
+ * })
132
+ * ```
133
+ */
134
+ export type ColdStartPhase =
135
+ | 'not_started'
136
+ | 'wasm_loading'
137
+ | 'data_fetching'
138
+ | 'parallel_loading'
139
+ | 'pglite_init'
140
+ | 'ready'
141
+ | 'error'
142
+
143
+ /**
144
+ * Detailed phase timing breakdown for profiling
145
+ */
146
+ export interface PhaseTimingBreakdown {
147
+ /** Phase name */
148
+ phase: ColdStartPhase
149
+ /** Start timestamp (high-resolution) */
150
+ startTime: number
151
+ /** End timestamp (high-resolution) */
152
+ endTime: number
153
+ /** Duration in milliseconds */
154
+ durationMs: number
155
+ /** Any sub-phase timings */
156
+ subPhases?: Array<{
157
+ name: string
158
+ startTime: number
159
+ endTime: number
160
+ durationMs: number
161
+ }>
162
+ }
163
+
164
+ /**
165
+ * WASM loading strategy comparison metrics
166
+ */
167
+ export interface WasmStrategyMetrics {
168
+ /** Strategy name */
169
+ strategy: 'static_import' | 'dynamic_import' | 'streaming' | 'cached'
170
+ /** Time to obtain the WASM module */
171
+ moduleLoadMs: number
172
+ /** Time to instantiate the module */
173
+ instantiateMs: number
174
+ /** Total WASM preparation time */
175
+ totalMs: number
176
+ /** Whether the module was from cache */
177
+ fromCache: boolean
178
+ /** Module size in bytes (if known) */
179
+ moduleSizeBytes?: number
180
+ }
181
+
182
+ /**
183
+ * Detailed timing metrics for cold start optimization
184
+ *
185
+ * These metrics provide comprehensive visibility into cold start performance,
186
+ * enabling identification of bottlenecks and performance regression detection.
187
+ *
188
+ * ## Key Metrics
189
+ *
190
+ * | Metric | Description | Target |
191
+ * |--------|-------------|--------|
192
+ * | `totalMs` | End-to-end cold start time | < 1500ms (p95) |
193
+ * | `wasmPrepMs` | WASM module preparation | < 10ms (pre-compiled) |
194
+ * | `dataFetchMs` | Data fetch from storage tier | < 500ms (p95) |
195
+ * | `pgliteInitMs` | PGLite instance creation | < 800ms (p95) |
196
+ * | `firstQueryMs` | Prewarm query execution | < 50ms (p95) |
197
+ *
198
+ * ## Interpreting Results
199
+ *
200
+ * - High `dataFetchMs` → Consider promoting data to a faster tier
201
+ * - High `pgliteInitMs` → Consider using the tiny PGLite variant
202
+ * - `isWarmStart: true` → Instance was reused from cache (best case)
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * const metrics = optimizer.getMetrics()
207
+ * if (metrics) {
208
+ * console.log(`Total: ${metrics.totalMs}ms`)
209
+ * console.log(`Source: ${metrics.dataSource}`)
210
+ * console.log(`Warm start: ${metrics.isWarmStart}`)
211
+ * console.log(`Data size: ${metrics.dataSizeBytes} bytes`)
212
+ * }
213
+ * ```
214
+ */
215
+ export interface ColdStartMetrics {
216
+ /** Total cold start time in milliseconds */
217
+ totalMs: number
218
+ /** WASM module preparation time (usually near-zero for pre-compiled) */
219
+ wasmPrepMs: number
220
+ /** Data fetch time from storage tier */
221
+ dataFetchMs: number
222
+ /** Overlap time saved by parallel loading */
223
+ parallelSavingsMs: number
224
+ /** PGLite instance creation time */
225
+ pgliteInitMs: number
226
+ /** First query time (query planner warmup) */
227
+ firstQueryMs: number
228
+ /** Data source that provided the filesystem bundle */
229
+ dataSource: 'hot' | 'warm' | 'cold' | 'empty'
230
+ /** Size of data loaded in bytes */
231
+ dataSizeBytes: number
232
+ /** Whether this was a warm start (cached instance) */
233
+ isWarmStart: boolean
234
+ /** Current phase */
235
+ phase: ColdStartPhase
236
+ /** Timestamp when cold start began */
237
+ startedAt: number
238
+ /** Timestamp when cold start completed */
239
+ completedAt: number
240
+ /** Memory usage at completion (if available) */
241
+ memoryUsedMB?: number
242
+ /** Detailed phase timing breakdown for profiling */
243
+ phaseBreakdown?: PhaseTimingBreakdown[]
244
+ /** WASM strategy metrics (for comparison) */
245
+ wasmStrategy?: WasmStrategyMetrics
246
+ /** Individual tier fetch timings */
247
+ tierFetchTimings?: {
248
+ hot?: { attempted: boolean; durationMs: number; success: boolean }
249
+ warm?: { attempted: boolean; durationMs: number; success: boolean }
250
+ cold?: { attempted: boolean; durationMs: number; success: boolean }
251
+ }
252
+ /** Dynamic import time for @dotdo/pglite module */
253
+ pgliteImportMs?: number
254
+ /** Prewarm query individual timings */
255
+ prewarmTimings?: Array<{ query: string; durationMs: number }>
256
+ }
257
+
258
+ /**
259
+ * Configuration for cold start optimization
260
+ *
261
+ * This configuration controls how the optimizer initializes PGLite and
262
+ * fetches data from tiered storage.
263
+ *
264
+ * ## Required Configuration
265
+ *
266
+ * - `wasmModule`: Pre-compiled WASM module (must be statically imported)
267
+ *
268
+ * ## Storage Tiers (in priority order)
269
+ *
270
+ * 1. **HOT tier** (`hotData`): Data already in memory from DO SQLite.
271
+ * Synchronous access, fastest possible. If provided, skips all other tiers.
272
+ *
273
+ * 2. **WARM tier** (`cacheLayer` + `warmCacheKey`): Cloudflare Cache API.
274
+ * FREE and fast (~10-50ms). Data is cached at edge locations.
275
+ *
276
+ * 3. **COLD tier** (`r2Layer`/`r2Bucket` + `coldStorageKey`): R2 storage.
277
+ * Durable but slower (~100-500ms). Used for persistence and recovery.
278
+ *
279
+ * ## Initialization Behavior
280
+ *
281
+ * - `lazy: true` (default): Defer initialization until first query
282
+ * - `lazy: false`: Initialize immediately when optimizer is created
283
+ * - `prewarm: true` (default): Run warmup queries after initialization
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * // Minimal configuration (empty database)
288
+ * const config: ColdStartConfig = {
289
+ * wasmModule: pgliteWasm,
290
+ * }
291
+ *
292
+ * // Full tiered storage configuration
293
+ * const config: ColdStartConfig = {
294
+ * wasmModule: pgliteWasm,
295
+ * cacheLayer: myCacheLayer,
296
+ * warmCacheKey: `db:${databaseId}`,
297
+ * r2Bucket: env.R2_BUCKET,
298
+ * coldStorageKey: `databases/${databaseId}/data.tar`,
299
+ * lazy: true,
300
+ * prewarm: true,
301
+ * debug: true,
302
+ * onReady: (metrics) => {
303
+ * console.log(`Initialized in ${metrics.totalMs}ms`)
304
+ * },
305
+ * }
306
+ * ```
307
+ */
308
+ export interface ColdStartConfig {
309
+ /**
310
+ * Pre-compiled WASM module
311
+ * MUST be statically imported: import pgliteWasm from './pglite.wasm'
312
+ */
313
+ wasmModule: WebAssembly.Module
314
+
315
+ /**
316
+ * HOT tier: Data from DO SQLite (synchronous)
317
+ * Highest priority - if provided, skips all other tiers
318
+ */
319
+ hotData?: ArrayBuffer | Uint8Array
320
+
321
+ /**
322
+ * WARM tier: Cache layer for Cloudflare Cache API
323
+ */
324
+ cacheLayer?: CacheLayer
325
+
326
+ /**
327
+ * Key for warm cache lookup
328
+ */
329
+ warmCacheKey?: string
330
+
331
+ /**
332
+ * COLD tier: R2 storage layer
333
+ */
334
+ r2Layer?: R2StorageLayer
335
+
336
+ /**
337
+ * COLD tier: Raw R2 bucket (alternative to r2Layer)
338
+ */
339
+ r2Bucket?: R2Bucket
340
+
341
+ /**
342
+ * Key for cold storage lookup
343
+ */
344
+ coldStorageKey?: string
345
+
346
+ /**
347
+ * Enable lazy initialization (default: true)
348
+ * When true, PGLite initializes on first query, not construction
349
+ */
350
+ lazy?: boolean
351
+
352
+ /**
353
+ * Enable pre-warming queries after initialization (default: true)
354
+ * Runs simple queries to warm up the query planner
355
+ */
356
+ prewarm?: boolean
357
+
358
+ /**
359
+ * Custom pre-warm queries to run after initialization
360
+ */
361
+ prewarmQueries?: string[]
362
+
363
+ /**
364
+ * Timeout for cold fetch in milliseconds (default: 5000)
365
+ */
366
+ coldFetchTimeoutMs?: number
367
+
368
+ /**
369
+ * Database name for PGLite (default: 'postgres')
370
+ */
371
+ database?: string
372
+
373
+ /**
374
+ * Additional PGLite options
375
+ */
376
+ pgliteOptions?: Partial<PGliteOptions>
377
+
378
+ /**
379
+ * Enable debug logging
380
+ */
381
+ debug?: boolean
382
+
383
+ /**
384
+ * Callback when initialization phase changes
385
+ */
386
+ onPhaseChange?: (phase: ColdStartPhase, metrics: Partial<ColdStartMetrics>) => void
387
+
388
+ /**
389
+ * Callback when initialization completes
390
+ */
391
+ onReady?: (metrics: ColdStartMetrics) => void
392
+
393
+ /**
394
+ * Callback when an error occurs
395
+ */
396
+ onError?: (error: Error, phase: ColdStartPhase) => void
397
+ }
398
+
399
+ /**
400
+ * Result from cold start optimization
401
+ */
402
+ export interface ColdStartResult {
403
+ /** The initialized PGLite instance */
404
+ pglite: PGlite
405
+ /** Detailed metrics from initialization */
406
+ metrics: ColdStartMetrics
407
+ }
408
+
409
+ /**
410
+ * Cold start optimizer interface
411
+ *
412
+ * This interface provides methods for managing PGLite lifecycle with
413
+ * optimized cold start handling. The optimizer handles:
414
+ *
415
+ * - Lazy initialization (deferred until first query)
416
+ * - WASM instance caching for warm starts
417
+ * - Parallel data fetching from tiered storage
418
+ * - Pre-warming queries for query planner cache
419
+ *
420
+ * ## Lifecycle Methods
421
+ *
422
+ * | Method | Description |
423
+ * |--------|-------------|
424
+ * | `getInstance()` | Get PGLite instance, initializing if needed |
425
+ * | `initialize()` | Force initialization (useful for pre-warming) |
426
+ * | `query()` | Execute query, auto-initializing if lazy |
427
+ * | `close()` | Release resources and remove from cache |
428
+ *
429
+ * ## Status Methods
430
+ *
431
+ * | Method | Description |
432
+ * |--------|-------------|
433
+ * | `isReady()` | Check if initialization is complete |
434
+ * | `isInitializing()` | Check if initialization is in progress |
435
+ * | `getPhase()` | Get current initialization phase |
436
+ * | `getMetrics()` | Get detailed timing metrics |
437
+ *
438
+ * @example
439
+ * ```typescript
440
+ * const optimizer = createColdStartOptimizer(config)
441
+ *
442
+ * // Lazy initialization - first query triggers init
443
+ * const result = await optimizer.query('SELECT 1')
444
+ *
445
+ * // Check status
446
+ * console.log(`Ready: ${optimizer.isReady()}`)
447
+ * console.log(`Phase: ${optimizer.getPhase()}`)
448
+ *
449
+ * // Get metrics after initialization
450
+ * const metrics = optimizer.getMetrics()
451
+ * if (metrics) {
452
+ * console.log(`Cold start: ${metrics.totalMs}ms`)
453
+ * console.log(`Data source: ${metrics.dataSource}`)
454
+ * }
455
+ *
456
+ * // Clean up when done
457
+ * await optimizer.close()
458
+ * ```
459
+ */
460
+ export interface ColdStartOptimizer {
461
+ /**
462
+ * Get the PGLite instance
463
+ *
464
+ * If lazy initialization is enabled (default), this triggers initialization
465
+ * on first call. Subsequent calls return the cached instance.
466
+ *
467
+ * @returns The initialized PGLite instance
468
+ * @throws Error if the optimizer is closed or initialization failed
469
+ */
470
+ getInstance(): Promise<PGlite>
471
+
472
+ /**
473
+ * Check if PGLite is ready for queries
474
+ *
475
+ * @returns true if initialization is complete and queries can be executed
476
+ */
477
+ isReady(): boolean
478
+
479
+ /**
480
+ * Check if initialization is currently in progress
481
+ *
482
+ * @returns true if initialization has started but not completed
483
+ */
484
+ isInitializing(): boolean
485
+
486
+ /**
487
+ * Get the current initialization phase
488
+ *
489
+ * @returns The current phase of the cold start process
490
+ */
491
+ getPhase(): ColdStartPhase
492
+
493
+ /**
494
+ * Get detailed timing metrics from initialization
495
+ *
496
+ * Returns null if initialization has not completed.
497
+ *
498
+ * @returns Detailed metrics or null if not yet initialized
499
+ */
500
+ getMetrics(): ColdStartMetrics | null
501
+
502
+ /**
503
+ * Force initialization
504
+ *
505
+ * Use this to pre-warm the optimizer before the first query.
506
+ * Has no effect if already initialized.
507
+ *
508
+ * @example
509
+ * ```typescript
510
+ * // Pre-warm in DO constructor
511
+ * this.pgliteInitPromise = optimizer.initialize()
512
+ *
513
+ * // Later in fetch handler
514
+ * await this.pgliteInitPromise
515
+ * const result = await optimizer.query('SELECT 1')
516
+ * ```
517
+ */
518
+ initialize(): Promise<void>
519
+
520
+ /**
521
+ * Execute a SQL query
522
+ *
523
+ * Auto-initializes if lazy mode is enabled and not yet initialized.
524
+ *
525
+ * @param sql - The SQL query to execute
526
+ * @param params - Optional query parameters
527
+ * @returns Query result with rows
528
+ * @throws Error if the optimizer is closed or query fails
529
+ */
530
+ query<T = unknown>(sql: string, params?: unknown[]): Promise<{ rows: T[] }>
531
+
532
+ /**
533
+ * Close the optimizer and release resources
534
+ *
535
+ * Removes the PGLite instance from the warm start cache and closes
536
+ * the underlying database connection.
537
+ */
538
+ close(): Promise<void>
539
+ }
540
+
541
+ // ============================================================================
542
+ // WASM Caching Strategy
543
+ // ============================================================================
544
+
545
+ /**
546
+ * Module-level cache for WASM initialization state
547
+ *
548
+ * In Cloudflare Workers, isolates persist across requests within the same
549
+ * execution context. This cache enables "warm starts" by reusing already-
550
+ * initialized PGLite instances instead of performing a full cold start.
551
+ *
552
+ * ## How Warm Starts Work
553
+ *
554
+ * 1. First request to a DO performs cold start (full initialization)
555
+ * 2. Initialized PGLite is cached with database-specific key
556
+ * 3. Subsequent requests find cached instance and reuse it
557
+ * 4. Cache is cleared when `close()` is called or isolate is evicted
558
+ *
559
+ * ## Cache Key Generation
560
+ *
561
+ * Keys are generated from: `${database}:${warmCacheKey}:${coldStorageKey}`
562
+ * This ensures different databases don't share instances.
563
+ *
564
+ * ## Memory Considerations
565
+ *
566
+ * Each cached instance uses ~64MB. With Workers' 128MB limit:
567
+ * - Only one instance can be effectively cached per isolate
568
+ * - Multiple databases should use ColdStartManager for lifecycle
569
+ *
570
+ * @internal
571
+ */
572
+ interface WasmCacheEntry {
573
+ /** The initialized PGLite instance */
574
+ pglite: PGlite
575
+ /** When this entry was created */
576
+ createdAt: number
577
+ /** Metrics from initial cold start */
578
+ metrics: ColdStartMetrics
579
+ /** Number of times this cached instance was reused */
580
+ reuseCount: number
581
+ }
582
+
583
+ /**
584
+ * Isolate-level WASM cache
585
+ *
586
+ * This Map persists across requests within the same Worker isolate.
587
+ * When the isolate is evicted, the cache is cleared automatically.
588
+ *
589
+ * @internal
590
+ */
591
+ const wasmCache = new Map<string, WasmCacheEntry>()
592
+
593
+ /**
594
+ * Generate a cache key for WASM instance caching
595
+ *
596
+ * The key should uniquely identify the WASM module and configuration.
597
+ */
598
+ function generateCacheKey(config: ColdStartConfig): string {
599
+ // Use database name as primary key differentiator
600
+ const dbName = config.database ?? 'postgres'
601
+ // Include warm/cold keys to differentiate data sources
602
+ const warmKey = config.warmCacheKey ?? ''
603
+ const coldKey = config.coldStorageKey ?? ''
604
+ return `${dbName}:${warmKey}:${coldKey}`
605
+ }
606
+
607
+ /**
608
+ * Get cached WASM instance if available
609
+ */
610
+ function getCachedInstance(cacheKey: string): WasmCacheEntry | null {
611
+ const entry = wasmCache.get(cacheKey)
612
+ if (entry) {
613
+ entry.reuseCount++
614
+ return entry
615
+ }
616
+ return null
617
+ }
618
+
619
+ /**
620
+ * Cache a WASM instance for warm starts
621
+ */
622
+ function cacheInstance(cacheKey: string, entry: WasmCacheEntry): void {
623
+ wasmCache.set(cacheKey, entry)
624
+ }
625
+
626
+ /**
627
+ * Clear all cached WASM instances
628
+ *
629
+ * Use this function to:
630
+ * - Reset state between tests
631
+ * - Force cold starts for benchmarking
632
+ * - Clear memory when switching databases
633
+ *
634
+ * @example
635
+ * ```typescript
636
+ * // In tests
637
+ * beforeEach(() => {
638
+ * clearWasmCache()
639
+ * })
640
+ *
641
+ * // Force cold start for benchmarking
642
+ * clearWasmCache()
643
+ * const start = performance.now()
644
+ * await optimizer.initialize()
645
+ * const coldStartMs = performance.now() - start
646
+ * ```
647
+ */
648
+ export function clearWasmCache(): void {
649
+ wasmCache.clear()
650
+ }
651
+
652
+ /**
653
+ * Get WASM cache statistics
654
+ *
655
+ * Returns information about cached PGLite instances for monitoring
656
+ * and debugging purposes.
657
+ *
658
+ * @returns Object containing:
659
+ * - `size`: Number of cached instances
660
+ * - `entries`: Array of cache entries with reuse count and age
661
+ *
662
+ * @example
663
+ * ```typescript
664
+ * const stats = getWasmCacheStats()
665
+ * console.log(`Cached instances: ${stats.size}`)
666
+ *
667
+ * for (const entry of stats.entries) {
668
+ * console.log(`${entry.key}: ${entry.reuseCount} reuses, ${entry.ageMs}ms old`)
669
+ * }
670
+ * ```
671
+ */
672
+ export function getWasmCacheStats(): {
673
+ size: number
674
+ entries: Array<{ key: string; reuseCount: number; ageMs: number }>
675
+ } {
676
+ const now = Date.now()
677
+ const entries: Array<{ key: string; reuseCount: number; ageMs: number }> = []
678
+
679
+ for (const [key, entry] of wasmCache.entries()) {
680
+ entries.push({
681
+ key,
682
+ reuseCount: entry.reuseCount,
683
+ ageMs: now - entry.createdAt,
684
+ })
685
+ }
686
+
687
+ return { size: wasmCache.size, entries }
688
+ }
689
+
690
+ // ============================================================================
691
+ // Parallel Loading Strategy
692
+ // ============================================================================
693
+
694
+ /**
695
+ * Result from parallel data fetch
696
+ */
697
+ interface ParallelFetchResult {
698
+ data: Uint8Array | null
699
+ source: 'hot' | 'warm' | 'cold' | 'empty'
700
+ fetchTimeMs: number
701
+ /** Individual tier timing details */
702
+ tierTimings?: {
703
+ hot?: { attempted: boolean; durationMs: number; success: boolean }
704
+ warm?: { attempted: boolean; durationMs: number; success: boolean }
705
+ cold?: { attempted: boolean; durationMs: number; success: boolean }
706
+ }
707
+ }
708
+
709
+ /**
710
+ * Fetch data from tiered storage in parallel with WASM preparation
711
+ *
712
+ * This function implements the parallel loading pattern:
713
+ * - WASM module is already pre-compiled (zero prep time)
714
+ * - Data fetch from warm/cold tiers happens during that "zero time"
715
+ * - We race warm and cold fetches to get data ASAP
716
+ */
717
+ async function parallelFetchData(
718
+ config: ColdStartConfig,
719
+ debug: (msg: string) => void
720
+ ): Promise<ParallelFetchResult> {
721
+ const startTime = performance.now()
722
+ const tierTimings: ParallelFetchResult['tierTimings'] = {}
723
+
724
+ // Priority 1: Hot data (synchronous, already in memory)
725
+ if (config.hotData) {
726
+ const hotStart = performance.now()
727
+ debug('Using hot data from DO SQLite')
728
+ const data =
729
+ config.hotData instanceof Uint8Array
730
+ ? config.hotData
731
+ : new Uint8Array(config.hotData)
732
+ const hotDuration = performance.now() - hotStart
733
+ tierTimings.hot = { attempted: true, durationMs: hotDuration, success: true }
734
+ return {
735
+ data,
736
+ source: 'hot',
737
+ fetchTimeMs: performance.now() - startTime,
738
+ tierTimings,
739
+ }
740
+ }
741
+
742
+ // Set up parallel fetches for warm and cold tiers
743
+ interface TierFetchResult extends ParallelFetchResult {
744
+ tierType: 'warm' | 'cold'
745
+ }
746
+ const fetchPromises: Promise<TierFetchResult>[] = []
747
+
748
+ // Warm tier fetch (Cloudflare Cache - FREE!)
749
+ if (config.cacheLayer && config.warmCacheKey) {
750
+ const warmPromise = (async (): Promise<TierFetchResult> => {
751
+ const warmStart = performance.now()
752
+ try {
753
+ const data = await config.cacheLayer!.get(config.warmCacheKey!)
754
+ const durationMs = performance.now() - warmStart
755
+ if (data) {
756
+ debug(`Warm cache hit: ${data.length} bytes in ${durationMs.toFixed(2)}ms`)
757
+ return {
758
+ data,
759
+ source: 'warm',
760
+ fetchTimeMs: durationMs,
761
+ tierType: 'warm',
762
+ tierTimings: { warm: { attempted: true, durationMs, success: true } },
763
+ }
764
+ }
765
+ return {
766
+ data: null,
767
+ source: 'warm',
768
+ fetchTimeMs: durationMs,
769
+ tierType: 'warm',
770
+ tierTimings: { warm: { attempted: true, durationMs, success: false } },
771
+ }
772
+ } catch (err) {
773
+ const durationMs = performance.now() - warmStart
774
+ debug(`Warm cache error after ${durationMs.toFixed(2)}ms: ${err}`)
775
+ return {
776
+ data: null,
777
+ source: 'warm',
778
+ fetchTimeMs: durationMs,
779
+ tierType: 'warm',
780
+ tierTimings: { warm: { attempted: true, durationMs, success: false } },
781
+ }
782
+ }
783
+ })()
784
+ fetchPromises.push(warmPromise)
785
+ }
786
+
787
+ // Cold tier fetch (R2 - durable storage)
788
+ if ((config.r2Layer || config.r2Bucket) && config.coldStorageKey) {
789
+ const coldPromise = (async (): Promise<TierFetchResult> => {
790
+ const coldStart = performance.now()
791
+ const timeout = config.coldFetchTimeoutMs ?? 5000
792
+
793
+ try {
794
+ let data: Uint8Array | null = null
795
+
796
+ if (config.r2Layer) {
797
+ // Use R2StorageLayer with timeout
798
+ data = await Promise.race([
799
+ config.r2Layer.get(config.coldStorageKey!),
800
+ new Promise<null>((_, reject) =>
801
+ setTimeout(() => reject(new Error('Cold fetch timeout')), timeout)
802
+ ),
803
+ ])
804
+ } else if (config.r2Bucket) {
805
+ // Use raw R2Bucket with timeout
806
+ const obj = await Promise.race([
807
+ config.r2Bucket.get(config.coldStorageKey!),
808
+ new Promise<null>((_, reject) =>
809
+ setTimeout(() => reject(new Error('Cold fetch timeout')), timeout)
810
+ ),
811
+ ])
812
+ if (obj) {
813
+ data = new Uint8Array(await obj.arrayBuffer())
814
+ }
815
+ }
816
+
817
+ const durationMs = performance.now() - coldStart
818
+ if (data) {
819
+ debug(`Cold storage hit: ${data.length} bytes in ${durationMs.toFixed(2)}ms`)
820
+ return {
821
+ data,
822
+ source: 'cold',
823
+ fetchTimeMs: durationMs,
824
+ tierType: 'cold',
825
+ tierTimings: { cold: { attempted: true, durationMs, success: true } },
826
+ }
827
+ }
828
+ return {
829
+ data: null,
830
+ source: 'cold',
831
+ fetchTimeMs: durationMs,
832
+ tierType: 'cold',
833
+ tierTimings: { cold: { attempted: true, durationMs, success: false } },
834
+ }
835
+ } catch (err) {
836
+ const durationMs = performance.now() - coldStart
837
+ debug(`Cold storage error after ${durationMs.toFixed(2)}ms: ${err}`)
838
+ return {
839
+ data: null,
840
+ source: 'cold',
841
+ fetchTimeMs: durationMs,
842
+ tierType: 'cold',
843
+ tierTimings: { cold: { attempted: true, durationMs, success: false } },
844
+ }
845
+ }
846
+ })()
847
+ fetchPromises.push(coldPromise)
848
+ }
849
+
850
+ // Execute fetches in parallel, return first successful result
851
+ if (fetchPromises.length > 0) {
852
+ debug(`Starting ${fetchPromises.length} parallel fetches`)
853
+
854
+ // Use Promise.all to get all results, then pick the best one
855
+ // (We want metrics from all attempts, not just the winner)
856
+ const results = await Promise.all(fetchPromises)
857
+
858
+ // Merge all tier timings
859
+ for (const result of results) {
860
+ if (result.tierTimings) {
861
+ Object.assign(tierTimings, result.tierTimings)
862
+ }
863
+ }
864
+
865
+ // Prefer warm over cold (warm is faster and FREE)
866
+ const warmResult = results.find((r) => r.source === 'warm' && r.data)
867
+ if (warmResult?.data) {
868
+ return { ...warmResult, tierTimings }
869
+ }
870
+
871
+ const coldResult = results.find((r) => r.source === 'cold' && r.data)
872
+ if (coldResult?.data) {
873
+ return { ...coldResult, tierTimings }
874
+ }
875
+ }
876
+
877
+ // No data found anywhere
878
+ debug('No data found, returning empty')
879
+ return {
880
+ data: null,
881
+ source: 'empty',
882
+ fetchTimeMs: performance.now() - startTime,
883
+ tierTimings,
884
+ }
885
+ }
886
+
887
+ // ============================================================================
888
+ // Lazy Initialization Pattern
889
+ // ============================================================================
890
+
891
+ /**
892
+ * Default pre-warm queries to run after initialization
893
+ *
894
+ * These queries warm up:
895
+ * - Query planner cache
896
+ * - System catalog cache
897
+ * - Connection state
898
+ */
899
+ const DEFAULT_PREWARM_QUERIES = [
900
+ 'SELECT 1', // Basic connectivity
901
+ 'SELECT current_database()', // Database state
902
+ 'SELECT version()', // System catalog access
903
+ ]
904
+
905
+ /**
906
+ * Run pre-warm queries to optimize subsequent query latency
907
+ */
908
+ async function runPrewarmQueries(
909
+ pglite: PGlite,
910
+ queries: string[],
911
+ debug: (msg: string) => void
912
+ ): Promise<number> {
913
+ const startTime = performance.now()
914
+
915
+ for (const sql of queries) {
916
+ try {
917
+ await pglite.query(sql)
918
+ } catch {
919
+ // Ignore errors in pre-warm queries (table might not exist, etc.)
920
+ debug(`Prewarm query failed (ignored): ${sql}`)
921
+ }
922
+ }
923
+
924
+ const durationMs = performance.now() - startTime
925
+ debug(`Prewarm completed: ${queries.length} queries in ${durationMs.toFixed(2)}ms`)
926
+ return durationMs
927
+ }
928
+
929
+ /**
930
+ * Run pre-warm queries with individual timing tracking
931
+ */
932
+ async function runPrewarmQueriesWithTimings(
933
+ pglite: PGlite,
934
+ queries: string[],
935
+ debug: (msg: string) => void
936
+ ): Promise<Array<{ query: string; durationMs: number }>> {
937
+ const timings: Array<{ query: string; durationMs: number }> = []
938
+
939
+ for (const sql of queries) {
940
+ const queryStart = performance.now()
941
+ try {
942
+ await pglite.query(sql)
943
+ } catch {
944
+ // Ignore errors in pre-warm queries (table might not exist, etc.)
945
+ debug(`Prewarm query failed (ignored): ${sql}`)
946
+ }
947
+ const queryEnd = performance.now()
948
+ timings.push({ query: sql, durationMs: queryEnd - queryStart })
949
+ }
950
+
951
+ const totalMs = timings.reduce((sum, t) => sum + t.durationMs, 0)
952
+ debug(`Prewarm completed: ${queries.length} queries in ${totalMs.toFixed(2)}ms`)
953
+ return timings
954
+ }
955
+
956
+ // ============================================================================
957
+ // Memory Allocation Optimization
958
+ // ============================================================================
959
+
960
+ /**
961
+ * Buffer pool for reducing memory allocation overhead
962
+ *
963
+ * ## Memory Constraints
964
+ *
965
+ * Cloudflare Workers have a 128MB memory limit. PGLite uses approximately:
966
+ * - ~15MB for WASM + data + JS runtime
967
+ * - ~16MB for shared_buffers
968
+ * - ~16MB for WAL + buffers
969
+ * - ~10MB for PostgreSQL catalog/metadata
970
+ *
971
+ * This leaves ~71MB for queries, results, and runtime operations.
972
+ *
973
+ * ## Buffer Pool Strategy
974
+ *
975
+ * Pre-allocated buffers reduce allocation overhead during query execution:
976
+ *
977
+ * | Size | Bytes | Use Case |
978
+ * |------|-------|----------|
979
+ * | small | 4KB | Small operations, metadata |
980
+ * | medium | 64KB | Typical query results |
981
+ * | large | 1MB | Large result sets, bulk operations |
982
+ *
983
+ * ## Usage Pattern
984
+ *
985
+ * ```typescript
986
+ * const buffer = getPooledBuffer('medium')
987
+ * try {
988
+ * // Use buffer for operation
989
+ * const view = new Uint8Array(buffer)
990
+ * // ... process data
991
+ * } finally {
992
+ * returnPooledBuffer(buffer, 'medium')
993
+ * }
994
+ * ```
995
+ *
996
+ * @internal
997
+ */
998
+ interface BufferPool {
999
+ small: ArrayBuffer | null // 4KB for small operations
1000
+ medium: ArrayBuffer | null // 64KB for typical queries
1001
+ large: ArrayBuffer | null // 1MB for large result sets
1002
+ }
1003
+
1004
+ /**
1005
+ * Buffer pool for reducing allocation overhead
1006
+ * @internal
1007
+ */
1008
+ const bufferPool: BufferPool = {
1009
+ small: null,
1010
+ medium: null,
1011
+ large: null,
1012
+ }
1013
+
1014
+ /**
1015
+ * Get a buffer from the pool or allocate a new one
1016
+ *
1017
+ * Buffers are returned from the pool if available, otherwise a new
1018
+ * buffer is allocated. This reduces allocation overhead for repeated
1019
+ * operations of similar size.
1020
+ *
1021
+ * @param size - Buffer size category: 'small' (4KB), 'medium' (64KB), or 'large' (1MB)
1022
+ * @returns ArrayBuffer of the specified size
1023
+ *
1024
+ * @example
1025
+ * ```typescript
1026
+ * const buffer = getPooledBuffer('medium') // 64KB
1027
+ * const view = new Uint8Array(buffer)
1028
+ * // Use the buffer...
1029
+ * returnPooledBuffer(buffer, 'medium')
1030
+ * ```
1031
+ */
1032
+ export function getPooledBuffer(
1033
+ size: 'small' | 'medium' | 'large'
1034
+ ): ArrayBuffer {
1035
+ const sizes = { small: 4096, medium: 65536, large: 1048576 }
1036
+
1037
+ if (bufferPool[size]) {
1038
+ const buffer = bufferPool[size]!
1039
+ bufferPool[size] = null
1040
+ return buffer
1041
+ }
1042
+
1043
+ return new ArrayBuffer(sizes[size])
1044
+ }
1045
+
1046
+ /**
1047
+ * Return a buffer to the pool for reuse
1048
+ *
1049
+ * Only returns the buffer if it hasn't been detached (transferred).
1050
+ * Detached buffers have byteLength of 0.
1051
+ *
1052
+ * @param buffer - The buffer to return
1053
+ * @param size - The size category of the buffer
1054
+ *
1055
+ * @example
1056
+ * ```typescript
1057
+ * const buffer = getPooledBuffer('small')
1058
+ * // Use buffer...
1059
+ * returnPooledBuffer(buffer, 'small')
1060
+ * ```
1061
+ */
1062
+ export function returnPooledBuffer(
1063
+ buffer: ArrayBuffer,
1064
+ size: 'small' | 'medium' | 'large'
1065
+ ): void {
1066
+ // Only pool if the buffer hasn't been transferred
1067
+ if (buffer.byteLength > 0) {
1068
+ bufferPool[size] = buffer
1069
+ }
1070
+ }
1071
+
1072
+ /**
1073
+ * Clear the buffer pool
1074
+ *
1075
+ * Use this to:
1076
+ * - Reset state between tests
1077
+ * - Free memory when it's no longer needed
1078
+ * - Prepare for a clean shutdown
1079
+ *
1080
+ * @example
1081
+ * ```typescript
1082
+ * // In tests
1083
+ * afterEach(() => {
1084
+ * clearBufferPool()
1085
+ * })
1086
+ * ```
1087
+ */
1088
+ export function clearBufferPool(): void {
1089
+ bufferPool.small = null
1090
+ bufferPool.medium = null
1091
+ bufferPool.large = null
1092
+ }
1093
+
1094
+ // ============================================================================
1095
+ // Cold Start Optimizer Implementation
1096
+ // ============================================================================
1097
+
1098
+ /**
1099
+ * Create a cold start optimized PGLite instance
1100
+ *
1101
+ * This is the main entry point for optimized PGLite initialization in Workers.
1102
+ *
1103
+ * @example
1104
+ * ```typescript
1105
+ * import pgliteWasm from './pglite.wasm'
1106
+ *
1107
+ * const optimizer = createColdStartOptimizer({
1108
+ * wasmModule: pgliteWasm,
1109
+ * cacheLayer: myCacheLayer,
1110
+ * warmCacheKey: `db:${databaseId}`,
1111
+ * r2Layer: myR2Layer,
1112
+ * coldStorageKey: `databases/${databaseId}/data.tar`,
1113
+ * lazy: true,
1114
+ * prewarm: true,
1115
+ * })
1116
+ *
1117
+ * // First query triggers initialization
1118
+ * const result = await optimizer.query('SELECT * FROM users')
1119
+ *
1120
+ * // Check metrics
1121
+ * const metrics = optimizer.getMetrics()
1122
+ * console.log(`Cold start: ${metrics?.totalMs}ms from ${metrics?.dataSource}`)
1123
+ * ```
1124
+ */
1125
+ export function createColdStartOptimizer(
1126
+ config: ColdStartConfig
1127
+ ): ColdStartOptimizer {
1128
+ const {
1129
+ lazy = true,
1130
+ prewarm = true,
1131
+ prewarmQueries = DEFAULT_PREWARM_QUERIES,
1132
+ debug: enableDebug = false,
1133
+ onPhaseChange,
1134
+ onReady,
1135
+ onError,
1136
+ } = config
1137
+
1138
+ // State
1139
+ let pglite: PGlite | null = null
1140
+ let initPromise: Promise<void> | null = null
1141
+ let phase: ColdStartPhase = 'not_started'
1142
+ let metrics: ColdStartMetrics | null = null
1143
+ let closed = false
1144
+
1145
+ // Debug logging
1146
+ const debug = enableDebug ? console.log.bind(console, '[ColdStartOptimizer]') : () => {}
1147
+
1148
+ // Generate cache key for WASM caching
1149
+ const cacheKey = generateCacheKey(config)
1150
+
1151
+ /**
1152
+ * Update phase and notify callback
1153
+ */
1154
+ function setPhase(newPhase: ColdStartPhase): void {
1155
+ phase = newPhase
1156
+ debug(`Phase: ${newPhase}`)
1157
+ onPhaseChange?.(newPhase, metrics ?? {})
1158
+ }
1159
+
1160
+ /**
1161
+ * Perform the actual initialization
1162
+ */
1163
+ async function doInitialize(): Promise<void> {
1164
+ const startTime = performance.now()
1165
+ const startedAt = Date.now()
1166
+ const phaseBreakdown: PhaseTimingBreakdown[] = []
1167
+
1168
+ // Initialize metrics
1169
+ const initMetrics: ColdStartMetrics = {
1170
+ totalMs: 0,
1171
+ wasmPrepMs: 0,
1172
+ dataFetchMs: 0,
1173
+ parallelSavingsMs: 0,
1174
+ pgliteInitMs: 0,
1175
+ firstQueryMs: 0,
1176
+ dataSource: 'empty',
1177
+ dataSizeBytes: 0,
1178
+ isWarmStart: false,
1179
+ phase: 'not_started',
1180
+ startedAt,
1181
+ completedAt: 0,
1182
+ phaseBreakdown: [],
1183
+ prewarmTimings: [],
1184
+ }
1185
+
1186
+ try {
1187
+ // Check WASM cache first (warm start)
1188
+ const cached = getCachedInstance(cacheKey)
1189
+ if (cached) {
1190
+ debug('Warm start: using cached PGLite instance')
1191
+ pglite = cached.pglite
1192
+ initMetrics.isWarmStart = true
1193
+ initMetrics.totalMs = performance.now() - startTime
1194
+ initMetrics.completedAt = Date.now()
1195
+ initMetrics.phase = 'ready'
1196
+ initMetrics.wasmStrategy = {
1197
+ strategy: 'cached',
1198
+ moduleLoadMs: 0,
1199
+ instantiateMs: 0,
1200
+ totalMs: 0,
1201
+ fromCache: true,
1202
+ }
1203
+ metrics = initMetrics
1204
+ setPhase('ready')
1205
+ onReady?.(initMetrics)
1206
+ return
1207
+ }
1208
+
1209
+ // Cold start: full initialization
1210
+ debug('Cold start: initializing new PGLite instance')
1211
+
1212
+ // Phase 1: WASM preparation (usually instant for pre-compiled modules)
1213
+ setPhase('wasm_loading')
1214
+ const wasmPhaseStart = performance.now()
1215
+ // WASM module is pre-compiled via static import, nothing to do here
1216
+ // But we track it for comparison with other strategies
1217
+ const wasmPhaseEnd = performance.now()
1218
+ initMetrics.wasmPrepMs = wasmPhaseEnd - wasmPhaseStart
1219
+
1220
+ // Estimate WASM module size based on variant
1221
+ // Tiny variant: ~4.8MB (target: under 5MB), Full variant: ~13MB
1222
+ const variant = (config.pgliteOptions as { variant?: 'tiny' | 'full' } | undefined)?.variant
1223
+ const estimatedModuleSizeBytes = variant === 'tiny' ? 4.8 * 1024 * 1024 : 13 * 1024 * 1024
1224
+
1225
+ initMetrics.wasmStrategy = {
1226
+ strategy: 'static_import',
1227
+ moduleLoadMs: 0, // Pre-compiled at build time
1228
+ instantiateMs: initMetrics.wasmPrepMs,
1229
+ totalMs: initMetrics.wasmPrepMs,
1230
+ fromCache: false,
1231
+ moduleSizeBytes: estimatedModuleSizeBytes,
1232
+ }
1233
+ phaseBreakdown.push({
1234
+ phase: 'wasm_loading',
1235
+ startTime: wasmPhaseStart,
1236
+ endTime: wasmPhaseEnd,
1237
+ durationMs: initMetrics.wasmPrepMs,
1238
+ })
1239
+
1240
+ // Phase 2: Parallel data fetch
1241
+ // This happens "in parallel" with the zero-time WASM prep
1242
+ // The real savings come from starting this early
1243
+ setPhase('parallel_loading')
1244
+ const dataFetchStart = performance.now()
1245
+ const fetchResult = await parallelFetchData(config, debug)
1246
+ const dataFetchEnd = performance.now()
1247
+ initMetrics.dataFetchMs = fetchResult.fetchTimeMs
1248
+ initMetrics.dataSource = fetchResult.source
1249
+ initMetrics.dataSizeBytes = fetchResult.data?.length ?? 0
1250
+ initMetrics.tierFetchTimings = fetchResult.tierTimings
1251
+
1252
+ phaseBreakdown.push({
1253
+ phase: 'parallel_loading',
1254
+ startTime: dataFetchStart,
1255
+ endTime: dataFetchEnd,
1256
+ durationMs: dataFetchEnd - dataFetchStart,
1257
+ subPhases: Object.entries(fetchResult.tierTimings || {}).map(([tier, timing]) => ({
1258
+ name: `${tier}_fetch`,
1259
+ startTime: dataFetchStart,
1260
+ endTime: dataFetchStart + timing.durationMs,
1261
+ durationMs: timing.durationMs,
1262
+ })),
1263
+ })
1264
+
1265
+ // Calculate parallel savings (would have been sequential without this)
1266
+ // Since WASM prep is ~0ms, parallel savings = max(0, wasmPrepMs)
1267
+ initMetrics.parallelSavingsMs = Math.max(
1268
+ 0,
1269
+ initMetrics.wasmPrepMs - initMetrics.dataFetchMs
1270
+ )
1271
+
1272
+ // Phase 3: PGLite initialization
1273
+ setPhase('pglite_init')
1274
+ const pglitePhaseStart = performance.now()
1275
+
1276
+ // Track dynamic import time separately
1277
+ const importStart = performance.now()
1278
+ const { PGlite } = await import('@dotdo/pglite')
1279
+ const importEnd = performance.now()
1280
+ initMetrics.pgliteImportMs = importEnd - importStart
1281
+
1282
+ // Build PGLite configuration
1283
+ const pgliteConfig: PGliteOptions = {
1284
+ ...config.pgliteOptions,
1285
+ wasmModule: config.wasmModule,
1286
+ database: config.database ?? 'postgres',
1287
+ }
1288
+
1289
+ // Add filesystem bundle if data was fetched
1290
+ if (fetchResult.data) {
1291
+ pgliteConfig.fsBundle = new Blob([fetchResult.data])
1292
+ }
1293
+
1294
+ // Create PGLite instance
1295
+ const createStart = performance.now()
1296
+ pglite = await PGlite.create(pgliteConfig)
1297
+ const createEnd = performance.now()
1298
+
1299
+ const pglitePhaseEnd = performance.now()
1300
+ initMetrics.pgliteInitMs = pglitePhaseEnd - pglitePhaseStart
1301
+
1302
+ phaseBreakdown.push({
1303
+ phase: 'pglite_init',
1304
+ startTime: pglitePhaseStart,
1305
+ endTime: pglitePhaseEnd,
1306
+ durationMs: initMetrics.pgliteInitMs,
1307
+ subPhases: [
1308
+ {
1309
+ name: 'dynamic_import',
1310
+ startTime: importStart,
1311
+ endTime: importEnd,
1312
+ durationMs: initMetrics.pgliteImportMs,
1313
+ },
1314
+ {
1315
+ name: 'pglite_create',
1316
+ startTime: createStart,
1317
+ endTime: createEnd,
1318
+ durationMs: createEnd - createStart,
1319
+ },
1320
+ ],
1321
+ })
1322
+
1323
+ // Phase 4: Pre-warming (optional but recommended)
1324
+ if (prewarm && prewarmQueries.length > 0) {
1325
+ const prewarmStart = performance.now()
1326
+ const prewarmTimings = await runPrewarmQueriesWithTimings(pglite, prewarmQueries, debug)
1327
+ const prewarmEnd = performance.now()
1328
+ initMetrics.firstQueryMs = prewarmEnd - prewarmStart
1329
+ initMetrics.prewarmTimings = prewarmTimings
1330
+
1331
+ phaseBreakdown.push({
1332
+ phase: 'ready', // Prewarm is the final phase before ready
1333
+ startTime: prewarmStart,
1334
+ endTime: prewarmEnd,
1335
+ durationMs: initMetrics.firstQueryMs,
1336
+ subPhases: prewarmTimings.map((t, i) => ({
1337
+ name: `prewarm_query_${i}`,
1338
+ startTime: prewarmStart,
1339
+ endTime: prewarmStart + t.durationMs,
1340
+ durationMs: t.durationMs,
1341
+ })),
1342
+ })
1343
+ }
1344
+
1345
+ // Complete initialization
1346
+ initMetrics.totalMs = performance.now() - startTime
1347
+ initMetrics.completedAt = Date.now()
1348
+ initMetrics.phase = 'ready'
1349
+ initMetrics.phaseBreakdown = phaseBreakdown
1350
+
1351
+ // Try to capture memory usage
1352
+ if (typeof process !== 'undefined' && process.memoryUsage) {
1353
+ initMetrics.memoryUsedMB = process.memoryUsage().heapUsed / (1024 * 1024)
1354
+ }
1355
+
1356
+ metrics = initMetrics
1357
+
1358
+ // Cache for warm starts
1359
+ cacheInstance(cacheKey, {
1360
+ pglite,
1361
+ createdAt: Date.now(),
1362
+ metrics: initMetrics,
1363
+ reuseCount: 0,
1364
+ })
1365
+
1366
+ setPhase('ready')
1367
+ onReady?.(initMetrics)
1368
+
1369
+ debug(
1370
+ `Cold start complete: ${initMetrics.totalMs.toFixed(2)}ms ` +
1371
+ `(data: ${initMetrics.dataFetchMs.toFixed(2)}ms from ${initMetrics.dataSource}, ` +
1372
+ `pglite: ${initMetrics.pgliteInitMs.toFixed(2)}ms, ` +
1373
+ `import: ${initMetrics.pgliteImportMs?.toFixed(2)}ms)`
1374
+ )
1375
+ } catch (error) {
1376
+ setPhase('error')
1377
+ onError?.(error as Error, phase)
1378
+ throw error
1379
+ }
1380
+ }
1381
+
1382
+ /**
1383
+ * Ensure PGLite is initialized
1384
+ */
1385
+ async function ensureInitialized(): Promise<void> {
1386
+ if (pglite && phase === 'ready') return
1387
+
1388
+ if (closed) {
1389
+ throw new Error('ColdStartOptimizer is closed')
1390
+ }
1391
+
1392
+ if (phase === 'error') {
1393
+ throw new Error('ColdStartOptimizer initialization failed')
1394
+ }
1395
+
1396
+ if (!initPromise) {
1397
+ initPromise = doInitialize()
1398
+ }
1399
+
1400
+ await initPromise
1401
+ }
1402
+
1403
+ // Start initialization immediately if not lazy
1404
+ if (!lazy) {
1405
+ initPromise = doInitialize()
1406
+ }
1407
+
1408
+ return {
1409
+ async getInstance(): Promise<PGlite> {
1410
+ await ensureInitialized()
1411
+ return pglite!
1412
+ },
1413
+
1414
+ isReady(): boolean {
1415
+ return phase === 'ready'
1416
+ },
1417
+
1418
+ isInitializing(): boolean {
1419
+ return (
1420
+ phase !== 'not_started' &&
1421
+ phase !== 'ready' &&
1422
+ phase !== 'error'
1423
+ )
1424
+ },
1425
+
1426
+ getPhase(): ColdStartPhase {
1427
+ return phase
1428
+ },
1429
+
1430
+ getMetrics(): ColdStartMetrics | null {
1431
+ return metrics
1432
+ },
1433
+
1434
+ async initialize(): Promise<void> {
1435
+ await ensureInitialized()
1436
+ },
1437
+
1438
+ async query<T = unknown>(
1439
+ sql: string,
1440
+ params?: unknown[]
1441
+ ): Promise<{ rows: T[] }> {
1442
+ await ensureInitialized()
1443
+ const result = await pglite!.query<T>(sql, params)
1444
+ return { rows: result.rows }
1445
+ },
1446
+
1447
+ async close(): Promise<void> {
1448
+ closed = true
1449
+
1450
+ if (initPromise) {
1451
+ try {
1452
+ await initPromise
1453
+ } catch {
1454
+ // Ignore errors from pending initialization
1455
+ }
1456
+ }
1457
+
1458
+ if (pglite) {
1459
+ // Remove from cache
1460
+ wasmCache.delete(cacheKey)
1461
+
1462
+ try {
1463
+ await pglite.close()
1464
+ } catch {
1465
+ // Ignore close errors
1466
+ }
1467
+ pglite = null
1468
+ }
1469
+
1470
+ initPromise = null
1471
+ },
1472
+ }
1473
+ }
1474
+
1475
+ // ============================================================================
1476
+ // Factory Functions
1477
+ // ============================================================================
1478
+
1479
+ /**
1480
+ * Create a cold start optimizer factory with pre-configured storage layers
1481
+ *
1482
+ * Use this in a Durable Object to create optimizer instances with consistent config.
1483
+ *
1484
+ * @example
1485
+ * ```typescript
1486
+ * // In DO constructor
1487
+ * const createOptimizer = createColdStartOptimizerFactory({
1488
+ * cacheLayer: myCacheLayer,
1489
+ * r2Layer: myR2Layer,
1490
+ * })
1491
+ *
1492
+ * // In DO fetch handler
1493
+ * const optimizer = createOptimizer({
1494
+ * wasmModule: pgliteWasm,
1495
+ * warmCacheKey: `db:${this.id}`,
1496
+ * coldStorageKey: `databases/${this.id}/data.tar`,
1497
+ * })
1498
+ * ```
1499
+ */
1500
+ export function createColdStartOptimizerFactory(
1501
+ baseConfig: Partial<ColdStartConfig>
1502
+ ): (instanceConfig: ColdStartConfig) => ColdStartOptimizer {
1503
+ return (instanceConfig) => {
1504
+ return createColdStartOptimizer({
1505
+ ...baseConfig,
1506
+ ...instanceConfig,
1507
+ })
1508
+ }
1509
+ }
1510
+
1511
+ /**
1512
+ * Create a cold start optimizer with automatic tier detection
1513
+ *
1514
+ * Simplifies configuration by automatically detecting available tiers.
1515
+ *
1516
+ * @example
1517
+ * ```typescript
1518
+ * const optimizer = createAutoTieredOptimizer({
1519
+ * wasmModule: pgliteWasm,
1520
+ * env: {
1521
+ * R2_BUCKET: env.R2_BUCKET,
1522
+ * },
1523
+ * databaseId: 'my-database',
1524
+ * })
1525
+ * ```
1526
+ */
1527
+ export function createAutoTieredOptimizer(options: {
1528
+ wasmModule: WebAssembly.Module
1529
+ databaseId: string
1530
+ env?: {
1531
+ R2_BUCKET?: R2Bucket
1532
+ }
1533
+ cacheLayer?: CacheLayer
1534
+ r2Layer?: R2StorageLayer
1535
+ hotData?: ArrayBuffer | Uint8Array
1536
+ lazy?: boolean
1537
+ debug?: boolean
1538
+ }): ColdStartOptimizer {
1539
+ const {
1540
+ wasmModule,
1541
+ databaseId,
1542
+ env,
1543
+ cacheLayer,
1544
+ r2Layer,
1545
+ hotData,
1546
+ lazy = true,
1547
+ debug = false,
1548
+ } = options
1549
+
1550
+ return createColdStartOptimizer({
1551
+ wasmModule,
1552
+ hotData,
1553
+ cacheLayer,
1554
+ warmCacheKey: cacheLayer ? `pglite:${databaseId}` : undefined,
1555
+ r2Layer,
1556
+ r2Bucket: env?.R2_BUCKET,
1557
+ coldStorageKey:
1558
+ r2Layer || env?.R2_BUCKET ? `databases/${databaseId}/data.tar` : undefined,
1559
+ database: databaseId,
1560
+ lazy,
1561
+ debug,
1562
+ })
1563
+ }
1564
+
1565
+ // ============================================================================
1566
+ // Exports
1567
+ // ============================================================================
1568
+
1569
+ export {
1570
+ createColdStartOptimizer as default,
1571
+ }
1572
+
1573
+ // ============================================================================
1574
+ // WASM Strategy Comparison
1575
+ // ============================================================================
1576
+
1577
+ /**
1578
+ * WASM loading strategy types for benchmarking
1579
+ *
1580
+ * Different strategies have different performance characteristics:
1581
+ *
1582
+ * | Strategy | Description | Best For |
1583
+ * |----------|-------------|----------|
1584
+ * | `static_import` | Pre-compiled at build time | Production (Cloudflare Workers) |
1585
+ * | `dynamic_import` | Compiled on demand | Development, testing |
1586
+ * | `streaming` | Compile during download | Large modules, Node.js |
1587
+ * | `cached` | Reused from isolate cache | Warm starts |
1588
+ *
1589
+ * In Cloudflare Workers, `static_import` is required because runtime
1590
+ * WASM compilation is blocked for security reasons.
1591
+ */
1592
+ export type WasmLoadingStrategy = 'static_import' | 'dynamic_import' | 'streaming' | 'cached'
1593
+
1594
+ /**
1595
+ * Results from comparing different WASM loading strategies
1596
+ *
1597
+ * Contains statistical analysis of multiple profiling runs for a single strategy.
1598
+ * Used to compare performance across different loading approaches.
1599
+ */
1600
+ export interface WasmStrategyComparisonResult {
1601
+ strategy: WasmLoadingStrategy
1602
+ samples: number
1603
+ meanMs: number
1604
+ medianMs: number
1605
+ p95Ms: number
1606
+ p99Ms: number
1607
+ minMs: number
1608
+ maxMs: number
1609
+ stdDevMs: number
1610
+ available: boolean
1611
+ vsBaselinePercent?: number
1612
+ }
1613
+
1614
+ /**
1615
+ * Profile a WASM loading strategy by running multiple iterations
1616
+ *
1617
+ * Runs the provided loader function multiple times and calculates
1618
+ * statistical metrics (mean, median, percentiles) for comparison.
1619
+ *
1620
+ * @param strategy - The strategy name for labeling results
1621
+ * @param loader - Function that loads the WASM module
1622
+ * @param iterations - Number of times to run the loader (default: 5)
1623
+ * @returns Statistical analysis of loading times
1624
+ *
1625
+ * @example
1626
+ * ```typescript
1627
+ * const result = await profileWasmStrategy(
1628
+ * 'static_import',
1629
+ * async () => {
1630
+ * // Load WASM module
1631
+ * return WebAssembly.compile(wasmBytes)
1632
+ * },
1633
+ * 10 // Run 10 iterations
1634
+ * )
1635
+ *
1636
+ * console.log(`Median: ${result.medianMs}ms`)
1637
+ * console.log(`P95: ${result.p95Ms}ms`)
1638
+ * ```
1639
+ */
1640
+ export async function profileWasmStrategy(
1641
+ strategy: WasmLoadingStrategy,
1642
+ loader: () => Promise<WebAssembly.Module | void>,
1643
+ iterations = 5
1644
+ ): Promise<WasmStrategyComparisonResult> {
1645
+ const samples: number[] = []
1646
+
1647
+ for (let i = 0; i < iterations; i++) {
1648
+ const start = performance.now()
1649
+ await loader()
1650
+ const end = performance.now()
1651
+ samples.push(end - start)
1652
+ }
1653
+
1654
+ const sorted = [...samples].sort((a, b) => a - b)
1655
+ const sum = sorted.reduce((a, b) => a + b, 0)
1656
+ const mean = sum / sorted.length
1657
+ const variance = sorted.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / sorted.length
1658
+
1659
+ const percentile = (p: number): number => {
1660
+ const index = Math.ceil((p / 100) * sorted.length) - 1
1661
+ return sorted[Math.max(0, Math.min(index, sorted.length - 1))]
1662
+ }
1663
+
1664
+ return {
1665
+ strategy,
1666
+ samples: iterations,
1667
+ meanMs: mean,
1668
+ medianMs: percentile(50),
1669
+ p95Ms: percentile(95),
1670
+ p99Ms: percentile(99),
1671
+ minMs: sorted[0],
1672
+ maxMs: sorted[sorted.length - 1],
1673
+ stdDevMs: Math.sqrt(variance),
1674
+ available: true,
1675
+ }
1676
+ }
1677
+
1678
+ /**
1679
+ * Compare multiple WASM loading strategies
1680
+ *
1681
+ * Profiles multiple loading strategies and provides a recommendation
1682
+ * based on median performance. Generates a human-readable analysis report.
1683
+ *
1684
+ * @param strategies - Map of strategy names to loader functions
1685
+ * @param iterations - Number of iterations per strategy (default: 5)
1686
+ * @returns Object containing:
1687
+ * - `results`: Statistical results for each strategy
1688
+ * - `recommendation`: The fastest strategy based on median time
1689
+ * - `analysis`: Human-readable performance report
1690
+ *
1691
+ * @example
1692
+ * ```typescript
1693
+ * const strategies = new Map([
1694
+ * ['static_import', async () => staticWasmModule],
1695
+ * ['dynamic_import', async () => {
1696
+ * const { PGlite } = await import('@dotdo/pglite')
1697
+ * return PGlite.wasmModule
1698
+ * }],
1699
+ * ])
1700
+ *
1701
+ * const { results, recommendation, analysis } = await compareWasmStrategies(strategies, 5)
1702
+ *
1703
+ * console.log(analysis)
1704
+ * // Output:
1705
+ * // WASM Loading Strategy Analysis
1706
+ * // ========================================
1707
+ * // static_import:
1708
+ * // Median: 0.05ms
1709
+ * // P95: 0.10ms
1710
+ * // dynamic_import:
1711
+ * // Median: 15.00ms
1712
+ * // P95: 20.00ms
1713
+ * // vs static_import: 29900% slower
1714
+ * // ========================================
1715
+ * // Recommendation: static_import
1716
+ * ```
1717
+ */
1718
+ export async function compareWasmStrategies(
1719
+ strategies: Map<WasmLoadingStrategy, () => Promise<WebAssembly.Module | void>>,
1720
+ iterations = 5
1721
+ ): Promise<{
1722
+ results: WasmStrategyComparisonResult[]
1723
+ recommendation: WasmLoadingStrategy
1724
+ analysis: string
1725
+ }> {
1726
+ const results: WasmStrategyComparisonResult[] = []
1727
+ let baselineMedian: number | null = null
1728
+
1729
+ for (const [strategy, loader] of strategies) {
1730
+ try {
1731
+ const result = await profileWasmStrategy(strategy, loader, iterations)
1732
+ if (strategy === 'static_import') {
1733
+ baselineMedian = result.medianMs
1734
+ }
1735
+ results.push(result)
1736
+ } catch {
1737
+ results.push({
1738
+ strategy,
1739
+ samples: 0,
1740
+ meanMs: 0,
1741
+ medianMs: 0,
1742
+ p95Ms: 0,
1743
+ p99Ms: 0,
1744
+ minMs: 0,
1745
+ maxMs: 0,
1746
+ stdDevMs: 0,
1747
+ available: false,
1748
+ })
1749
+ }
1750
+ }
1751
+
1752
+ if (baselineMedian !== null) {
1753
+ for (const result of results) {
1754
+ if (result.available && result.strategy !== 'static_import') {
1755
+ result.vsBaselinePercent = ((result.medianMs - baselineMedian) / baselineMedian) * 100
1756
+ }
1757
+ }
1758
+ }
1759
+
1760
+ const availableResults = results.filter((r) => r.available)
1761
+ const sortedByMedian = [...availableResults].sort((a, b) => a.medianMs - b.medianMs)
1762
+ const recommendation = sortedByMedian[0]?.strategy ?? 'static_import'
1763
+
1764
+ const lines: string[] = ['WASM Loading Strategy Analysis', '='.repeat(40)]
1765
+ for (const result of results) {
1766
+ if (!result.available) {
1767
+ lines.push('\n' + result.strategy + ': NOT AVAILABLE')
1768
+ continue
1769
+ }
1770
+ lines.push('\n' + result.strategy + ':')
1771
+ lines.push(' Median: ' + result.medianMs.toFixed(2) + 'ms')
1772
+ lines.push(' P95: ' + result.p95Ms.toFixed(2) + 'ms')
1773
+ lines.push(' StdDev: ' + result.stdDevMs.toFixed(2) + 'ms')
1774
+ if (result.vsBaselinePercent !== undefined) {
1775
+ const comparison = result.vsBaselinePercent > 0 ? 'slower' : 'faster'
1776
+ lines.push(' vs static_import: ' + Math.abs(result.vsBaselinePercent).toFixed(1) + '% ' + comparison)
1777
+ }
1778
+ }
1779
+ lines.push('\n' + '='.repeat(40))
1780
+ lines.push('Recommendation: ' + recommendation)
1781
+
1782
+ return { results, recommendation, analysis: lines.join('\n') }
1783
+ }
1784
+
1785
+ // ============================================================================
1786
+ // Cold Start Profiler
1787
+ // ============================================================================
1788
+
1789
+ /**
1790
+ * Profiling result from multiple cold start runs
1791
+ *
1792
+ * Contains comprehensive statistical analysis of cold start performance,
1793
+ * including per-phase breakdown and data source distribution.
1794
+ *
1795
+ * ## Key Metrics
1796
+ *
1797
+ * - `totalMs`: Overall cold start time statistics
1798
+ * - `phases`: Per-phase timing breakdown (WASM prep, data fetch, PGLite init, prewarm)
1799
+ * - `dataSourceDistribution`: How often each storage tier was used
1800
+ * - `memoryMB`: Memory usage statistics (if available)
1801
+ *
1802
+ * ## Usage in CI
1803
+ *
1804
+ * Use this for performance regression detection:
1805
+ *
1806
+ * ```typescript
1807
+ * const result = await profileColdStarts(optimizer, 10)
1808
+ *
1809
+ * // Assert against performance budget
1810
+ * expect(result.totalMs.p95).toBeLessThan(1500)
1811
+ * expect(result.totalMs.median).toBeLessThan(800)
1812
+ * ```
1813
+ */
1814
+ export interface ColdStartProfilingResult {
1815
+ samples: number
1816
+ totalMs: {
1817
+ mean: number
1818
+ median: number
1819
+ p95: number
1820
+ p99: number
1821
+ min: number
1822
+ max: number
1823
+ stdDev: number
1824
+ }
1825
+ phases: {
1826
+ wasmPrep: { mean: number; median: number; p95: number }
1827
+ dataFetch: { mean: number; median: number; p95: number }
1828
+ pgliteInit: { mean: number; median: number; p95: number }
1829
+ prewarm: { mean: number; median: number; p95: number }
1830
+ }
1831
+ dataSourceDistribution: Record<string, number>
1832
+ memoryMB?: { mean: number; max: number }
1833
+ rawMetrics: ColdStartMetrics[]
1834
+ }
1835
+
1836
+ /**
1837
+ * Format profiling results as human-readable string
1838
+ *
1839
+ * Generates a comprehensive text report suitable for logging, CI output,
1840
+ * or documentation.
1841
+ *
1842
+ * @param result - Profiling results to format
1843
+ * @returns Multi-line string with formatted statistics
1844
+ *
1845
+ * @example
1846
+ * ```typescript
1847
+ * const result = await profileColdStarts(optimizer, 10)
1848
+ * const report = formatProfilingResult(result)
1849
+ * console.log(report)
1850
+ *
1851
+ * // Output:
1852
+ * // Cold Start Profiling Results
1853
+ * // ========================================
1854
+ * // Samples: 10
1855
+ * //
1856
+ * // Total Cold Start Time:
1857
+ * // Mean: 750.00ms
1858
+ * // Median (p50): 720.00ms
1859
+ * // P95: 1200.00ms
1860
+ * // ...
1861
+ * ```
1862
+ */
1863
+ export function formatProfilingResult(result: ColdStartProfilingResult): string {
1864
+ const lines: string[] = [
1865
+ 'Cold Start Profiling Results',
1866
+ '='.repeat(40),
1867
+ 'Samples: ' + result.samples,
1868
+ '',
1869
+ 'Total Cold Start Time:',
1870
+ ' Mean: ' + result.totalMs.mean.toFixed(2) + 'ms',
1871
+ ' Median (p50): ' + result.totalMs.median.toFixed(2) + 'ms',
1872
+ ' P95: ' + result.totalMs.p95.toFixed(2) + 'ms',
1873
+ ' P99: ' + result.totalMs.p99.toFixed(2) + 'ms',
1874
+ ' Min: ' + result.totalMs.min.toFixed(2) + 'ms',
1875
+ ' Max: ' + result.totalMs.max.toFixed(2) + 'ms',
1876
+ ' StdDev: ' + result.totalMs.stdDev.toFixed(2) + 'ms',
1877
+ '',
1878
+ 'Phase Breakdown (median):',
1879
+ ' WASM Prep: ' + result.phases.wasmPrep.median.toFixed(2) + 'ms',
1880
+ ' Data Fetch: ' + result.phases.dataFetch.median.toFixed(2) + 'ms',
1881
+ ' PGLite Init: ' + result.phases.pgliteInit.median.toFixed(2) + 'ms',
1882
+ ' Prewarm: ' + result.phases.prewarm.median.toFixed(2) + 'ms',
1883
+ '',
1884
+ 'Data Source Distribution:',
1885
+ ...Object.entries(result.dataSourceDistribution).map(
1886
+ ([source, count]) => ' ' + source + ': ' + count + ' (' + ((count / result.samples) * 100).toFixed(1) + '%)'
1887
+ ),
1888
+ ]
1889
+
1890
+ if (result.memoryMB) {
1891
+ lines.push('', 'Memory Usage:', ' Mean: ' + result.memoryMB.mean.toFixed(2) + 'MB', ' Max: ' + result.memoryMB.max.toFixed(2) + 'MB')
1892
+ }
1893
+
1894
+ return lines.join('\n')
1895
+ }