@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.
- package/LICENSE +21 -0
- package/README.md +17 -2
- package/dist/adapters/adapter.d.ts +693 -0
- package/dist/adapters/adapter.js +444 -0
- package/dist/adapters/cache/cacheStore.d.ts +75 -0
- package/dist/adapters/cache/cacheStore.js +160 -0
- package/dist/adapters/cache/resp.d.ts +52 -0
- package/dist/adapters/cache/resp.js +237 -0
- package/dist/adapters/commands/canonicalJson.d.ts +19 -0
- package/dist/adapters/commands/canonicalJson.js +154 -0
- package/dist/adapters/connect.d.ts +29 -0
- package/dist/adapters/connect.js +40 -0
- package/dist/adapters/connectionBudget.d.ts +101 -0
- package/dist/adapters/connectionBudget.js +128 -0
- package/dist/adapters/dbLatency.d.ts +35 -0
- package/dist/adapters/dbLatency.js +79 -0
- package/dist/adapters/epochCache.d.ts +50 -0
- package/dist/adapters/epochCache.js +85 -0
- package/dist/adapters/http/egress.d.ts +48 -0
- package/dist/adapters/http/egress.js +175 -0
- package/dist/adapters/http/httpAdapter.d.ts +71 -0
- package/dist/adapters/http/httpAdapter.js +512 -0
- package/dist/adapters/http/httpDescription.d.ts +32 -0
- package/dist/adapters/http/httpDescription.js +246 -0
- package/dist/adapters/http/openapi.d.ts +98 -0
- package/dist/adapters/http/openapi.js +487 -0
- package/dist/adapters/layoutRefusal.d.ts +24 -0
- package/dist/adapters/layoutRefusal.js +35 -0
- package/dist/adapters/net/networkPolicy.d.ts +44 -0
- package/dist/adapters/net/networkPolicy.js +123 -0
- package/dist/adapters/net/untrustedDatabase.d.ts +18 -0
- package/dist/adapters/net/untrustedDatabase.js +120 -0
- package/dist/adapters/poolAdmission.d.ts +43 -0
- package/dist/adapters/poolAdmission.js +184 -0
- package/dist/adapters/poolMetrics.d.ts +121 -0
- package/dist/adapters/poolMetrics.js +185 -0
- package/dist/adapters/postgres.d.ts +436 -0
- package/dist/adapters/postgres.js +1890 -0
- package/dist/adapters/postgresCatalog.d.ts +96 -0
- package/dist/adapters/postgresCatalog.js +387 -0
- package/dist/adapters/postgresCatalogDigest.d.ts +30 -0
- package/dist/adapters/postgresCatalogDigest.js +87 -0
- package/dist/adapters/postgresCatalogRows.d.ts +62 -0
- package/dist/adapters/postgresCatalogRows.js +37 -0
- package/dist/adapters/postgresDates.d.ts +1 -0
- package/dist/adapters/postgresDates.js +39 -0
- package/dist/adapters/postgresMaintenance.d.ts +33 -0
- package/dist/adapters/postgresMaintenance.js +179 -0
- package/dist/adapters/postgresPool.d.ts +255 -0
- package/dist/adapters/postgresPool.js +838 -0
- package/dist/adapters/postgresPooler.d.ts +28 -0
- package/dist/adapters/postgresPooler.js +267 -0
- package/dist/adapters/postgresReadCatalog.d.ts +31 -0
- package/dist/adapters/postgresReadCatalog.js +226 -0
- package/dist/adapters/postgresReadSnapshot.d.ts +46 -0
- package/dist/adapters/postgresReadSnapshot.js +133 -0
- package/dist/adapters/postgresSchemaEpoch.d.ts +24 -0
- package/dist/adapters/postgresSchemaEpoch.js +149 -0
- package/dist/adapters/postgresTransactionHandle.d.ts +173 -0
- package/dist/adapters/postgresTransactionHandle.js +524 -0
- package/dist/adapters/postgresValues.d.ts +30 -0
- package/dist/adapters/postgresValues.js +75 -0
- package/dist/adapters/replicas.d.ts +70 -0
- package/dist/adapters/replicas.js +208 -0
- package/dist/adapters/reservedSql.d.ts +38 -0
- package/dist/adapters/reservedSql.js +264 -0
- package/dist/adapters/rolePrivileges.d.ts +17 -0
- package/dist/adapters/rolePrivileges.js +22 -0
- package/dist/adapters/scoped/keyRows.d.ts +65 -0
- package/dist/adapters/scoped/keyRows.js +173 -0
- package/dist/adapters/scoped/postgresScopeCatalog.d.ts +16 -0
- package/dist/adapters/scoped/postgresScopeCatalog.js +117 -0
- package/dist/adapters/scoped/scopedCommandOperations.d.ts +5 -0
- package/dist/adapters/scoped/scopedCommandOperations.js +48 -0
- package/dist/adapters/scoped/scopedReads.d.ts +20 -0
- package/dist/adapters/scoped/scopedReads.js +174 -0
- package/dist/adapters/scoped/scopedTransaction.d.ts +89 -0
- package/dist/adapters/scoped/scopedTransaction.js +303 -0
- package/dist/adapters/scoped/sqliteScopeCatalog.d.ts +16 -0
- package/dist/adapters/scoped/sqliteScopeCatalog.js +241 -0
- package/dist/adapters/scoped/updateGuard.d.ts +3 -0
- package/dist/adapters/scoped/updateGuard.js +40 -0
- package/dist/adapters/serverSettings.d.ts +45 -0
- package/dist/adapters/serverSettings.js +46 -0
- package/dist/adapters/sqlite.d.ts +262 -0
- package/dist/adapters/sqlite.js +1434 -0
- package/dist/adapters/sqliteCostlyReads.d.ts +33 -0
- package/dist/adapters/sqliteCostlyReads.js +49 -0
- package/dist/adapters/sqliteDecimals.d.ts +22 -0
- package/dist/adapters/sqliteDecimals.js +57 -0
- package/dist/adapters/sqliteHandles.d.ts +43 -0
- package/dist/adapters/sqliteHandles.js +143 -0
- package/dist/adapters/sqliteStatementProcess.d.ts +29 -0
- package/dist/adapters/sqliteStatementProcess.js +131 -0
- package/dist/adapters/statementControl.d.ts +34 -0
- package/dist/adapters/statementControl.js +90 -0
- package/dist/adapters/storeHost.d.ts +130 -0
- package/dist/adapters/storeHost.js +13 -0
- package/dist/adapters/telemetry/drivers.d.ts +21 -0
- package/dist/adapters/telemetry/drivers.js +321 -0
- package/dist/adapters/telemetry/metrics.d.ts +63 -0
- package/dist/adapters/telemetry/metrics.js +122 -0
- package/dist/adapters/telemetry/otlp.d.ts +12 -0
- package/dist/adapters/telemetry/otlp.js +320 -0
- package/dist/adapters/telemetry/otlpEncode.d.ts +48 -0
- package/dist/adapters/telemetry/otlpEncode.js +366 -0
- package/dist/adapters/telemetry/otlpEnv.d.ts +1 -0
- package/dist/adapters/telemetry/otlpEnv.js +12 -0
- package/dist/adapters/telemetry/serverTiming.d.ts +83 -0
- package/dist/adapters/telemetry/serverTiming.js +503 -0
- package/dist/adapters/telemetry/start.d.ts +10 -0
- package/dist/adapters/telemetry/start.js +25 -0
- package/dist/adapters/telemetry/statement.d.ts +16 -0
- package/dist/adapters/telemetry/statement.js +134 -0
- package/dist/adapters/telemetry/trace.d.ts +127 -0
- package/dist/adapters/telemetry/trace.js +295 -0
- package/dist/adapters/writeAhead.d.ts +27 -0
- package/dist/adapters/writeAhead.js +46 -0
- package/dist/adapters/writeAttribution.d.ts +18 -0
- package/dist/adapters/writeAttribution.js +23 -0
- package/dist/adapters/writeCapture.d.ts +73 -0
- package/dist/adapters/writeCapture.js +20 -0
- package/dist/adapters/writeLanes.d.ts +94 -0
- package/dist/adapters/writeLanes.js +232 -0
- package/dist/engine.d.ts +15 -0
- package/dist/engine.js +13 -0
- package/dist/server/auth/credentials.d.ts +61 -0
- package/dist/server/auth/credentials.js +260 -0
- package/dist/server/cacheService.d.ts +50 -0
- package/dist/server/cacheService.js +110 -0
- package/dist/server/cli/args.d.ts +176 -0
- package/dist/server/cli/args.js +342 -0
- package/dist/server/cli/bin.d.ts +5 -0
- package/dist/server/cli/bin.js +66 -0
- package/dist/server/cli/browser.d.ts +15 -0
- package/dist/server/cli/browser.js +37 -0
- package/dist/server/cli/config.d.ts +50 -0
- package/dist/server/cli/config.js +206 -0
- package/dist/server/cli/startup.d.ts +36 -0
- package/dist/server/cli/startup.js +128 -0
- package/dist/server/cli/startupOptions.d.ts +63 -0
- package/dist/server/cli/startupOptions.js +143 -0
- package/dist/server/cli/subcommand.d.ts +28 -0
- package/dist/server/cli/subcommand.js +32 -0
- package/dist/server/cli/usage.d.ts +13 -0
- package/dist/server/cli/usage.js +31 -0
- package/dist/server/clientHttp.d.ts +184 -0
- package/dist/server/clientHttp.js +700 -0
- package/dist/server/clientSurface.d.ts +128 -0
- package/dist/server/clientSurface.js +182 -0
- package/dist/server/columnGrants.d.ts +103 -0
- package/dist/server/columnGrants.js +730 -0
- package/dist/server/compileCache.d.ts +1 -0
- package/dist/server/compileCache.js +30 -0
- package/dist/server/config/locations.d.ts +1 -0
- package/dist/server/config/locations.js +15 -0
- package/dist/server/configPaths.d.ts +7 -0
- package/dist/server/configPaths.js +34 -0
- package/dist/server/configSections.d.ts +64 -0
- package/dist/server/configSections.js +72 -0
- package/dist/server/connectionRedaction.d.ts +30 -0
- package/dist/server/connectionRedaction.js +77 -0
- package/dist/server/connections.d.ts +353 -0
- package/dist/server/connections.js +978 -0
- package/dist/server/constraints.d.ts +82 -0
- package/dist/server/constraints.js +169 -0
- package/dist/server/demo.d.ts +9 -0
- package/dist/server/demo.js +554 -0
- package/dist/server/devclient.d.ts +108 -0
- package/dist/server/devclient.js +361 -0
- package/dist/server/evidence.d.ts +55 -0
- package/dist/server/evidence.js +323 -0
- package/dist/server/hiddenColumns.d.ts +32 -0
- package/dist/server/hiddenColumns.js +238 -0
- package/dist/server/http/baselineHeaders.d.ts +24 -0
- package/dist/server/http/baselineHeaders.js +12 -0
- package/dist/server/http/captured.d.ts +35 -0
- package/dist/server/http/captured.js +73 -0
- package/dist/server/http/clock.d.ts +1 -0
- package/dist/server/http/clock.js +14 -0
- package/dist/server/http/connectionSource.d.ts +4 -0
- package/dist/server/http/connectionSource.js +48 -0
- package/dist/server/http/context.d.ts +189 -0
- package/dist/server/http/context.js +11 -0
- package/dist/server/http/crawlerText.d.ts +15 -0
- package/dist/server/http/crawlerText.js +32 -0
- package/dist/server/http/dataRoutes.d.ts +88 -0
- package/dist/server/http/dataRoutes.js +137 -0
- package/dist/server/http/door.d.ts +57 -0
- package/dist/server/http/door.js +39 -0
- package/dist/server/http/exportRoute.d.ts +15 -0
- package/dist/server/http/exportRoute.js +320 -0
- package/dist/server/http/firstPaint.d.ts +108 -0
- package/dist/server/http/firstPaint.js +262 -0
- package/dist/server/http/httpOperationRoutes.d.ts +11 -0
- package/dist/server/http/httpOperationRoutes.js +50 -0
- package/dist/server/http/pageReads.d.ts +20 -0
- package/dist/server/http/pageReads.js +205 -0
- package/dist/server/http/pageRoutes.d.ts +39 -0
- package/dist/server/http/pageRoutes.js +291 -0
- package/dist/server/http/probes.d.ts +22 -0
- package/dist/server/http/probes.js +27 -0
- package/dist/server/http/rateLimit.d.ts +131 -0
- package/dist/server/http/rateLimit.js +351 -0
- package/dist/server/http/readRoutes.d.ts +9 -0
- package/dist/server/http/readRoutes.js +131 -0
- package/dist/server/http/readRouting.d.ts +20 -0
- package/dist/server/http/readRouting.js +80 -0
- package/dist/server/http/recordCompose.d.ts +67 -0
- package/dist/server/http/recordCompose.js +167 -0
- package/dist/server/http/recordWrites.d.ts +89 -0
- package/dist/server/http/recordWrites.js +298 -0
- package/dist/server/http/refusalReport.d.ts +38 -0
- package/dist/server/http/refusalReport.js +63 -0
- package/dist/server/http/reply.d.ts +130 -0
- package/dist/server/http/reply.js +394 -0
- package/dist/server/http/requestOrigin.d.ts +11 -0
- package/dist/server/http/requestOrigin.js +8 -0
- package/dist/server/http/router.d.ts +45 -0
- package/dist/server/http/router.js +22 -0
- package/dist/server/http/serverCore.d.ts +68 -0
- package/dist/server/http/serverCore.js +177 -0
- package/dist/server/http/traceRequest.d.ts +30 -0
- package/dist/server/http/traceRequest.js +224 -0
- package/dist/server/http/trust.d.ts +261 -0
- package/dist/server/http/trust.js +472 -0
- package/dist/server/http/writeRefusal.d.ts +33 -0
- package/dist/server/http/writeRefusal.js +24 -0
- package/dist/server/httpConnection.d.ts +49 -0
- package/dist/server/httpConnection.js +170 -0
- package/dist/server/impact.d.ts +55 -0
- package/dist/server/impact.js +47 -0
- package/dist/server/journal.d.ts +134 -0
- package/dist/server/journal.js +398 -0
- package/dist/server/keysetReadHttp.d.ts +52 -0
- package/dist/server/keysetReadHttp.js +85 -0
- package/dist/server/layouts.d.ts +49 -0
- package/dist/server/layouts.js +192 -0
- package/dist/server/migrate/cli.d.ts +55 -0
- package/dist/server/migrate/cli.js +517 -0
- package/dist/server/migrate/database.d.ts +37 -0
- package/dist/server/migrate/database.js +247 -0
- package/dist/server/migrate/desired.d.ts +76 -0
- package/dist/server/migrate/desired.js +292 -0
- package/dist/server/migrate/files.d.ts +34 -0
- package/dist/server/migrate/files.js +141 -0
- package/dist/server/migrate/flyway.d.ts +7 -0
- package/dist/server/migrate/flyway.js +69 -0
- package/dist/server/migrate/history.d.ts +70 -0
- package/dist/server/migrate/history.js +211 -0
- package/dist/server/migrate/runner.d.ts +100 -0
- package/dist/server/migrate/runner.js +409 -0
- package/dist/server/migrate/snapshot.d.ts +30 -0
- package/dist/server/migrate/snapshot.js +239 -0
- package/dist/server/migrate/target.d.ts +33 -0
- package/dist/server/migrate/target.js +82 -0
- package/dist/server/openapiDraft.d.ts +25 -0
- package/dist/server/openapiDraft.js +171 -0
- package/dist/server/operations/diagnostics.d.ts +101 -0
- package/dist/server/operations/diagnostics.js +284 -0
- package/dist/server/operations/requestMetrics.d.ts +33 -0
- package/dist/server/operations/requestMetrics.js +94 -0
- package/dist/server/packageVersion.d.ts +1 -0
- package/dist/server/packageVersion.js +11 -0
- package/dist/server/poolConfig.d.ts +34 -0
- package/dist/server/poolConfig.js +114 -0
- package/dist/server/product.d.ts +20 -0
- package/dist/server/product.js +12 -0
- package/dist/server/recordHistoryOperations.d.ts +39 -0
- package/dist/server/recordHistoryOperations.js +43 -0
- package/dist/server/recordWriteOperations.d.ts +111 -0
- package/dist/server/recordWriteOperations.js +329 -0
- package/dist/server/resourceReadHttp.d.ts +81 -0
- package/dist/server/resourceReadHttp.js +606 -0
- package/dist/server/resourceReadOperations.d.ts +147 -0
- package/dist/server/resourceReadOperations.js +452 -0
- package/dist/server/scaffoldMachine.d.ts +54 -0
- package/dist/server/scaffoldMachine.js +184 -0
- package/dist/server/seed/cli.d.ts +20 -0
- package/dist/server/seed/cli.js +164 -0
- package/dist/server/seed/lexicon.d.ts +26 -0
- package/dist/server/seed/lexicon.js +585 -0
- package/dist/server/seed/seed.d.ts +70 -0
- package/dist/server/seed/seed.js +779 -0
- package/dist/server/seed/words.d.ts +21 -0
- package/dist/server/seed/words.js +164 -0
- package/dist/server/serverRequests.d.ts +6 -0
- package/dist/server/serverRequests.js +33 -0
- package/dist/server/serverTimeouts.d.ts +33 -0
- package/dist/server/serverTimeouts.js +32 -0
- package/dist/server/shapeonly.d.ts +32 -0
- package/dist/server/shapeonly.js +110 -0
- package/dist/server/startupWarnings.d.ts +32 -0
- package/dist/server/startupWarnings.js +92 -0
- package/dist/shared/addressParams.d.ts +28 -0
- package/dist/shared/addressParams.js +47 -0
- package/dist/shared/appCards.d.ts +123 -0
- package/dist/shared/appCards.js +385 -0
- package/dist/shared/appComponents.d.ts +177 -0
- package/dist/shared/appComponents.js +422 -0
- package/dist/shared/appDocuments.d.ts +43 -0
- package/dist/shared/appDocuments.js +131 -0
- package/dist/shared/appEmbeds.d.ts +21 -0
- package/dist/shared/appEmbeds.js +24 -0
- package/dist/shared/appIcons.d.ts +28 -0
- package/dist/shared/appIcons.js +223 -0
- package/dist/shared/appLinks.d.ts +17 -0
- package/dist/shared/appLinks.js +124 -0
- package/dist/shared/appListColumns.d.ts +3 -0
- package/dist/shared/appListColumns.js +66 -0
- package/dist/shared/appLocale.d.ts +36 -0
- package/dist/shared/appLocale.js +86 -0
- package/dist/shared/appMessages.d.ts +44 -0
- package/dist/shared/appMessages.js +78 -0
- package/dist/shared/appNoun.d.ts +21 -0
- package/dist/shared/appNoun.js +32 -0
- package/dist/shared/autoBucket.d.ts +98 -0
- package/dist/shared/autoBucket.js +305 -0
- package/dist/shared/autoValues.d.ts +25 -0
- package/dist/shared/autoValues.js +25 -0
- package/dist/shared/breakdown.d.ts +228 -0
- package/dist/shared/breakdown.js +557 -0
- package/dist/shared/breakdowntext.d.ts +41 -0
- package/dist/shared/breakdowntext.js +400 -0
- package/dist/shared/builtInThemes.d.ts +2 -0
- package/dist/shared/builtInThemes.js +771 -0
- package/dist/shared/chartSeparation.d.ts +11 -0
- package/dist/shared/chartSeparation.js +58 -0
- package/dist/shared/clauses.d.ts +22 -0
- package/dist/shared/clauses.js +97 -0
- package/dist/shared/columnCaption.d.ts +16 -0
- package/dist/shared/columnCaption.js +90 -0
- package/dist/shared/commandFieldPath.d.ts +2 -0
- package/dist/shared/commandFieldPath.js +7 -0
- package/dist/shared/commandWire.d.ts +26 -0
- package/dist/shared/commandWire.js +41 -0
- package/dist/shared/computed.d.ts +161 -0
- package/dist/shared/computed.js +378 -0
- package/dist/shared/computedParse.d.ts +13 -0
- package/dist/shared/computedParse.js +278 -0
- package/dist/shared/computedValue.d.ts +47 -0
- package/dist/shared/computedValue.js +191 -0
- package/dist/shared/connection.d.ts +30 -0
- package/dist/shared/connection.js +1 -0
- package/dist/shared/csv.d.ts +20 -0
- package/dist/shared/csv.js +63 -0
- package/dist/shared/dashLayout.d.ts +30 -0
- package/dist/shared/dashLayout.js +132 -0
- package/dist/shared/dashboardAsks.d.ts +93 -0
- package/dist/shared/dashboardAsks.js +129 -0
- package/dist/shared/dashboardTrend.d.ts +20 -0
- package/dist/shared/dashboardTrend.js +50 -0
- package/dist/shared/declaredReferences.d.ts +50 -0
- package/dist/shared/declaredReferences.js +202 -0
- package/dist/shared/definedFields.d.ts +63 -0
- package/dist/shared/definedFields.js +103 -0
- package/dist/shared/definedValues.d.ts +63 -0
- package/dist/shared/definedValues.js +184 -0
- package/dist/shared/displayDefaults.d.ts +135 -0
- package/dist/shared/displayDefaults.js +529 -0
- package/dist/shared/dueDate.d.ts +6 -0
- package/dist/shared/dueDate.js +6 -0
- package/dist/shared/duration.d.ts +4 -0
- package/dist/shared/duration.js +23 -0
- package/dist/shared/fileBounds.d.ts +9 -0
- package/dist/shared/fileBounds.js +9 -0
- package/dist/shared/filter.d.ts +217 -0
- package/dist/shared/filter.js +305 -0
- package/dist/shared/firstPaint.d.ts +24 -0
- package/dist/shared/firstPaint.js +33 -0
- package/dist/shared/form.d.ts +21 -0
- package/dist/shared/form.js +25 -0
- package/dist/shared/formValues.d.ts +104 -0
- package/dist/shared/formValues.js +352 -0
- package/dist/shared/funnel.d.ts +45 -0
- package/dist/shared/funnel.js +108 -0
- package/dist/shared/httpOperations.d.ts +48 -0
- package/dist/shared/httpOperations.js +9 -0
- package/dist/shared/iconGlyphs.d.ts +4 -0
- package/dist/shared/iconGlyphs.js +151 -0
- package/dist/shared/iconWeights.d.ts +3 -0
- package/dist/shared/iconWeights.js +162 -0
- package/dist/shared/imageWidths.d.ts +32 -0
- package/dist/shared/imageWidths.js +38 -0
- package/dist/shared/keysetPage.d.ts +64 -0
- package/dist/shared/keysetPage.js +161 -0
- package/dist/shared/like.d.ts +20 -0
- package/dist/shared/like.js +29 -0
- package/dist/shared/listEmpty.d.ts +12 -0
- package/dist/shared/listEmpty.js +36 -0
- package/dist/shared/listFilters.d.ts +28 -0
- package/dist/shared/listFilters.js +84 -0
- package/dist/shared/listPresentations.d.ts +199 -0
- package/dist/shared/listPresentations.js +7 -0
- package/dist/shared/listQuestion.d.ts +52 -0
- package/dist/shared/listQuestion.js +137 -0
- package/dist/shared/lookPalettes.d.ts +62 -0
- package/dist/shared/lookPalettes.js +306 -0
- package/dist/shared/maskQuoted.d.ts +24 -0
- package/dist/shared/maskQuoted.js +48 -0
- package/dist/shared/mentionLabel.d.ts +19 -0
- package/dist/shared/mentionLabel.js +38 -0
- package/dist/shared/mentionLookup.d.ts +17 -0
- package/dist/shared/mentionLookup.js +64 -0
- package/dist/shared/menuCounts.d.ts +16 -0
- package/dist/shared/menuCounts.js +74 -0
- package/dist/shared/model.d.ts +79 -0
- package/dist/shared/model.js +153 -0
- package/dist/shared/money.d.ts +44 -0
- package/dist/shared/money.js +81 -0
- package/dist/shared/moneyEntry.d.ts +7 -0
- package/dist/shared/moneyEntry.js +27 -0
- package/dist/shared/mount.d.ts +118 -0
- package/dist/shared/mount.js +248 -0
- package/dist/shared/niceTicks.d.ts +26 -0
- package/dist/shared/niceTicks.js +50 -0
- package/dist/shared/order.d.ts +59 -0
- package/dist/shared/order.js +133 -0
- package/dist/shared/page.d.ts +135 -0
- package/dist/shared/page.js +1187 -0
- package/dist/shared/pageAnatomy.d.ts +99 -0
- package/dist/shared/pageAnatomy.js +370 -0
- package/dist/shared/pageConfig.d.ts +25 -0
- package/dist/shared/pageConfig.js +1308 -0
- package/dist/shared/pageEmptyActions.d.ts +12 -0
- package/dist/shared/pageEmptyActions.js +20 -0
- package/dist/shared/pageLayouts.d.ts +72 -0
- package/dist/shared/pageLayouts.js +205 -0
- package/dist/shared/pageModel.d.ts +785 -0
- package/dist/shared/pageModel.js +121 -0
- package/dist/shared/pagePaths.d.ts +180 -0
- package/dist/shared/pagePaths.js +869 -0
- package/dist/shared/pagePlans.d.ts +52 -0
- package/dist/shared/pagePlans.js +108 -0
- package/dist/shared/pageRoutes.d.ts +9 -0
- package/dist/shared/pageRoutes.js +9 -0
- package/dist/shared/query.d.ts +166 -0
- package/dist/shared/query.js +1302 -0
- package/dist/shared/queryDates.d.ts +12 -0
- package/dist/shared/queryDates.js +101 -0
- package/dist/shared/queryOperands.d.ts +99 -0
- package/dist/shared/queryOperands.js +131 -0
- package/dist/shared/reads.d.ts +103 -0
- package/dist/shared/reads.js +154 -0
- package/dist/shared/recordLabel.d.ts +51 -0
- package/dist/shared/recordLabel.js +123 -0
- package/dist/shared/recordReadKeys.d.ts +30 -0
- package/dist/shared/recordReadKeys.js +51 -0
- package/dist/shared/recordReads.d.ts +268 -0
- package/dist/shared/recordReads.js +368 -0
- package/dist/shared/recordview.d.ts +198 -0
- package/dist/shared/recordview.js +356 -0
- package/dist/shared/referenceModel.d.ts +58 -0
- package/dist/shared/referenceModel.js +194 -0
- package/dist/shared/refusal.d.ts +64 -0
- package/dist/shared/refusal.js +144 -0
- package/dist/shared/relatedCreate.d.ts +30 -0
- package/dist/shared/relatedCreate.js +162 -0
- package/dist/shared/resourceHttp.d.ts +464 -0
- package/dist/shared/resourceHttp.js +1 -0
- package/dist/shared/richText.d.ts +85 -0
- package/dist/shared/richText.js +305 -0
- package/dist/shared/rollups.d.ts +143 -0
- package/dist/shared/rollups.js +64 -0
- package/dist/shared/rowScope.d.ts +72 -0
- package/dist/shared/rowScope.js +376 -0
- package/dist/shared/runtimeTables.d.ts +44 -0
- package/dist/shared/runtimeTables.js +79 -0
- package/dist/shared/schema.d.ts +523 -0
- package/dist/shared/schema.js +627 -0
- package/dist/shared/schematext.d.ts +38 -0
- package/dist/shared/schematext.js +101 -0
- package/dist/shared/scopeCatalog.d.ts +29 -0
- package/dist/shared/scopeCatalog.js +468 -0
- package/dist/shared/servedApp.d.ts +681 -0
- package/dist/shared/servedApp.js +45 -0
- package/dist/shared/sessionLease.d.ts +34 -0
- package/dist/shared/sessionLease.js +3 -0
- package/dist/shared/shape.d.ts +55 -0
- package/dist/shared/shape.js +168 -0
- package/dist/shared/slug.d.ts +1 -0
- package/dist/shared/slug.js +12 -0
- package/dist/shared/sortText.d.ts +14 -0
- package/dist/shared/sortText.js +26 -0
- package/dist/shared/sqlRelation.d.ts +4 -0
- package/dist/shared/sqlRelation.js +8 -0
- package/dist/shared/sqlsaved.d.ts +44 -0
- package/dist/shared/sqlsaved.js +63 -0
- package/dist/shared/stitchedPaths.d.ts +27 -0
- package/dist/shared/stitchedPaths.js +38 -0
- package/dist/shared/structuredFilter.d.ts +22 -0
- package/dist/shared/structuredFilter.js +1 -0
- package/dist/shared/subtitlePath.d.ts +20 -0
- package/dist/shared/subtitlePath.js +24 -0
- package/dist/shared/suggest.d.ts +18 -0
- package/dist/shared/suggest.js +59 -0
- package/dist/shared/tableSizing.d.ts +4 -0
- package/dist/shared/tableSizing.js +9 -0
- package/dist/shared/tagLists.d.ts +57 -0
- package/dist/shared/tagLists.js +34 -0
- package/dist/shared/textRules.d.ts +54 -0
- package/dist/shared/textRules.js +133 -0
- package/dist/shared/theme.d.ts +94 -0
- package/dist/shared/theme.js +800 -0
- package/dist/shared/themeColor.d.ts +34 -0
- package/dist/shared/themeColor.js +109 -0
- package/dist/shared/themeFaces.d.ts +30 -0
- package/dist/shared/themeFaces.js +42 -0
- package/dist/shared/themeInk.d.ts +20 -0
- package/dist/shared/themeInk.js +52 -0
- package/dist/shared/themeLooks.d.ts +9 -0
- package/dist/shared/themeLooks.js +572 -0
- package/dist/shared/themeParts.d.ts +26 -0
- package/dist/shared/themeParts.js +71 -0
- package/dist/shared/themePartsCheck.d.ts +21 -0
- package/dist/shared/themePartsCheck.js +91 -0
- package/dist/shared/themePresets.d.ts +85 -0
- package/dist/shared/themePresets.js +139 -0
- package/dist/shared/themeRecipeWords.d.ts +156 -0
- package/dist/shared/themeRecipeWords.js +156 -0
- package/dist/shared/themeRecipes.d.ts +213 -0
- package/dist/shared/themeRecipes.js +234 -0
- package/dist/shared/themeResolve.d.ts +55 -0
- package/dist/shared/themeResolve.js +52 -0
- package/dist/shared/themeTokens.d.ts +107 -0
- package/dist/shared/themeTokens.js +116 -0
- package/dist/shared/themeType.d.ts +38 -0
- package/dist/shared/themeType.js +205 -0
- package/dist/shared/unitWord.d.ts +4 -0
- package/dist/shared/unitWord.js +37 -0
- package/dist/shared/view.d.ts +195 -0
- package/dist/shared/view.js +987 -0
- package/dist/shared/viewLabels.d.ts +47 -0
- package/dist/shared/viewLabels.js +459 -0
- package/dist/shared/viewPaths.d.ts +248 -0
- package/dist/shared/viewPaths.js +294 -0
- package/dist/shared/viewtext.d.ts +57 -0
- package/dist/shared/viewtext.js +282 -0
- package/dist/shared/vocabulary.d.ts +71 -0
- package/dist/shared/vocabulary.js +249 -0
- package/dist/shared/weekStart.d.ts +7 -0
- package/dist/shared/weekStart.js +36 -0
- package/mark.svg +1 -0
- package/package.json +261 -4
- package/schema/model.d.ts +298 -0
- package/schema/theme.d.ts +587 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PgQuery } from './postgresPool.js';
|
|
2
|
+
export interface TransactionScopedClient extends PgQuery {
|
|
3
|
+
/** Invalidate future SQL without waiting for the current driver operation.
|
|
4
|
+
* The lease owner destroys that operation's physical client separately. */
|
|
5
|
+
close(reason: Error): void;
|
|
6
|
+
/** Close a transaction the lease's work left open, rather than hand the
|
|
7
|
+
* pooler a server connection mid-transaction. */
|
|
8
|
+
settle(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The statement past its leading space and comments. PostgreSQL nests block
|
|
12
|
+
* comments, so this does too: a misread edge here is a transaction left open
|
|
13
|
+
* on a pooled server connection, not a cosmetic slip.
|
|
14
|
+
*/
|
|
15
|
+
export declare function statementHead(text: string): string;
|
|
16
|
+
export declare function transactionScoped(client: PgQuery, options: Readonly<{
|
|
17
|
+
role: 'read' | 'write';
|
|
18
|
+
capMs: number;
|
|
19
|
+
untrusted: boolean;
|
|
20
|
+
/** A writer's lock wait (writeLanes.ts). */
|
|
21
|
+
lockTimeoutMs?: number;
|
|
22
|
+
/** The path a store's unqualified names resolve on (the authentication
|
|
23
|
+
* store's, for Better Auth), set per transaction for the same reason. */
|
|
24
|
+
searchPath?: string;
|
|
25
|
+
/** The client sends each query as it is asked (node-postgres's `pipeline`):
|
|
26
|
+
* a statement's own transaction is then sent with it, not around it. */
|
|
27
|
+
pipelines?: boolean;
|
|
28
|
+
}>): TransactionScopedClient;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A leased PostgreSQL client made safe behind a transaction-mode pooler:
|
|
3
|
+
* PgBouncer with `pool_mode = transaction`, or RDS Proxy, which multiplexes
|
|
4
|
+
* the same way until a session setting pins a connection.
|
|
5
|
+
*
|
|
6
|
+
* Such a pooler lends a server connection for one transaction and gives it to
|
|
7
|
+
* another client for the next. A setting made on the session therefore does
|
|
8
|
+
* not follow this client to its next transaction, and does follow the server
|
|
9
|
+
* connection to the pooler's next client. The direct path's per-connection
|
|
10
|
+
* defaults — `default_transaction_read_only` on every reader, a
|
|
11
|
+
* `statement_timeout` everywhere — are made per transaction here, with
|
|
12
|
+
* `SET LOCAL`, which dies with its transaction:
|
|
13
|
+
*
|
|
14
|
+
* - A transaction a caller begins gets the cap, and on a reader
|
|
15
|
+
* `SET TRANSACTION READ ONLY`, in the same round trip as its BEGIN.
|
|
16
|
+
* - A statement sent outside a transaction is wrapped in one of its own:
|
|
17
|
+
* BEGIN with the settings, the statement, COMMIT. A bare statement is
|
|
18
|
+
* exactly what a pooler may run on any server connection. On a client that
|
|
19
|
+
* pipelines, the three leave together: one round trip, not three, and the
|
|
20
|
+
* same statements in the same order on the same connection. The statement
|
|
21
|
+
* cannot run outside them: the BEGIN and the settings are one simple query,
|
|
22
|
+
* so a setting that fails leaves the transaction aborted, the statement
|
|
23
|
+
* refused in it, and the COMMIT a ROLLBACK.
|
|
24
|
+
* - An untrusted lease — user-authored SQL — fences each statement with a
|
|
25
|
+
* savepoint, and before its transaction ends runs the part of DISCARD ALL
|
|
26
|
+
* a transaction block allows. An advisory lock or a prepared statement
|
|
27
|
+
* survives ROLLBACK and a setting survives COMMIT; none of them may reach
|
|
28
|
+
* the pooler's next client.
|
|
29
|
+
*
|
|
30
|
+
* Transaction edges are read off each statement's first keyword. That is
|
|
31
|
+
* sound here: every BEGIN, COMMIT and ROLLBACK this codebase sends is a
|
|
32
|
+
* literal of its own, and user-authored SQL is one statement at a time
|
|
33
|
+
* (the extended protocol, behind refuseStacked) on a lease that is discarded
|
|
34
|
+
* afterwards.
|
|
35
|
+
*/
|
|
36
|
+
import { trimStatement } from './adapter.js';
|
|
37
|
+
/* The in-transaction half of DISCARD ALL, which itself refuses a transaction
|
|
38
|
+
block. Every part of it also runs inside a read-only transaction. */
|
|
39
|
+
const RESET = 'SET SESSION AUTHORIZATION DEFAULT; RESET ALL; DEALLOCATE ALL; CLOSE ALL; UNLISTEN *; ' +
|
|
40
|
+
'SELECT pg_catalog.pg_advisory_unlock_all(); DISCARD PLANS; DISCARD SEQUENCES; DISCARD TEMP';
|
|
41
|
+
const MARK = 'mistri_statement';
|
|
42
|
+
const BEGINS = /^(?:BEGIN|START\s+TRANSACTION)\b/i;
|
|
43
|
+
/** COMMIT, END, ABORT or ROLLBACK: not ROLLBACK TO a savepoint, and not the PREPARED forms. */
|
|
44
|
+
const ENDS = /^(?:COMMIT|END|ABORT|ROLLBACK)\b(?!\s+(?:(?:WORK|TRANSACTION)\s+)?(?:TO|PREPARED)\b)/i;
|
|
45
|
+
/** Neither wrapped nor fenced: statements that only mean something at a transaction's edge. */
|
|
46
|
+
const EDGES = /^(?:SAVEPOINT|RELEASE|ROLLBACK\s+(?:(?:WORK|TRANSACTION)\s+)?TO|PREPARE\s+TRANSACTION|COMMIT\s+PREPARED|ROLLBACK\s+PREPARED)\b/i;
|
|
47
|
+
/**
|
|
48
|
+
* The statement past its leading space and comments. PostgreSQL nests block
|
|
49
|
+
* comments, so this does too: a misread edge here is a transaction left open
|
|
50
|
+
* on a pooled server connection, not a cosmetic slip.
|
|
51
|
+
*/
|
|
52
|
+
export function statementHead(text) {
|
|
53
|
+
let i = 0;
|
|
54
|
+
while (i < text.length) {
|
|
55
|
+
if (/\s/.test(text[i])) {
|
|
56
|
+
i += 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (text.startsWith('--', i)) {
|
|
60
|
+
const end = text.indexOf('\n', i);
|
|
61
|
+
if (end < 0)
|
|
62
|
+
return '';
|
|
63
|
+
i = end + 1;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (text.startsWith('/*', i)) {
|
|
67
|
+
let depth = 0;
|
|
68
|
+
do {
|
|
69
|
+
if (text.startsWith('/*', i)) {
|
|
70
|
+
depth += 1;
|
|
71
|
+
i += 2;
|
|
72
|
+
}
|
|
73
|
+
else if (text.startsWith('*/', i)) {
|
|
74
|
+
depth -= 1;
|
|
75
|
+
i += 2;
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
i += 1;
|
|
79
|
+
} while (depth > 0 && i < text.length);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
return text.slice(i);
|
|
85
|
+
}
|
|
86
|
+
export function transactionScoped(client, options) {
|
|
87
|
+
let closed;
|
|
88
|
+
const raw = (request, params) => {
|
|
89
|
+
if (closed)
|
|
90
|
+
return Promise.reject(closed);
|
|
91
|
+
return client.query(request, params);
|
|
92
|
+
};
|
|
93
|
+
const reader = options.role === 'read';
|
|
94
|
+
/* On a reader the transaction is read-only whatever its BEGIN said: the
|
|
95
|
+
session default that promised it on a direct connection is not here. */
|
|
96
|
+
const lockWait = !reader && options.lockTimeoutMs !== undefined ? `; SET LOCAL lock_timeout = ${Math.max(1, Math.floor(options.lockTimeoutMs))}` : '';
|
|
97
|
+
const path = options.searchPath === undefined ? '' : `; SET LOCAL search_path TO ${options.searchPath}`;
|
|
98
|
+
const settings = `${reader ? 'SET TRANSACTION READ ONLY; ' : ''}SET LOCAL statement_timeout = ${Math.max(1, Math.floor(options.capMs))}${lockWait}${path}`;
|
|
99
|
+
const settingCount = 1 + (reader ? 1 : 0) + (lockWait ? 1 : 0) + (path ? 1 : 0);
|
|
100
|
+
let open = false;
|
|
101
|
+
// A simple-protocol string with several statements answers with one result each.
|
|
102
|
+
const first = (result) => (Array.isArray(result) ? result[0] : result);
|
|
103
|
+
const simple = (request, params) => typeof request === 'string' && (params === undefined || (Array.isArray(params) && params.length === 0));
|
|
104
|
+
const begin = async (text, request, params) => {
|
|
105
|
+
/* Open from the moment the BEGIN is sent, not answered: a statement a
|
|
106
|
+
pipelining caller sends right behind it (pipelined,
|
|
107
|
+
postgresTransactionHandle.ts) belongs to this transaction, and must not
|
|
108
|
+
be wrapped in one of its own. */
|
|
109
|
+
open = true;
|
|
110
|
+
try {
|
|
111
|
+
let result;
|
|
112
|
+
if (simple(request, params)) {
|
|
113
|
+
/* A BEGIN may carry a prologue (a read snapshot's LOCK and first
|
|
114
|
+
query, PostgresAdapter.readSnapshot). The settings go straight
|
|
115
|
+
after the BEGIN, so the cap is in force before the prologue runs,
|
|
116
|
+
and the settings' own results are taken out of the answer. The
|
|
117
|
+
BEGIN is one of this codebase's literals, so its first `;` is
|
|
118
|
+
where it ends. */
|
|
119
|
+
const statement = trimStatement(text), cut = statement.indexOf(';');
|
|
120
|
+
if (cut < 0)
|
|
121
|
+
result = first(await raw(`${statement}; ${settings}`));
|
|
122
|
+
else {
|
|
123
|
+
const answers = (await raw(`${statement.slice(0, cut)}; ${settings}; ${statement.slice(cut + 1).trimStart()}`));
|
|
124
|
+
result = [answers[0], ...answers.slice(1 + settingCount)];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
/* Asked together, so the settings are in force before anything a
|
|
129
|
+
pipelining caller sent behind the BEGIN. */
|
|
130
|
+
const answer = raw(request, params), set = raw(settings);
|
|
131
|
+
void set.catch(() => { });
|
|
132
|
+
result = await answer;
|
|
133
|
+
await set;
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
open = false;
|
|
139
|
+
// BEGIN may have taken effect before a setting failed; if not, ROLLBACK costs a warning.
|
|
140
|
+
await raw('ROLLBACK').catch(() => { });
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const end = async (request, params) => {
|
|
145
|
+
open = false;
|
|
146
|
+
if (options.untrusted) {
|
|
147
|
+
try {
|
|
148
|
+
await raw(RESET);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
// A transaction that cannot shed what its statement left behind does not commit with it.
|
|
152
|
+
await raw('ROLLBACK').catch(() => { });
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return raw(request, params);
|
|
157
|
+
};
|
|
158
|
+
const within = async (request, params) => {
|
|
159
|
+
if (!options.untrusted)
|
|
160
|
+
return raw(request, params);
|
|
161
|
+
await raw(`SAVEPOINT ${MARK}`);
|
|
162
|
+
try {
|
|
163
|
+
return await raw(request, params);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
/* Back to before the statement, so the transaction can still shed what
|
|
167
|
+
the statement took before it failed: an advisory lock outlives both
|
|
168
|
+
the failure and a rollback. */
|
|
169
|
+
await raw(`ROLLBACK TO SAVEPOINT ${MARK}`).catch(() => { });
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
/* BEGIN with the settings, the statement and COMMIT asked at once. Each is
|
|
174
|
+
answered on its own (a pipelining client syncs every query), so a failed
|
|
175
|
+
statement leaves the transaction aborted and the COMMIT behind it ends it
|
|
176
|
+
as a ROLLBACK: nothing is left open, and nothing commits. Trusted
|
|
177
|
+
statements only: an untrusted one is fenced by a savepoint it awaits. */
|
|
178
|
+
const together = async (request, params) => {
|
|
179
|
+
const opened = raw(`BEGIN${reader ? ' READ ONLY' : ''}; ${settings}`), answer = raw(request, params), ended = raw('COMMIT');
|
|
180
|
+
for (const pending of [opened, answer, ended])
|
|
181
|
+
void pending.catch(() => { });
|
|
182
|
+
try {
|
|
183
|
+
await opened;
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
await answer.catch(() => { });
|
|
187
|
+
await ended.catch(() => raw('ROLLBACK').catch(() => { }));
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
let result;
|
|
191
|
+
try {
|
|
192
|
+
result = await answer;
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
await ended.catch(() => raw('ROLLBACK').catch(() => { }));
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
await ended;
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
await raw('ROLLBACK').catch(() => { });
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
};
|
|
207
|
+
const alone = async (request, params) => {
|
|
208
|
+
if (options.pipelines && !options.untrusted)
|
|
209
|
+
return together(request, params);
|
|
210
|
+
try {
|
|
211
|
+
await raw(`BEGIN${reader ? ' READ ONLY' : ''}; ${settings}${options.untrusted ? `; SAVEPOINT ${MARK}` : ''}`);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
await raw('ROLLBACK').catch(() => { });
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
let result;
|
|
218
|
+
try {
|
|
219
|
+
result = await raw(request, params);
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
await raw(options.untrusted ? `ROLLBACK TO SAVEPOINT ${MARK}; ${RESET}; ROLLBACK` : 'ROLLBACK').catch(() => raw('ROLLBACK').catch(() => { }));
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
await raw(options.untrusted ? `${RESET}; COMMIT` : 'COMMIT');
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
await raw('ROLLBACK').catch(() => { });
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
return result;
|
|
233
|
+
};
|
|
234
|
+
const query = (request, params) => {
|
|
235
|
+
if (closed)
|
|
236
|
+
return Promise.reject(closed);
|
|
237
|
+
const text = typeof request === 'string'
|
|
238
|
+
? request
|
|
239
|
+
: request && typeof request === 'object' && typeof request.text === 'string'
|
|
240
|
+
? request.text
|
|
241
|
+
: undefined;
|
|
242
|
+
// Nothing to read an edge from: the driver says what is wrong with it.
|
|
243
|
+
if (text === undefined)
|
|
244
|
+
return raw(request, params);
|
|
245
|
+
const statement = statementHead(text);
|
|
246
|
+
if (BEGINS.test(statement))
|
|
247
|
+
return open ? raw(request, params) : begin(text, request, params);
|
|
248
|
+
if (ENDS.test(statement))
|
|
249
|
+
return open ? end(request, params) : raw(request, params);
|
|
250
|
+
if (EDGES.test(statement))
|
|
251
|
+
return raw(request, params);
|
|
252
|
+
return open ? within(request, params) : alone(request, params);
|
|
253
|
+
};
|
|
254
|
+
const settle = async () => {
|
|
255
|
+
if (!open)
|
|
256
|
+
return;
|
|
257
|
+
open = false;
|
|
258
|
+
await raw(options.untrusted ? `${RESET}; ROLLBACK` : 'ROLLBACK').catch(() => raw('ROLLBACK'));
|
|
259
|
+
};
|
|
260
|
+
return {
|
|
261
|
+
query: query,
|
|
262
|
+
settle,
|
|
263
|
+
close: (reason) => {
|
|
264
|
+
closed ??= reason;
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Private native read-snapshot shape owner. Locks and native catalog identity
|
|
2
|
+
* are evidence of source shape, never caller authorization or an ACL fence.
|
|
3
|
+
* Only PostgresAdapter supplies the snapshot runner in production. */
|
|
4
|
+
import { type SqlFragment, type QueryResult } from './adapter.js';
|
|
5
|
+
import type { PostgresReadSnapshot } from './postgres.js';
|
|
6
|
+
import type { DatabaseSchema } from '../shared/schema.js';
|
|
7
|
+
export interface PostgresReadDependency {
|
|
8
|
+
readonly schema: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PinnedPostgresRead {
|
|
12
|
+
readonly schema: DatabaseSchema;
|
|
13
|
+
assertCurrent(): void;
|
|
14
|
+
execute(statement: SqlFragment, hint?: {
|
|
15
|
+
binary?: true;
|
|
16
|
+
}): Promise<QueryResult>;
|
|
17
|
+
}
|
|
18
|
+
export interface PinnedPostgresReadOwner {
|
|
19
|
+
readonly schema: DatabaseSchema;
|
|
20
|
+
withSnapshot<T>(callback: (read: PinnedPostgresRead) => Promise<T>): Promise<T>;
|
|
21
|
+
/** Whether a snapshot has seen these tables differ from the baseline: then
|
|
22
|
+
* no later one will match, and an owner holding several may retire them all. */
|
|
23
|
+
drifted(): boolean;
|
|
24
|
+
retire(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
type Runner = <T>(run: (snapshot: PostgresReadSnapshot) => Promise<T>) => Promise<T>;
|
|
27
|
+
/** Adapter-only construction seam. Baseline is captured from that adapter's
|
|
28
|
+
* native transaction, not accepted as a caller-authored schema/hash. Callback
|
|
29
|
+
* code is trusted and must not await retirement of its own active operation. */
|
|
30
|
+
export declare function createPinnedPostgresReadOwner(run: Runner, raw: readonly PostgresReadDependency[], assertCurrent: () => void): Promise<PinnedPostgresReadOwner>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/** Private native read-snapshot shape owner. Locks and native catalog identity
|
|
2
|
+
* are evidence of source shape, never caller authorization or an ACL fence.
|
|
3
|
+
* Only PostgresAdapter supplies the snapshot runner in production. */
|
|
4
|
+
import { POSTGRES_STYLE, Refusal, TransactionOperations } from './adapter.js';
|
|
5
|
+
import { snapshot } from './commands/canonicalJson.js';
|
|
6
|
+
import { assertScopeCatalog, captureScopeCatalog } from '../shared/scopeCatalog.js';
|
|
7
|
+
import { isProxy } from 'node:util/types';
|
|
8
|
+
const refuse = () => {
|
|
9
|
+
throw new Refusal('The pinned PostgreSQL read snapshot is unavailable.');
|
|
10
|
+
};
|
|
11
|
+
const order = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
12
|
+
const id = (value) => JSON.stringify([value.schema, value.name]);
|
|
13
|
+
function dependencies(raw) {
|
|
14
|
+
const value = snapshot(raw, 65536).value;
|
|
15
|
+
if (!Array.isArray(value) || !value.length || value.length > 128)
|
|
16
|
+
return refuse();
|
|
17
|
+
const captured = value
|
|
18
|
+
.map((item) => {
|
|
19
|
+
if (!item || typeof item !== 'object' || Array.isArray(item) || Object.keys(item).sort().join(',') !== 'name,schema')
|
|
20
|
+
return refuse();
|
|
21
|
+
const valid = (text) => typeof text === 'string' && text.length > 0 && Buffer.byteLength(text) <= 63 && !/[\p{Cc}\p{Cs}]/u.test(text);
|
|
22
|
+
if (!valid(item.schema) || !valid(item.name) || item.schema === 'information_schema' || item.schema.startsWith('pg_'))
|
|
23
|
+
return refuse();
|
|
24
|
+
return Object.freeze({ schema: item.schema, name: item.name });
|
|
25
|
+
})
|
|
26
|
+
.sort((a, b) => order(a.schema, b.schema) || order(a.name, b.name));
|
|
27
|
+
if (new Set(captured.map(id)).size !== captured.length)
|
|
28
|
+
return refuse();
|
|
29
|
+
return Object.freeze(captured);
|
|
30
|
+
}
|
|
31
|
+
const FACTS = `SELECT n.nspname AS schema, c.relname AS name, c.oid::text AS oid,
|
|
32
|
+
c.relkind::text AS kind, c.relpersistence::text AS persistence,
|
|
33
|
+
c.relispartition AS partition, c.relrowsecurity AS rls, c.relforcerowsecurity AS force,
|
|
34
|
+
EXISTS (SELECT 1 FROM pg_catalog.pg_inherits i WHERE i.inhrelid=c.oid OR i.inhparent=c.oid) AS inheritance,
|
|
35
|
+
EXISTS (SELECT 1 FROM pg_catalog.pg_rewrite r WHERE r.ev_class=c.oid) AS rules,
|
|
36
|
+
EXISTS (SELECT 1 FROM pg_catalog.pg_policy p WHERE p.polrelid=c.oid) AS policies,
|
|
37
|
+
COALESCE((SELECT json_agg(json_build_object('name', a.attname, 'number', a.attnum,
|
|
38
|
+
'typeOid', a.atttypid::text, 'type', t.typname, 'typeSchema', tn.nspname, 'typeKind', t.typtype,
|
|
39
|
+
'modifier', a.atttypmod, 'notnull', a.attnotnull, 'dropped', a.attisdropped,
|
|
40
|
+
'generated', a.attgenerated, 'identity', a.attidentity, 'collation', a.attcollation::text) ORDER BY a.attnum)
|
|
41
|
+
FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t ON t.oid=a.atttypid
|
|
42
|
+
LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid=t.typnamespace
|
|
43
|
+
WHERE a.attrelid=c.oid AND a.attnum>0), '[]'::json) AS columns,
|
|
44
|
+
COALESCE((SELECT json_agg(json_build_object('oid', p.oid::text, 'index', p.conindid::text,
|
|
45
|
+
'keys', p.conkey, 'valid', i.indisvalid, 'ready', i.indisready, 'deferrable', p.condeferrable))
|
|
46
|
+
FROM pg_catalog.pg_constraint p JOIN pg_catalog.pg_index i ON i.indexrelid=p.conindid
|
|
47
|
+
WHERE p.conrelid=c.oid AND p.contype='p'), '[]'::json) AS primary
|
|
48
|
+
FROM unnest($1::text[], $2::text[]) AS w(schema, name)
|
|
49
|
+
JOIN pg_catalog.pg_namespace n ON n.nspname=w.schema
|
|
50
|
+
JOIN pg_catalog.pg_class c ON c.relnamespace=n.oid AND c.relname=w.name
|
|
51
|
+
ORDER BY n.nspname COLLATE "C", c.relname COLLATE "C"`;
|
|
52
|
+
const record = (value) => value && typeof value === 'object' && !Array.isArray(value) ? value : refuse();
|
|
53
|
+
const oid = (value) => typeof value === 'string' && /^[1-9][0-9]{0,9}(?![\s\S])/.test(value) && BigInt(value) <= 4294967295n;
|
|
54
|
+
const TYPES = new Set(['int2', 'int4', 'int8', 'float4', 'float8', 'text', 'varchar', 'bpchar', 'bool', 'date']);
|
|
55
|
+
async function capture(lease, wanted, current) {
|
|
56
|
+
if (typeof lease.assertCurrent !== 'function')
|
|
57
|
+
return refuse();
|
|
58
|
+
const ownerCurrent = current;
|
|
59
|
+
current = () => {
|
|
60
|
+
ownerCurrent();
|
|
61
|
+
lease.assertCurrent();
|
|
62
|
+
};
|
|
63
|
+
current();
|
|
64
|
+
await lease.client.query(`LOCK TABLE ${wanted.map((at) => `ONLY ${POSTGRES_STYLE.quote(at.schema)}.${POSTGRES_STYLE.quote(at.name)}`).join(', ')} IN ACCESS SHARE MODE`);
|
|
65
|
+
current();
|
|
66
|
+
const rows = snapshot((await lease.client.query(FACTS, [wanted.map((at) => at.schema), wanted.map((at) => at.name)])).rows, 1048576).value;
|
|
67
|
+
current();
|
|
68
|
+
if (!Array.isArray(rows) || rows.length !== wanted.length)
|
|
69
|
+
return refuse();
|
|
70
|
+
const seen = new Set();
|
|
71
|
+
for (const value of rows) {
|
|
72
|
+
const row = record(value), key = JSON.stringify([row.schema, row.name]);
|
|
73
|
+
if (!wanted.some((at) => id(at) === key) ||
|
|
74
|
+
seen.has(key) ||
|
|
75
|
+
!oid(row.oid) ||
|
|
76
|
+
row.kind !== 'r' ||
|
|
77
|
+
row.persistence !== 'p' ||
|
|
78
|
+
['partition', 'rls', 'force', 'inheritance', 'rules', 'policies'].some((field) => row[field] !== false) ||
|
|
79
|
+
!Array.isArray(row.columns) ||
|
|
80
|
+
!row.columns.length ||
|
|
81
|
+
!Array.isArray(row.primary) ||
|
|
82
|
+
row.primary.length !== 1)
|
|
83
|
+
return refuse();
|
|
84
|
+
seen.add(key);
|
|
85
|
+
const numbers = new Set(), names = new Set();
|
|
86
|
+
for (const value of row.columns) {
|
|
87
|
+
const column = record(value);
|
|
88
|
+
if (typeof column.name !== 'string' ||
|
|
89
|
+
!column.name ||
|
|
90
|
+
names.has(column.name) ||
|
|
91
|
+
!Number.isSafeInteger(column.number) ||
|
|
92
|
+
Number(column.number) < 1 ||
|
|
93
|
+
numbers.has(Number(column.number)) ||
|
|
94
|
+
!oid(column.typeOid) ||
|
|
95
|
+
column.typeSchema !== 'pg_catalog' ||
|
|
96
|
+
column.typeKind !== 'b' ||
|
|
97
|
+
typeof column.type !== 'string' ||
|
|
98
|
+
!TYPES.has(column.type) ||
|
|
99
|
+
column.dropped !== false ||
|
|
100
|
+
// A generated column ('s' stored, 'v' virtual) is read like any other: the database computes it from the row.
|
|
101
|
+
!['', 's', 'v'].includes(String(column.generated)) ||
|
|
102
|
+
!['', 'a', 'd'].includes(String(column.identity)) ||
|
|
103
|
+
!Number.isSafeInteger(column.modifier) ||
|
|
104
|
+
typeof column.notnull !== 'boolean' ||
|
|
105
|
+
typeof column.collation !== 'string' ||
|
|
106
|
+
!/^(?:0|[1-9][0-9]{0,9})(?![\s\S])/.test(column.collation))
|
|
107
|
+
return refuse();
|
|
108
|
+
names.add(column.name);
|
|
109
|
+
numbers.add(Number(column.number));
|
|
110
|
+
}
|
|
111
|
+
const columns = row.columns;
|
|
112
|
+
const primary = record(row.primary[0]);
|
|
113
|
+
if (!oid(primary.oid) ||
|
|
114
|
+
!oid(primary.index) ||
|
|
115
|
+
primary.valid !== true ||
|
|
116
|
+
primary.ready !== true ||
|
|
117
|
+
primary.deferrable !== false ||
|
|
118
|
+
!Array.isArray(primary.keys) ||
|
|
119
|
+
!primary.keys.length ||
|
|
120
|
+
new Set(primary.keys).size !== primary.keys.length ||
|
|
121
|
+
primary.keys.some((key) => typeof key !== 'number' ||
|
|
122
|
+
!numbers.has(key) ||
|
|
123
|
+
!columns.some((value) => record(value).number === key && record(value).notnull === true)))
|
|
124
|
+
return refuse();
|
|
125
|
+
}
|
|
126
|
+
const described = await lease.describe();
|
|
127
|
+
current();
|
|
128
|
+
const selected = described.tables.filter((table) => wanted.some((at) => at.schema === table.schema && at.name === table.name));
|
|
129
|
+
if (described.dialect !== 'postgres' || selected.length !== wanted.length)
|
|
130
|
+
return refuse();
|
|
131
|
+
const selectedIds = new Set(selected.map((table) => table.id));
|
|
132
|
+
if (described.foreignKeys.some((fk) => selectedIds.has(fk.from.table) && !selectedIds.has(fk.to.table)))
|
|
133
|
+
return refuse();
|
|
134
|
+
const schema = captureScopeCatalog({
|
|
135
|
+
...described,
|
|
136
|
+
label: 'Pinned PostgreSQL read',
|
|
137
|
+
readAt: '',
|
|
138
|
+
tables: selected,
|
|
139
|
+
foreignKeys: described.foreignKeys.filter((fk) => selectedIds.has(fk.from.table) && selectedIds.has(fk.to.table)),
|
|
140
|
+
});
|
|
141
|
+
return { facts: snapshot(rows, 1048576).json, schema };
|
|
142
|
+
}
|
|
143
|
+
/** Adapter-only construction seam. Baseline is captured from that adapter's
|
|
144
|
+
* native transaction, not accepted as a caller-authored schema/hash. Callback
|
|
145
|
+
* code is trusted and must not await retirement of its own active operation. */
|
|
146
|
+
export async function createPinnedPostgresReadOwner(run, raw, assertCurrent) {
|
|
147
|
+
if (typeof run !== 'function' || isProxy(run) || typeof assertCurrent !== 'function' || isProxy(assertCurrent))
|
|
148
|
+
return refuse();
|
|
149
|
+
const wanted = dependencies(raw), pending = new Set();
|
|
150
|
+
let retired = false, drift = false;
|
|
151
|
+
const current = () => {
|
|
152
|
+
if (retired)
|
|
153
|
+
return refuse();
|
|
154
|
+
assertCurrent();
|
|
155
|
+
if (retired)
|
|
156
|
+
return refuse();
|
|
157
|
+
};
|
|
158
|
+
current();
|
|
159
|
+
const baseline = await run((lease) => capture(lease, wanted, current));
|
|
160
|
+
current();
|
|
161
|
+
return Object.freeze({
|
|
162
|
+
schema: baseline.schema,
|
|
163
|
+
withSnapshot: (callback) => {
|
|
164
|
+
const work = Promise.resolve().then(async () => {
|
|
165
|
+
current();
|
|
166
|
+
if (typeof callback !== 'function' || isProxy(callback))
|
|
167
|
+
return refuse();
|
|
168
|
+
const result = await run(async (lease) => {
|
|
169
|
+
current();
|
|
170
|
+
const observed = await capture(lease, wanted, current);
|
|
171
|
+
current();
|
|
172
|
+
try {
|
|
173
|
+
if (observed.facts !== baseline.facts)
|
|
174
|
+
return refuse();
|
|
175
|
+
assertScopeCatalog(baseline.schema, observed.schema);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
drift = true;
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
let active = true;
|
|
182
|
+
const operations = new TransactionOperations();
|
|
183
|
+
const held = () => {
|
|
184
|
+
current();
|
|
185
|
+
if (!active || !lease.assertCurrent)
|
|
186
|
+
return refuse();
|
|
187
|
+
lease.assertCurrent();
|
|
188
|
+
};
|
|
189
|
+
try {
|
|
190
|
+
const output = await callback(Object.freeze({
|
|
191
|
+
schema: baseline.schema,
|
|
192
|
+
assertCurrent: held,
|
|
193
|
+
execute: (statement, hint) => {
|
|
194
|
+
const captured = snapshot(statement, 1048576).value;
|
|
195
|
+
return operations.run(async () => {
|
|
196
|
+
held();
|
|
197
|
+
const result = await lease.execute(captured, hint?.binary ? { binary: true } : undefined);
|
|
198
|
+
held();
|
|
199
|
+
return result;
|
|
200
|
+
});
|
|
201
|
+
},
|
|
202
|
+
}));
|
|
203
|
+
held();
|
|
204
|
+
await operations.finish();
|
|
205
|
+
held();
|
|
206
|
+
return output;
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
active = false;
|
|
210
|
+
await operations.finish();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
current();
|
|
214
|
+
return result;
|
|
215
|
+
});
|
|
216
|
+
pending.add(work);
|
|
217
|
+
void work.then(() => pending.delete(work), () => pending.delete(work));
|
|
218
|
+
return work;
|
|
219
|
+
},
|
|
220
|
+
drifted: () => drift,
|
|
221
|
+
retire: async () => {
|
|
222
|
+
retired = true;
|
|
223
|
+
await Promise.allSettled([...pending]);
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The read snapshot a trusted owner is lent (postgres.ts `readSnapshot`): one `REPEATABLE READ, READ ONLY` transaction
|
|
3
|
+
* on a leased reader, with its prologue sent in the BEGIN's own message, an `ahead` form whose first statements leave
|
|
4
|
+
* behind the BEGIN, a `whole` form that is a single round trip, and the `finish` that commits it and reads a fence in a
|
|
5
|
+
* fresh snapshot. Apart from the adapter because it needs nothing of it but the reader pool and its introspection.
|
|
6
|
+
*/
|
|
7
|
+
import { type QueryResult, type SqlFragment } from './adapter.js';
|
|
8
|
+
import { type PgConnectionManager, type PgQuery, type PgResult } from './postgresPool.js';
|
|
9
|
+
import type { DatabaseSchema } from '../shared/schema.js';
|
|
10
|
+
/** What a trusted read-snapshot owner is lent: the leased reader inside its
|
|
11
|
+
* transaction, the adapter's own introspection on it, and scoped-read
|
|
12
|
+
* execution on it with the adapter's value mapping. Never retained. */
|
|
13
|
+
export interface PostgresReadSnapshot {
|
|
14
|
+
readonly client: PgQuery;
|
|
15
|
+
/** The results of the owner's prologue, in order, when it passed one. */
|
|
16
|
+
readonly prologue?: readonly PgResult<Record<string, unknown>>[];
|
|
17
|
+
/**
|
|
18
|
+
* For an owner that asked `ahead`: the same results, still on their way.
|
|
19
|
+
* The owner is handed the snapshot as soon as its BEGIN is sent, so what it
|
|
20
|
+
* asks next leaves right behind it on a reader that pipelines; it must
|
|
21
|
+
* await this, and stand on what it says, before it relies on anything it
|
|
22
|
+
* read. A BEGIN that failed rejects it, and fails every statement behind.
|
|
23
|
+
*/
|
|
24
|
+
readonly opened?: Promise<readonly PgResult<Record<string, unknown>>[]>;
|
|
25
|
+
/** Present only for observed checkouts; native local lifetime, not a grant. */
|
|
26
|
+
assertCurrent?(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Commit this snapshot and read `next` — parameter-free statements — in a
|
|
29
|
+
* fresh snapshot of its own, committed too, all in the one message: the
|
|
30
|
+
* COMMIT and a question that must see what committed after this snapshot
|
|
31
|
+
* began (a release fence) in one round trip where they were three. Its
|
|
32
|
+
* answers are `next`'s, in order. Nothing is asked on the snapshot once it
|
|
33
|
+
* is called. Absent from a whole snapshot and an observed checkout.
|
|
34
|
+
*/
|
|
35
|
+
finish?(next: string): Promise<readonly PgResult<Record<string, unknown>>[]>;
|
|
36
|
+
describe(): Promise<DatabaseSchema>;
|
|
37
|
+
/** A file's read keeps its bytes (`hint.binary`); every other read gets the `<n bytes>` label. */
|
|
38
|
+
execute(statement: SqlFragment, hint?: {
|
|
39
|
+
binary?: true;
|
|
40
|
+
}): Promise<QueryResult>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Run `run` in a snapshot on `connections`' reader. `describe` is the adapter's own introspection on the leased
|
|
44
|
+
* client; `onCheckout` says it is a pinned owner's, whose introspection is the class's and not an instance's.
|
|
45
|
+
*/
|
|
46
|
+
export declare function readSnapshotOn<T>(connections: PgConnectionManager, describe: (db: PgQuery, checkout: boolean) => Promise<DatabaseSchema>, run: (snapshot: PostgresReadSnapshot) => Promise<T>, observeCheckout: boolean, prologue: string | undefined, ahead: boolean, whole: boolean): Promise<T>;
|