@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,123 @@
1
+ /**
2
+ * Where a socket this process opens on the operator's behalf may go.
3
+ *
4
+ * Every outbound connection a config file can point somewhere — an API
5
+ * (egress.ts), a cache, a search service — resolves its host through
6
+ * `checkedLookup`, so the address checked is the address connected: a name
7
+ * that resolves somewhere else a moment later (DNS rebinding) changes
8
+ * nothing. One set of ranges, one rule, whichever protocol rides on top.
9
+ *
10
+ * Private networks are reachable by default, because internal services are
11
+ * the common case and these connections only ever come from the operator's
12
+ * config, never from a browser. Link-local addresses, where cloud metadata
13
+ * services answer, are not, unless the connection says so: they hand out
14
+ * credentials to whoever asks.
15
+ */
16
+ import { lookup as dnsLookup } from 'node:dns';
17
+ import { BlockList, isIP } from 'node:net';
18
+ const ranges = (entries) => {
19
+ const list = new BlockList();
20
+ for (const [address, prefix] of entries)
21
+ list.addSubnet(address, prefix, isIP(address) === 6 ? 'ipv6' : 'ipv4');
22
+ return list;
23
+ };
24
+ /* An unspecified address reaches whatever listens on this machine; never a destination. */
25
+ const NEVER = ranges([
26
+ ['0.0.0.0', 8],
27
+ ['::', 128],
28
+ // NAT64's local-use prefix (RFC 8215): the IPv4 address sits where the operator's gateway puts it, so none can be vouched for.
29
+ ['64:ff9b:1::', 48],
30
+ ]);
31
+ const LINK_LOCAL = ranges([
32
+ ['169.254.0.0', 16],
33
+ ['fe80::', 10],
34
+ ['fd00:ec2::254', 128],
35
+ ]);
36
+ const PRIVATE = ranges([
37
+ ['127.0.0.0', 8],
38
+ ['10.0.0.0', 8],
39
+ ['172.16.0.0', 12],
40
+ ['192.168.0.0', 16],
41
+ ['100.64.0.0', 10],
42
+ ['::1', 128],
43
+ ['fc00::', 7],
44
+ ]);
45
+ /* The sixteen bytes of an IPv6 address, or undefined when it is not one (a zone id, `::`, and a dotted tail are read). */
46
+ function sixteen(address) {
47
+ const bare = address.split('%')[0].toLowerCase();
48
+ const tail = /(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(bare);
49
+ const text = tail
50
+ ? bare.slice(0, bare.length - tail[0].length) +
51
+ [(+tail[1] << 8) | +tail[2], (+tail[3] << 8) | +tail[4]].map((n) => n.toString(16)).join(':')
52
+ : bare;
53
+ const halves = text.split('::');
54
+ if (halves.length > 2)
55
+ return undefined;
56
+ const groups = (part) => (part ? part.split(':') : []);
57
+ const head = groups(halves[0]);
58
+ const rest = halves.length === 2 ? groups(halves[1]) : [];
59
+ const fill = halves.length === 2 ? 8 - head.length - rest.length : 0;
60
+ const all = [...head, ...Array(Math.max(fill, 0)).fill('0'), ...rest];
61
+ if (all.length !== 8 || all.some((group) => !/^[0-9a-f]{1,4}$/.test(group)))
62
+ return undefined;
63
+ return all.flatMap((group) => [parseInt(group, 16) >> 8, parseInt(group, 16) & 255]);
64
+ }
65
+ /* The IPv4 address an IPv6 spelling carries inside it, which is the address a gateway or a tunnel then connects to:
66
+ NAT64 (64:ff9b::/96), 6to4 (2002::/16) and the long-retired IPv4-compatible form (::/96). BlockList already reads the
67
+ IPv4-mapped spelling (`::ffff:a.b.c.d`) by its IPv4 rules. */
68
+ function embedded(address) {
69
+ const bytes = sixteen(address);
70
+ if (!bytes)
71
+ return undefined;
72
+ const v4 = (at) => bytes.slice(at, at + 4).join('.');
73
+ if (bytes[0] === 0x20 && bytes[1] === 0x02)
74
+ return v4(2);
75
+ if (bytes.slice(0, 12).every((byte, index) => byte === [0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0][index]))
76
+ return v4(12);
77
+ if (bytes.slice(0, 12).every((byte) => byte === 0))
78
+ return v4(12);
79
+ return undefined;
80
+ }
81
+ function reachable(address, policy) {
82
+ const type = isIP(address) === 6 ? 'ipv6' : 'ipv4';
83
+ if (NEVER.check(address, type))
84
+ return false;
85
+ if (!policy.allowLinkLocal && LINK_LOCAL.check(address, type))
86
+ return false;
87
+ if (!policy.allowPrivate && PRIVATE.check(address, type))
88
+ return false;
89
+ // An address that wraps another is as reachable as the one inside it.
90
+ const inside = type === 'ipv6' ? embedded(address) : undefined;
91
+ return inside === undefined || reachable(inside, policy);
92
+ }
93
+ /**
94
+ * A host written as an address is never looked up, so it is checked before
95
+ * any socket opens: the address it names when that address is refused,
96
+ * undefined when it is a name or a reachable address.
97
+ */
98
+ export function refusedLiteral(hostname, policy) {
99
+ const literal = hostname.replace(/^\[|\]$/g, '');
100
+ return isIP(literal) && !reachable(literal, policy) ? literal : undefined;
101
+ }
102
+ /**
103
+ * The lookup a socket uses: resolve, keep only reachable addresses, and hand
104
+ * those back, so the address checked is the address connected. Node asks for
105
+ * one address or for all (happy eyeballs); both are answered. `refuse` makes
106
+ * the caller's own error for a name that resolves only to refused addresses.
107
+ */
108
+ export function checkedLookup(policy, refuse) {
109
+ const resolve = policy.resolver ?? ((hostname, options, callback) => dnsLookup(hostname, options, callback));
110
+ return (hostname, options, callback) => {
111
+ resolve(hostname, { all: true }, (error, addresses) => {
112
+ if (error)
113
+ return callback(error);
114
+ const allowed = addresses.filter((each) => reachable(each.address, policy));
115
+ if (!allowed.length)
116
+ return callback(refuse(hostname, addresses.map((each) => each.address)));
117
+ if (options.all)
118
+ callback(null, allowed);
119
+ else
120
+ callback(null, allowed[0].address, allowed[0].family);
121
+ });
122
+ };
123
+ }
@@ -0,0 +1,18 @@
1
+ import { type NetworkPolicy } from './networkPolicy.js';
2
+ /** Where an untrusted address may go: the public network only. */
3
+ export declare const UNTRUSTED_NETWORK: NetworkPolicy;
4
+ /**
5
+ * Why a database URL from an untrusted client is refused before anything is
6
+ * dialled, or null. Only PostgreSQL URLs are read; the caller has
7
+ * already refused the forms that are not network URLs.
8
+ */
9
+ export declare function untrustedDatabaseRefusal(target: string): string | null;
10
+ /**
11
+ * The `pg` options for a sealed address: no `connectionString`, because pg
12
+ * merges its parse of one over explicit values, and its parse gives an absent
13
+ * password as the empty string — which pg then reads as "not given" and fills
14
+ * from `PGPASSWORD`. The password is a function for the same reason: it is
15
+ * the one form pg takes as given even when it is empty, and the one that
16
+ * skips `~/.pgpass`.
17
+ */
18
+ export declare function sealedPgOptions(target: string, policy: NetworkPolicy): Record<string, unknown>;
@@ -0,0 +1,120 @@
1
+ /**
2
+ * A database address that a browser beyond this machine typed.
3
+ *
4
+ * The connection form on a server bound past loopback is anyone's on the
5
+ * network (trust.ts `clientTrusted`). What they type is dialled by this
6
+ * process, with two consequences the operator never chose. The drivers fill a
7
+ * part the URL leaves out from this process: `pg` takes a missing user and
8
+ * password from `PGUSER`/`PGPASSWORD` (and `~/.pgpass`), so
9
+ * `postgres://u@attacker.example/db` sent the operator's password to the
10
+ * attacker's host. And the dial itself is a probe of whatever this machine can
11
+ * reach — a port scanner for the private network, a client for the cloud
12
+ * metadata service — with the driver's error as the answer.
13
+ *
14
+ * So an untrusted address is sealed: every part the driver would look up is
15
+ * given explicitly from the URL (a missing password is the empty one, never
16
+ * the environment's), the URL may carry only the parameters that read nothing
17
+ * from this machine, and its host is resolved through the network policy with
18
+ * loopback, private and link-local ranges refused — the address checked is
19
+ * the address connected (networkPolicy.ts), so a name that rebinds changes
20
+ * nothing. A connection the operator wrote (tablewalk.json, the command line,
21
+ * a loopback browser) is untouched.
22
+ */
23
+ import { Socket } from 'node:net';
24
+ import { checkedLookup, refusedLiteral } from './networkPolicy.js';
25
+ /** Where an untrusted address may go: the public network only. */
26
+ export const UNTRUSTED_NETWORK = Object.freeze({ allowPrivate: false, allowLinkLocal: false });
27
+ /* The parameters that change nothing on this machine. Everything else is
28
+ refused rather than dropped: `host=/var/run/postgresql` is a local socket,
29
+ and `sslcert=/path` and `sslrootcert=/path` read files. */
30
+ const PG_PARAMETERS = new Set(['sslmode', 'application_name']);
31
+ const PG_SSLMODES = new Set(['disable', 'prefer', 'require', 'verify-ca', 'verify-full', 'no-verify']);
32
+ const MOVE_IT = 'This server is reachable beyond this machine, so a connection added from the browser ' +
33
+ 'is dialled exactly as written and nothing is filled in from the server. ';
34
+ /**
35
+ * Why a database URL from an untrusted client is refused before anything is
36
+ * dialled, or null. Only PostgreSQL URLs are read; the caller has
37
+ * already refused the forms that are not network URLs.
38
+ */
39
+ export function untrustedDatabaseRefusal(target) {
40
+ if (!/^postgres(ql)?:\/\//i.test(target))
41
+ return null;
42
+ let url;
43
+ try {
44
+ url = new URL(target);
45
+ }
46
+ catch {
47
+ return `${MOVE_IT}This is not a URL that can be read.`;
48
+ }
49
+ if (!url.hostname)
50
+ return `${MOVE_IT}Name the host in the URL.`;
51
+ if (!url.username)
52
+ return `${MOVE_IT}Name the user in the URL (user@host).`;
53
+ const allowed = PG_PARAMETERS;
54
+ for (const [key, value] of url.searchParams) {
55
+ const ok = allowed.has(key) || (key === 'sslrootcert' && value === 'system');
56
+ if (!ok)
57
+ return `${MOVE_IT}"${key}" cannot be set from the browser; put this connection in the config file on the server.`;
58
+ if (key === 'sslmode' && !PG_SSLMODES.has(value))
59
+ return `${MOVE_IT}"sslmode=${value}" is not one this connection can use.`;
60
+ }
61
+ return null;
62
+ }
63
+ /* Kept out of the message a driver reports: the host is the caller's own, the addresses are what it resolved to. */
64
+ function refusal(host, addresses) {
65
+ return new Error(`${host} resolves only to addresses a connection added from the browser may not reach (${addresses.join(', ')}). ` +
66
+ 'Put a connection to a private or local database in the config file on the server.');
67
+ }
68
+ /**
69
+ * A socket for a driver's `stream` option whose `connect(port, host)` is
70
+ * resolved through `policy`. A host written as an address is checked before
71
+ * any packet leaves, since Node never looks one up.
72
+ */
73
+ function guardedSocket(policy) {
74
+ const socket = new Socket();
75
+ const connect = socket.connect.bind(socket);
76
+ const lookup = checkedLookup(policy, refusal);
77
+ socket.connect = ((port, host) => {
78
+ const literal = refusedLiteral(host, policy);
79
+ if (literal) {
80
+ // After the driver's own 'error' listener is in place, which it adds once connect returns.
81
+ process.nextTick(() => socket.destroy(new Error(`The address ${literal} is one a connection added from the browser may not reach.`)));
82
+ return socket;
83
+ }
84
+ return connect({ port, host, lookup });
85
+ });
86
+ return socket;
87
+ }
88
+ const decoded = (part) => decodeURIComponent(part);
89
+ /**
90
+ * The `pg` options for a sealed address: no `connectionString`, because pg
91
+ * merges its parse of one over explicit values, and its parse gives an absent
92
+ * password as the empty string — which pg then reads as "not given" and fills
93
+ * from `PGPASSWORD`. The password is a function for the same reason: it is
94
+ * the one form pg takes as given even when it is empty, and the one that
95
+ * skips `~/.pgpass`.
96
+ */
97
+ export function sealedPgOptions(target, policy) {
98
+ const url = new URL(target);
99
+ const user = decoded(url.username);
100
+ const password = decoded(url.password);
101
+ const sslmode = url.searchParams.get('sslmode');
102
+ const system = url.searchParams.get('sslrootcert') === 'system';
103
+ const ssl = sslmode === 'disable'
104
+ ? false
105
+ : sslmode === 'no-verify'
106
+ ? { rejectUnauthorized: false }
107
+ : sslmode || system
108
+ ? { rejectUnauthorized: true }
109
+ : false;
110
+ return {
111
+ host: url.hostname.replace(/^\[|\]$/g, ''),
112
+ port: url.port ? Number(url.port) : 5432,
113
+ user,
114
+ database: decoded(url.pathname.slice(1)) || user,
115
+ password: () => password,
116
+ ssl,
117
+ ...(url.searchParams.get('application_name') ? { application_name: url.searchParams.get('application_name') } : {}),
118
+ stream: () => guardedSocket(policy),
119
+ };
120
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Run a request's `work` with its checkouts filed under the client that sent
3
+ * it: `address` as the server reads it, a forwarded one only from a trusted
4
+ * proxy (trust.ts forwardedClient), so a signed-out storm cannot spread itself
5
+ * over invented addresses.
6
+ */
7
+ export declare function withAdmission<T>(address: string, work: () => T): T;
8
+ /** The request's session names its account: its checkouts from here on wait as that account's. */
9
+ export declare function admitAs(account: string | undefined): void;
10
+ export declare class PoolAdmission {
11
+ private readonly role;
12
+ private size;
13
+ private readonly most;
14
+ private inUse;
15
+ private waiting;
16
+ /** Each account's waiters in arrival order; the Map's own order is the turn's, the first account's next. */
17
+ private readonly lines;
18
+ /**
19
+ * @param size the pool's connections: how many checkouts hold one at once.
20
+ * @param most how many may wait.
21
+ */
22
+ constructor(role: 'read' | 'write', size: number, most: number);
23
+ /**
24
+ * How many places there are from now on. A pool held at the connections it
25
+ * has (postgresPool.ts holdAtLimit) is resized to them, so the checkouts past
26
+ * them wait here, in their turns, rather than in the driver's line, which
27
+ * cannot withdraw a request nor take turns; and back again when the hold ends.
28
+ */
29
+ resize(size: number): void;
30
+ /**
31
+ * A place among the pool's connections, now or at this checkout's turn:
32
+ * call the returned function to give it back. Refused with PoolBusy past
33
+ * the line's bounds or once `waitMs` is spent.
34
+ */
35
+ enter(waitMs: number): Promise<() => void>;
36
+ /** Give the place to whoever's turn it is, while places are free. */
37
+ private serve;
38
+ /** A held place, given back once. */
39
+ private place;
40
+ private leave;
41
+ /** At a full line, refuse the longest other account's newest waiter for a newcomer holding `held` places: whether one was. */
42
+ private turnAwayLongest;
43
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * The line a checkout waits in for one of a pool's connections, and whose turn
3
+ * it is. One per role of a manager (postgresPool.ts): the readers, the writers.
4
+ *
5
+ * The line used to be the driver's own, first come first served, bounded only
6
+ * in length (POOL_QUEUE_PER_CONNECTION) and wait (POOL_QUEUE_WAIT_MS). Under a
7
+ * retry storm at `--read-pool 1` — a few accounts answering every 503 by
8
+ * asking again at once, Retry-After unread — their requests filled it, every
9
+ * other account's arrived to a full line and was refused, and what got in
10
+ * waited behind the storm until its budget ran out: a live load test saw the
11
+ * useful work done collapse. The driver made it worse: it cannot withdraw a
12
+ * request it has queued, so each one that gave up still took its turn later,
13
+ * and a connection went round the abandoned requests before reaching a live
14
+ * one. Now the line is ours, the driver is asked for a connection only once
15
+ * one is this checkout's, and a waiter that gives up leaves the line.
16
+ *
17
+ * Each waiting checkout is filed under the account it runs for (below: the
18
+ * signed-in account, or a signed-out client's address), and three rules keep
19
+ * one account from taking the line from the others:
20
+ *
21
+ * - Turns go round the accounts: one checkout from each account waiting,
22
+ * then the next, so a quiet account's request is the next or nearly the
23
+ * next served however long a storming account's line is. Within an
24
+ * account, arrival order: one person's saves sent together still apply in
25
+ * the order they were sent.
26
+ * - An account may hold at most half the line's places. Past that its next
27
+ * request is refused at once, busy, with Retry-After, rather than queued
28
+ * to time out. Half, not a small fixed number: one person's own fan-out
29
+ * (a page's boot sends up to eight reads, a dashboard one per section) is
30
+ * waited for, not refused, on any pool, and the other half stays open to
31
+ * everyone else.
32
+ * - A full line turns away its longest account's newest waiter, not the
33
+ * newcomer, when the newcomer's account holds fewer places by more than
34
+ * one: two or three storming accounts cannot fill the line between them
35
+ * and refuse a fourth. The one turned away waited least and leaves its
36
+ * account the most still queued; nothing was leased for it, so it is a
37
+ * busy refusal like any other (a write's outcome `not_applied`).
38
+ *
39
+ * The bounds themselves are unchanged: the line's length is the pool's
40
+ * connections times POOL_QUEUE_PER_CONNECTION, and a checkout that waits
41
+ * POOL_QUEUE_WAIT_MS is refused.
42
+ *
43
+ * A checkout that runs for no request — a job's read, the stdio MCP server, a
44
+ * process's start — is filed under no account. It takes its turn with the
45
+ * accounts, as one of them, but is never refused for its share nor turned
46
+ * away for another's: it is the server's own work, and it waited in one line
47
+ * with everything else before.
48
+ */
49
+ import { AsyncLocalStorage } from 'node:async_hooks';
50
+ import { PoolBusy } from './poolMetrics.js';
51
+ const admissions = new AsyncLocalStorage();
52
+ /**
53
+ * Run a request's `work` with its checkouts filed under the client that sent
54
+ * it: `address` as the server reads it, a forwarded one only from a trusted
55
+ * proxy (trust.ts forwardedClient), so a signed-out storm cannot spread itself
56
+ * over invented addresses.
57
+ */
58
+ export function withAdmission(address, work) {
59
+ return admissions.run({ key: `client:${address}` }, work);
60
+ }
61
+ /** The request's session names its account: its checkouts from here on wait as that account's. */
62
+ export function admitAs(account) {
63
+ const admission = admissions.getStore();
64
+ if (admission && account)
65
+ admission.key = `account:${account}`;
66
+ }
67
+ /** The waiters filed under no account: a key no request's can be, since every request's carries a prefix. */
68
+ const UNFILED = '';
69
+ export class PoolAdmission {
70
+ role;
71
+ size;
72
+ most;
73
+ inUse = 0;
74
+ waiting = 0;
75
+ /** Each account's waiters in arrival order; the Map's own order is the turn's, the first account's next. */
76
+ lines = new Map();
77
+ /**
78
+ * @param size the pool's connections: how many checkouts hold one at once.
79
+ * @param most how many may wait.
80
+ */
81
+ constructor(role, size, most) {
82
+ this.role = role;
83
+ this.size = size;
84
+ this.most = most;
85
+ }
86
+ /**
87
+ * How many places there are from now on. A pool held at the connections it
88
+ * has (postgresPool.ts holdAtLimit) is resized to them, so the checkouts past
89
+ * them wait here, in their turns, rather than in the driver's line, which
90
+ * cannot withdraw a request nor take turns; and back again when the hold ends.
91
+ */
92
+ resize(size) {
93
+ this.size = size;
94
+ this.serve();
95
+ }
96
+ /**
97
+ * A place among the pool's connections, now or at this checkout's turn:
98
+ * call the returned function to give it back. Refused with PoolBusy past
99
+ * the line's bounds or once `waitMs` is spent.
100
+ */
101
+ enter(waitMs) {
102
+ if (this.inUse < this.size && this.waiting === 0) {
103
+ this.inUse += 1;
104
+ return Promise.resolve(this.place());
105
+ }
106
+ const key = admissions.getStore()?.key ?? UNFILED;
107
+ const held = this.lines.get(key)?.length ?? 0;
108
+ const full = () => Promise.reject(new PoolBusy(this.role, 'queue_full'));
109
+ if (key !== UNFILED && held >= Math.max(1, Math.floor(this.most / 2)))
110
+ return full();
111
+ if (this.waiting >= this.most && !this.turnAwayLongest(key, held))
112
+ return full();
113
+ return new Promise((resolve, reject) => {
114
+ const waiter = { resolve, reject };
115
+ waiter.timer = setTimeout(() => {
116
+ this.leave(key, waiter);
117
+ reject(new PoolBusy(this.role, 'queue_timeout'));
118
+ }, waitMs);
119
+ const line = this.lines.get(key);
120
+ if (line)
121
+ line.push(waiter);
122
+ else
123
+ this.lines.set(key, [waiter]);
124
+ this.waiting += 1;
125
+ this.serve();
126
+ });
127
+ }
128
+ /** Give the place to whoever's turn it is, while places are free. */
129
+ serve() {
130
+ while (this.inUse < this.size) {
131
+ const next = this.lines.entries().next();
132
+ if (next.done)
133
+ return;
134
+ const [key, line] = next.value;
135
+ const waiter = line.shift();
136
+ // To the back of the turn, behind every other account waiting.
137
+ this.lines.delete(key);
138
+ if (line.length)
139
+ this.lines.set(key, line);
140
+ this.waiting -= 1;
141
+ this.inUse += 1;
142
+ clearTimeout(waiter.timer);
143
+ waiter.resolve(this.place());
144
+ }
145
+ }
146
+ /** A held place, given back once. */
147
+ place() {
148
+ let given = false;
149
+ return () => {
150
+ if (given)
151
+ return;
152
+ given = true;
153
+ this.inUse -= 1;
154
+ this.serve();
155
+ };
156
+ }
157
+ leave(key, waiter) {
158
+ const line = this.lines.get(key);
159
+ const at = line?.indexOf(waiter) ?? -1;
160
+ if (!line || at < 0)
161
+ return;
162
+ line.splice(at, 1);
163
+ this.waiting -= 1;
164
+ if (!line.length)
165
+ this.lines.delete(key);
166
+ }
167
+ /** At a full line, refuse the longest other account's newest waiter for a newcomer holding `held` places: whether one was. */
168
+ turnAwayLongest(key, held) {
169
+ if (key === UNFILED)
170
+ return false;
171
+ let longest;
172
+ for (const entry of this.lines) {
173
+ if (entry[0] !== UNFILED && entry[0] !== key && entry[1].length > (longest?.[1].length ?? 0))
174
+ longest = entry;
175
+ }
176
+ if (!longest || longest[1].length <= held + 1)
177
+ return false;
178
+ const waiter = longest[1][longest[1].length - 1];
179
+ clearTimeout(waiter.timer);
180
+ this.leave(longest[0], waiter);
181
+ waiter.reject(new PoolBusy(this.role, 'queue_full'));
182
+ return true;
183
+ }
184
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * What a connection pool can say about itself: how long each checkout waited
3
+ * for a connection, how long it held one, and how full the pool is now.
4
+ *
5
+ * Engine-neutral and fixed-size: cumulative counters and bucket counts on the
6
+ * HTTP request metrics' bounds, so the operator surface carries them without
7
+ * learning a driver, and their size never grows with traffic. One meter per
8
+ * role of a pool — the readers, the writers, the background writer — and nothing in it names the
9
+ * database, because the operator surface must not.
10
+ */
11
+ /** Inclusive upper bounds, the same as the HTTP request metrics', so one scale reads both. */
12
+ export declare const POOL_DURATION_BOUNDS_MS: readonly number[];
13
+ /**
14
+ * How long a checkout may queue behind a full pool before it is refused, and
15
+ * how many may queue (per connection the pool holds). Without them a
16
+ * saturated server held every request for the driver's ten-second timeout and
17
+ * then failed it as a 500: slow, and no better informed. Past either bound the
18
+ * request is refused at once, as busy, and its client is told to come back.
19
+ *
20
+ * The count is about as many checkouts as a connection works through in that
21
+ * wait (a few tens of milliseconds each): past it, the wait would run out
22
+ * anyway. At eight, a burst a server answers well inside the wait was refused
23
+ * at once — a page's boot has up to eight reads in flight, and a field report saw
24
+ * two thirds of the tabs opened at one moment by 25 people turned away busy
25
+ * on a server with its loop idle. The wait is what bounds a slow server.
26
+ * Who gets the places in the line, account by account, is poolAdmission.ts's.
27
+ */
28
+ export declare const POOL_QUEUE_WAIT_MS = 2000;
29
+ export declare const POOL_QUEUE_PER_CONNECTION = 64;
30
+ /** What a person is told when the server is busy, and how soon to try again. */
31
+ export declare const POOL_BUSY_MESSAGE = "The server is busy; try again in a moment.";
32
+ /** How long a pool the server refused stays at the connections it holds before it asks for more: its idle timeout. */
33
+ export declare const POOL_LIMIT_HOLD_MS = 30000;
34
+ /**
35
+ * A checkout refused because the pool is full and its queue is too long or
36
+ * has waited too long, or because the database refused this process another
37
+ * connection and the pool held none to wait for (`connection_limit`, the
38
+ * refusal as its cause). Thrown before anything was leased, so no statement
39
+ * ran: a read can be asked again and a write was never begun.
40
+ */
41
+ export declare class PoolBusy extends Error {
42
+ readonly role: 'read' | 'write';
43
+ readonly why: 'queue_full' | 'queue_timeout' | 'connection_limit';
44
+ constructor(role: 'read' | 'write', why: 'queue_full' | 'queue_timeout' | 'connection_limit', cause?: unknown);
45
+ }
46
+ /**
47
+ * When to come back after a refused checkout. A full queue clears in a moment; a pool the database refused another
48
+ * connection holds at what it has and asks for more only after POOL_LIMIT_HOLD_MS, so a retry in one second lands on
49
+ * the same refusal. A `connection_limit` refusal says the hold's length instead.
50
+ */
51
+ export declare function poolBusyRetryAfterSeconds(error: unknown): number;
52
+ /**
53
+ * Whether `error` is a refused checkout, anywhere in its causes, and not one
54
+ * that reports an unknown outcome (a transaction whose commit was never
55
+ * acknowledged is not "busy": it may have landed).
56
+ */
57
+ export declare function isPoolBusy(error: unknown): boolean;
58
+ /** The readers, the writers, the one connection background work writes through, and a read replica's readers. */
59
+ export type PoolRole = 'read' | 'write' | 'background' | 'replica';
60
+ /** What sits between the process and the server: nothing that moves server
61
+ * connections between clients mid-session (`session`), or a pooler that
62
+ * does so after every transaction (`transaction`). */
63
+ export type PoolerMode = 'session' | 'transaction';
64
+ export interface PoolRoleStats {
65
+ readonly role: PoolRole;
66
+ /** Which of the connection's replicas, from 1, for a replica's readers. */
67
+ readonly replica?: number;
68
+ readonly pooler: PoolerMode;
69
+ /** The most connections this role may hold at once. */
70
+ readonly size: number;
71
+ /** Physical connections the driver holds now, idle ones included; null when it does not say. */
72
+ readonly open: number | null;
73
+ /** Checked out now. */
74
+ readonly inUse: number;
75
+ /** Checkouts queued now behind a pool whose every connection is in use. */
76
+ readonly waiting: number;
77
+ /** A checkout is queued now, or one timed out within the last minute. */
78
+ readonly saturated: boolean;
79
+ /** Checkouts started, cumulative. */
80
+ readonly checkouts: number;
81
+ /** Checkouts that found every connection in use or already being opened, cumulative. */
82
+ readonly queued: number;
83
+ /** Checkouts refused at the acquisition timeout or by the queue's bounds (PoolBusy), cumulative. */
84
+ readonly timedOut: number;
85
+ /** Checkouts that failed otherwise: a refused connection, a failed session setup. */
86
+ readonly failed: number;
87
+ /** From asking to holding (or failing), one count per bucket of POOL_DURATION_BOUNDS_MS, then overflow. */
88
+ readonly waitBuckets: readonly number[];
89
+ /** From holding to giving back, bucketed the same way. */
90
+ readonly holdBuckets: readonly number[];
91
+ }
92
+ /** One checkout in progress. */
93
+ export interface PoolCheckout {
94
+ /** The connection arrived. The returned function gives it back. */
95
+ acquired(): () => void;
96
+ /** The checkout failed; `timedOut` when the driver gave up waiting for a connection. */
97
+ failed(timedOut: boolean): void;
98
+ }
99
+ export declare class PoolMeter {
100
+ readonly role: PoolRole;
101
+ readonly size: number;
102
+ private readonly now;
103
+ private leased;
104
+ private pending;
105
+ private checkouts;
106
+ private queued;
107
+ private timeouts;
108
+ private failures;
109
+ private lastTimeoutAt;
110
+ private readonly waits;
111
+ private readonly holds;
112
+ constructor(role: PoolRole, size: number, now?: () => number);
113
+ /** Every connection is leased or being opened: a checkout begun now waits. */
114
+ full(): boolean;
115
+ /** Checkouts queued now behind a pool whose every connection is in use. */
116
+ waiting(): number;
117
+ /** A checkout turned away before it began: counted as a timeout, so the pool reads saturated and readiness says so. */
118
+ refuse(): void;
119
+ begin(): PoolCheckout;
120
+ stats(pooler: PoolerMode, open: number | null): PoolRoleStats;
121
+ }