@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,1990 @@
1
+ /**
2
+ * Memory Pressure Monitoring and OOM Protection for PostgresDO
3
+ *
4
+ * This module provides memory monitoring capabilities for PGLite running
5
+ * in Cloudflare Workers (128MB limit). It detects high memory usage and
6
+ * can automatically take protective actions to prevent OOM crashes.
7
+ *
8
+ * ## Key Features
9
+ *
10
+ * - **Real-time memory pressure tracking** - Monitors heap usage and classifies
11
+ * pressure levels (normal, warning, critical, oom)
12
+ * - **Automatic extension unloading** - Drops least-important PostgreSQL extensions
13
+ * when memory is critically low
14
+ * - **GC hint triggering** - Suggests garbage collection at configurable thresholds
15
+ * with rate limiting to prevent thrashing
16
+ * - **Cache eviction** - Automatically evicts cache entries under pressure using
17
+ * configurable strategies (LRU, largest-first)
18
+ * - **Query management** - Pauses or rejects queries under extreme pressure
19
+ * - **Recovery with hysteresis** - Prevents oscillation by requiring sustained
20
+ * normal pressure before full recovery
21
+ * - **Metrics export** - Prometheus and JSON format metrics for observability
22
+ *
23
+ * ## Usage
24
+ *
25
+ * ```typescript
26
+ * import { createMemoryPressureManager } from './memory-pressure'
27
+ *
28
+ * const manager = createMemoryPressureManager({
29
+ * warningThresholdPercent: 70,
30
+ * criticalThresholdPercent: 85,
31
+ * autoUnloadExtensions: true,
32
+ * })
33
+ *
34
+ * // Listen for pressure changes
35
+ * const unsubscribe = manager.onPressureChange((event) => {
36
+ * console.log(`Pressure: ${event.previousLevel} -> ${event.currentLevel}`)
37
+ * })
38
+ *
39
+ * // Start monitoring
40
+ * manager.startMonitoring()
41
+ *
42
+ * // Check status at any time
43
+ * const stats = manager.getMemoryStats()
44
+ *
45
+ * // Clean up when done
46
+ * manager.dispose()
47
+ * ```
48
+ *
49
+ * ## Cloudflare Workers Constraints
50
+ *
51
+ * - 128MB total memory limit per isolate
52
+ * - ~15MB static (WASM + data + JS)
53
+ * - ~16MB shared_buffers
54
+ * - ~16MB WAL + buffers
55
+ * - ~10MB PostgreSQL catalog/metadata
56
+ * - ~71MB available for queries, results, and runtime
57
+ *
58
+ * @module worker/memory-pressure
59
+ */
60
+ // =============================================================================
61
+ // Imported Constants (from centralized config)
62
+ // =============================================================================
63
+ import { WORKER_MEMORY_LIMIT_BYTES, PGLITE_BASELINE_BYTES, DEFAULT_WARNING_THRESHOLD_PERCENT, DEFAULT_CRITICAL_THRESHOLD_PERCENT, DEFAULT_OOM_THRESHOLD_PERCENT, MEMORY_SPIKE_THRESHOLD_BYTES, DEFAULT_METRICS_HISTORY_SIZE, } from '../config/memory';
64
+ import { DEFAULT_CHECK_INTERVAL_MS, DEFAULT_GC_HINT_MIN_INTERVAL_MS, DEFAULT_RECOVERY_HYSTERESIS_MS, DEFAULT_QUERY_PAUSE_TIMEOUT_MS, DEFAULT_RECOVERY_STEP_INTERVAL_MS, DEFAULT_SUSTAINED_PRESSURE_THRESHOLD_MS, DEFAULT_MAX_LISTENERS, } from '../config/timeouts';
65
+ // =============================================================================
66
+ // Local Constant Aliases (for backward compatibility in this module)
67
+ // =============================================================================
68
+ /** Default Cloudflare Worker memory limit: 128MB */
69
+ const DEFAULT_MEMORY_LIMIT_BYTES = WORKER_MEMORY_LIMIT_BYTES;
70
+ /** Default pressure thresholds (percentage of memory limit) */
71
+ const DEFAULT_WARNING_THRESHOLD = DEFAULT_WARNING_THRESHOLD_PERCENT;
72
+ const DEFAULT_CRITICAL_THRESHOLD = DEFAULT_CRITICAL_THRESHOLD_PERCENT;
73
+ const DEFAULT_OOM_THRESHOLD = DEFAULT_OOM_THRESHOLD_PERCENT;
74
+ /** Spike detection threshold: 10MB sudden increase */
75
+ const SPIKE_DETECTION_THRESHOLD_BYTES = MEMORY_SPIKE_THRESHOLD_BYTES;
76
+ /**
77
+ * Extensions safe to unload under memory pressure, ordered by priority.
78
+ * First = least important = dropped first.
79
+ */
80
+ const DEFAULT_EXTENSION_UNLOAD_PRIORITY = [
81
+ 'tablefunc', // Rarely used in typical workloads
82
+ 'fuzzystrmatch', // Nice to have for fuzzy matching
83
+ 'unaccent', // Text processing utility
84
+ 'btree_gist', // Index type - usually not critical
85
+ 'btree_gin', // Index type - usually not critical
86
+ 'intarray', // Array functions
87
+ 'cube', // Multi-dimensional data
88
+ 'earthdistance', // Geo calculations (depends on cube)
89
+ 'ltree', // Tree data
90
+ 'hstore', // Key-value pairs
91
+ 'citext', // Case-insensitive text
92
+ 'pg_trgm', // Trigram matching
93
+ 'pgcrypto', // Crypto functions - often important
94
+ 'uuid_ossp', // UUID generation - often important
95
+ 'vector', // Vector search - often critical for AI apps
96
+ ];
97
+ /** Default features that can be disabled under pressure */
98
+ const DEFAULT_FEATURES_TO_DISABLE = ['caching', 'prefetching', 'parallel-queries'];
99
+ /** Default eviction target percentages by pressure level */
100
+ const DEFAULT_EVICTION_TARGET_PERCENT = {
101
+ normal: 0,
102
+ warning: 20,
103
+ critical: 50,
104
+ oom: 100,
105
+ };
106
+ /** Pressure level numeric indices for fast comparison */
107
+ const PRESSURE_LEVEL_INDEX = {
108
+ normal: 0,
109
+ warning: 1,
110
+ critical: 2,
111
+ oom: 3,
112
+ };
113
+ /** Default demotion configuration per pressure level */
114
+ const DEFAULT_DEMOTION_CONFIG = {
115
+ warning: { hotEvictCount: 10, warmDemoteCount: 0 },
116
+ critical: { hotEvictCount: 25, warmDemoteCount: 5 },
117
+ oom: { hotEvictCount: 50, warmDemoteCount: 15 },
118
+ };
119
+ /** Default minimum interval between pressure-triggered demotions */
120
+ const DEFAULT_DEMOTION_MIN_INTERVAL_MS = 500;
121
+ // =============================================================================
122
+ // Optimized Constants for Memory Pressure Heuristics
123
+ // =============================================================================
124
+ /**
125
+ * EMA (Exponential Moving Average) smoothing factor for heap usage.
126
+ * Range: 0-1, higher = more weight on recent samples, lower = more smoothing.
127
+ * 0.3 provides good balance between responsiveness and noise reduction.
128
+ */
129
+ const EMA_SMOOTHING_FACTOR = 0.3;
130
+ /**
131
+ * Minimum samples required for reliable trend detection.
132
+ * Below this, predictions have low confidence.
133
+ */
134
+ const MIN_SAMPLES_FOR_TREND = 5;
135
+ /**
136
+ * Minimum samples for high-confidence OOM prediction.
137
+ */
138
+ const MIN_SAMPLES_FOR_OOM_PREDICTION = 10;
139
+ /**
140
+ * Growth rate threshold for "stable" classification (1KB/s).
141
+ * Memory changes below this are considered noise.
142
+ */
143
+ const STABLE_GROWTH_THRESHOLD_BYTES_PER_SEC = 1024;
144
+ /**
145
+ * Rapid growth threshold (5MB/s) - triggers more aggressive responses.
146
+ */
147
+ const RAPID_GROWTH_THRESHOLD_BYTES_PER_SEC = 5 * 1024 * 1024;
148
+ /**
149
+ * OOM prediction horizon - warn if OOM predicted within this time.
150
+ */
151
+ const OOM_PREDICTION_HORIZON_MS = 60000;
152
+ /**
153
+ * Hysteresis margin for pressure level changes (2%).
154
+ * Prevents oscillation when hovering near thresholds.
155
+ * Reserved for future hysteresis implementation.
156
+ */
157
+ const _PRESSURE_HYSTERESIS_PERCENT = 2;
158
+ void _PRESSURE_HYSTERESIS_PERCENT; // Suppress unused warning - reserved for future use
159
+ /**
160
+ * Heap sampling constants - optimized for balance between accuracy and speed.
161
+ * Reserved for future heap sampling implementation.
162
+ */
163
+ const _HEAP_SAMPLE_STRIDE_SHIFT = 8; // ~256 samples, uses bit shift for speed
164
+ const _HEAP_SAMPLE_UNROLL_FACTOR = 4; // Unroll factor for loop optimization
165
+ void _HEAP_SAMPLE_STRIDE_SHIFT; // Suppress unused warning - reserved for future use
166
+ void _HEAP_SAMPLE_UNROLL_FACTOR; // Suppress unused warning - reserved for future use
167
+ /**
168
+ * Error thrown when memory pressure prevents an operation
169
+ */
170
+ export class MemoryPressureError extends Error {
171
+ code = 'MEMORY_PRESSURE_HIGH';
172
+ memoryStats;
173
+ constructor(message, memoryStats) {
174
+ super(message);
175
+ this.name = 'MemoryPressureError';
176
+ this.memoryStats = memoryStats;
177
+ }
178
+ }
179
+ // =============================================================================
180
+ // Helper Functions
181
+ // =============================================================================
182
+ // Cache performance.memory reference to avoid repeated property access
183
+ let cachedPerformanceMemory;
184
+ /**
185
+ * Estimate WASM heap memory usage.
186
+ *
187
+ * In Cloudflare Workers, we can't directly access Emscripten's HEAP.
188
+ * This function provides an estimate based on available metrics.
189
+ *
190
+ * Optimized: Caches performance.memory reference to reduce property lookups.
191
+ *
192
+ * Priority:
193
+ * 1. performance.memory.usedJSHeapSize (if available)
194
+ * 2. Conservative estimate based on typical PGLite footprint
195
+ */
196
+ function estimateHeapUsage() {
197
+ // Check cache first (undefined = not checked, null = not available)
198
+ if (cachedPerformanceMemory === undefined) {
199
+ if (typeof performance !== 'undefined' && 'memory' in performance) {
200
+ cachedPerformanceMemory = performance.memory ?? null;
201
+ }
202
+ else {
203
+ cachedPerformanceMemory = null;
204
+ }
205
+ }
206
+ if (cachedPerformanceMemory && typeof cachedPerformanceMemory.usedJSHeapSize === 'number') {
207
+ return cachedPerformanceMemory.usedJSHeapSize;
208
+ }
209
+ // Fallback: use pre-computed constant
210
+ return PGLITE_BASELINE_BYTES;
211
+ }
212
+ /**
213
+ * Determine memory pressure level from usage percentage.
214
+ * Optimized: Uses direct comparisons in descending order for early exit.
215
+ */
216
+ function getPressureLevelFromPercent(usagePercent, thresholds) {
217
+ // Check highest threshold first for fast rejection
218
+ if (usagePercent >= thresholds.oomThresholdPercent)
219
+ return 'oom';
220
+ if (usagePercent >= thresholds.criticalThresholdPercent)
221
+ return 'critical';
222
+ if (usagePercent >= thresholds.warningThresholdPercent)
223
+ return 'warning';
224
+ return 'normal';
225
+ }
226
+ /**
227
+ * Get numeric index for pressure level comparison.
228
+ * Optimized: Uses pre-computed lookup table instead of array search.
229
+ */
230
+ function getPressureLevelIndex(level) {
231
+ return PRESSURE_LEVEL_INDEX[level];
232
+ }
233
+ /**
234
+ * Calculate average of an array of numbers.
235
+ * Optimized: Uses for loop instead of reduce for better performance.
236
+ */
237
+ function average(values) {
238
+ const len = values.length;
239
+ if (len === 0)
240
+ return 0;
241
+ let sum = 0;
242
+ for (let i = 0; i < len; i++) {
243
+ sum += values[i] ?? 0;
244
+ }
245
+ return sum / len;
246
+ }
247
+ /**
248
+ * Calculate variance of an array of numbers.
249
+ * Optimized: Single-pass Welford's algorithm for numerical stability.
250
+ */
251
+ function variance(values) {
252
+ const len = values.length;
253
+ if (len < 2)
254
+ return 0;
255
+ let mean = 0;
256
+ let m2 = 0;
257
+ for (let i = 0; i < len; i++) {
258
+ const value = values[i] ?? 0;
259
+ const delta = value - mean;
260
+ mean += delta / (i + 1);
261
+ m2 += delta * (value - mean);
262
+ }
263
+ return m2 / (len - 1);
264
+ }
265
+ /**
266
+ * Simple linear regression for trend analysis.
267
+ * Returns slope (bytes/ms), intercept, and R-squared.
268
+ * Optimized: Single-pass calculation.
269
+ */
270
+ function linearRegression(samples) {
271
+ const n = samples.length;
272
+ if (n < 2)
273
+ return { slope: 0, intercept: 0, rSquared: 0 };
274
+ // Use first timestamp as origin for numerical stability
275
+ const t0 = samples[0].timestamp.getTime();
276
+ let sumX = 0;
277
+ let sumY = 0;
278
+ let sumXY = 0;
279
+ let sumX2 = 0;
280
+ let sumY2 = 0;
281
+ for (let i = 0; i < n; i++) {
282
+ const sample = samples[i];
283
+ const x = sample.timestamp.getTime() - t0;
284
+ const y = sample.heapUsed;
285
+ sumX += x;
286
+ sumY += y;
287
+ sumXY += x * y;
288
+ sumX2 += x * x;
289
+ sumY2 += y * y;
290
+ }
291
+ const denom = n * sumX2 - sumX * sumX;
292
+ if (Math.abs(denom) < 1e-10)
293
+ return { slope: 0, intercept: sumY / n, rSquared: 0 };
294
+ const slope = (n * sumXY - sumX * sumY) / denom;
295
+ const intercept = (sumY - slope * sumX) / n;
296
+ // Calculate R-squared
297
+ const meanY = sumY / n;
298
+ let ssRes = 0;
299
+ let ssTot = 0;
300
+ for (let i = 0; i < n; i++) {
301
+ const sample = samples[i];
302
+ const x = sample.timestamp.getTime() - t0;
303
+ const y = sample.heapUsed;
304
+ const yPred = slope * x + intercept;
305
+ ssRes += (y - yPred) ** 2;
306
+ ssTot += (y - meanY) ** 2;
307
+ }
308
+ const rSquared = ssTot > 0 ? 1 - ssRes / ssTot : 0;
309
+ return { slope, intercept, rSquared };
310
+ }
311
+ /**
312
+ * Apply EMA (Exponential Moving Average) update.
313
+ * @param current - Current EMA value
314
+ * @param newValue - New sample value
315
+ * @param alpha - Smoothing factor (0-1)
316
+ */
317
+ function updateEMA(current, newValue, alpha = EMA_SMOOTHING_FACTOR) {
318
+ return alpha * newValue + (1 - alpha) * current;
319
+ }
320
+ /**
321
+ * Ring buffer for efficient fixed-size history storage.
322
+ * Avoids shift() operations which are O(n) on arrays.
323
+ */
324
+ class RingBuffer {
325
+ buffer;
326
+ capacity;
327
+ head = 0;
328
+ _size = 0;
329
+ constructor(capacity) {
330
+ this.capacity = capacity;
331
+ this.buffer = new Array(capacity);
332
+ }
333
+ push(item) {
334
+ this.buffer[this.head] = item;
335
+ this.head = (this.head + 1) % this.capacity;
336
+ if (this._size < this.capacity)
337
+ this._size++;
338
+ }
339
+ get size() {
340
+ return this._size;
341
+ }
342
+ /** Get item at logical index (0 = oldest, size-1 = newest) */
343
+ get(index) {
344
+ if (index < 0 || index >= this._size)
345
+ return undefined;
346
+ const bufferIndex = (this.head - this._size + index + this.capacity) % this.capacity;
347
+ return this.buffer[bufferIndex];
348
+ }
349
+ /** Get the oldest item */
350
+ first() {
351
+ return this._size > 0 ? this.get(0) : undefined;
352
+ }
353
+ /** Get the newest item */
354
+ last() {
355
+ return this._size > 0 ? this.get(this._size - 1) : undefined;
356
+ }
357
+ /** Convert to array (oldest to newest) */
358
+ toArray() {
359
+ const result = [];
360
+ for (let i = 0; i < this._size; i++) {
361
+ const item = this.get(i);
362
+ if (item !== undefined)
363
+ result.push(item);
364
+ }
365
+ return result;
366
+ }
367
+ clear() {
368
+ this.head = 0;
369
+ this._size = 0;
370
+ // Don't clear buffer - items will be overwritten
371
+ }
372
+ }
373
+ // =============================================================================
374
+ // Memory Pressure Manager
375
+ // =============================================================================
376
+ /**
377
+ * Memory Pressure Manager for PostgresDO
378
+ *
379
+ * Monitors memory usage and takes protective actions to prevent OOM crashes
380
+ * in Cloudflare Workers. Provides configurable thresholds, automatic actions,
381
+ * and detailed metrics for observability.
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const manager = new MemoryPressureManager({
386
+ * warningThresholdPercent: 70,
387
+ * criticalThresholdPercent: 85,
388
+ * onGCHint: (level, { aggressive }) => {
389
+ * if (aggressive) globalThis.gc?.()
390
+ * },
391
+ * })
392
+ *
393
+ * manager.onPressureChange((event) => {
394
+ * console.log(`Pressure: ${event.currentLevel}`)
395
+ * })
396
+ *
397
+ * manager.startMonitoring()
398
+ * ```
399
+ */
400
+ export class MemoryPressureManager {
401
+ // === Configuration ===
402
+ config;
403
+ extendedConfig;
404
+ metricsHistorySize;
405
+ // === External Dependencies ===
406
+ pglite = null;
407
+ wasmModule = null;
408
+ cacheManager = null;
409
+ // === State Tracking ===
410
+ lastPressureLevel = 'normal';
411
+ pressureLevelStartTime = Date.now();
412
+ pressureDurations = { normal: 0, warning: 0, critical: 0, oom: 0 };
413
+ sustainedPressureAlerted = false;
414
+ // === Recovery State ===
415
+ inRecoveryMode = false;
416
+ recoveryProgress = 1.0;
417
+ recoveryStartTime = null;
418
+ recoveryPaused = false;
419
+ recoveryStepsExecuted = [];
420
+ // === Feature Management ===
421
+ enabledFeatures;
422
+ disabledFeatures = new Set();
423
+ unloadedExtensions = new Set();
424
+ // === Query Management ===
425
+ pausedQueries = new Map();
426
+ inFlightQueries = new Map();
427
+ // === Metrics & History (using ring buffers for efficiency) ===
428
+ metricsHistory;
429
+ lastHeapSample = 0;
430
+ gcMetrics;
431
+ lastGCHintTime = 0;
432
+ // === Listeners ===
433
+ listeners = [];
434
+ memorySpikeListeners = [];
435
+ recoveryListeners = [];
436
+ pressureDemotionListeners = [];
437
+ // === Tiered Storage Integration ===
438
+ tieredStorageOrchestrator = null;
439
+ demotionMetrics = {
440
+ pressureTriggeredDemotions: 0,
441
+ demotionsByPressureLevel: { normal: 0, warning: 0, critical: 0, oom: 0 },
442
+ failedDemotions: 0,
443
+ bytesFreedByDemotion: 0,
444
+ lastDemotionTimestamp: null,
445
+ };
446
+ lastPressureDemotionTime = 0;
447
+ // === Intervals ===
448
+ checkInterval = null;
449
+ sustainedPressureCheckInterval = null;
450
+ gradualRecoveryInterval = null;
451
+ // === Smoothed Pressure State (for EMA-based detection) ===
452
+ smoothedState = {
453
+ emaHeapUsage: 0,
454
+ emaPressureLevel: 0,
455
+ recentVariance: 0,
456
+ trend: 'stable',
457
+ lastRawHeapUsage: 0,
458
+ };
459
+ smoothedStateInitialized = false;
460
+ // === Testing Support ===
461
+ simulatedHeapBytes = 0;
462
+ forcedHeapUsage = null;
463
+ constructor(config = {}) {
464
+ this.extendedConfig = config;
465
+ this.config = {
466
+ enabled: config.enabled ?? true,
467
+ memoryLimitBytes: config.memoryLimitBytes ?? DEFAULT_MEMORY_LIMIT_BYTES,
468
+ warningThresholdPercent: config.warningThresholdPercent ?? DEFAULT_WARNING_THRESHOLD,
469
+ criticalThresholdPercent: config.criticalThresholdPercent ?? DEFAULT_CRITICAL_THRESHOLD,
470
+ oomThresholdPercent: config.oomThresholdPercent ?? DEFAULT_OOM_THRESHOLD,
471
+ checkIntervalMs: config.checkIntervalMs ?? DEFAULT_CHECK_INTERVAL_MS,
472
+ autoUnloadExtensions: config.autoUnloadExtensions ?? true,
473
+ extensionUnloadPriority: config.extensionUnloadPriority ?? DEFAULT_EXTENSION_UNLOAD_PRIORITY,
474
+ maxListeners: config.maxListeners ?? DEFAULT_MAX_LISTENERS,
475
+ };
476
+ this.metricsHistorySize = config.metricsHistorySize ?? DEFAULT_METRICS_HISTORY_SIZE;
477
+ this.enabledFeatures = new Set(config.featuresToDisable ?? DEFAULT_FEATURES_TO_DISABLE);
478
+ // Initialize ring buffers for efficient history storage
479
+ this.metricsHistory = new RingBuffer(this.metricsHistorySize);
480
+ this.gcMetrics = {
481
+ hints: 0,
482
+ bytesFreed: new RingBuffer(50), // Keep last 50 GC results
483
+ durations: new RingBuffer(50),
484
+ };
485
+ }
486
+ // ===========================================================================
487
+ // Configuration & Setup
488
+ // ===========================================================================
489
+ /**
490
+ * Set the PGlite instance for extension unloading operations.
491
+ *
492
+ * @param pglite - PGLite instance with query method
493
+ */
494
+ setPGlite(pglite) {
495
+ this.pglite = pglite;
496
+ }
497
+ /**
498
+ * Set the WASM module for real-time heap tracking.
499
+ *
500
+ * When set, heap usage is calculated by sampling the HEAPU8 array
501
+ * instead of using estimates.
502
+ *
503
+ * @param module - Emscripten module with HEAPU8 property
504
+ */
505
+ setWasmHeapSource(module) {
506
+ this.wasmModule = module;
507
+ }
508
+ /**
509
+ * Set the cache manager for eviction operations.
510
+ *
511
+ * @param manager - Cache manager with eviction methods
512
+ */
513
+ setCacheManager(manager) {
514
+ this.cacheManager = manager;
515
+ }
516
+ /**
517
+ * Get the current configuration.
518
+ *
519
+ * @returns Copy of the current configuration
520
+ */
521
+ getConfig() {
522
+ return { ...this.config };
523
+ }
524
+ /**
525
+ * Update configuration at runtime.
526
+ *
527
+ * If checkIntervalMs is changed and monitoring is active, it will be restarted.
528
+ *
529
+ * @param config - Partial configuration to merge
530
+ */
531
+ setConfig(config) {
532
+ Object.assign(this.config, config);
533
+ // Restart monitoring if interval changed
534
+ if (config.checkIntervalMs !== undefined && this.checkInterval) {
535
+ this.stopMonitoring();
536
+ this.startMonitoring();
537
+ }
538
+ }
539
+ // ===========================================================================
540
+ // Tiered Storage Orchestrator Integration
541
+ // ===========================================================================
542
+ /**
543
+ * Connect a TieredStorageOrchestrator for pressure-triggered demotions.
544
+ *
545
+ * When connected, the manager will automatically trigger demotions
546
+ * when memory pressure rises above warning level.
547
+ *
548
+ * @param orchestrator - TieredStorageOrchestrator instance or null to disconnect
549
+ */
550
+ setTieredStorageOrchestrator(orchestrator) {
551
+ this.tieredStorageOrchestrator = orchestrator;
552
+ }
553
+ /**
554
+ * Check if a TieredStorageOrchestrator is connected.
555
+ *
556
+ * @returns True if an orchestrator is connected
557
+ */
558
+ hasTieredStorageOrchestrator() {
559
+ return this.tieredStorageOrchestrator !== null;
560
+ }
561
+ /**
562
+ * Get demotion metrics for pressure-triggered demotions.
563
+ *
564
+ * @returns Demotion metrics
565
+ */
566
+ getDemotionMetrics() {
567
+ return { ...this.demotionMetrics };
568
+ }
569
+ /**
570
+ * Add a listener for pressure-triggered demotion events.
571
+ *
572
+ * @param listener - Callback for demotion events
573
+ * @returns Unsubscribe function
574
+ */
575
+ onPressureDemotion(listener) {
576
+ this.pressureDemotionListeners.push(listener);
577
+ return () => {
578
+ const index = this.pressureDemotionListeners.indexOf(listener);
579
+ if (index >= 0)
580
+ this.pressureDemotionListeners.splice(index, 1);
581
+ };
582
+ }
583
+ /**
584
+ * Manually trigger demotions.
585
+ *
586
+ * @param options - Demotion options specifying counts
587
+ * @returns Result of the demotion operation
588
+ */
589
+ async triggerDemotion(options) {
590
+ if (!this.tieredStorageOrchestrator) {
591
+ return { success: false, demotedCount: 0, error: 'Tiered storage orchestrator not connected' };
592
+ }
593
+ try {
594
+ let totalDemoted = 0;
595
+ // Evict from hot tier
596
+ if (options.hotEvictCount > 0) {
597
+ const hotEvents = await this.tieredStorageOrchestrator.evictLRUFromHot(options.hotEvictCount);
598
+ totalDemoted += hotEvents.filter((e) => e.success).length;
599
+ }
600
+ // Demote from warm tier
601
+ if (options.warmDemoteCount > 0) {
602
+ const warmEvents = await this.tieredStorageOrchestrator.runDemotionCycle(options.warmDemoteCount);
603
+ totalDemoted += warmEvents.filter((e) => e.success).length;
604
+ }
605
+ return { success: true, demotedCount: totalDemoted };
606
+ }
607
+ catch (error) {
608
+ return {
609
+ success: false,
610
+ demotedCount: 0,
611
+ error: error instanceof Error ? error.message : String(error),
612
+ };
613
+ }
614
+ }
615
+ /**
616
+ * Handle pressure-triggered demotion based on the current level.
617
+ *
618
+ * This is called automatically when pressure changes if autoDemoteOnPressure is enabled.
619
+ *
620
+ * @param level - Current pressure level
621
+ * @param forceBypassRateLimit - If true, bypass rate limiting (used when pressure escalates)
622
+ */
623
+ async handlePressureDemotion(level, forceBypassRateLimit = false) {
624
+ // Skip if auto-demotion is disabled
625
+ if (this.extendedConfig.autoDemoteOnPressure === false)
626
+ return;
627
+ // Skip if no orchestrator connected
628
+ if (!this.tieredStorageOrchestrator)
629
+ return;
630
+ // Skip for normal pressure
631
+ if (level === 'normal')
632
+ return;
633
+ // Check rate limiting (can be bypassed for escalation)
634
+ const now = Date.now();
635
+ const minInterval = this.extendedConfig.demotionMinIntervalMs ?? DEFAULT_DEMOTION_MIN_INTERVAL_MS;
636
+ if (!forceBypassRateLimit && now - this.lastPressureDemotionTime < minInterval)
637
+ return;
638
+ // Get demotion config for this level
639
+ const demotionConfig = this.extendedConfig.demotionConfig ?? DEFAULT_DEMOTION_CONFIG;
640
+ const levelConfig = demotionConfig[level];
641
+ if (!levelConfig || (levelConfig.hotEvictCount === 0 && levelConfig.warmDemoteCount === 0))
642
+ return;
643
+ // Optionally trigger GC before demotion
644
+ if (this.extendedConfig.gcBeforeDemotion && this.extendedConfig.onGCHint) {
645
+ this.extendedConfig.onGCHint(level, { aggressive: level === 'critical' || level === 'oom' });
646
+ }
647
+ this.lastPressureDemotionTime = now;
648
+ try {
649
+ const allDemotions = [];
650
+ let bytesFreed = 0;
651
+ // Evict from hot tier
652
+ if (levelConfig.hotEvictCount > 0) {
653
+ const hotEvents = await this.tieredStorageOrchestrator.evictLRUFromHot(levelConfig.hotEvictCount);
654
+ allDemotions.push(...hotEvents);
655
+ // Track bytes freed
656
+ for (const event of hotEvents) {
657
+ if (event.success) {
658
+ const entry = this.tieredStorageOrchestrator.getIndexEntry(event.key);
659
+ if (entry)
660
+ bytesFreed += entry.size;
661
+ }
662
+ }
663
+ }
664
+ // Demote from warm tier if critical or oom
665
+ if (levelConfig.warmDemoteCount > 0 && (level === 'critical' || level === 'oom')) {
666
+ const warmEvents = await this.tieredStorageOrchestrator.runDemotionCycle(levelConfig.warmDemoteCount);
667
+ allDemotions.push(...warmEvents);
668
+ }
669
+ // Update metrics
670
+ const successCount = allDemotions.filter((e) => e.success).length;
671
+ const failCount = allDemotions.filter((e) => !e.success).length;
672
+ this.demotionMetrics.pressureTriggeredDemotions += successCount;
673
+ this.demotionMetrics.demotionsByPressureLevel[level] += successCount;
674
+ this.demotionMetrics.failedDemotions += failCount;
675
+ this.demotionMetrics.bytesFreedByDemotion += bytesFreed;
676
+ this.demotionMetrics.lastDemotionTimestamp = now;
677
+ // Emit demotion event
678
+ if (allDemotions.length > 0) {
679
+ const event = {
680
+ pressureLevel: level,
681
+ demotions: allDemotions,
682
+ totalDemoted: successCount,
683
+ timestamp: new Date(),
684
+ };
685
+ for (const listener of this.pressureDemotionListeners) {
686
+ try {
687
+ listener(event);
688
+ }
689
+ catch {
690
+ // Ignore listener errors
691
+ }
692
+ }
693
+ }
694
+ }
695
+ catch (error) {
696
+ this.demotionMetrics.failedDemotions++;
697
+ console.error('Pressure-triggered demotion failed:', error);
698
+ }
699
+ }
700
+ // ===========================================================================
701
+ // Monitoring Control
702
+ // ===========================================================================
703
+ /**
704
+ * Start periodic memory monitoring.
705
+ *
706
+ * Checks memory pressure at the configured interval and takes
707
+ * automatic actions when thresholds are crossed.
708
+ */
709
+ startMonitoring() {
710
+ if (!this.config.enabled || this.checkInterval)
711
+ return;
712
+ this.checkInterval = setInterval(() => {
713
+ this.checkMemoryPressure();
714
+ }, this.config.checkIntervalMs);
715
+ }
716
+ /**
717
+ * Stop periodic memory monitoring.
718
+ */
719
+ stopMonitoring() {
720
+ if (this.checkInterval) {
721
+ clearInterval(this.checkInterval);
722
+ this.checkInterval = null;
723
+ }
724
+ }
725
+ // ===========================================================================
726
+ // Memory Stats & Pressure Detection
727
+ // ===========================================================================
728
+ /**
729
+ * Get current memory statistics.
730
+ *
731
+ * @returns Current memory stats including pressure level
732
+ */
733
+ getMemoryStats() {
734
+ const heapUsed = this.getCurrentHeapUsage();
735
+ const heapLimit = this.config.memoryLimitBytes;
736
+ const usagePercent = (heapUsed / heapLimit) * 100;
737
+ const pressureLevel = getPressureLevelFromPercent(usagePercent, this.config);
738
+ return {
739
+ heapUsed,
740
+ heapLimit,
741
+ usagePercent,
742
+ pressureLevel,
743
+ timestamp: new Date(),
744
+ };
745
+ }
746
+ /**
747
+ * Get current memory pressure level.
748
+ *
749
+ * This calculates the level based on current heap usage,
750
+ * not the cached lastPressureLevel.
751
+ *
752
+ * @returns Current pressure level
753
+ */
754
+ getPressureLevel() {
755
+ return this.getMemoryStats().pressureLevel;
756
+ }
757
+ /**
758
+ * Check if current pressure is at or above a threshold.
759
+ *
760
+ * Uses the cached lastPressureLevel for efficiency.
761
+ *
762
+ * @param level - Level to compare against
763
+ * @returns True if current pressure >= level
764
+ */
765
+ isPressureAtOrAbove(level) {
766
+ return getPressureLevelIndex(this.lastPressureLevel) >= getPressureLevelIndex(level);
767
+ }
768
+ /**
769
+ * Get current heap usage from the best available source.
770
+ *
771
+ * Priority:
772
+ * 1. Forced heap usage (for testing)
773
+ * 2. Simulated heap (for testing)
774
+ * 3. WASM module HEAPU8 (sampled)
775
+ * 4. Estimation fallback
776
+ */
777
+ getCurrentHeapUsage() {
778
+ // Testing overrides
779
+ if (this.forcedHeapUsage !== null)
780
+ return this.forcedHeapUsage;
781
+ if (this.simulatedHeapBytes > 0)
782
+ return this.simulatedHeapBytes;
783
+ // Real WASM heap measurement via sampling
784
+ if (this.wasmModule?.HEAPU8) {
785
+ return this.sampleHeapUsage(this.wasmModule.HEAPU8);
786
+ }
787
+ // Fallback estimation
788
+ return estimateHeapUsage();
789
+ }
790
+ /**
791
+ * Sample WASM heap to estimate used bytes.
792
+ *
793
+ * Optimized: Uses bit-shift for stride calculation (avoiding division),
794
+ * reduced sample size for lower overhead, and unrolled loop for better
795
+ * CPU branch prediction.
796
+ */
797
+ sampleHeapUsage(heap) {
798
+ const len = heap.length;
799
+ if (len === 0)
800
+ return 0;
801
+ // Use bit shift for fast stride calculation (4KB stride = 2^12)
802
+ // This gives us len >> 12 samples, capped at HEAP_SAMPLE_SIZE
803
+ const stride = Math.max(1, len >> 8); // ~256 samples for typical heaps
804
+ let nonZeroCount = 0;
805
+ let sampledCount = 0;
806
+ // Unrolled loop: check 4 positions per iteration when possible
807
+ const end = len - (stride * 3);
808
+ let i = 0;
809
+ for (; i < end; i += stride * 4) {
810
+ if (heap[i] !== 0)
811
+ nonZeroCount++;
812
+ if (heap[i + stride] !== 0)
813
+ nonZeroCount++;
814
+ if (heap[i + stride * 2] !== 0)
815
+ nonZeroCount++;
816
+ if (heap[i + stride * 3] !== 0)
817
+ nonZeroCount++;
818
+ sampledCount += 4;
819
+ }
820
+ // Handle remaining samples
821
+ for (; i < len; i += stride) {
822
+ if (heap[i] !== 0)
823
+ nonZeroCount++;
824
+ sampledCount++;
825
+ }
826
+ if (sampledCount === 0)
827
+ return 0;
828
+ // Use integer math where possible
829
+ return ((len * nonZeroCount) / sampledCount) | 0;
830
+ }
831
+ // ===========================================================================
832
+ // Pressure Check & Response
833
+ // ===========================================================================
834
+ /**
835
+ * Check current memory pressure and take appropriate actions.
836
+ *
837
+ * This is called periodically by startMonitoring() and can also
838
+ * be called manually before expensive operations.
839
+ *
840
+ * @returns Pressure event if level changed, null otherwise
841
+ */
842
+ async checkMemoryPressure() {
843
+ if (!this.config.enabled)
844
+ return null;
845
+ const stats = this.getMemoryStats();
846
+ const previousLevel = this.lastPressureLevel;
847
+ const currentLevel = stats.pressureLevel;
848
+ const now = Date.now();
849
+ // Always record metrics
850
+ this.recordMetricSample();
851
+ // No change - handle sustained pressure check
852
+ if (previousLevel === currentLevel) {
853
+ this.handleSustainedPressure(currentLevel, now);
854
+ return null;
855
+ }
856
+ // Level changed - update tracking
857
+ this.updatePressureDuration(previousLevel, now);
858
+ this.lastPressureLevel = currentLevel;
859
+ this.sustainedPressureAlerted = false;
860
+ // Handle transitions
861
+ const previousIndex = getPressureLevelIndex(previousLevel);
862
+ const currentIndex = getPressureLevelIndex(currentLevel);
863
+ const actionsTaken = [];
864
+ if (currentIndex < previousIndex) {
865
+ // Pressure dropped - handle recovery
866
+ this.handleRecovery(previousLevel, currentLevel, now);
867
+ }
868
+ else {
869
+ // Pressure rose - exit recovery mode
870
+ this.exitRecoveryMode();
871
+ }
872
+ // Take actions based on new pressure level
873
+ if (currentLevel !== 'normal') {
874
+ actionsTaken.push(...(await this.handleElevatedPressure(currentLevel, now)));
875
+ }
876
+ // Emit event
877
+ const event = {
878
+ previousLevel,
879
+ currentLevel,
880
+ stats,
881
+ actionsTaken,
882
+ timestamp: new Date(),
883
+ };
884
+ this.emitPressureEvent(event);
885
+ return event;
886
+ }
887
+ /**
888
+ * Handle sustained pressure alerts.
889
+ */
890
+ handleSustainedPressure(level, now) {
891
+ if (level === 'normal' || this.sustainedPressureAlerted)
892
+ return;
893
+ const threshold = this.extendedConfig.sustainedPressureThresholdMs ?? DEFAULT_SUSTAINED_PRESSURE_THRESHOLD_MS;
894
+ const elapsed = now - this.pressureLevelStartTime;
895
+ if (elapsed >= threshold && this.extendedConfig.onSustainedPressure) {
896
+ this.extendedConfig.onSustainedPressure(level, elapsed);
897
+ this.sustainedPressureAlerted = true;
898
+ }
899
+ }
900
+ /**
901
+ * Handle recovery from elevated pressure.
902
+ */
903
+ handleRecovery(fromLevel, toLevel, now) {
904
+ this.inRecoveryMode = true;
905
+ this.recoveryStartTime = now;
906
+ this.recoveryProgress = 0;
907
+ if (toLevel === 'normal') {
908
+ this.resumePausedOperations();
909
+ if (this.extendedConfig.autoDisableFeatures) {
910
+ this.enableFeaturesAfterRecovery();
911
+ }
912
+ const elapsed = now - this.pressureLevelStartTime;
913
+ const recoveryEvent = {
914
+ fromLevel,
915
+ toLevel,
916
+ recoveryDurationMs: elapsed,
917
+ };
918
+ this.extendedConfig.onRecovery?.(recoveryEvent);
919
+ this.recoveryListeners.forEach((listener) => listener(recoveryEvent));
920
+ }
921
+ }
922
+ /**
923
+ * Exit recovery mode when pressure rises.
924
+ */
925
+ exitRecoveryMode() {
926
+ this.inRecoveryMode = false;
927
+ this.recoveryProgress = 0;
928
+ this.recoveryStartTime = null;
929
+ this.pauseGradualRecovery();
930
+ }
931
+ /**
932
+ * Handle actions for elevated pressure levels.
933
+ * Optimized: Uses adaptive GC timing based on pressure level and memory growth rate.
934
+ */
935
+ async handleElevatedPressure(level, now) {
936
+ const actionsTaken = [];
937
+ // GC hint with adaptive timing based on pressure level
938
+ if (this.extendedConfig.onGCHint) {
939
+ const minInterval = this.getAdaptiveGCInterval(level, now);
940
+ if (now - this.lastGCHintTime >= minInterval) {
941
+ this.lastGCHintTime = now;
942
+ const aggressive = level === 'critical' || level === 'oom';
943
+ this.extendedConfig.onGCHint(level, { aggressive });
944
+ actionsTaken.push('gc_triggered');
945
+ }
946
+ }
947
+ // Cache eviction
948
+ if (this.extendedConfig.autoCacheEviction && this.cacheManager) {
949
+ const evicted = this.evictCache(level);
950
+ if (evicted)
951
+ actionsTaken.push('cache_cleared');
952
+ }
953
+ // Feature disabling
954
+ if ((level === 'critical' || level === 'oom') && this.extendedConfig.autoDisableFeatures) {
955
+ this.disableFeaturesUnderPressure();
956
+ }
957
+ // Extension unloading
958
+ if ((level === 'critical' || level === 'oom') && this.config.autoUnloadExtensions && this.pglite) {
959
+ const result = await this.unloadLeastImportantExtension();
960
+ if (result.success)
961
+ actionsTaken.push('extension_unloaded');
962
+ actionsTaken.push('warning_emitted');
963
+ }
964
+ return actionsTaken;
965
+ }
966
+ /**
967
+ * Calculate adaptive GC interval based on pressure level and memory growth rate.
968
+ *
969
+ * - At OOM: Minimal delay (500ms) to maximize chances of freeing memory
970
+ * - At critical: Reduced delay (2s) with faster triggering if memory is growing rapidly
971
+ * - At warning: Standard delay (5s) unless memory is growing rapidly
972
+ *
973
+ * @param level - Current pressure level
974
+ * @param now - Current timestamp
975
+ * @returns Minimum interval in milliseconds before next GC hint
976
+ */
977
+ getAdaptiveGCInterval(level, _now) {
978
+ const baseInterval = this.extendedConfig.gcHintMinIntervalMs ?? DEFAULT_GC_HINT_MIN_INTERVAL_MS;
979
+ // At OOM, be very aggressive
980
+ if (level === 'oom') {
981
+ return Math.min(500, baseInterval);
982
+ }
983
+ // At critical, reduce interval and consider growth rate
984
+ if (level === 'critical') {
985
+ const growthRate = this.getMemoryGrowthRate();
986
+ // If memory is growing rapidly (>5MB/s), be more aggressive
987
+ if (growthRate.bytesPerSecond > 5 * 1024 * 1024) {
988
+ return Math.min(1000, baseInterval / 2);
989
+ }
990
+ return Math.min(2000, baseInterval);
991
+ }
992
+ // At warning level, check if we should trigger earlier based on OOM prediction
993
+ if (level === 'warning') {
994
+ const prediction = this.predictTimeToOOM();
995
+ // If OOM predicted within 30 seconds with high confidence, reduce interval
996
+ if (prediction.willOOM && prediction.estimatedMs < 30000 && prediction.confidence > 0.7) {
997
+ return Math.min(2000, baseInterval / 2);
998
+ }
999
+ }
1000
+ return baseInterval;
1001
+ }
1002
+ /**
1003
+ * Evict cache entries based on pressure level.
1004
+ */
1005
+ evictCache(level) {
1006
+ if (!this.cacheManager)
1007
+ return false;
1008
+ const evictionTargets = this.extendedConfig.evictionTargetPercent ?? DEFAULT_EVICTION_TARGET_PERCENT;
1009
+ const targetPercent = evictionTargets[level] ?? 0;
1010
+ if (targetPercent <= 0)
1011
+ return false;
1012
+ const totalCacheSize = this.cacheManager.getTotalSize();
1013
+ const targetBytes = Math.floor(totalCacheSize * (targetPercent / 100));
1014
+ if (level === 'oom' && this.cacheManager.clear) {
1015
+ this.cacheManager.clear();
1016
+ return true;
1017
+ }
1018
+ if (this.cacheManager.evictLRU) {
1019
+ this.cacheManager.evictLRU(targetBytes);
1020
+ return true;
1021
+ }
1022
+ return false;
1023
+ }
1024
+ /**
1025
+ * Update pressure duration tracking.
1026
+ */
1027
+ updatePressureDuration(level, now) {
1028
+ const elapsed = now - this.pressureLevelStartTime;
1029
+ this.pressureDurations[level] += elapsed;
1030
+ this.pressureLevelStartTime = now;
1031
+ }
1032
+ // ===========================================================================
1033
+ // Extension Management
1034
+ // ===========================================================================
1035
+ /**
1036
+ * Unload the least important extension to free memory.
1037
+ *
1038
+ * Uses the extensionUnloadPriority list to determine which extension
1039
+ * to drop first.
1040
+ *
1041
+ * @returns Result of the unload operation
1042
+ */
1043
+ async unloadLeastImportantExtension() {
1044
+ if (!this.pglite) {
1045
+ return { action: 'extension_unloaded', success: false, error: 'PGlite not available' };
1046
+ }
1047
+ // Get installed extensions
1048
+ let installedExtensions;
1049
+ try {
1050
+ const result = await this.pglite.query(`SELECT extname FROM pg_extension WHERE extname != 'plpgsql'`);
1051
+ installedExtensions = new Set(result.rows
1052
+ .map((r) => r.extname)
1053
+ .filter((name) => !this.unloadedExtensions.has(name)));
1054
+ }
1055
+ catch (error) {
1056
+ return {
1057
+ action: 'extension_unloaded',
1058
+ success: false,
1059
+ error: `Failed to get extensions: ${error instanceof Error ? error.message : 'Unknown'}`,
1060
+ };
1061
+ }
1062
+ // Find and unload the least important
1063
+ for (const extName of this.config.extensionUnloadPriority) {
1064
+ if (installedExtensions.has(extName)) {
1065
+ try {
1066
+ await this.pglite.query(`DROP EXTENSION IF EXISTS "${extName}" CASCADE`);
1067
+ this.unloadedExtensions.add(extName);
1068
+ return { action: 'extension_unloaded', success: true, extensionName: extName };
1069
+ }
1070
+ catch (error) {
1071
+ return {
1072
+ action: 'extension_unloaded',
1073
+ success: false,
1074
+ extensionName: extName,
1075
+ error: `Failed to unload: ${error instanceof Error ? error.message : 'Unknown'}`,
1076
+ };
1077
+ }
1078
+ }
1079
+ }
1080
+ return { action: 'extension_unloaded', success: false, error: 'No extensions available to unload' };
1081
+ }
1082
+ /**
1083
+ * Get list of extensions unloaded due to memory pressure.
1084
+ */
1085
+ getUnloadedExtensions() {
1086
+ return Array.from(this.unloadedExtensions);
1087
+ }
1088
+ /**
1089
+ * Check if an extension was unloaded due to memory pressure.
1090
+ */
1091
+ wasExtensionUnloaded(extensionName) {
1092
+ return this.unloadedExtensions.has(extensionName);
1093
+ }
1094
+ /**
1095
+ * Clear the list of unloaded extensions.
1096
+ */
1097
+ clearUnloadedExtensions() {
1098
+ this.unloadedExtensions.clear();
1099
+ }
1100
+ // ===========================================================================
1101
+ // GC Hints
1102
+ // ===========================================================================
1103
+ /**
1104
+ * Request a garbage collection hint.
1105
+ *
1106
+ * Attempts to trigger GC if available and tracks effectiveness.
1107
+ * Optimized: Uses performance.now() for higher precision timing.
1108
+ *
1109
+ * @returns Result including bytes freed estimate
1110
+ */
1111
+ async requestGC() {
1112
+ const startTime = performance.now();
1113
+ const heapBefore = this.getCurrentHeapUsage();
1114
+ let triggered = false;
1115
+ // Try to trigger GC if available
1116
+ const gc = globalThis.gc;
1117
+ if (typeof gc === 'function') {
1118
+ try {
1119
+ gc();
1120
+ triggered = true;
1121
+ }
1122
+ catch {
1123
+ // GC not available or failed
1124
+ }
1125
+ }
1126
+ const durationMs = performance.now() - startTime;
1127
+ const heapAfter = this.getCurrentHeapUsage();
1128
+ const bytesFreedEstimate = Math.max(0, heapBefore - heapAfter);
1129
+ // Track metrics using ring buffers
1130
+ this.gcMetrics.hints++;
1131
+ this.gcMetrics.bytesFreed.push(bytesFreedEstimate);
1132
+ this.gcMetrics.durations.push(durationMs);
1133
+ return { triggered, bytesFreedEstimate, durationMs };
1134
+ }
1135
+ /**
1136
+ * Get aggregated GC metrics.
1137
+ * Optimized: Uses ring buffer's toArray() for efficient conversion.
1138
+ */
1139
+ getGCMetrics() {
1140
+ const { hints, bytesFreed, durations } = this.gcMetrics;
1141
+ const bytesFreedArray = bytesFreed.toArray();
1142
+ const durationsArray = durations.toArray();
1143
+ // Count successful GC hints (where memory was actually freed)
1144
+ let successCount = 0;
1145
+ for (let i = 0; i < bytesFreedArray.length; i++) {
1146
+ if ((bytesFreedArray[i] ?? 0) > 0)
1147
+ successCount++;
1148
+ }
1149
+ return {
1150
+ totalHints: hints,
1151
+ avgBytesFreed: average(bytesFreedArray),
1152
+ avgDurationMs: average(durationsArray),
1153
+ successRate: hints > 0 ? successCount / Math.min(hints, bytesFreedArray.length) : 0,
1154
+ };
1155
+ }
1156
+ // ===========================================================================
1157
+ // Metrics & History
1158
+ // ===========================================================================
1159
+ /**
1160
+ * Record a metric sample for history tracking.
1161
+ *
1162
+ * Also detects memory spikes, updates EMA state, and emits events.
1163
+ * Optimized: Uses ring buffer (no shift operations).
1164
+ */
1165
+ recordMetricSample() {
1166
+ const stats = this.getMemoryStats();
1167
+ const sample = {
1168
+ timestamp: new Date(),
1169
+ heapUsed: stats.heapUsed,
1170
+ pressureLevel: stats.pressureLevel,
1171
+ };
1172
+ // Add to ring buffer (automatically handles size limit)
1173
+ this.metricsHistory.push(sample);
1174
+ // Update smoothed state for EMA-based detection
1175
+ this.updateSmoothedState(stats.heapUsed, PRESSURE_LEVEL_INDEX[stats.pressureLevel]);
1176
+ // Spike detection
1177
+ if (this.lastHeapSample > 0 && stats.heapUsed - this.lastHeapSample >= SPIKE_DETECTION_THRESHOLD_BYTES) {
1178
+ const spike = {
1179
+ deltaBytes: stats.heapUsed - this.lastHeapSample,
1180
+ previousBytes: this.lastHeapSample,
1181
+ currentBytes: stats.heapUsed,
1182
+ timestamp: new Date(),
1183
+ };
1184
+ // Use for loop instead of forEach for better performance
1185
+ const listeners = this.memorySpikeListeners;
1186
+ for (let i = 0; i < listeners.length; i++) {
1187
+ const listener = listeners[i];
1188
+ if (listener)
1189
+ listener(spike);
1190
+ }
1191
+ }
1192
+ this.lastHeapSample = stats.heapUsed;
1193
+ }
1194
+ /**
1195
+ * Update smoothed pressure state using EMA.
1196
+ * This provides noise-resistant pressure tracking.
1197
+ */
1198
+ updateSmoothedState(rawHeapUsage, rawPressureLevel) {
1199
+ if (!this.smoothedStateInitialized) {
1200
+ // Initialize with first sample
1201
+ this.smoothedState = {
1202
+ emaHeapUsage: rawHeapUsage,
1203
+ emaPressureLevel: rawPressureLevel,
1204
+ recentVariance: 0,
1205
+ trend: 'stable',
1206
+ lastRawHeapUsage: rawHeapUsage,
1207
+ };
1208
+ this.smoothedStateInitialized = true;
1209
+ return;
1210
+ }
1211
+ // Update EMAs
1212
+ this.smoothedState.emaHeapUsage = updateEMA(this.smoothedState.emaHeapUsage, rawHeapUsage);
1213
+ this.smoothedState.emaPressureLevel = updateEMA(this.smoothedState.emaPressureLevel, rawPressureLevel);
1214
+ // Calculate variance from recent samples
1215
+ if (this.metricsHistory.size >= 3) {
1216
+ const recentSamples = this.metricsHistory.toArray().slice(-10);
1217
+ const heapValues = recentSamples.map((s) => s.heapUsed);
1218
+ this.smoothedState.recentVariance = variance(heapValues);
1219
+ }
1220
+ // Determine trend from delta
1221
+ const delta = rawHeapUsage - this.smoothedState.lastRawHeapUsage;
1222
+ if (delta > STABLE_GROWTH_THRESHOLD_BYTES_PER_SEC) {
1223
+ this.smoothedState.trend = 'rising';
1224
+ }
1225
+ else if (delta < -STABLE_GROWTH_THRESHOLD_BYTES_PER_SEC) {
1226
+ this.smoothedState.trend = 'falling';
1227
+ }
1228
+ else {
1229
+ this.smoothedState.trend = 'stable';
1230
+ }
1231
+ this.smoothedState.lastRawHeapUsage = rawHeapUsage;
1232
+ }
1233
+ /**
1234
+ * Get the smoothed pressure state.
1235
+ * Useful for observability and debugging.
1236
+ */
1237
+ getSmoothedPressureState() {
1238
+ return { ...this.smoothedState };
1239
+ }
1240
+ /**
1241
+ * Get the smoothed pressure level (EMA-based).
1242
+ * This is less sensitive to momentary spikes than raw pressure level.
1243
+ */
1244
+ getSmoothedPressureLevel() {
1245
+ const levelIndex = Math.round(this.smoothedState.emaPressureLevel);
1246
+ const levels = ['normal', 'warning', 'critical', 'oom'];
1247
+ return levels[Math.max(0, Math.min(3, levelIndex))] ?? 'normal';
1248
+ }
1249
+ /**
1250
+ * Check if pressure is volatile (high variance in recent samples).
1251
+ * Useful for deciding whether to take aggressive action.
1252
+ */
1253
+ isPressureVolatile() {
1254
+ const stats = this.getMemoryStats();
1255
+ // Coefficient of variation > 10% indicates volatility
1256
+ const cv = stats.heapUsed > 0
1257
+ ? Math.sqrt(this.smoothedState.recentVariance) / stats.heapUsed
1258
+ : 0;
1259
+ return cv > 0.1;
1260
+ }
1261
+ /**
1262
+ * Get adaptive thresholds based on current memory behavior.
1263
+ *
1264
+ * Adjusts thresholds based on:
1265
+ * 1. Memory growth rate - faster growth = lower thresholds
1266
+ * 2. Volatility - high volatility = higher thresholds (less sensitive)
1267
+ * 3. OOM prediction - imminent OOM = lower thresholds
1268
+ */
1269
+ getAdaptiveThresholds() {
1270
+ const baseConfig = this.config;
1271
+ // Return base thresholds if insufficient data
1272
+ if (this.metricsHistory.size < MIN_SAMPLES_FOR_TREND) {
1273
+ return {
1274
+ warningThresholdPercent: baseConfig.warningThresholdPercent,
1275
+ criticalThresholdPercent: baseConfig.criticalThresholdPercent,
1276
+ oomThresholdPercent: baseConfig.oomThresholdPercent,
1277
+ };
1278
+ }
1279
+ const growthRate = this.getMemoryGrowthRate();
1280
+ const oomPrediction = this.predictTimeToOOM();
1281
+ let warningAdjustment = 0;
1282
+ let criticalAdjustment = 0;
1283
+ // Adjust for growth rate
1284
+ if (growthRate.bytesPerSecond > RAPID_GROWTH_THRESHOLD_BYTES_PER_SEC) {
1285
+ // Rapid growth - lower thresholds by up to 10%
1286
+ warningAdjustment -= 10;
1287
+ criticalAdjustment -= 5;
1288
+ }
1289
+ else if (growthRate.trend === 'increasing') {
1290
+ // Moderate growth - lower thresholds by up to 5%
1291
+ warningAdjustment -= 5;
1292
+ criticalAdjustment -= 3;
1293
+ }
1294
+ // Adjust for volatility (increase thresholds if volatile to reduce false alarms)
1295
+ if (this.isPressureVolatile()) {
1296
+ warningAdjustment += 3;
1297
+ criticalAdjustment += 2;
1298
+ }
1299
+ // Adjust for imminent OOM prediction
1300
+ if (oomPrediction.willOOM && (oomPrediction.rSquared ?? 0) > 0.5) {
1301
+ warningAdjustment -= 5;
1302
+ criticalAdjustment -= 3;
1303
+ }
1304
+ // Apply adjustments with clamping
1305
+ const warningThresholdPercent = Math.max(50, Math.min(80, baseConfig.warningThresholdPercent + warningAdjustment));
1306
+ const criticalThresholdPercent = Math.max(warningThresholdPercent + 5, Math.min(90, baseConfig.criticalThresholdPercent + criticalAdjustment));
1307
+ const oomThresholdPercent = Math.max(criticalThresholdPercent + 5, baseConfig.oomThresholdPercent);
1308
+ return { warningThresholdPercent, criticalThresholdPercent, oomThresholdPercent };
1309
+ }
1310
+ /**
1311
+ * Get pressure level using adaptive thresholds.
1312
+ * This provides more intelligent pressure detection based on memory behavior.
1313
+ */
1314
+ getAdaptivePressureLevel() {
1315
+ const stats = this.getMemoryStats();
1316
+ const adaptiveThresholds = this.getAdaptiveThresholds();
1317
+ return getPressureLevelFromPercent(stats.usagePercent, adaptiveThresholds);
1318
+ }
1319
+ /**
1320
+ * Get metrics history.
1321
+ * Returns a copy of the samples array.
1322
+ */
1323
+ getMetricsHistory() {
1324
+ return { samples: this.metricsHistory.toArray() };
1325
+ }
1326
+ /**
1327
+ * Calculate memory growth rate using linear regression.
1328
+ *
1329
+ * Optimized improvements over simple first/last calculation:
1330
+ * 1. Uses all samples via linear regression for more accurate trend
1331
+ * 2. Filters out noise using configurable threshold
1332
+ * 3. Provides confidence via R-squared value
1333
+ *
1334
+ * Falls back to simple calculation if insufficient samples.
1335
+ */
1336
+ getMemoryGrowthRate() {
1337
+ const historySize = this.metricsHistory.size;
1338
+ if (historySize < 2) {
1339
+ return { bytesPerSecond: 0, trend: 'stable' };
1340
+ }
1341
+ // For small sample counts, use simple first/last calculation
1342
+ if (historySize < MIN_SAMPLES_FOR_TREND) {
1343
+ const first = this.metricsHistory.first();
1344
+ const last = this.metricsHistory.last();
1345
+ if (!first || !last)
1346
+ return { bytesPerSecond: 0, trend: 'stable' };
1347
+ const timeDeltaMs = last.timestamp.getTime() - first.timestamp.getTime();
1348
+ if (timeDeltaMs <= 0)
1349
+ return { bytesPerSecond: 0, trend: 'stable' };
1350
+ const bytesDelta = last.heapUsed - first.heapUsed;
1351
+ const bytesPerSecond = (bytesDelta / timeDeltaMs) * 1000;
1352
+ return {
1353
+ bytesPerSecond,
1354
+ trend: this.classifyGrowthTrend(bytesPerSecond),
1355
+ };
1356
+ }
1357
+ // Use linear regression for more accurate trend analysis
1358
+ const samples = this.metricsHistory.toArray();
1359
+ const { slope, rSquared } = linearRegression(samples);
1360
+ // slope is in bytes/ms, convert to bytes/second
1361
+ const bytesPerSecond = slope * 1000;
1362
+ // If regression fit is poor (R² < 0.5), the trend is likely noisy/unstable
1363
+ // Use a higher threshold for stable classification
1364
+ const effectiveThreshold = rSquared < 0.5
1365
+ ? STABLE_GROWTH_THRESHOLD_BYTES_PER_SEC * 2
1366
+ : STABLE_GROWTH_THRESHOLD_BYTES_PER_SEC;
1367
+ return {
1368
+ bytesPerSecond,
1369
+ trend: this.classifyGrowthTrend(bytesPerSecond, effectiveThreshold),
1370
+ };
1371
+ }
1372
+ /**
1373
+ * Classify growth trend based on bytes per second.
1374
+ */
1375
+ classifyGrowthTrend(bytesPerSecond, threshold = STABLE_GROWTH_THRESHOLD_BYTES_PER_SEC) {
1376
+ if (bytesPerSecond > threshold)
1377
+ return 'increasing';
1378
+ if (bytesPerSecond < -threshold)
1379
+ return 'decreasing';
1380
+ return 'stable';
1381
+ }
1382
+ /**
1383
+ * Predict time to OOM using linear regression and statistical analysis.
1384
+ *
1385
+ * Improved prediction algorithm:
1386
+ * 1. Uses linear regression for trend-based prediction
1387
+ * 2. Includes R-squared for confidence estimation
1388
+ * 3. Accounts for variance in samples (high variance = lower confidence)
1389
+ * 4. Predicts usage at OOM horizon for early warning
1390
+ */
1391
+ predictTimeToOOM() {
1392
+ const stats = this.getMemoryStats();
1393
+ const historySize = this.metricsHistory.size;
1394
+ // Default return for insufficient data
1395
+ const defaultPrediction = {
1396
+ estimatedMs: Infinity,
1397
+ confidence: 0,
1398
+ willOOM: false,
1399
+ rSquared: 0,
1400
+ predictedUsageAtHorizon: stats.heapUsed,
1401
+ };
1402
+ if (historySize < 2) {
1403
+ return defaultPrediction;
1404
+ }
1405
+ const samples = this.metricsHistory.toArray();
1406
+ const { slope, intercept, rSquared } = linearRegression(samples);
1407
+ // slope is bytes/ms
1408
+ // If not growing (slope <= 0), no OOM predicted
1409
+ if (slope <= 0) {
1410
+ return {
1411
+ ...defaultPrediction,
1412
+ rSquared,
1413
+ predictedUsageAtHorizon: Math.max(0, stats.heapUsed + slope * OOM_PREDICTION_HORIZON_MS),
1414
+ };
1415
+ }
1416
+ // Calculate time to reach OOM threshold
1417
+ const oomThresholdBytes = (stats.heapLimit * this.config.oomThresholdPercent) / 100;
1418
+ const bytesRemaining = oomThresholdBytes - stats.heapUsed;
1419
+ if (bytesRemaining <= 0) {
1420
+ // Already at or above OOM threshold
1421
+ return {
1422
+ estimatedMs: 0,
1423
+ confidence: 1.0,
1424
+ willOOM: true,
1425
+ rSquared,
1426
+ predictedUsageAtHorizon: stats.heapUsed,
1427
+ };
1428
+ }
1429
+ // Time to OOM in milliseconds: (oomThreshold - currentUsage) / slope
1430
+ const estimatedMs = bytesRemaining / slope;
1431
+ // Calculate confidence based on multiple factors:
1432
+ // 1. Sample count (more samples = more confidence)
1433
+ // 2. R-squared (better fit = more confidence)
1434
+ // 3. Variance consistency (less variance = more confidence)
1435
+ const sampleConfidence = Math.min(1.0, historySize / MIN_SAMPLES_FOR_OOM_PREDICTION);
1436
+ const fitConfidence = Math.max(0, rSquared); // R² is already 0-1
1437
+ // Calculate variance confidence
1438
+ const heapValues = samples.map((s) => s.heapUsed);
1439
+ const sampleVariance = variance(heapValues);
1440
+ const meanHeap = average(heapValues);
1441
+ // Coefficient of variation - lower is more consistent
1442
+ const cv = meanHeap > 0 ? Math.sqrt(sampleVariance) / meanHeap : 0;
1443
+ const varianceConfidence = Math.max(0, 1 - cv * 10); // Scale CV to 0-1 range
1444
+ // Combined confidence (weighted average)
1445
+ const confidence = Math.min(1.0, sampleConfidence * 0.3 +
1446
+ fitConfidence * 0.5 +
1447
+ varianceConfidence * 0.2);
1448
+ // Predict usage at the OOM horizon
1449
+ const now = Date.now();
1450
+ const horizonTime = now + OOM_PREDICTION_HORIZON_MS;
1451
+ const t0 = samples[0]?.timestamp.getTime() ?? now;
1452
+ const predictedUsageAtHorizon = Math.max(0, slope * (horizonTime - t0) + intercept);
1453
+ return {
1454
+ estimatedMs: Math.max(0, estimatedMs),
1455
+ confidence,
1456
+ willOOM: estimatedMs < OOM_PREDICTION_HORIZON_MS && confidence > 0.5,
1457
+ rSquared,
1458
+ predictedUsageAtHorizon,
1459
+ };
1460
+ }
1461
+ /**
1462
+ * Get time spent at each pressure level.
1463
+ */
1464
+ getPressureDurations() {
1465
+ const now = Date.now();
1466
+ const currentElapsed = now - this.pressureLevelStartTime;
1467
+ const durations = { ...this.pressureDurations };
1468
+ durations[this.lastPressureLevel] += currentElapsed;
1469
+ return durations;
1470
+ }
1471
+ /**
1472
+ * Export metrics in Prometheus format.
1473
+ * Enhanced: Includes heuristics metrics for better observability.
1474
+ */
1475
+ exportPrometheusMetrics() {
1476
+ const stats = this.getMemoryStats();
1477
+ const gcMetrics = this.getGCMetrics();
1478
+ const demotionMetrics = this.getDemotionMetrics();
1479
+ const growthRate = this.getMemoryGrowthRate();
1480
+ const oomPrediction = this.predictTimeToOOM();
1481
+ const smoothedState = this.getSmoothedPressureState();
1482
+ const adaptiveThresholds = this.getAdaptiveThresholds();
1483
+ const levels = { normal: 0, warning: 1, critical: 2, oom: 3 };
1484
+ const trends = { decreasing: -1, stable: 0, increasing: 1 };
1485
+ return [
1486
+ // Core metrics
1487
+ `# HELP postgres_memory_heap_bytes Current WASM heap usage in bytes`,
1488
+ `# TYPE postgres_memory_heap_bytes gauge`,
1489
+ `postgres_memory_heap_bytes ${stats.heapUsed}`,
1490
+ `# HELP postgres_memory_pressure_level Current memory pressure level (0=normal, 1=warning, 2=critical, 3=oom)`,
1491
+ `# TYPE postgres_memory_pressure_level gauge`,
1492
+ `postgres_memory_pressure_level ${levels[stats.pressureLevel]}`,
1493
+ `# HELP postgres_memory_gc_count Total number of GC hints triggered`,
1494
+ `# TYPE postgres_memory_gc_count counter`,
1495
+ `postgres_memory_gc_count ${gcMetrics.totalHints}`,
1496
+ `# HELP postgres_memory_pressure_demotions_total Total number of pressure-triggered demotions`,
1497
+ `# TYPE postgres_memory_pressure_demotions_total counter`,
1498
+ `postgres_memory_pressure_demotions_total ${demotionMetrics.pressureTriggeredDemotions}`,
1499
+ `# HELP postgres_memory_pressure_demotions_failed Total number of failed pressure-triggered demotions`,
1500
+ `# TYPE postgres_memory_pressure_demotions_failed counter`,
1501
+ `postgres_memory_pressure_demotions_failed ${demotionMetrics.failedDemotions}`,
1502
+ // Heuristics metrics
1503
+ `# HELP postgres_memory_heap_ema_bytes Exponential moving average of heap usage`,
1504
+ `# TYPE postgres_memory_heap_ema_bytes gauge`,
1505
+ `postgres_memory_heap_ema_bytes ${Math.round(smoothedState.emaHeapUsage)}`,
1506
+ `# HELP postgres_memory_growth_rate_bytes_per_sec Memory growth rate in bytes per second`,
1507
+ `# TYPE postgres_memory_growth_rate_bytes_per_sec gauge`,
1508
+ `postgres_memory_growth_rate_bytes_per_sec ${Math.round(growthRate.bytesPerSecond)}`,
1509
+ `# HELP postgres_memory_growth_trend Memory growth trend (-1=decreasing, 0=stable, 1=increasing)`,
1510
+ `# TYPE postgres_memory_growth_trend gauge`,
1511
+ `postgres_memory_growth_trend ${trends[growthRate.trend] ?? 0}`,
1512
+ `# HELP postgres_memory_oom_prediction_ms Predicted time to OOM in milliseconds (-1 if not growing)`,
1513
+ `# TYPE postgres_memory_oom_prediction_ms gauge`,
1514
+ `postgres_memory_oom_prediction_ms ${oomPrediction.estimatedMs === Infinity ? -1 : Math.round(oomPrediction.estimatedMs)}`,
1515
+ `# HELP postgres_memory_oom_prediction_confidence Confidence in OOM prediction (0-1)`,
1516
+ `# TYPE postgres_memory_oom_prediction_confidence gauge`,
1517
+ `postgres_memory_oom_prediction_confidence ${oomPrediction.confidence.toFixed(3)}`,
1518
+ `# HELP postgres_memory_pressure_volatile Whether pressure readings are currently volatile (0=stable, 1=volatile)`,
1519
+ `# TYPE postgres_memory_pressure_volatile gauge`,
1520
+ `postgres_memory_pressure_volatile ${this.isPressureVolatile() ? 1 : 0}`,
1521
+ `# HELP postgres_memory_adaptive_warning_threshold Current adaptive warning threshold percentage`,
1522
+ `# TYPE postgres_memory_adaptive_warning_threshold gauge`,
1523
+ `postgres_memory_adaptive_warning_threshold ${adaptiveThresholds.warningThresholdPercent}`,
1524
+ `# HELP postgres_memory_adaptive_critical_threshold Current adaptive critical threshold percentage`,
1525
+ `# TYPE postgres_memory_adaptive_critical_threshold gauge`,
1526
+ `postgres_memory_adaptive_critical_threshold ${adaptiveThresholds.criticalThresholdPercent}`,
1527
+ ].join('\n');
1528
+ }
1529
+ /**
1530
+ * Export metrics in JSON format.
1531
+ * Optimized: Calculates aggregates in a single pass.
1532
+ * Enhanced: Includes heuristics data for observability.
1533
+ */
1534
+ exportJSONMetrics() {
1535
+ const current = this.getMemoryStats();
1536
+ const history = this.getMetricsHistory();
1537
+ const gcMetrics = this.getGCMetrics();
1538
+ // Single-pass calculation of avg and peak
1539
+ const samples = history.samples;
1540
+ let sum = 0;
1541
+ let peak = current.heapUsed;
1542
+ if (samples.length > 0) {
1543
+ for (let i = 0; i < samples.length; i++) {
1544
+ const sample = samples[i];
1545
+ if (sample) {
1546
+ const heapUsed = sample.heapUsed;
1547
+ sum += heapUsed;
1548
+ if (heapUsed > peak)
1549
+ peak = heapUsed;
1550
+ }
1551
+ }
1552
+ }
1553
+ const avgHeapUsed = samples.length > 0 ? sum / samples.length : current.heapUsed;
1554
+ const demotionMetrics = this.getDemotionMetrics();
1555
+ return {
1556
+ current,
1557
+ history,
1558
+ aggregates: {
1559
+ avgHeapUsed,
1560
+ peakHeapUsed: peak,
1561
+ totalGCCount: gcMetrics.totalHints,
1562
+ pressureTriggeredDemotions: demotionMetrics.pressureTriggeredDemotions,
1563
+ failedDemotions: demotionMetrics.failedDemotions,
1564
+ bytesFreedByDemotion: demotionMetrics.bytesFreedByDemotion,
1565
+ },
1566
+ heuristics: {
1567
+ smoothedState: this.getSmoothedPressureState(),
1568
+ adaptiveThresholds: this.getAdaptiveThresholds(),
1569
+ oomPrediction: this.predictTimeToOOM(),
1570
+ growthRate: this.getMemoryGrowthRate(),
1571
+ isVolatile: this.isPressureVolatile(),
1572
+ },
1573
+ };
1574
+ }
1575
+ // ===========================================================================
1576
+ // Query Management
1577
+ // ===========================================================================
1578
+ /**
1579
+ * Execute a query with memory pressure guards.
1580
+ *
1581
+ * - Pauses at critical pressure (with timeout)
1582
+ * - Rejects at OOM pressure
1583
+ * - Enforces hard limits if configured
1584
+ */
1585
+ async guardedQuery(sql, params, options) {
1586
+ const stats = this.getMemoryStats();
1587
+ // Hard limit enforcement
1588
+ if (this.extendedConfig.hardLimitEnforcement && this.forcedHeapUsage !== null) {
1589
+ const estimatedUsage = options?.estimatedResultBytes ?? 0;
1590
+ if (this.forcedHeapUsage + estimatedUsage > this.config.memoryLimitBytes) {
1591
+ throw new MemoryPressureError('Would exceed Worker memory limit', stats);
1592
+ }
1593
+ }
1594
+ // OOM rejection
1595
+ if (this.extendedConfig.queryRejectionEnabled && this.lastPressureLevel === 'oom') {
1596
+ throw new MemoryPressureError('Memory pressure too high', stats);
1597
+ }
1598
+ // Critical pausing
1599
+ if (this.extendedConfig.queryPausingEnabled && this.lastPressureLevel === 'critical') {
1600
+ await this.waitForPressureRelief();
1601
+ }
1602
+ // Execute query
1603
+ if (this.pglite) {
1604
+ const result = await this.pglite.query(sql, params);
1605
+ return result;
1606
+ }
1607
+ return { rows: [], fields: [] };
1608
+ }
1609
+ /**
1610
+ * Wait for pressure to drop with timeout.
1611
+ */
1612
+ async waitForPressureRelief() {
1613
+ const timeoutMs = this.extendedConfig.queryPauseTimeoutMs ?? DEFAULT_QUERY_PAUSE_TIMEOUT_MS;
1614
+ const operation = this.pauseOperation(`query-${Date.now()}`);
1615
+ // Track the operation so it can be resumed when pressure drops
1616
+ const dummyPromise = Promise.resolve();
1617
+ this.pausedQueries.set(dummyPromise, operation);
1618
+ const timeoutPromise = new Promise((_, reject) => {
1619
+ setTimeout(() => {
1620
+ operation.status = 'cancelled';
1621
+ this.pausedQueries.delete(dummyPromise);
1622
+ reject(new Error('Query paused due to memory pressure and timed out'));
1623
+ }, timeoutMs);
1624
+ });
1625
+ try {
1626
+ await Promise.race([operation.resumePromise, timeoutPromise]);
1627
+ }
1628
+ finally {
1629
+ this.pausedQueries.delete(dummyPromise);
1630
+ }
1631
+ }
1632
+ /**
1633
+ * Get status of a query promise.
1634
+ */
1635
+ getQueryStatus(queryPromise) {
1636
+ const operation = this.pausedQueries.get(queryPromise);
1637
+ if (operation) {
1638
+ return operation.status === 'paused' ? 'paused' : 'executing';
1639
+ }
1640
+ return 'unknown';
1641
+ }
1642
+ /**
1643
+ * Pause an operation and return a handle.
1644
+ */
1645
+ pauseOperation(id) {
1646
+ let resolveFunc = () => { };
1647
+ let rejectFunc = () => { };
1648
+ const resumePromise = new Promise((resolve, reject) => {
1649
+ resolveFunc = resolve;
1650
+ rejectFunc = reject;
1651
+ });
1652
+ return {
1653
+ id,
1654
+ status: 'paused',
1655
+ pausedAt: new Date(),
1656
+ resumePromise,
1657
+ resolve: resolveFunc,
1658
+ reject: rejectFunc,
1659
+ };
1660
+ }
1661
+ /**
1662
+ * Resume all paused operations.
1663
+ */
1664
+ resumePausedOperations() {
1665
+ for (const [, operation] of this.pausedQueries) {
1666
+ if (operation.status === 'paused') {
1667
+ operation.status = 'resumed';
1668
+ operation.resolve();
1669
+ }
1670
+ }
1671
+ this.pausedQueries.clear();
1672
+ }
1673
+ /**
1674
+ * Enforce a hard allocation limit.
1675
+ *
1676
+ * Throws if the allocation would exceed the memory limit.
1677
+ */
1678
+ async guardedAllocation(bytes) {
1679
+ const currentUsage = this.forcedHeapUsage ?? this.getCurrentHeapUsage();
1680
+ const totalAfter = currentUsage + bytes;
1681
+ if (this.extendedConfig.hardLimitEnforcement && totalAfter > this.config.memoryLimitBytes) {
1682
+ throw new MemoryPressureError('Would exceed Worker memory limit', this.getMemoryStats());
1683
+ }
1684
+ return { allowed: true };
1685
+ }
1686
+ // ===========================================================================
1687
+ // Feature Management
1688
+ // ===========================================================================
1689
+ /**
1690
+ * Check if a feature is currently enabled.
1691
+ */
1692
+ isFeatureEnabled(feature) {
1693
+ return this.enabledFeatures.has(feature) && !this.disabledFeatures.has(feature);
1694
+ }
1695
+ /**
1696
+ * Get count of enabled features.
1697
+ */
1698
+ getEnabledFeatureCount() {
1699
+ let count = 0;
1700
+ for (const feature of this.enabledFeatures) {
1701
+ if (!this.disabledFeatures.has(feature))
1702
+ count++;
1703
+ }
1704
+ return count;
1705
+ }
1706
+ /**
1707
+ * Disable features under pressure.
1708
+ */
1709
+ disableFeaturesUnderPressure() {
1710
+ if (!this.extendedConfig.autoDisableFeatures)
1711
+ return;
1712
+ const features = this.extendedConfig.featuresToDisable ?? DEFAULT_FEATURES_TO_DISABLE;
1713
+ for (const feature of features) {
1714
+ this.disabledFeatures.add(feature);
1715
+ }
1716
+ }
1717
+ /**
1718
+ * Re-enable features after recovery.
1719
+ */
1720
+ enableFeaturesAfterRecovery() {
1721
+ if (!this.extendedConfig.autoDisableFeatures)
1722
+ return;
1723
+ this.disabledFeatures.clear();
1724
+ }
1725
+ // ===========================================================================
1726
+ // Recovery Management
1727
+ // ===========================================================================
1728
+ /**
1729
+ * Check if manager is in recovery mode.
1730
+ */
1731
+ isInRecoveryMode() {
1732
+ return this.inRecoveryMode;
1733
+ }
1734
+ /**
1735
+ * Get recovery progress (0.0 to 1.0).
1736
+ */
1737
+ getRecoveryProgress() {
1738
+ if (!this.inRecoveryMode) {
1739
+ return this.lastPressureLevel === 'normal' ? 1.0 : 0.0;
1740
+ }
1741
+ const hysteresisMs = this.extendedConfig.recoveryHysteresisMs ?? DEFAULT_RECOVERY_HYSTERESIS_MS;
1742
+ if (this.recoveryStartTime && hysteresisMs > 0) {
1743
+ const elapsed = Date.now() - this.recoveryStartTime;
1744
+ this.recoveryProgress = Math.min(1.0, elapsed / hysteresisMs);
1745
+ if (this.recoveryProgress >= 1.0 && this.lastPressureLevel === 'normal') {
1746
+ this.inRecoveryMode = false;
1747
+ }
1748
+ }
1749
+ return this.recoveryProgress;
1750
+ }
1751
+ /**
1752
+ * Start gradual recovery of features.
1753
+ */
1754
+ async startGradualRecovery() {
1755
+ if (!this.extendedConfig.gradualRecovery)
1756
+ return;
1757
+ this.recoveryPaused = false;
1758
+ const intervalMs = this.extendedConfig.recoveryStepIntervalMs ?? DEFAULT_RECOVERY_STEP_INTERVAL_MS;
1759
+ const features = this.extendedConfig.featuresToDisable ?? DEFAULT_FEATURES_TO_DISABLE;
1760
+ let featureIndex = 0;
1761
+ this.gradualRecoveryInterval = setInterval(() => {
1762
+ if (this.recoveryPaused || featureIndex >= features.length) {
1763
+ if (this.gradualRecoveryInterval) {
1764
+ clearInterval(this.gradualRecoveryInterval);
1765
+ this.gradualRecoveryInterval = null;
1766
+ }
1767
+ return;
1768
+ }
1769
+ const feature = features[featureIndex];
1770
+ if (feature) {
1771
+ this.disabledFeatures.delete(feature);
1772
+ this.recoveryStepsExecuted.push(feature);
1773
+ this.extendedConfig.onRecoveryStep?.(feature);
1774
+ }
1775
+ featureIndex++;
1776
+ }, intervalMs);
1777
+ }
1778
+ /**
1779
+ * Pause gradual recovery.
1780
+ */
1781
+ pauseGradualRecovery() {
1782
+ this.recoveryPaused = true;
1783
+ if (this.gradualRecoveryInterval) {
1784
+ clearInterval(this.gradualRecoveryInterval);
1785
+ this.gradualRecoveryInterval = null;
1786
+ }
1787
+ }
1788
+ /**
1789
+ * Check if recovery is paused.
1790
+ */
1791
+ isRecoveryPaused() {
1792
+ return this.recoveryPaused;
1793
+ }
1794
+ // ===========================================================================
1795
+ // Event Listeners
1796
+ // ===========================================================================
1797
+ /**
1798
+ * Add a memory pressure event listener.
1799
+ *
1800
+ * @param listener - Callback for pressure events
1801
+ * @returns Unsubscribe function
1802
+ */
1803
+ onPressureChange(listener) {
1804
+ // Warn when approaching limit
1805
+ const warningThreshold = Math.floor(this.config.maxListeners * 0.8);
1806
+ if (this.listeners.length >= warningThreshold && this.listeners.length < this.config.maxListeners) {
1807
+ console.warn(`Approaching memory pressure listener limit: ${this.listeners.length}/${this.config.maxListeners}`);
1808
+ }
1809
+ // Cap at max listeners (drop oldest)
1810
+ if (this.listeners.length >= this.config.maxListeners) {
1811
+ console.warn(`Memory pressure listener limit (${this.config.maxListeners}) reached. Dropping oldest listener.`);
1812
+ this.listeners.shift();
1813
+ }
1814
+ this.listeners.push(listener);
1815
+ return () => {
1816
+ const index = this.listeners.indexOf(listener);
1817
+ if (index >= 0)
1818
+ this.listeners.splice(index, 1);
1819
+ };
1820
+ }
1821
+ /**
1822
+ * Get current listener count.
1823
+ */
1824
+ getListenerCount() {
1825
+ return this.listeners.length;
1826
+ }
1827
+ /**
1828
+ * Add a memory spike listener.
1829
+ *
1830
+ * @param listener - Callback for spike events
1831
+ * @returns Unsubscribe function
1832
+ */
1833
+ onMemorySpike(listener) {
1834
+ this.memorySpikeListeners.push(listener);
1835
+ return () => {
1836
+ const index = this.memorySpikeListeners.indexOf(listener);
1837
+ if (index >= 0)
1838
+ this.memorySpikeListeners.splice(index, 1);
1839
+ };
1840
+ }
1841
+ /**
1842
+ * Add a recovery event listener.
1843
+ *
1844
+ * @param listener - Callback for recovery events
1845
+ * @returns Unsubscribe function
1846
+ */
1847
+ onRecovery(listener) {
1848
+ this.recoveryListeners.push(listener);
1849
+ return () => {
1850
+ const index = this.recoveryListeners.indexOf(listener);
1851
+ if (index >= 0)
1852
+ this.recoveryListeners.splice(index, 1);
1853
+ };
1854
+ }
1855
+ /**
1856
+ * Emit a pressure event to all listeners.
1857
+ */
1858
+ emitPressureEvent(event) {
1859
+ for (const listener of this.listeners) {
1860
+ try {
1861
+ listener(event);
1862
+ }
1863
+ catch (error) {
1864
+ console.error('Memory pressure listener error:', error);
1865
+ }
1866
+ }
1867
+ }
1868
+ // ===========================================================================
1869
+ // Testing Support
1870
+ // ===========================================================================
1871
+ /**
1872
+ * Simulate heap growth for testing.
1873
+ * @internal
1874
+ */
1875
+ _simulateHeapGrowth(bytes) {
1876
+ this.simulatedHeapBytes += bytes;
1877
+ }
1878
+ /**
1879
+ * Set current heap usage for testing.
1880
+ * @internal
1881
+ */
1882
+ _setCurrentHeapUsage(bytes) {
1883
+ this.forcedHeapUsage = bytes;
1884
+ }
1885
+ /**
1886
+ * Force a memory pressure level for testing.
1887
+ *
1888
+ * This updates the internal state and emits events as if the pressure
1889
+ * had actually changed. Useful for testing pressure handling without
1890
+ * actually consuming memory.
1891
+ *
1892
+ * @internal
1893
+ */
1894
+ _forceMemoryPressure(level) {
1895
+ const previousLevel = this.lastPressureLevel;
1896
+ if (previousLevel === level)
1897
+ return null;
1898
+ const now = Date.now();
1899
+ this.updatePressureDuration(previousLevel, now);
1900
+ // Handle recovery/escalation transitions
1901
+ const previousIndex = getPressureLevelIndex(previousLevel);
1902
+ const newIndex = getPressureLevelIndex(level);
1903
+ if (previousIndex > 0 && newIndex < previousIndex) {
1904
+ // Pressure dropped
1905
+ this.handleRecovery(previousLevel, level, now);
1906
+ }
1907
+ else if (newIndex > 0 && newIndex >= previousIndex) {
1908
+ // Pressure rose
1909
+ this.exitRecoveryMode();
1910
+ }
1911
+ this.lastPressureLevel = level;
1912
+ // Create synthetic stats
1913
+ const usagePercent = level === 'oom' ? 96 : level === 'critical' ? 88 : level === 'warning' ? 75 : 50;
1914
+ const stats = {
1915
+ heapUsed: this.config.memoryLimitBytes * (usagePercent / 100),
1916
+ heapLimit: this.config.memoryLimitBytes,
1917
+ usagePercent,
1918
+ pressureLevel: level,
1919
+ timestamp: new Date(),
1920
+ };
1921
+ const event = {
1922
+ previousLevel,
1923
+ currentLevel: level,
1924
+ stats,
1925
+ actionsTaken: [],
1926
+ timestamp: new Date(),
1927
+ };
1928
+ this.emitPressureEvent(event);
1929
+ // Trigger pressure-triggered demotion if pressure rose
1930
+ if (newIndex > previousIndex && level !== 'normal') {
1931
+ // Fire and forget - don't await to avoid blocking test
1932
+ // Pass true to bypass rate limiting since this is a pressure escalation
1933
+ this.handlePressureDemotion(level, true).catch(() => { });
1934
+ }
1935
+ return event;
1936
+ }
1937
+ // ===========================================================================
1938
+ // Cleanup
1939
+ // ===========================================================================
1940
+ /**
1941
+ * Dispose of the manager and clean up all resources.
1942
+ *
1943
+ * This stops all intervals, clears all listeners, and releases references.
1944
+ * Always call this when the manager is no longer needed.
1945
+ */
1946
+ dispose() {
1947
+ // Stop all intervals
1948
+ this.stopMonitoring();
1949
+ this.pauseGradualRecovery();
1950
+ if (this.sustainedPressureCheckInterval) {
1951
+ clearInterval(this.sustainedPressureCheckInterval);
1952
+ this.sustainedPressureCheckInterval = null;
1953
+ }
1954
+ // Clear all listeners (set to empty arrays to avoid memory leaks)
1955
+ this.listeners.length = 0;
1956
+ this.memorySpikeListeners.length = 0;
1957
+ this.recoveryListeners.length = 0;
1958
+ this.pressureDemotionListeners.length = 0;
1959
+ // Release external references
1960
+ this.pglite = null;
1961
+ this.wasmModule = null;
1962
+ this.cacheManager = null;
1963
+ this.tieredStorageOrchestrator = null;
1964
+ // Clear state
1965
+ this.unloadedExtensions.clear();
1966
+ this.pausedQueries.clear();
1967
+ this.inFlightQueries.clear();
1968
+ this.metricsHistory.clear();
1969
+ this.gcMetrics.bytesFreed.clear();
1970
+ this.gcMetrics.durations.clear();
1971
+ this.disabledFeatures.clear();
1972
+ this.recoveryStepsExecuted.length = 0;
1973
+ // Reset testing state
1974
+ this.simulatedHeapBytes = 0;
1975
+ this.forcedHeapUsage = null;
1976
+ }
1977
+ }
1978
+ // =============================================================================
1979
+ // Factory Function
1980
+ // =============================================================================
1981
+ /**
1982
+ * Create a memory pressure manager with default configuration.
1983
+ *
1984
+ * @param config - Optional configuration overrides
1985
+ * @returns Configured MemoryPressureManager instance
1986
+ */
1987
+ export function createMemoryPressureManager(config) {
1988
+ return new MemoryPressureManager(config);
1989
+ }
1990
+ //# sourceMappingURL=memory-pressure.js.map