@mistriwork/engine 0.0.0-stage → 1.0.0-rc.10

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 (546) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -2
  3. package/dist/adapters/adapter.d.ts +693 -0
  4. package/dist/adapters/adapter.js +444 -0
  5. package/dist/adapters/cache/cacheStore.d.ts +75 -0
  6. package/dist/adapters/cache/cacheStore.js +160 -0
  7. package/dist/adapters/cache/resp.d.ts +52 -0
  8. package/dist/adapters/cache/resp.js +237 -0
  9. package/dist/adapters/commands/canonicalJson.d.ts +19 -0
  10. package/dist/adapters/commands/canonicalJson.js +154 -0
  11. package/dist/adapters/connect.d.ts +29 -0
  12. package/dist/adapters/connect.js +40 -0
  13. package/dist/adapters/connectionBudget.d.ts +101 -0
  14. package/dist/adapters/connectionBudget.js +128 -0
  15. package/dist/adapters/dbLatency.d.ts +35 -0
  16. package/dist/adapters/dbLatency.js +79 -0
  17. package/dist/adapters/epochCache.d.ts +50 -0
  18. package/dist/adapters/epochCache.js +85 -0
  19. package/dist/adapters/http/egress.d.ts +48 -0
  20. package/dist/adapters/http/egress.js +175 -0
  21. package/dist/adapters/http/httpAdapter.d.ts +71 -0
  22. package/dist/adapters/http/httpAdapter.js +512 -0
  23. package/dist/adapters/http/httpDescription.d.ts +32 -0
  24. package/dist/adapters/http/httpDescription.js +246 -0
  25. package/dist/adapters/http/openapi.d.ts +98 -0
  26. package/dist/adapters/http/openapi.js +487 -0
  27. package/dist/adapters/layoutRefusal.d.ts +24 -0
  28. package/dist/adapters/layoutRefusal.js +35 -0
  29. package/dist/adapters/net/networkPolicy.d.ts +44 -0
  30. package/dist/adapters/net/networkPolicy.js +123 -0
  31. package/dist/adapters/net/untrustedDatabase.d.ts +18 -0
  32. package/dist/adapters/net/untrustedDatabase.js +120 -0
  33. package/dist/adapters/poolAdmission.d.ts +43 -0
  34. package/dist/adapters/poolAdmission.js +184 -0
  35. package/dist/adapters/poolMetrics.d.ts +121 -0
  36. package/dist/adapters/poolMetrics.js +185 -0
  37. package/dist/adapters/postgres.d.ts +436 -0
  38. package/dist/adapters/postgres.js +1890 -0
  39. package/dist/adapters/postgresCatalog.d.ts +96 -0
  40. package/dist/adapters/postgresCatalog.js +387 -0
  41. package/dist/adapters/postgresCatalogDigest.d.ts +30 -0
  42. package/dist/adapters/postgresCatalogDigest.js +87 -0
  43. package/dist/adapters/postgresCatalogRows.d.ts +62 -0
  44. package/dist/adapters/postgresCatalogRows.js +37 -0
  45. package/dist/adapters/postgresDates.d.ts +1 -0
  46. package/dist/adapters/postgresDates.js +39 -0
  47. package/dist/adapters/postgresMaintenance.d.ts +33 -0
  48. package/dist/adapters/postgresMaintenance.js +179 -0
  49. package/dist/adapters/postgresPool.d.ts +255 -0
  50. package/dist/adapters/postgresPool.js +838 -0
  51. package/dist/adapters/postgresPooler.d.ts +28 -0
  52. package/dist/adapters/postgresPooler.js +267 -0
  53. package/dist/adapters/postgresReadCatalog.d.ts +31 -0
  54. package/dist/adapters/postgresReadCatalog.js +226 -0
  55. package/dist/adapters/postgresReadSnapshot.d.ts +46 -0
  56. package/dist/adapters/postgresReadSnapshot.js +133 -0
  57. package/dist/adapters/postgresSchemaEpoch.d.ts +24 -0
  58. package/dist/adapters/postgresSchemaEpoch.js +149 -0
  59. package/dist/adapters/postgresTransactionHandle.d.ts +173 -0
  60. package/dist/adapters/postgresTransactionHandle.js +524 -0
  61. package/dist/adapters/postgresValues.d.ts +30 -0
  62. package/dist/adapters/postgresValues.js +75 -0
  63. package/dist/adapters/replicas.d.ts +70 -0
  64. package/dist/adapters/replicas.js +208 -0
  65. package/dist/adapters/reservedSql.d.ts +38 -0
  66. package/dist/adapters/reservedSql.js +264 -0
  67. package/dist/adapters/rolePrivileges.d.ts +17 -0
  68. package/dist/adapters/rolePrivileges.js +22 -0
  69. package/dist/adapters/scoped/keyRows.d.ts +65 -0
  70. package/dist/adapters/scoped/keyRows.js +173 -0
  71. package/dist/adapters/scoped/postgresScopeCatalog.d.ts +16 -0
  72. package/dist/adapters/scoped/postgresScopeCatalog.js +117 -0
  73. package/dist/adapters/scoped/scopedCommandOperations.d.ts +5 -0
  74. package/dist/adapters/scoped/scopedCommandOperations.js +48 -0
  75. package/dist/adapters/scoped/scopedReads.d.ts +20 -0
  76. package/dist/adapters/scoped/scopedReads.js +174 -0
  77. package/dist/adapters/scoped/scopedTransaction.d.ts +89 -0
  78. package/dist/adapters/scoped/scopedTransaction.js +303 -0
  79. package/dist/adapters/scoped/sqliteScopeCatalog.d.ts +16 -0
  80. package/dist/adapters/scoped/sqliteScopeCatalog.js +241 -0
  81. package/dist/adapters/scoped/updateGuard.d.ts +3 -0
  82. package/dist/adapters/scoped/updateGuard.js +40 -0
  83. package/dist/adapters/serverSettings.d.ts +45 -0
  84. package/dist/adapters/serverSettings.js +46 -0
  85. package/dist/adapters/sqlite.d.ts +262 -0
  86. package/dist/adapters/sqlite.js +1434 -0
  87. package/dist/adapters/sqliteCostlyReads.d.ts +33 -0
  88. package/dist/adapters/sqliteCostlyReads.js +49 -0
  89. package/dist/adapters/sqliteDecimals.d.ts +22 -0
  90. package/dist/adapters/sqliteDecimals.js +57 -0
  91. package/dist/adapters/sqliteHandles.d.ts +43 -0
  92. package/dist/adapters/sqliteHandles.js +143 -0
  93. package/dist/adapters/sqliteStatementProcess.d.ts +29 -0
  94. package/dist/adapters/sqliteStatementProcess.js +131 -0
  95. package/dist/adapters/statementControl.d.ts +34 -0
  96. package/dist/adapters/statementControl.js +90 -0
  97. package/dist/adapters/storeHost.d.ts +130 -0
  98. package/dist/adapters/storeHost.js +13 -0
  99. package/dist/adapters/telemetry/drivers.d.ts +21 -0
  100. package/dist/adapters/telemetry/drivers.js +321 -0
  101. package/dist/adapters/telemetry/metrics.d.ts +63 -0
  102. package/dist/adapters/telemetry/metrics.js +122 -0
  103. package/dist/adapters/telemetry/otlp.d.ts +12 -0
  104. package/dist/adapters/telemetry/otlp.js +320 -0
  105. package/dist/adapters/telemetry/otlpEncode.d.ts +48 -0
  106. package/dist/adapters/telemetry/otlpEncode.js +366 -0
  107. package/dist/adapters/telemetry/otlpEnv.d.ts +1 -0
  108. package/dist/adapters/telemetry/otlpEnv.js +12 -0
  109. package/dist/adapters/telemetry/serverTiming.d.ts +83 -0
  110. package/dist/adapters/telemetry/serverTiming.js +503 -0
  111. package/dist/adapters/telemetry/start.d.ts +10 -0
  112. package/dist/adapters/telemetry/start.js +25 -0
  113. package/dist/adapters/telemetry/statement.d.ts +16 -0
  114. package/dist/adapters/telemetry/statement.js +134 -0
  115. package/dist/adapters/telemetry/trace.d.ts +127 -0
  116. package/dist/adapters/telemetry/trace.js +295 -0
  117. package/dist/adapters/writeAhead.d.ts +27 -0
  118. package/dist/adapters/writeAhead.js +46 -0
  119. package/dist/adapters/writeAttribution.d.ts +18 -0
  120. package/dist/adapters/writeAttribution.js +23 -0
  121. package/dist/adapters/writeCapture.d.ts +73 -0
  122. package/dist/adapters/writeCapture.js +20 -0
  123. package/dist/adapters/writeLanes.d.ts +94 -0
  124. package/dist/adapters/writeLanes.js +232 -0
  125. package/dist/engine.d.ts +15 -0
  126. package/dist/engine.js +13 -0
  127. package/dist/server/auth/credentials.d.ts +61 -0
  128. package/dist/server/auth/credentials.js +260 -0
  129. package/dist/server/cacheService.d.ts +50 -0
  130. package/dist/server/cacheService.js +110 -0
  131. package/dist/server/cli/args.d.ts +176 -0
  132. package/dist/server/cli/args.js +342 -0
  133. package/dist/server/cli/bin.d.ts +5 -0
  134. package/dist/server/cli/bin.js +66 -0
  135. package/dist/server/cli/browser.d.ts +15 -0
  136. package/dist/server/cli/browser.js +37 -0
  137. package/dist/server/cli/config.d.ts +50 -0
  138. package/dist/server/cli/config.js +206 -0
  139. package/dist/server/cli/startup.d.ts +36 -0
  140. package/dist/server/cli/startup.js +128 -0
  141. package/dist/server/cli/startupOptions.d.ts +63 -0
  142. package/dist/server/cli/startupOptions.js +143 -0
  143. package/dist/server/cli/subcommand.d.ts +28 -0
  144. package/dist/server/cli/subcommand.js +32 -0
  145. package/dist/server/cli/usage.d.ts +13 -0
  146. package/dist/server/cli/usage.js +31 -0
  147. package/dist/server/clientHttp.d.ts +184 -0
  148. package/dist/server/clientHttp.js +700 -0
  149. package/dist/server/clientSurface.d.ts +128 -0
  150. package/dist/server/clientSurface.js +182 -0
  151. package/dist/server/columnGrants.d.ts +103 -0
  152. package/dist/server/columnGrants.js +730 -0
  153. package/dist/server/compileCache.d.ts +1 -0
  154. package/dist/server/compileCache.js +30 -0
  155. package/dist/server/config/locations.d.ts +1 -0
  156. package/dist/server/config/locations.js +15 -0
  157. package/dist/server/configPaths.d.ts +7 -0
  158. package/dist/server/configPaths.js +34 -0
  159. package/dist/server/configSections.d.ts +64 -0
  160. package/dist/server/configSections.js +72 -0
  161. package/dist/server/connectionRedaction.d.ts +30 -0
  162. package/dist/server/connectionRedaction.js +77 -0
  163. package/dist/server/connections.d.ts +353 -0
  164. package/dist/server/connections.js +978 -0
  165. package/dist/server/constraints.d.ts +82 -0
  166. package/dist/server/constraints.js +169 -0
  167. package/dist/server/demo.d.ts +9 -0
  168. package/dist/server/demo.js +554 -0
  169. package/dist/server/devclient.d.ts +108 -0
  170. package/dist/server/devclient.js +361 -0
  171. package/dist/server/evidence.d.ts +55 -0
  172. package/dist/server/evidence.js +323 -0
  173. package/dist/server/hiddenColumns.d.ts +32 -0
  174. package/dist/server/hiddenColumns.js +238 -0
  175. package/dist/server/http/baselineHeaders.d.ts +24 -0
  176. package/dist/server/http/baselineHeaders.js +12 -0
  177. package/dist/server/http/captured.d.ts +35 -0
  178. package/dist/server/http/captured.js +73 -0
  179. package/dist/server/http/clock.d.ts +1 -0
  180. package/dist/server/http/clock.js +14 -0
  181. package/dist/server/http/connectionSource.d.ts +4 -0
  182. package/dist/server/http/connectionSource.js +48 -0
  183. package/dist/server/http/context.d.ts +189 -0
  184. package/dist/server/http/context.js +11 -0
  185. package/dist/server/http/crawlerText.d.ts +15 -0
  186. package/dist/server/http/crawlerText.js +32 -0
  187. package/dist/server/http/dataRoutes.d.ts +88 -0
  188. package/dist/server/http/dataRoutes.js +137 -0
  189. package/dist/server/http/door.d.ts +57 -0
  190. package/dist/server/http/door.js +39 -0
  191. package/dist/server/http/exportRoute.d.ts +15 -0
  192. package/dist/server/http/exportRoute.js +320 -0
  193. package/dist/server/http/firstPaint.d.ts +108 -0
  194. package/dist/server/http/firstPaint.js +262 -0
  195. package/dist/server/http/httpOperationRoutes.d.ts +11 -0
  196. package/dist/server/http/httpOperationRoutes.js +50 -0
  197. package/dist/server/http/pageReads.d.ts +20 -0
  198. package/dist/server/http/pageReads.js +205 -0
  199. package/dist/server/http/pageRoutes.d.ts +39 -0
  200. package/dist/server/http/pageRoutes.js +291 -0
  201. package/dist/server/http/probes.d.ts +22 -0
  202. package/dist/server/http/probes.js +27 -0
  203. package/dist/server/http/rateLimit.d.ts +131 -0
  204. package/dist/server/http/rateLimit.js +351 -0
  205. package/dist/server/http/readRoutes.d.ts +9 -0
  206. package/dist/server/http/readRoutes.js +131 -0
  207. package/dist/server/http/readRouting.d.ts +20 -0
  208. package/dist/server/http/readRouting.js +80 -0
  209. package/dist/server/http/recordCompose.d.ts +67 -0
  210. package/dist/server/http/recordCompose.js +167 -0
  211. package/dist/server/http/recordWrites.d.ts +89 -0
  212. package/dist/server/http/recordWrites.js +298 -0
  213. package/dist/server/http/refusalReport.d.ts +38 -0
  214. package/dist/server/http/refusalReport.js +63 -0
  215. package/dist/server/http/reply.d.ts +130 -0
  216. package/dist/server/http/reply.js +394 -0
  217. package/dist/server/http/requestOrigin.d.ts +11 -0
  218. package/dist/server/http/requestOrigin.js +8 -0
  219. package/dist/server/http/router.d.ts +45 -0
  220. package/dist/server/http/router.js +22 -0
  221. package/dist/server/http/serverCore.d.ts +68 -0
  222. package/dist/server/http/serverCore.js +177 -0
  223. package/dist/server/http/traceRequest.d.ts +30 -0
  224. package/dist/server/http/traceRequest.js +224 -0
  225. package/dist/server/http/trust.d.ts +261 -0
  226. package/dist/server/http/trust.js +472 -0
  227. package/dist/server/http/writeRefusal.d.ts +33 -0
  228. package/dist/server/http/writeRefusal.js +24 -0
  229. package/dist/server/httpConnection.d.ts +49 -0
  230. package/dist/server/httpConnection.js +170 -0
  231. package/dist/server/impact.d.ts +55 -0
  232. package/dist/server/impact.js +47 -0
  233. package/dist/server/journal.d.ts +134 -0
  234. package/dist/server/journal.js +398 -0
  235. package/dist/server/keysetReadHttp.d.ts +52 -0
  236. package/dist/server/keysetReadHttp.js +85 -0
  237. package/dist/server/layouts.d.ts +49 -0
  238. package/dist/server/layouts.js +192 -0
  239. package/dist/server/migrate/cli.d.ts +55 -0
  240. package/dist/server/migrate/cli.js +517 -0
  241. package/dist/server/migrate/database.d.ts +37 -0
  242. package/dist/server/migrate/database.js +247 -0
  243. package/dist/server/migrate/desired.d.ts +76 -0
  244. package/dist/server/migrate/desired.js +292 -0
  245. package/dist/server/migrate/files.d.ts +34 -0
  246. package/dist/server/migrate/files.js +141 -0
  247. package/dist/server/migrate/flyway.d.ts +7 -0
  248. package/dist/server/migrate/flyway.js +69 -0
  249. package/dist/server/migrate/history.d.ts +70 -0
  250. package/dist/server/migrate/history.js +211 -0
  251. package/dist/server/migrate/runner.d.ts +100 -0
  252. package/dist/server/migrate/runner.js +409 -0
  253. package/dist/server/migrate/snapshot.d.ts +30 -0
  254. package/dist/server/migrate/snapshot.js +239 -0
  255. package/dist/server/migrate/target.d.ts +33 -0
  256. package/dist/server/migrate/target.js +82 -0
  257. package/dist/server/openapiDraft.d.ts +25 -0
  258. package/dist/server/openapiDraft.js +171 -0
  259. package/dist/server/operations/diagnostics.d.ts +101 -0
  260. package/dist/server/operations/diagnostics.js +284 -0
  261. package/dist/server/operations/requestMetrics.d.ts +33 -0
  262. package/dist/server/operations/requestMetrics.js +94 -0
  263. package/dist/server/packageVersion.d.ts +1 -0
  264. package/dist/server/packageVersion.js +11 -0
  265. package/dist/server/poolConfig.d.ts +34 -0
  266. package/dist/server/poolConfig.js +114 -0
  267. package/dist/server/product.d.ts +20 -0
  268. package/dist/server/product.js +12 -0
  269. package/dist/server/recordHistoryOperations.d.ts +39 -0
  270. package/dist/server/recordHistoryOperations.js +43 -0
  271. package/dist/server/recordWriteOperations.d.ts +111 -0
  272. package/dist/server/recordWriteOperations.js +329 -0
  273. package/dist/server/resourceReadHttp.d.ts +81 -0
  274. package/dist/server/resourceReadHttp.js +606 -0
  275. package/dist/server/resourceReadOperations.d.ts +147 -0
  276. package/dist/server/resourceReadOperations.js +452 -0
  277. package/dist/server/scaffoldMachine.d.ts +54 -0
  278. package/dist/server/scaffoldMachine.js +184 -0
  279. package/dist/server/seed/cli.d.ts +20 -0
  280. package/dist/server/seed/cli.js +164 -0
  281. package/dist/server/seed/lexicon.d.ts +26 -0
  282. package/dist/server/seed/lexicon.js +585 -0
  283. package/dist/server/seed/seed.d.ts +70 -0
  284. package/dist/server/seed/seed.js +779 -0
  285. package/dist/server/seed/words.d.ts +21 -0
  286. package/dist/server/seed/words.js +164 -0
  287. package/dist/server/serverRequests.d.ts +6 -0
  288. package/dist/server/serverRequests.js +33 -0
  289. package/dist/server/serverTimeouts.d.ts +33 -0
  290. package/dist/server/serverTimeouts.js +32 -0
  291. package/dist/server/shapeonly.d.ts +32 -0
  292. package/dist/server/shapeonly.js +110 -0
  293. package/dist/server/startupWarnings.d.ts +32 -0
  294. package/dist/server/startupWarnings.js +92 -0
  295. package/dist/shared/addressParams.d.ts +28 -0
  296. package/dist/shared/addressParams.js +47 -0
  297. package/dist/shared/appCards.d.ts +123 -0
  298. package/dist/shared/appCards.js +385 -0
  299. package/dist/shared/appComponents.d.ts +177 -0
  300. package/dist/shared/appComponents.js +422 -0
  301. package/dist/shared/appDocuments.d.ts +43 -0
  302. package/dist/shared/appDocuments.js +131 -0
  303. package/dist/shared/appEmbeds.d.ts +21 -0
  304. package/dist/shared/appEmbeds.js +24 -0
  305. package/dist/shared/appIcons.d.ts +28 -0
  306. package/dist/shared/appIcons.js +223 -0
  307. package/dist/shared/appLinks.d.ts +17 -0
  308. package/dist/shared/appLinks.js +124 -0
  309. package/dist/shared/appListColumns.d.ts +3 -0
  310. package/dist/shared/appListColumns.js +66 -0
  311. package/dist/shared/appLocale.d.ts +36 -0
  312. package/dist/shared/appLocale.js +86 -0
  313. package/dist/shared/appMessages.d.ts +44 -0
  314. package/dist/shared/appMessages.js +78 -0
  315. package/dist/shared/appNoun.d.ts +21 -0
  316. package/dist/shared/appNoun.js +32 -0
  317. package/dist/shared/autoBucket.d.ts +98 -0
  318. package/dist/shared/autoBucket.js +305 -0
  319. package/dist/shared/autoValues.d.ts +25 -0
  320. package/dist/shared/autoValues.js +25 -0
  321. package/dist/shared/breakdown.d.ts +228 -0
  322. package/dist/shared/breakdown.js +557 -0
  323. package/dist/shared/breakdowntext.d.ts +41 -0
  324. package/dist/shared/breakdowntext.js +400 -0
  325. package/dist/shared/builtInThemes.d.ts +2 -0
  326. package/dist/shared/builtInThemes.js +771 -0
  327. package/dist/shared/chartSeparation.d.ts +11 -0
  328. package/dist/shared/chartSeparation.js +58 -0
  329. package/dist/shared/clauses.d.ts +22 -0
  330. package/dist/shared/clauses.js +97 -0
  331. package/dist/shared/columnCaption.d.ts +16 -0
  332. package/dist/shared/columnCaption.js +90 -0
  333. package/dist/shared/commandFieldPath.d.ts +2 -0
  334. package/dist/shared/commandFieldPath.js +7 -0
  335. package/dist/shared/commandWire.d.ts +26 -0
  336. package/dist/shared/commandWire.js +41 -0
  337. package/dist/shared/computed.d.ts +161 -0
  338. package/dist/shared/computed.js +378 -0
  339. package/dist/shared/computedParse.d.ts +13 -0
  340. package/dist/shared/computedParse.js +278 -0
  341. package/dist/shared/computedValue.d.ts +47 -0
  342. package/dist/shared/computedValue.js +191 -0
  343. package/dist/shared/connection.d.ts +30 -0
  344. package/dist/shared/connection.js +1 -0
  345. package/dist/shared/csv.d.ts +20 -0
  346. package/dist/shared/csv.js +63 -0
  347. package/dist/shared/dashLayout.d.ts +30 -0
  348. package/dist/shared/dashLayout.js +132 -0
  349. package/dist/shared/dashboardAsks.d.ts +93 -0
  350. package/dist/shared/dashboardAsks.js +129 -0
  351. package/dist/shared/dashboardTrend.d.ts +20 -0
  352. package/dist/shared/dashboardTrend.js +50 -0
  353. package/dist/shared/declaredReferences.d.ts +50 -0
  354. package/dist/shared/declaredReferences.js +202 -0
  355. package/dist/shared/definedFields.d.ts +63 -0
  356. package/dist/shared/definedFields.js +103 -0
  357. package/dist/shared/definedValues.d.ts +63 -0
  358. package/dist/shared/definedValues.js +184 -0
  359. package/dist/shared/displayDefaults.d.ts +135 -0
  360. package/dist/shared/displayDefaults.js +529 -0
  361. package/dist/shared/dueDate.d.ts +6 -0
  362. package/dist/shared/dueDate.js +6 -0
  363. package/dist/shared/duration.d.ts +4 -0
  364. package/dist/shared/duration.js +23 -0
  365. package/dist/shared/fileBounds.d.ts +9 -0
  366. package/dist/shared/fileBounds.js +9 -0
  367. package/dist/shared/filter.d.ts +217 -0
  368. package/dist/shared/filter.js +305 -0
  369. package/dist/shared/firstPaint.d.ts +24 -0
  370. package/dist/shared/firstPaint.js +33 -0
  371. package/dist/shared/form.d.ts +21 -0
  372. package/dist/shared/form.js +25 -0
  373. package/dist/shared/formValues.d.ts +104 -0
  374. package/dist/shared/formValues.js +352 -0
  375. package/dist/shared/funnel.d.ts +45 -0
  376. package/dist/shared/funnel.js +108 -0
  377. package/dist/shared/httpOperations.d.ts +48 -0
  378. package/dist/shared/httpOperations.js +9 -0
  379. package/dist/shared/iconGlyphs.d.ts +4 -0
  380. package/dist/shared/iconGlyphs.js +151 -0
  381. package/dist/shared/iconWeights.d.ts +3 -0
  382. package/dist/shared/iconWeights.js +162 -0
  383. package/dist/shared/imageWidths.d.ts +32 -0
  384. package/dist/shared/imageWidths.js +38 -0
  385. package/dist/shared/keysetPage.d.ts +64 -0
  386. package/dist/shared/keysetPage.js +161 -0
  387. package/dist/shared/like.d.ts +20 -0
  388. package/dist/shared/like.js +29 -0
  389. package/dist/shared/listEmpty.d.ts +12 -0
  390. package/dist/shared/listEmpty.js +36 -0
  391. package/dist/shared/listFilters.d.ts +28 -0
  392. package/dist/shared/listFilters.js +84 -0
  393. package/dist/shared/listPresentations.d.ts +199 -0
  394. package/dist/shared/listPresentations.js +7 -0
  395. package/dist/shared/listQuestion.d.ts +52 -0
  396. package/dist/shared/listQuestion.js +137 -0
  397. package/dist/shared/lookPalettes.d.ts +62 -0
  398. package/dist/shared/lookPalettes.js +306 -0
  399. package/dist/shared/maskQuoted.d.ts +24 -0
  400. package/dist/shared/maskQuoted.js +48 -0
  401. package/dist/shared/mentionLabel.d.ts +19 -0
  402. package/dist/shared/mentionLabel.js +38 -0
  403. package/dist/shared/mentionLookup.d.ts +17 -0
  404. package/dist/shared/mentionLookup.js +64 -0
  405. package/dist/shared/menuCounts.d.ts +16 -0
  406. package/dist/shared/menuCounts.js +74 -0
  407. package/dist/shared/model.d.ts +79 -0
  408. package/dist/shared/model.js +153 -0
  409. package/dist/shared/money.d.ts +44 -0
  410. package/dist/shared/money.js +81 -0
  411. package/dist/shared/moneyEntry.d.ts +7 -0
  412. package/dist/shared/moneyEntry.js +27 -0
  413. package/dist/shared/mount.d.ts +118 -0
  414. package/dist/shared/mount.js +248 -0
  415. package/dist/shared/niceTicks.d.ts +26 -0
  416. package/dist/shared/niceTicks.js +50 -0
  417. package/dist/shared/order.d.ts +59 -0
  418. package/dist/shared/order.js +133 -0
  419. package/dist/shared/page.d.ts +135 -0
  420. package/dist/shared/page.js +1187 -0
  421. package/dist/shared/pageAnatomy.d.ts +99 -0
  422. package/dist/shared/pageAnatomy.js +370 -0
  423. package/dist/shared/pageConfig.d.ts +25 -0
  424. package/dist/shared/pageConfig.js +1308 -0
  425. package/dist/shared/pageEmptyActions.d.ts +12 -0
  426. package/dist/shared/pageEmptyActions.js +20 -0
  427. package/dist/shared/pageLayouts.d.ts +72 -0
  428. package/dist/shared/pageLayouts.js +205 -0
  429. package/dist/shared/pageModel.d.ts +785 -0
  430. package/dist/shared/pageModel.js +121 -0
  431. package/dist/shared/pagePaths.d.ts +180 -0
  432. package/dist/shared/pagePaths.js +869 -0
  433. package/dist/shared/pagePlans.d.ts +52 -0
  434. package/dist/shared/pagePlans.js +108 -0
  435. package/dist/shared/pageRoutes.d.ts +9 -0
  436. package/dist/shared/pageRoutes.js +9 -0
  437. package/dist/shared/query.d.ts +166 -0
  438. package/dist/shared/query.js +1302 -0
  439. package/dist/shared/queryDates.d.ts +12 -0
  440. package/dist/shared/queryDates.js +101 -0
  441. package/dist/shared/queryOperands.d.ts +99 -0
  442. package/dist/shared/queryOperands.js +131 -0
  443. package/dist/shared/reads.d.ts +103 -0
  444. package/dist/shared/reads.js +154 -0
  445. package/dist/shared/recordLabel.d.ts +51 -0
  446. package/dist/shared/recordLabel.js +123 -0
  447. package/dist/shared/recordReadKeys.d.ts +30 -0
  448. package/dist/shared/recordReadKeys.js +51 -0
  449. package/dist/shared/recordReads.d.ts +268 -0
  450. package/dist/shared/recordReads.js +368 -0
  451. package/dist/shared/recordview.d.ts +198 -0
  452. package/dist/shared/recordview.js +356 -0
  453. package/dist/shared/referenceModel.d.ts +58 -0
  454. package/dist/shared/referenceModel.js +194 -0
  455. package/dist/shared/refusal.d.ts +64 -0
  456. package/dist/shared/refusal.js +144 -0
  457. package/dist/shared/relatedCreate.d.ts +30 -0
  458. package/dist/shared/relatedCreate.js +162 -0
  459. package/dist/shared/resourceHttp.d.ts +464 -0
  460. package/dist/shared/resourceHttp.js +1 -0
  461. package/dist/shared/richText.d.ts +85 -0
  462. package/dist/shared/richText.js +305 -0
  463. package/dist/shared/rollups.d.ts +143 -0
  464. package/dist/shared/rollups.js +64 -0
  465. package/dist/shared/rowScope.d.ts +72 -0
  466. package/dist/shared/rowScope.js +376 -0
  467. package/dist/shared/runtimeTables.d.ts +44 -0
  468. package/dist/shared/runtimeTables.js +79 -0
  469. package/dist/shared/schema.d.ts +523 -0
  470. package/dist/shared/schema.js +627 -0
  471. package/dist/shared/schematext.d.ts +38 -0
  472. package/dist/shared/schematext.js +101 -0
  473. package/dist/shared/scopeCatalog.d.ts +29 -0
  474. package/dist/shared/scopeCatalog.js +468 -0
  475. package/dist/shared/servedApp.d.ts +681 -0
  476. package/dist/shared/servedApp.js +45 -0
  477. package/dist/shared/sessionLease.d.ts +34 -0
  478. package/dist/shared/sessionLease.js +3 -0
  479. package/dist/shared/shape.d.ts +55 -0
  480. package/dist/shared/shape.js +168 -0
  481. package/dist/shared/slug.d.ts +1 -0
  482. package/dist/shared/slug.js +12 -0
  483. package/dist/shared/sortText.d.ts +14 -0
  484. package/dist/shared/sortText.js +26 -0
  485. package/dist/shared/sqlRelation.d.ts +4 -0
  486. package/dist/shared/sqlRelation.js +8 -0
  487. package/dist/shared/sqlsaved.d.ts +44 -0
  488. package/dist/shared/sqlsaved.js +63 -0
  489. package/dist/shared/stitchedPaths.d.ts +27 -0
  490. package/dist/shared/stitchedPaths.js +38 -0
  491. package/dist/shared/structuredFilter.d.ts +22 -0
  492. package/dist/shared/structuredFilter.js +1 -0
  493. package/dist/shared/subtitlePath.d.ts +20 -0
  494. package/dist/shared/subtitlePath.js +24 -0
  495. package/dist/shared/suggest.d.ts +18 -0
  496. package/dist/shared/suggest.js +59 -0
  497. package/dist/shared/tableSizing.d.ts +4 -0
  498. package/dist/shared/tableSizing.js +9 -0
  499. package/dist/shared/tagLists.d.ts +57 -0
  500. package/dist/shared/tagLists.js +34 -0
  501. package/dist/shared/textRules.d.ts +54 -0
  502. package/dist/shared/textRules.js +133 -0
  503. package/dist/shared/theme.d.ts +94 -0
  504. package/dist/shared/theme.js +800 -0
  505. package/dist/shared/themeColor.d.ts +34 -0
  506. package/dist/shared/themeColor.js +109 -0
  507. package/dist/shared/themeFaces.d.ts +30 -0
  508. package/dist/shared/themeFaces.js +42 -0
  509. package/dist/shared/themeInk.d.ts +20 -0
  510. package/dist/shared/themeInk.js +52 -0
  511. package/dist/shared/themeLooks.d.ts +9 -0
  512. package/dist/shared/themeLooks.js +572 -0
  513. package/dist/shared/themeParts.d.ts +26 -0
  514. package/dist/shared/themeParts.js +71 -0
  515. package/dist/shared/themePartsCheck.d.ts +21 -0
  516. package/dist/shared/themePartsCheck.js +91 -0
  517. package/dist/shared/themePresets.d.ts +85 -0
  518. package/dist/shared/themePresets.js +139 -0
  519. package/dist/shared/themeRecipeWords.d.ts +156 -0
  520. package/dist/shared/themeRecipeWords.js +156 -0
  521. package/dist/shared/themeRecipes.d.ts +213 -0
  522. package/dist/shared/themeRecipes.js +234 -0
  523. package/dist/shared/themeResolve.d.ts +55 -0
  524. package/dist/shared/themeResolve.js +52 -0
  525. package/dist/shared/themeTokens.d.ts +107 -0
  526. package/dist/shared/themeTokens.js +116 -0
  527. package/dist/shared/themeType.d.ts +38 -0
  528. package/dist/shared/themeType.js +205 -0
  529. package/dist/shared/unitWord.d.ts +4 -0
  530. package/dist/shared/unitWord.js +37 -0
  531. package/dist/shared/view.d.ts +195 -0
  532. package/dist/shared/view.js +987 -0
  533. package/dist/shared/viewLabels.d.ts +47 -0
  534. package/dist/shared/viewLabels.js +459 -0
  535. package/dist/shared/viewPaths.d.ts +248 -0
  536. package/dist/shared/viewPaths.js +294 -0
  537. package/dist/shared/viewtext.d.ts +57 -0
  538. package/dist/shared/viewtext.js +282 -0
  539. package/dist/shared/vocabulary.d.ts +71 -0
  540. package/dist/shared/vocabulary.js +249 -0
  541. package/dist/shared/weekStart.d.ts +7 -0
  542. package/dist/shared/weekStart.js +36 -0
  543. package/mark.svg +1 -0
  544. package/package.json +261 -4
  545. package/schema/model.d.ts +298 -0
  546. package/schema/theme.d.ts +587 -0
@@ -0,0 +1,838 @@
1
+ /**
2
+ * The PostgreSQL connections of one database: a bounded reader pool, a
3
+ * writer pool, and one background writer, each opened on first use, every
4
+ * lease given back in `finally`.
5
+ *
6
+ * Three things vary by deployment, per manager or, for the whole process,
7
+ * from the command line:
8
+ *
9
+ * - How many readers the pool may hold: for an App as many as its writers
10
+ * (at least balancedPoolSize), four for the database browser, unless told
11
+ * otherwise; one to sixty-four.
12
+ * - How many writers: balancedPoolSize for a process serving Apps unless told otherwise
13
+ * (`pool.write`, `--write-pool`; writeLanes.ts), one to sixty-four, each running one
14
+ * transaction beside the others (writeLanes.ts orders writes of one
15
+ * record). The database browser keeps one: its writes run one at a time,
16
+ * the order its Undo depends on (docs/postgresql.md).
17
+ * - Background work — a job's command — writes through a connection of its
18
+ * own, so it never takes the writer a person's save is waiting for.
19
+ * - What sits between this process and the server. Directly, or through a
20
+ * pooler that gives each client a whole server session, the read-only
21
+ * default and the statement cap are set once per physical connection.
22
+ * Through a transaction-mode pooler they are set per transaction instead
23
+ * (postgresPooler.ts): the next transaction may run on another server
24
+ * connection, and anything set on this one stays for the pooler's next
25
+ * client.
26
+ *
27
+ * Every checkout is metered (poolMetrics.ts) — the wait for a connection,
28
+ * how long it was held, how many are queued now — for the operator surface.
29
+ *
30
+ * A connection that names replicas gets a manager per replica, sized like
31
+ * this one's readers, and the reader handle's statements go to one of them
32
+ * when the work they run in tolerates lag (replicas.ts). Everything that
33
+ * leases a whole client — a snapshot, a raw SQL read, a store's read, every
34
+ * write — stays here, on the primary.
35
+ */
36
+ import { cancellation, onCancel, STATEMENT_TIMEOUT_MS, StatementStopped, throwIfCancelled } from './statementControl.js';
37
+ import { PoolBusy, PoolMeter, POOL_LIMIT_HOLD_MS, POOL_QUEUE_PER_CONNECTION, POOL_QUEUE_WAIT_MS, } from './poolMetrics.js';
38
+ import { PoolAdmission } from './poolAdmission.js';
39
+ import { holdConnections, managerConnections } from './connectionBudget.js';
40
+ import { pgConnectionOptions } from './postgresValues.js';
41
+ import { sealedPgOptions } from './net/untrustedDatabase.js';
42
+ import { transactionScoped } from './postgresPooler.js';
43
+ import { balancedPoolSize, inBackgroundWork, isWriterCount, lockTimeoutMs, MAX_WRITERS, writeOrder, writerPoolSize } from './writeLanes.js';
44
+ import { startSpan } from './telemetry/trace.js';
45
+ import { delayFlights } from './dbLatency.js';
46
+ import { configureServerSettings, serverSettings } from './serverSettings.js';
47
+ import { MAX_REPLICAS, noteWrite, primaryReads, ReplicaSet } from './replicas.js';
48
+ /* The leases whose client sends each query without waiting for the one before
49
+ (a writer's, on node-postgres): what pipelined() may send together. */
50
+ const pipelining = new WeakSet();
51
+ /** This lease's client pipelines: several queries asked at once leave together. */
52
+ export const pipelines = (client) => pipelining.has(client);
53
+ /** `wrapper` sends through `client` and nothing else: it pipelines where `client` does. */
54
+ export const pipelinesAs = (wrapper, client) => {
55
+ if (pipelining.has(client))
56
+ pipelining.add(wrapper);
57
+ };
58
+ const loadPg = async () => {
59
+ const specifier = 'pg';
60
+ return import(specifier).catch(() => {
61
+ throw new Error('Postgres support needs the "pg" package. Install it with: npm install pg');
62
+ });
63
+ };
64
+ /** The database browser's reader pool size unless a connection or the command line says otherwise.
65
+ * An App's is balanced against its writers (appReaders). */
66
+ export const DEFAULT_READERS = 4;
67
+ /** Readers kept connected through an idle spell. Without them the first read
68
+ * after thirty quiet seconds paid a new connection and its two SETs — and a
69
+ * dashboard's fan-out paid it several times at once. Two, not the whole pool:
70
+ * a warm connection is a server backend held for nothing most of the day. */
71
+ const WARM_READERS = 2;
72
+ /** The most readers one database's pool may hold. Past this, a pooler in front of the server is the tool. */
73
+ export const MAX_READERS = 64;
74
+ /** What pg-pool says when no connection came free within the acquisition timeout. */
75
+ const ACQUISITION_TIMEOUT = /timeout exceeded when trying to connect/i;
76
+ /** The server refused this process another connection: too many for its role, or for the server (SQLSTATE 53300). */
77
+ const atConnectionLimit = (error) => error !== null && typeof error === 'object' && error.code === '53300';
78
+ const LIMIT_HOLD_MS = POOL_LIMIT_HOLD_MS;
79
+ /** How many times one checkout asks again after a refusal, a held connection having gone meanwhile. */
80
+ const LIMIT_ATTEMPTS = 3;
81
+ /** Whether `value` is a reader pool size a manager accepts: a whole number from 1 to 64. */
82
+ export function isReaderCount(value) {
83
+ return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= MAX_READERS;
84
+ }
85
+ /* Server timing (telemetry/serverTiming.ts) is loaded with the first pool, not with this module: a print-and-exit
86
+ flag reaches this file through the settings it reads and never opens a pool (test/cli-startup.test.ts counts what
87
+ it loads). Every lease comes from a pool, so a lease always finds it loaded. */
88
+ let timing;
89
+ /** What no one chose: an App (keyed writes) reads as widely as it writes, never fewer, because writes without
90
+ * readers to match only moved the queue to the reads; the database browser keeps four. */
91
+ function defaultReaders(writers) {
92
+ return writeOrder() === 'keyed' ? appReaders(writers) : DEFAULT_READERS;
93
+ }
94
+ /** An App's reader pool where none was chosen: as wide as its writers, at least the balanced size for `cores`
95
+ * (this machine's, unless a deployment check asks for another's). */
96
+ export function appReaders(writers, cores) {
97
+ return Math.min(MAX_READERS, Math.max(balancedPoolSize(cores), writers));
98
+ }
99
+ /**
100
+ * The defaults every manager in this process takes when it names none: the
101
+ * command line's `--read-pool` and `--pooler`. Server-wide on purpose
102
+ * (serverSettings.ts): besides the registry's adapters, tenant sources, the
103
+ * job host and startup checks open pools of their own on the same databases,
104
+ * and a transaction-mode pooler in front of one of them has to be honored by
105
+ * every one; a per-connection switch would reach only some. Called once, at
106
+ * startup; whatever it leaves unsaid returns to the built-in default. The
107
+ * reader count stays unset until a manager is made: the write order, which
108
+ * says whether this is an App, is configured after the flags are read.
109
+ */
110
+ export function configurePostgresPools(options) {
111
+ const readers = options.readers;
112
+ if (readers !== undefined && !isReaderCount(readers))
113
+ throw new RangeError(`A PostgreSQL read pool holds 1 to ${MAX_READERS} connections; ${String(readers)} is not one of them.`);
114
+ const pooler = options.pooler ?? 'session';
115
+ if (pooler !== 'session' && pooler !== 'transaction')
116
+ throw new RangeError('The pooler is "session" or "transaction".');
117
+ configureServerSettings({ readers, pooler });
118
+ }
119
+ /** The defaults, as this server's settings leave them. */
120
+ export function postgresPoolDefaults() {
121
+ const settings = serverSettings();
122
+ return {
123
+ readers: settings.readers ?? defaultReaders(writerPoolSize()),
124
+ pooler: settings.pooler,
125
+ };
126
+ }
127
+ /** Separate bounded pools keep browsing read-only and transactions on one lease. */
128
+ export class PgConnectionManager {
129
+ connectionString;
130
+ onLoad;
131
+ load;
132
+ reader;
133
+ writer;
134
+ background;
135
+ /** The pools once they exist, for the meters' physical counts. */
136
+ opened = {};
137
+ closed = false;
138
+ /* Server timing's gauges on this manager's pools, taken out at its close: each holds its pool alive. */
139
+ gauges = [];
140
+ closing;
141
+ /** What sits between this process and the server, for every lease of this manager. */
142
+ pooler;
143
+ capMs;
144
+ lockMs;
145
+ queueWaitMs;
146
+ queuePerConnection;
147
+ meters;
148
+ /** The line each person-facing role's checkouts wait in, turn by turn across accounts (poolAdmission.ts). */
149
+ admissions;
150
+ /* One object, so every caller of read() holds the same handle, as when the handle was the pool itself. */
151
+ reads;
152
+ /** This database's replicas, each a manager of its own whose writers are never opened. */
153
+ replicas;
154
+ network;
155
+ pipelineReads;
156
+ timingLabel;
157
+ /** A pool the server refused another connection, held at what it had until the timer lets it ask again. */
158
+ limitHolds = {};
159
+ /** When each pool last said it reached the connection limit: once a spell, not once a checkout. */
160
+ limitSaid = {};
161
+ /** Gives back what this manager told the connection budget it may hold (connectionBudget.ts). */
162
+ releaseBudget;
163
+ constructor(connectionString, onLoad = () => { }, load = loadPg, options = {}) {
164
+ this.connectionString = connectionString;
165
+ this.onLoad = onLoad;
166
+ this.load = load;
167
+ /* Where writes run one at a time a second writer would sit idle: the
168
+ pool is one, whatever the connection asked for. */
169
+ const writers = writeOrder() === 'serial' ? 1 : (options.writers ?? writerPoolSize());
170
+ const readers = options.readers ?? serverSettings().readers ?? defaultReaders(writers);
171
+ if (!isReaderCount(readers))
172
+ throw new RangeError(`A PostgreSQL read pool holds 1 to ${MAX_READERS} connections; ${String(readers)} is not one of them.`);
173
+ if (!isWriterCount(writers))
174
+ throw new RangeError(`A PostgreSQL write pool holds 1 to ${MAX_WRITERS} connections; ${String(writers)} is not one of them.`);
175
+ this.pooler = options.pooler ?? serverSettings().pooler;
176
+ this.network = options.network;
177
+ this.pipelineReads = options.pipelineReads === true;
178
+ this.timingLabel = options.timingLabel ?? 'app';
179
+ this.capMs = options.capMs ?? STATEMENT_TIMEOUT_MS;
180
+ this.queueWaitMs = options.queueWaitMs ?? POOL_QUEUE_WAIT_MS;
181
+ this.queuePerConnection = options.queuePerConnection ?? POOL_QUEUE_PER_CONNECTION;
182
+ this.lockMs = Math.min(options.lockTimeoutMs ?? lockTimeoutMs(), this.capMs);
183
+ this.meters = Object.freeze({
184
+ read: new PoolMeter('read', readers),
185
+ write: new PoolMeter('write', writers),
186
+ background: new PoolMeter('background', 1),
187
+ });
188
+ this.admissions = Object.freeze({
189
+ read: new PoolAdmission('read', readers, readers * this.queuePerConnection),
190
+ write: new PoolAdmission('write', writers, writers * this.queuePerConnection),
191
+ });
192
+ const replicas = options.replicas ?? [];
193
+ if (replicas.length > MAX_REPLICAS)
194
+ throw new RangeError(`A connection names at most ${MAX_REPLICAS} replicas; this one names ${replicas.length}.`);
195
+ /* A manager may open readers, writers and the background writer; a replica's own are readers only. */
196
+ const releases = options.counted === false
197
+ ? []
198
+ : [
199
+ holdConnections(connectionString, options.readersOnly ? readers : managerConnections(readers, writers), () => this.read()),
200
+ ...replicas.map((url) => holdConnections(url, readers)),
201
+ ];
202
+ this.releaseBudget = () => releases.forEach((release) => release());
203
+ /* Sized as this manager's readers are, the same pooler, cap and queue
204
+ bounds: a replica is where this pool's reads go, so it must hold them. */
205
+ if (replicas.length)
206
+ this.replicas = new ReplicaSet(replicas.map((url) => new PgConnectionManager(url, onLoad, load, {
207
+ ...options,
208
+ readers,
209
+ writers,
210
+ replicas: undefined,
211
+ counted: false,
212
+ timingLabel: 'app-replica',
213
+ })));
214
+ const run = (client, text, params) => client.query(text, params);
215
+ const statement = (text, params) => {
216
+ const primary = () => this.withClient(false, (client) => run(client, text, params), false);
217
+ return this.replicas
218
+ ? this.replicas.read((replica) => replica.withReadClient((client) => run(client, text, params)), primary)
219
+ : primary();
220
+ };
221
+ this.reads = { query: statement };
222
+ }
223
+ /**
224
+ * A handle for single statements on the reader pool. Each statement leases
225
+ * a client of its own for exactly its length, which is what `pool.query`
226
+ * did — so the checkout is metered, a cancel knows which client to stop,
227
+ * and behind a transaction-mode pooler the statement runs inside a
228
+ * read-only transaction of its own.
229
+ */
230
+ async read() {
231
+ await this.pool('read');
232
+ return this.reads;
233
+ }
234
+ /** Native snapshot owners opt into callback drain after cancellation. A
235
+ * callback must settle after its driver operations are destroyed; arbitrary
236
+ * never-settling application work cannot offer a bounded drain guarantee. */
237
+ async withReadClient(run, destroyAfter = false, drainCancelled = false) {
238
+ return this.withClient(false, run, destroyAfter, drainCancelled);
239
+ }
240
+ /** Private native snapshot seam: guard observes this exact checkout, not
241
+ * instantaneous remote-server health. Ordinary read/write behavior is unchanged. */
242
+ async withObservedReadClient(run) {
243
+ return this.withClient(false, (client, current) => {
244
+ if (!current)
245
+ throw new Error('Observed PostgreSQL checkout is unavailable.');
246
+ return run(client, current);
247
+ }, false, true, true);
248
+ }
249
+ /** A writer for one transaction: from the writer pool, or inside background work (asBackgroundWork) the background writer. */
250
+ async withWriteClient(run, destroyAfter = false) {
251
+ return this.withClient(true, run, destroyAfter);
252
+ }
253
+ /** The meters of the pools opened so far, readers first, then each replica's readers. Readable after close. */
254
+ stats() {
255
+ const own = ['read', 'write', 'background'].flatMap((role) => {
256
+ const pool = this.opened[role];
257
+ if (!pool)
258
+ return [];
259
+ const total = pool.totalCount;
260
+ return [this.meters[role].stats(this.pooler, typeof total === 'number' ? total : null)];
261
+ });
262
+ const replicas = (this.replicas?.pools ?? []).flatMap((replica, index) => replica.stats().map((stats) => ({
263
+ ...stats,
264
+ role: 'replica',
265
+ replica: index + 1,
266
+ })));
267
+ return [...own, ...replicas];
268
+ }
269
+ /** Whether this database names any replica. */
270
+ hasReplicas() {
271
+ return this.replicas !== undefined;
272
+ }
273
+ /**
274
+ * `work` on each replica in use now, its failures left out: what live sync
275
+ * asks of every healthy replica before it tells readers of a change, so a
276
+ * refetch it sets off reads a replica that has the change (server/live).
277
+ */
278
+ async onHealthyReplicas(work) {
279
+ const set = this.replicas;
280
+ if (!set)
281
+ return [];
282
+ const answers = await Promise.allSettled(set.pools.map((replica, index) => (set.healthy(index) ? replica.withReadClient(work) : Promise.reject(new Error('passed over')))));
283
+ return answers.flatMap((answer) => (answer.status === 'fulfilled' ? [answer.value] : []));
284
+ }
285
+ /** Each replica: whether it is in use now, and how many reads it answered and handed back to the primary. */
286
+ replicaHealth() {
287
+ const set = this.replicas;
288
+ return set
289
+ ? set.pools.map((_, index) => ({
290
+ replica: index + 1,
291
+ healthy: set.healthy(index),
292
+ served: set.served[index],
293
+ fellBack: set.fellBack[index],
294
+ }))
295
+ : [];
296
+ }
297
+ close() {
298
+ this.closed = true;
299
+ this.releaseBudget();
300
+ for (const off of this.gauges.splice(0))
301
+ off();
302
+ for (const timer of Object.values(this.limitHolds))
303
+ clearTimeout(timer);
304
+ this.closing ??= Promise.all([this.endPools(), ...(this.replicas?.pools ?? []).map((replica) => replica.close())]).then(() => { });
305
+ return this.closing;
306
+ }
307
+ /* What pg is told about where to connect: the URL, or for an untrusted
308
+ address every part spelled out so nothing comes from this process. */
309
+ dialOptions() {
310
+ return this.network
311
+ ? sealedPgOptions(this.connectionString, this.network)
312
+ : pgConnectionOptions(this.connectionString);
313
+ }
314
+ assertOpen() {
315
+ if (this.closed)
316
+ throw new Error('Postgres connection manager is closed.');
317
+ }
318
+ async pool(role) {
319
+ this.assertOpen();
320
+ const pending = role === 'write'
321
+ ? (this.writer ??= this.createPool('write'))
322
+ : role === 'background'
323
+ ? (this.background ??= this.createPool('background'))
324
+ : (this.reader ??= this.createPool('read'));
325
+ const pool = await pending;
326
+ this.assertOpen();
327
+ return pool;
328
+ }
329
+ async createPool(role) {
330
+ const pg = await this.load();
331
+ timing ??= await import('./telemetry/serverTiming.js');
332
+ this.assertOpen();
333
+ this.onLoad(pg);
334
+ const module = pg;
335
+ const Pool = module.Pool ?? module.default?.Pool;
336
+ if (!Pool)
337
+ throw new Error('Could not find a Pool export in the "pg" package.');
338
+ const write = role !== 'read';
339
+ const session = this.pooler === 'session';
340
+ const pool = new Pool({
341
+ ...this.dialOptions(),
342
+ max: this.meters[role].size,
343
+ connectionTimeoutMillis: 10_000,
344
+ idleTimeoutMillis: 30_000,
345
+ /* Readers only: a writer is opened for a write and may go. The idle
346
+ ones never keep the process alive by themselves, so a one-shot mode
347
+ that forgets to close still exits. */
348
+ ...(write
349
+ ? {}
350
+ : {
351
+ min: Math.min(WARM_READERS, this.meters[role].size),
352
+ allowExitOnIdle: true,
353
+ }),
354
+ /* A writer sends each statement as it is asked, not after the one
355
+ before it is answered: a transaction that asks several at once
356
+ (pipelined, postgresTransactionHandle.ts) pays one round trip for
357
+ them. One asked at a time is sent and answered exactly as before.
358
+ A reader only where its owner asked (pipelineReads). */
359
+ ...(write || this.pipelineReads ? { pipeline: true } : {}),
360
+ /* pg awaits this hook for every physical client before its first
361
+ checkout. Behind a transaction-mode pooler a session setting would
362
+ land on whichever server connection the client holds at that moment
363
+ and stay there for the pooler's next client, so nothing is set; each
364
+ lease sets its own, per transaction. */
365
+ onConnect: async (client) => {
366
+ /* A leased client's 'error' is its own to hear: the pool listens only
367
+ while it is idle, and a backend ended under a lease (a failover, a
368
+ pg_terminate_backend) would otherwise end the process. The query it
369
+ was running rejects with the same failure, which is where it is
370
+ answered. */
371
+ client.on?.('error', () => { });
372
+ if (!session)
373
+ return;
374
+ if (!write)
375
+ await client.query('SET default_transaction_read_only = on');
376
+ /* A writer also stops waiting for a lock after lockMs: a row held by
377
+ another transaction (another pod, a migration's DDL) fails the
378
+ statement fast, with 55P03, rather than holding this connection —
379
+ and the save behind it — for the whole statement cap. One message:
380
+ the settings are two statements and one round trip. */
381
+ await client.query(write
382
+ ? `SET statement_timeout = '${this.capMs / 1000}s'; SET lock_timeout = '${this.lockMs}ms'`
383
+ : `SET statement_timeout = '${this.capMs / 1000}s'`);
384
+ },
385
+ });
386
+ // pg removes failed idle clients itself; an unhandled pool error would crash Node.
387
+ pool.on('error', () => { });
388
+ this.opened[role] = pool;
389
+ /* In use and waiting, for the process entry of server timing (a no-op when it is off). pg-pool's own counters. */
390
+ const counts = pool;
391
+ if (timing.serverTimingOn() && !this.closed)
392
+ this.gauges.push(timing.registerGauge(`pool-${role}-use`, () => (counts.totalCount ?? 0) - (counts.idleCount ?? 0)), timing.registerGauge(`pool-${role}-wait`, () => counts.waitingCount ?? 0));
393
+ /* With server timing on, the round trip from here to this database, once, on a connection of its own: a
394
+ driver without a Client (a test's) is not measured. */
395
+ if (!write)
396
+ void timing.probeRoundTrips(this.timingLabel, () => {
397
+ const found = pg;
398
+ const Client = found.Client ?? found.default?.Client;
399
+ return Client && new Client({ ...this.dialOptions(), connectionTimeoutMillis: 10_000 });
400
+ });
401
+ return pool;
402
+ }
403
+ /* `write` stays a boolean: test/support/tenantDialects.ts intercepts every
404
+ lease here, by that flag, to fault a writer's COMMIT and nothing else. */
405
+ async withClient(write, run, destroyAfter, drainCancelled = false, observeCheckout = false) {
406
+ const role = !write ? 'read' : inBackgroundWork() ? 'background' : 'write';
407
+ /* Only reads are stopped on cancel: a write that has started runs to its
408
+ end, so its outcome is known rather than guessed. */
409
+ const signal = write ? undefined : cancellation();
410
+ throwIfCancelled(signal);
411
+ const pool = await this.pool(role);
412
+ /* A write that finds every writer busy says so on the request's trace
413
+ (the dev observer): the wait for a connection, beside the wait in its
414
+ lane (writeLanes.ts) and the statements that follow. */
415
+ const waiting = write && this.meters[role].full()
416
+ ? startSpan('writer wait', {
417
+ childOnly: true,
418
+ attributes: { 'db.client.connection.pool.name': role },
419
+ })
420
+ : undefined;
421
+ const meter = this.meters[role];
422
+ /* The background writer is one connection that background work waits for by design, for as long as the driver's
423
+ connect timeout rather than the queue-wait budget a person's read or write has. Its line is bounded all the
424
+ same: past the queue's length, or past that timeout, the work is answered busy before anything was leased, so
425
+ a job's command, a delivery or a workflow step is asked again (temporarily_unavailable, a retry) instead of
426
+ a burst of them failing together as an unavailable store. */
427
+ const bounded = role !== 'background';
428
+ if (!bounded && meter.waiting() >= meter.size * this.queuePerConnection) {
429
+ meter.refuse();
430
+ throw new PoolBusy('write', 'queue_full');
431
+ }
432
+ const checkout = meter.begin();
433
+ const had = timing?.poolWait(`${this.timingLabel}-${role}`);
434
+ let client;
435
+ /* A person's checkout waits its turn in the manager's own line, and only
436
+ then asks the driver, for a connection that is its: the line and the
437
+ connection share the one queue-wait budget. */
438
+ let place;
439
+ try {
440
+ if (bounded) {
441
+ const deadline = performance.now() + this.queueWaitMs;
442
+ place = await this.admissions[role].enter(this.queueWaitMs);
443
+ client = await this.connectWithin(pool, role, Math.max(1, deadline - performance.now()));
444
+ }
445
+ else
446
+ client = await this.connectHeld(pool, role);
447
+ had?.();
448
+ }
449
+ catch (error) {
450
+ had?.();
451
+ place?.();
452
+ if (error instanceof PoolBusy) {
453
+ checkout.failed(true);
454
+ waiting?.fail('pool_busy');
455
+ waiting?.end();
456
+ throw error;
457
+ }
458
+ const timedOut = ACQUISITION_TIMEOUT.test(error instanceof Error ? error.message : '');
459
+ checkout.failed(timedOut);
460
+ waiting?.fail('pool_timeout');
461
+ waiting?.end();
462
+ if (!bounded && timedOut)
463
+ throw new PoolBusy('write', 'queue_timeout', error);
464
+ throw error;
465
+ }
466
+ waiting?.end();
467
+ timing?.timeClient(client, this.timingLabel);
468
+ delayFlights(client);
469
+ const giveBack = checkout.acquired();
470
+ const scoped = this.pooler === 'transaction'
471
+ ? transactionScoped(client, {
472
+ role: write ? 'write' : 'read',
473
+ capMs: this.capMs,
474
+ untrusted: destroyAfter,
475
+ ...(write ? { lockTimeoutMs: this.lockMs } : {}),
476
+ /* A writer's client pipelines (below): a statement it sends outside
477
+ a transaction leaves with its BEGIN and COMMIT, in one round trip. */
478
+ pipelines: client.pipeline === true,
479
+ })
480
+ : undefined;
481
+ let destroy = destroyAfter;
482
+ /* A cancelled client never goes back to the pool: the cancel travels on
483
+ another connection and can land late, and it must not land on a
484
+ statement a later lease of the same backend has started. */
485
+ let cancelled = false;
486
+ let released = false;
487
+ let invalidateHealth = () => { }, removeHealthListeners = () => { };
488
+ const release = (destroyed) => {
489
+ if (released)
490
+ return;
491
+ released = true;
492
+ invalidateHealth();
493
+ client.release(destroyed);
494
+ };
495
+ /* Behind a transaction-mode pooler the backend id a client was told is
496
+ the pooler's, not the server's, so a pg_cancel_backend by it would
497
+ stop whatever unrelated statement holds that id on the server. The
498
+ ordinary caller stops waiting at once instead; snapshot owners destroy
499
+ the client first and then drain their callback. Server work remains
500
+ bounded by the transaction's cap, not by local callback completion. */
501
+ let stop;
502
+ const stopped = scoped && signal && !drainCancelled
503
+ ? new Promise((_, reject) => {
504
+ stop = reject;
505
+ })
506
+ : undefined;
507
+ void stopped?.catch(() => { });
508
+ const disarm = onCancel(signal, () => {
509
+ cancelled = true;
510
+ invalidateHealth();
511
+ if (scoped) {
512
+ const reason = new StatementStopped('cancelled');
513
+ if (drainCancelled) {
514
+ // Invalidate continuations first, then break active driver I/O before
515
+ // awaiting callback/finally drain. This drains local promises, not
516
+ // server locks: server work may persist until its configured cap.
517
+ // Never cancel a pooler's backend ID.
518
+ scoped.close(reason);
519
+ // A release exception must not escape the AbortSignal listener. The
520
+ // operation remains cancelled, and still waits for its callback.
521
+ try {
522
+ release(true);
523
+ }
524
+ catch {
525
+ /* No retry of a possibly released client. */
526
+ }
527
+ }
528
+ else
529
+ stop?.(reason);
530
+ }
531
+ else
532
+ void this.cancel(client.processID);
533
+ });
534
+ try {
535
+ this.assertOpen();
536
+ throwIfCancelled(signal);
537
+ let borrowed = scoped ?? client;
538
+ let health;
539
+ if (observeCheckout) {
540
+ if (typeof client.on !== 'function' || typeof client.off !== 'function')
541
+ throw new Error('Observed PostgreSQL checkout is unavailable.');
542
+ let healthy = true;
543
+ const on = client.on.bind(client), off = client.off.bind(client);
544
+ invalidateHealth = () => {
545
+ healthy = false;
546
+ };
547
+ removeHealthListeners = () => {
548
+ off('error', invalidateHealth);
549
+ off('end', invalidateHealth);
550
+ };
551
+ on('error', invalidateHealth);
552
+ on('end', invalidateHealth);
553
+ health = () => {
554
+ this.assertOpen();
555
+ throwIfCancelled(signal);
556
+ if (!healthy || released)
557
+ throw new Error('Observed PostgreSQL checkout is unavailable.');
558
+ };
559
+ const current = health, target = borrowed;
560
+ async function query(text, params) {
561
+ try {
562
+ current();
563
+ const result = typeof text === 'string' ? await target.query(text, params) : await target.query(text);
564
+ current();
565
+ return result;
566
+ }
567
+ catch (error) {
568
+ invalidateHealth();
569
+ throw error;
570
+ }
571
+ }
572
+ borrowed = Object.freeze({ query });
573
+ }
574
+ /* A write's own reads — the pre-flight count, a reread — are of the
575
+ primary it writes. */
576
+ const lent = borrowed;
577
+ /* A lease that runs statements it does not control (destroyAfter: the
578
+ SQL tool's) brackets each in a savepoint it awaits first
579
+ (postgresPooler.ts), so one sent behind another would overtake it:
580
+ that lease asks one at a time. */
581
+ if (client.pipeline === true && !destroyAfter)
582
+ pipelining.add(lent);
583
+ const running = write ? primaryReads(() => run(lent, health)) : run(borrowed, health);
584
+ if (stopped)
585
+ void running.catch(() => { });
586
+ const out = await (stopped ? Promise.race([running, stopped]) : running);
587
+ health?.();
588
+ await scoped?.settle();
589
+ health?.();
590
+ if (drainCancelled)
591
+ throwIfCancelled(signal);
592
+ return out;
593
+ }
594
+ catch (error) {
595
+ destroy = true;
596
+ if (scoped && !cancelled)
597
+ await scoped.settle().catch(() => { });
598
+ if (cancelled)
599
+ throw error instanceof StatementStopped ? error : new StatementStopped('cancelled', undefined, { cause: error });
600
+ throw error;
601
+ }
602
+ finally {
603
+ /* The person who wrote reads the primary for a while after, so the
604
+ list they go back to shows what they saved (replicas.ts). Noted
605
+ however the write ended: a failed one may still have committed. */
606
+ if (write)
607
+ noteWrite();
608
+ disarm();
609
+ try {
610
+ release(destroy || cancelled);
611
+ }
612
+ finally {
613
+ try {
614
+ removeHealthListeners();
615
+ }
616
+ finally {
617
+ try {
618
+ giveBack();
619
+ }
620
+ finally {
621
+ place?.();
622
+ }
623
+ }
624
+ }
625
+ }
626
+ }
627
+ /**
628
+ * A connection, or PoolBusy once what is left of the queue-wait budget, `waitMs`, is spent. The driver
629
+ * cannot withdraw a request it has queued, so one that arrives late is given
630
+ * straight back to the pool rather than leaked.
631
+ */
632
+ connectWithin(pool, role, waitMs) {
633
+ const connecting = this.connectHeld(pool, role);
634
+ return new Promise((resolve, reject) => {
635
+ let over = false;
636
+ const timer = setTimeout(() => {
637
+ over = true;
638
+ reject(new PoolBusy(role, 'queue_timeout'));
639
+ }, waitMs);
640
+ connecting.then((client) => {
641
+ clearTimeout(timer);
642
+ if (over)
643
+ client.release();
644
+ else
645
+ resolve(client);
646
+ }, (error) => {
647
+ clearTimeout(timer);
648
+ if (!over)
649
+ reject(error);
650
+ });
651
+ });
652
+ }
653
+ /**
654
+ * `pool.connect()`, within the connections the server allows. Refused
655
+ * another one (53300), the pool is held at the connections it has, so this
656
+ * checkout and the next wait for one of them as they would behind a full
657
+ * pool, and it asks for more again after LIMIT_HOLD_MS; holding none, the
658
+ * checkout is refused as busy. A refusal at open leased nothing, so nothing
659
+ * on any connection moved: a tenant writer stays open on it
660
+ * (tenantWriteSource.ts). It used to rise as a database fault, and a
661
+ * tenant writer closed for it and reopened into the same refusal, again and
662
+ * again, with two commands in three failing at three users while its one
663
+ * connection sat idle (a field report: pools sized past the role's limit).
664
+ */
665
+ async connectHeld(pool, role) {
666
+ for (let attempt = 1;; attempt += 1) {
667
+ try {
668
+ return await pool.connect();
669
+ }
670
+ catch (error) {
671
+ if (!atConnectionLimit(error))
672
+ throw error;
673
+ const held = this.holdAtLimit(pool, role, error);
674
+ if (!held || this.closed || attempt >= LIMIT_ATTEMPTS)
675
+ throw new PoolBusy(role === 'read' ? 'read' : 'write', 'connection_limit', error);
676
+ }
677
+ }
678
+ }
679
+ /** Holds `pool` at the connections it has (pg-pool reads `options.max` at each checkout), says so once a spell, and returns how many. */
680
+ holdAtLimit(pool, role, refusal) {
681
+ const found = pool;
682
+ const held = typeof found.totalCount === 'number' ? found.totalCount : 0;
683
+ const size = this.meters[role].size;
684
+ const options = found.options;
685
+ if (held > 0 && options && typeof options.max === 'number') {
686
+ const most = Math.min(options.max, held);
687
+ options.max = most;
688
+ const line = role === 'background' ? undefined : this.admissions[role];
689
+ line?.resize(most);
690
+ clearTimeout(this.limitHolds[role]);
691
+ const timer = setTimeout(() => {
692
+ delete this.limitHolds[role];
693
+ options.max = size;
694
+ line?.resize(size);
695
+ }, LIMIT_HOLD_MS);
696
+ timer.unref?.();
697
+ this.limitHolds[role] = timer;
698
+ }
699
+ const now = Date.now();
700
+ if (now - (this.limitSaid[role] ?? -Infinity) >= LIMIT_HOLD_MS) {
701
+ this.limitSaid[role] = now;
702
+ const why = refusal instanceof Error ? refusal.message : 'refused';
703
+ console.error(`mistri: connection limit reached: the ${this.timingLabel} ${role} pool holds ${held} of ${size} connections; the database refused another (${why}). ` +
704
+ (held
705
+ ? `It goes on with ${held} and asks for more in ${LIMIT_HOLD_MS / 1000} s. `
706
+ : 'Its checkouts are answered busy (503, try again) until one opens. ') +
707
+ "This process's pools ask for more connections than the database allows: lower the pools (--read-pool, --write-pool, the auth pool) or raise the limit.");
708
+ }
709
+ return held;
710
+ }
711
+ /**
712
+ * Stop what backend `pid` is running, with pg_cancel_backend from a
713
+ * connection of its own: the pool's may all be busy, one of them with the
714
+ * statement being stopped. Best effort — a cancel that cannot connect
715
+ * leaves the statement to its cap.
716
+ */
717
+ async cancel(pid) {
718
+ if (!pid)
719
+ return;
720
+ try {
721
+ const pg = (await this.load());
722
+ const Client = pg.Client ?? pg.default?.Client;
723
+ if (!Client)
724
+ return;
725
+ const client = new Client({
726
+ ...this.dialOptions(),
727
+ connectionTimeoutMillis: 10_000,
728
+ });
729
+ client.on('error', () => { });
730
+ await client.connect();
731
+ try {
732
+ await client.query('SELECT pg_cancel_backend($1)', [pid]);
733
+ }
734
+ finally {
735
+ await client.end().catch(() => { });
736
+ }
737
+ }
738
+ catch {
739
+ /* The statement's cap still stops it. */
740
+ }
741
+ }
742
+ async endPools() {
743
+ const opened = await Promise.allSettled([this.reader, this.writer, this.background]);
744
+ const ended = await Promise.allSettled(opened.map((result) => (result.status === 'fulfilled' ? result.value?.end() : undefined)));
745
+ const failed = ended.find((result) => result.status === 'rejected');
746
+ if (failed?.status === 'rejected')
747
+ throw failed.reason;
748
+ }
749
+ }
750
+ /** The reader and writer counts a manager takes for `shape`: its own, else the process's (`--read-pool`, `--write-pool`) or the defaults. */
751
+ export function poolSizes(shape = {}) {
752
+ const writers = writeOrder() === 'serial' ? 1 : (shape.writers ?? writerPoolSize());
753
+ return { writers, readers: shape.readers ?? serverSettings().readers ?? defaultReaders(writers) };
754
+ }
755
+ /* The managers holders share, by database URL and the settings that make two managers alike (sharedPgConnections). */
756
+ const sharedManagers = new Map();
757
+ /* A load hook told apart by identity in the key: two holders share only where they load pg alike. */
758
+ const loadHooks = new WeakMap();
759
+ let hooks = 0;
760
+ const hookId = (hook) => {
761
+ let id = loadHooks.get(hook);
762
+ if (id === undefined)
763
+ loadHooks.set(hook, (id = ++hooks));
764
+ return id;
765
+ };
766
+ /**
767
+ * The manager every holder of `url` with this `shape` shares, instead of one
768
+ * each. Every pool sized for its process and blind to its neighbors was how a
769
+ * tenant App came to hold `3R + 6W + 5` connections on one database — its
770
+ * reader, discovery, writer, administration and support each with a manager of
771
+ * their own (docs/postgresql.md) — while each sat mostly idle: a field
772
+ * deployment whose role allowed eighteen ran fixed four-and-four pools and
773
+ * still could not fit. Shared, the readers and writers are one pool for all of
774
+ * them, sized once, and counted once (connectionBudget.ts).
775
+ *
776
+ * What sharing leaves alone: each holder keeps its own write lanes
777
+ * (writeLanes.ts), so per-record order is what it was; and a manager is shared
778
+ * only with holders that would have built the same one — the URL, the sizes
779
+ * after the process defaults, the pooler, the lock wait and the load hook all
780
+ * in the key — so a handler mounted with settings of its own never borrows
781
+ * another's pools.
782
+ *
783
+ * Each call is one holder. The handle is the manager behind a proxy whose
784
+ * `close` lets that holder go — once, however often it is called — and the
785
+ * pools close with the last holder; everything else is the manager's own, so
786
+ * the handle passes wherever a manager does (`instanceof` too).
787
+ */
788
+ export function sharedPgConnections(url, shape = {}, onLoad) {
789
+ const { readers, writers } = poolSizes(shape);
790
+ const pipelineReads = shape.pipelineReads === true;
791
+ const readersOnly = shape.readersOnly === true;
792
+ const key = JSON.stringify([
793
+ url,
794
+ readers,
795
+ writers,
796
+ pipelineReads,
797
+ readersOnly,
798
+ serverSettings().pooler,
799
+ lockTimeoutMs(),
800
+ onLoad ? hookId(onLoad) : 0,
801
+ ]);
802
+ let entry = sharedManagers.get(key);
803
+ if (!entry) {
804
+ const manager = new PgConnectionManager(url, onLoad, undefined, { readers, writers, pipelineReads, readersOnly });
805
+ entry = { manager, holders: 0 };
806
+ sharedManagers.set(key, entry);
807
+ }
808
+ const held = entry;
809
+ held.holders += 1;
810
+ let released = false;
811
+ const close = () => {
812
+ if (released)
813
+ return Promise.resolve();
814
+ released = true;
815
+ held.holders -= 1;
816
+ if (held.holders > 0)
817
+ return Promise.resolve();
818
+ if (sharedManagers.get(key) === held)
819
+ sharedManagers.delete(key);
820
+ return held.manager.close();
821
+ };
822
+ /* Methods are bound once per handle: a store asks for withWriteClient on every statement. Kept by the function
823
+ found, not its name, so a method replaced on the class (a test's mock) is the one called. */
824
+ const bound = new WeakMap();
825
+ return new Proxy(held.manager, {
826
+ get(target, property) {
827
+ if (property === 'close')
828
+ return close;
829
+ const value = Reflect.get(target, property, target);
830
+ if (typeof value !== 'function')
831
+ return value;
832
+ let method = bound.get(value);
833
+ if (method === undefined)
834
+ bound.set(value, (method = value.bind(target)));
835
+ return method;
836
+ },
837
+ });
838
+ }