@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,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQLite reads that could hold the whole server, and where they run.
|
|
3
|
+
*
|
|
4
|
+
* node:sqlite runs a statement on the thread that asked, to its end: a
|
|
5
|
+
* filtered list, a count or a breakdown over a million rows held every other
|
|
6
|
+
* request — a page of another table, the runtime check, a sign-in — for as
|
|
7
|
+
* long as it took (sqliteStatementProcess.ts says why a thread cannot help).
|
|
8
|
+
* Such a read runs in the statement process instead, on a read-only handle
|
|
9
|
+
* of its own on the same file, and the server goes on answering; its cap
|
|
10
|
+
* (30 seconds) stops one that would never finish.
|
|
11
|
+
*
|
|
12
|
+
* Which reads: those over a large relation that cannot stop after the page —
|
|
13
|
+
* an aggregate, a filter over a scan (one that matches rarely reads the whole
|
|
14
|
+
* table to fill twenty rows), or a plan that sorts everything it found
|
|
15
|
+
* (`USE TEMP B-TREE FOR ORDER BY`). A filter an index searches — an equality,
|
|
16
|
+
* or a keyset page's range (keysetPage.ts) — starts where its rows are and
|
|
17
|
+
* stays. A large relation is a table of
|
|
18
|
+
* PROCESS_ROWS or more, one whose size is unknown (a file past a quarter
|
|
19
|
+
* gigabyte that ANALYZE never read), or a SQL view, which may cost anything.
|
|
20
|
+
* An unfiltered page walked in an index's order stops at its LIMIT and stays
|
|
21
|
+
* in process: the child costs about 27 ms to start, which is more than that
|
|
22
|
+
* page ever took. An in-memory database has no second handle and never moves.
|
|
23
|
+
*/
|
|
24
|
+
import type { DatabaseSync, SQLInputValue } from 'node:sqlite';
|
|
25
|
+
import type { DatabaseSchema } from '../shared/schema.js';
|
|
26
|
+
/** Past this many rows a scan of a table is worth a process start: about 50 ms of filtering on one thread. */
|
|
27
|
+
export declare const PROCESS_ROWS = 250000;
|
|
28
|
+
/** The quoted names of the relations a read of which may stall: large, of unknown size, or a view. */
|
|
29
|
+
export declare function heavyRelations(schema: DatabaseSchema | null): string[];
|
|
30
|
+
/** Whether this statement may hold the thread: it reads a heavy relation and cannot stop at its page. */
|
|
31
|
+
export declare function stalls(db: DatabaseSync, text: string, params: readonly SQLInputValue[], relations: readonly string[], aggregate: boolean): boolean;
|
|
32
|
+
/** Run one compiled read in the statement process: its rows as objects, raw, as the in-process driver reads them. */
|
|
33
|
+
export declare function readInProcess(file: string, text: string, params: readonly SQLInputValue[]): Promise<Array<Record<string, unknown>>>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ANSI_STYLE, MAX_LIMIT } from './adapter.js';
|
|
2
|
+
import { scaleRows, scalesOf } from './sqliteDecimals.js';
|
|
3
|
+
import { runInStatementProcess } from './sqliteStatementProcess.js';
|
|
4
|
+
import { cancellation, STATEMENT_TIMEOUT_MS } from './statementControl.js';
|
|
5
|
+
/** Past this many rows a scan of a table is worth a process start: about 50 ms of filtering on one thread. */
|
|
6
|
+
export const PROCESS_ROWS = 250_000;
|
|
7
|
+
const heavy = new WeakMap();
|
|
8
|
+
/** The quoted names of the relations a read of which may stall: large, of unknown size, or a view. */
|
|
9
|
+
export function heavyRelations(schema) {
|
|
10
|
+
if (!schema)
|
|
11
|
+
return [];
|
|
12
|
+
let names = heavy.get(schema);
|
|
13
|
+
if (!names) {
|
|
14
|
+
names = schema.tables
|
|
15
|
+
.filter((table) => table.isView || table.approxRows === undefined || table.approxRows >= PROCESS_ROWS)
|
|
16
|
+
.map((table) => ANSI_STYLE.quote(table.name));
|
|
17
|
+
heavy.set(schema, names);
|
|
18
|
+
}
|
|
19
|
+
return names;
|
|
20
|
+
}
|
|
21
|
+
/** Whether this statement may hold the thread: it reads a heavy relation and cannot stop at its page. */
|
|
22
|
+
export function stalls(db, text, params, relations, aggregate) {
|
|
23
|
+
if (!relations.some((name) => text.includes(name)))
|
|
24
|
+
return false;
|
|
25
|
+
if (aggregate)
|
|
26
|
+
return true;
|
|
27
|
+
try {
|
|
28
|
+
const plan = db.prepare(`EXPLAIN QUERY PLAN ${text}`).all(...params).map((row) => row.detail);
|
|
29
|
+
/* A sort of everything found; a sort of ties within an index's order
|
|
30
|
+
("LAST TERM", "RIGHT PART") only reads as far as the page. */
|
|
31
|
+
if (plan.some((detail) => /TEMP B-TREE FOR (ORDER BY|GROUP BY|DISTINCT)/.test(detail)))
|
|
32
|
+
return true;
|
|
33
|
+
/* A filter over a scan may read the whole table to fill its page. An
|
|
34
|
+
index search (an equality, or a range such as a keyset page's bound)
|
|
35
|
+
starts where the rows are and reads in the list's order. */
|
|
36
|
+
return /\bWHERE\b/i.test(text) && plan.some((detail) => /^SCAN (?!CONSTANT ROW|\()/.test(detail));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* A statement that cannot be planned will not prepare either; it fails
|
|
40
|
+
in process with the engine's own words. */
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Run one compiled read in the statement process: its rows as objects, raw, as the in-process driver reads them. */
|
|
45
|
+
export async function readInProcess(file, text, params) {
|
|
46
|
+
const signal = cancellation() ?? new AbortController().signal;
|
|
47
|
+
const answer = await runInStatementProcess({ file, text, fallback: text, bounded: false, limit: MAX_LIMIT + 1, refuseReserved: false, params: [...params] }, STATEMENT_TIMEOUT_MS, signal);
|
|
48
|
+
return scaleRows(answer.rows.map((row) => Object.fromEntries(answer.columns.map((column, at) => [column, row[at]]))), answer.columns, scalesOf(answer.types.map((type) => ({ type }))));
|
|
49
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A decimal column keeps its scale, as it does on Postgres.
|
|
3
|
+
*
|
|
4
|
+
* SQLite stores `numeric(12,2)` 38 as the integer 38 and 19.9 as the float
|
|
5
|
+
* 19.9, so the scale the column was declared with is gone by the time a row is
|
|
6
|
+
* read. `pg` returns the same column as the text "38.00" and "19.90", and the
|
|
7
|
+
* money display depends on that text to show cents. This reads the declared
|
|
8
|
+
* type the driver reports for each result column (once per statement, not per
|
|
9
|
+
* cell) and says a number the way Postgres says a numeric. A column with no
|
|
10
|
+
* declared scale, an integer column and an expression (no declared type) are
|
|
11
|
+
* left exactly as they were.
|
|
12
|
+
*/
|
|
13
|
+
/** The scale a declared type asks for, when it is a DECIMAL/NUMERIC with one above zero. */
|
|
14
|
+
export declare function declaredScale(type: string | null | undefined): number;
|
|
15
|
+
/** Per output position, the scale to apply, or undefined when no column needs one. */
|
|
16
|
+
export declare function scalesOf(columns: ReadonlyArray<{
|
|
17
|
+
type?: string | null;
|
|
18
|
+
}>): number[] | undefined;
|
|
19
|
+
/** Rows read as objects: apply the scales of the columns named by `names` (positional, as `scalesOf`). */
|
|
20
|
+
export declare function scaleRows(rows: Array<Record<string, unknown>>, names: ReadonlyArray<string | null | undefined>, scales: number[] | undefined): Array<Record<string, unknown>>;
|
|
21
|
+
/** Rows read as arrays. */
|
|
22
|
+
export declare function scaleArrays(rows: unknown[][], scales: number[] | undefined): unknown[][];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A decimal column keeps its scale, as it does on Postgres.
|
|
3
|
+
*
|
|
4
|
+
* SQLite stores `numeric(12,2)` 38 as the integer 38 and 19.9 as the float
|
|
5
|
+
* 19.9, so the scale the column was declared with is gone by the time a row is
|
|
6
|
+
* read. `pg` returns the same column as the text "38.00" and "19.90", and the
|
|
7
|
+
* money display depends on that text to show cents. This reads the declared
|
|
8
|
+
* type the driver reports for each result column (once per statement, not per
|
|
9
|
+
* cell) and says a number the way Postgres says a numeric. A column with no
|
|
10
|
+
* declared scale, an integer column and an expression (no declared type) are
|
|
11
|
+
* left exactly as they were.
|
|
12
|
+
*/
|
|
13
|
+
const DECLARED_SCALE = /^\s*(?:decimal|numeric)\s*\(\s*\d+\s*,\s*(\d+)\s*\)\s*$/i;
|
|
14
|
+
/** The scale a declared type asks for, when it is a DECIMAL/NUMERIC with one above zero. */
|
|
15
|
+
export function declaredScale(type) {
|
|
16
|
+
if (!type)
|
|
17
|
+
return 0;
|
|
18
|
+
const scale = Number(DECLARED_SCALE.exec(type)?.[1] ?? 0);
|
|
19
|
+
return scale > 0 ? scale : 0;
|
|
20
|
+
}
|
|
21
|
+
/** Per output position, the scale to apply, or undefined when no column needs one. */
|
|
22
|
+
export function scalesOf(columns) {
|
|
23
|
+
let scales;
|
|
24
|
+
columns.forEach((column, at) => {
|
|
25
|
+
const scale = declaredScale(column.type);
|
|
26
|
+
if (scale > 0)
|
|
27
|
+
(scales ??= Array.from({ length: columns.length }, () => 0))[at] = scale;
|
|
28
|
+
});
|
|
29
|
+
return scales;
|
|
30
|
+
}
|
|
31
|
+
/** One stored value, said with `scale` places. Text, null and bytes pass through. */
|
|
32
|
+
function withScale(value, scale) {
|
|
33
|
+
if (typeof value === 'bigint')
|
|
34
|
+
return `${value}.${'0'.repeat(scale)}`;
|
|
35
|
+
if (typeof value === 'number' && Number.isFinite(value) && Math.abs(value) < 1e15)
|
|
36
|
+
return value.toFixed(scale);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
/** Rows read as objects: apply the scales of the columns named by `names` (positional, as `scalesOf`). */
|
|
40
|
+
export function scaleRows(rows, names, scales) {
|
|
41
|
+
if (!scales)
|
|
42
|
+
return rows;
|
|
43
|
+
const apply = names.flatMap((name, at) => (name != null && scales[at] > 0 ? [[name, scales[at]]] : []));
|
|
44
|
+
for (const row of rows)
|
|
45
|
+
for (const [name, scale] of apply)
|
|
46
|
+
if (row && name in row)
|
|
47
|
+
row[name] = withScale(row[name], scale);
|
|
48
|
+
return rows;
|
|
49
|
+
}
|
|
50
|
+
/** Rows read as arrays. */
|
|
51
|
+
export function scaleArrays(rows, scales) {
|
|
52
|
+
if (!scales)
|
|
53
|
+
return rows;
|
|
54
|
+
for (const row of rows)
|
|
55
|
+
scales.forEach((scale, at) => scale > 0 && at < row.length && (row[at] = withScale(row[at], scale)));
|
|
56
|
+
return rows;
|
|
57
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { DatabaseSync, StatementSync } from 'node:sqlite';
|
|
2
|
+
/**
|
|
3
|
+
* Wait rather than fail when someone else holds the file.
|
|
4
|
+
*
|
|
5
|
+
* A SQLite database is usually a file another process is also using — the
|
|
6
|
+
* application whose data this is, a migration, a test — and one writer at a
|
|
7
|
+
* time is the whole locking model. Without a busy timeout the very next read
|
|
8
|
+
* during someone else's write comes back "database is locked", which reads
|
|
9
|
+
* as a broken tool rather than as a lock that would have cleared in
|
|
10
|
+
* milliseconds. Five seconds is long enough to outlast an ordinary write and
|
|
11
|
+
* short enough that a genuinely stuck writer still surfaces.
|
|
12
|
+
*/
|
|
13
|
+
export declare function waitForLocks(db: DatabaseSync): void;
|
|
14
|
+
export declare function assertIndependentWrite(): void;
|
|
15
|
+
export declare function writeToFile<T>(identity: string | symbol, work: () => Promise<T>): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Prepare with SQLite's authorizer listening: preparing names every table the
|
|
18
|
+
* statement reads — views expanded, CTEs and subqueries included — which is
|
|
19
|
+
* the engine's half of the reserved-relation guard (reservedSql.ts). A build
|
|
20
|
+
* without the authorizer keeps the lexical half alone.
|
|
21
|
+
*/
|
|
22
|
+
export declare function prepareGuarded(db: DatabaseSync, sql: string): StatementSync;
|
|
23
|
+
/**
|
|
24
|
+
* The epoch a SQLite write transaction trusts, in one statement: the schema
|
|
25
|
+
* (SCHEMA_EPOCH) and the handle's foreign-key switch, which the scope catalog
|
|
26
|
+
* requires. `journal` also asks whether a journal's meta row says its
|
|
27
|
+
* version (a data fact: deleting the row changes no schema); the store that
|
|
28
|
+
* rides in the transaction names its row, so the engine knows no store's
|
|
29
|
+
* tables. A statement that cannot run — no journal table — is a miss, and the
|
|
30
|
+
* full attestation then says why.
|
|
31
|
+
*/
|
|
32
|
+
export declare function transactionEpoch(db: DatabaseSync, journal?: {
|
|
33
|
+
table: string;
|
|
34
|
+
version: number;
|
|
35
|
+
}): {
|
|
36
|
+
epoch?: string;
|
|
37
|
+
journal: boolean;
|
|
38
|
+
};
|
|
39
|
+
/** The schema and whether a store's meta row says its version, in one statement; undefined when the store is not there. */
|
|
40
|
+
export declare function storeEpoch(db: DatabaseSync, meta: {
|
|
41
|
+
table: string;
|
|
42
|
+
version: number;
|
|
43
|
+
}): string | undefined;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/** SQLite handle guards, per-file write coordination, and schema epoch probes. */
|
|
2
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
|
+
import { Refusal, Serial } from './adapter.js';
|
|
4
|
+
import { isRuntimeTable } from '../shared/runtimeTables.js';
|
|
5
|
+
import { reservedRefusal } from './reservedSql.js';
|
|
6
|
+
/**
|
|
7
|
+
* Wait rather than fail when someone else holds the file.
|
|
8
|
+
*
|
|
9
|
+
* A SQLite database is usually a file another process is also using — the
|
|
10
|
+
* application whose data this is, a migration, a test — and one writer at a
|
|
11
|
+
* time is the whole locking model. Without a busy timeout the very next read
|
|
12
|
+
* during someone else's write comes back "database is locked", which reads
|
|
13
|
+
* as a broken tool rather than as a lock that would have cleared in
|
|
14
|
+
* milliseconds. Five seconds is long enough to outlast an ordinary write and
|
|
15
|
+
* short enough that a genuinely stuck writer still surfaces.
|
|
16
|
+
*/
|
|
17
|
+
export function waitForLocks(db) {
|
|
18
|
+
try {
|
|
19
|
+
db.exec('PRAGMA busy_timeout = 5000');
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
/* An old build without the pragma is not a reason to refuse the
|
|
23
|
+
database; it is a reason to be no worse than before. */
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Native busy_timeout cannot yield to another owner in this JS isolate. While
|
|
27
|
+
// its transaction awaits verification, a second synchronous BEGIN would block
|
|
28
|
+
// the first owner's continuation until timeout. Serialize by actual file, not
|
|
29
|
+
// connection alias. SQLite still owns cross-process locking and atomicity.
|
|
30
|
+
const fileWrites = new Map();
|
|
31
|
+
const fileWriteContext = new AsyncLocalStorage();
|
|
32
|
+
export function assertIndependentWrite() {
|
|
33
|
+
for (let context = fileWriteContext.getStore(); context; context = context.parent) {
|
|
34
|
+
if (context.active) {
|
|
35
|
+
// Independent A->B and B->A transactions can deadlock even when neither
|
|
36
|
+
// repeats its own ancestry. Cross-source nesting is not a transaction
|
|
37
|
+
// capability: callbacks must use their supplied writer, not an adapter.
|
|
38
|
+
throw new Refusal('Use the active transaction writer; nested SQLite adapter writes are unavailable.');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function writeToFile(identity, work) {
|
|
43
|
+
let entry = fileWrites.get(identity);
|
|
44
|
+
if (!entry) {
|
|
45
|
+
entry = { queue: new Serial(), pending: 0 };
|
|
46
|
+
fileWrites.set(identity, entry);
|
|
47
|
+
}
|
|
48
|
+
const owned = entry;
|
|
49
|
+
owned.pending++;
|
|
50
|
+
return owned.queue
|
|
51
|
+
.run(async () => {
|
|
52
|
+
const context = { identity, active: true, parent: fileWriteContext.getStore() };
|
|
53
|
+
try {
|
|
54
|
+
return await fileWriteContext.run(context, work);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
context.active = false;
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
.finally(() => {
|
|
61
|
+
if (--owned.pending === 0)
|
|
62
|
+
fileWrites.delete(identity);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/* SQLite's authorizer action codes, from its C API: @types/node does not
|
|
66
|
+
declare node:sqlite's `constants` or `setAuthorizer` yet. */
|
|
67
|
+
const SQLITE_OK = 0;
|
|
68
|
+
const SQLITE_READ = 20;
|
|
69
|
+
/**
|
|
70
|
+
* Prepare with SQLite's authorizer listening: preparing names every table the
|
|
71
|
+
* statement reads — views expanded, CTEs and subqueries included — which is
|
|
72
|
+
* the engine's half of the reserved-relation guard (reservedSql.ts). A build
|
|
73
|
+
* without the authorizer keeps the lexical half alone.
|
|
74
|
+
*/
|
|
75
|
+
export function prepareGuarded(db, sql) {
|
|
76
|
+
const listen = db.setAuthorizer?.bind(db);
|
|
77
|
+
if (!listen)
|
|
78
|
+
return db.prepare(sql);
|
|
79
|
+
let reserved;
|
|
80
|
+
listen((action, table) => {
|
|
81
|
+
if (action === SQLITE_READ && typeof table === 'string' && isRuntimeTable(table))
|
|
82
|
+
reserved ??= table;
|
|
83
|
+
return SQLITE_OK;
|
|
84
|
+
});
|
|
85
|
+
let statement;
|
|
86
|
+
try {
|
|
87
|
+
statement = db.prepare(sql);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
listen(null);
|
|
91
|
+
}
|
|
92
|
+
if (reserved !== undefined)
|
|
93
|
+
throw reservedRefusal(reserved);
|
|
94
|
+
return statement;
|
|
95
|
+
}
|
|
96
|
+
/*
|
|
97
|
+
* The schema a connection sees, as one statement's columns: the main file's
|
|
98
|
+
* `schema_version`, which SQLite bumps on every schema change from any
|
|
99
|
+
* connection, and the connection's own TEMP schema, word for word. The TEMP
|
|
100
|
+
* schema has no version a query can read — `temp.pragma_schema_version`
|
|
101
|
+
* answers main's — so its definitions are the version: a TEMP table, view,
|
|
102
|
+
* trigger or index that shadows or hooks a reserved store changes them. It
|
|
103
|
+
* is empty on nearly every connection, so reading it costs nothing.
|
|
104
|
+
*/
|
|
105
|
+
const SCHEMA_EPOCH = `(SELECT schema_version FROM main.pragma_schema_version) AS main,
|
|
106
|
+
(SELECT coalesce(group_concat(type || ':' || name || ':' || tbl_name || ':' || coalesce(sql, ''), char(10)), '') FROM temp.sqlite_schema) AS temp`;
|
|
107
|
+
/**
|
|
108
|
+
* The epoch a SQLite write transaction trusts, in one statement: the schema
|
|
109
|
+
* (SCHEMA_EPOCH) and the handle's foreign-key switch, which the scope catalog
|
|
110
|
+
* requires. `journal` also asks whether a journal's meta row says its
|
|
111
|
+
* version (a data fact: deleting the row changes no schema); the store that
|
|
112
|
+
* rides in the transaction names its row, so the engine knows no store's
|
|
113
|
+
* tables. A statement that cannot run — no journal table — is a miss, and the
|
|
114
|
+
* full attestation then says why.
|
|
115
|
+
*/
|
|
116
|
+
export function transactionEpoch(db, journal) {
|
|
117
|
+
try {
|
|
118
|
+
const row = db
|
|
119
|
+
.prepare(`SELECT ${SCHEMA_EPOCH}, (SELECT foreign_keys FROM pragma_foreign_keys) AS fk${journal
|
|
120
|
+
? `, (SELECT count(*) FROM main."${journal.table}" WHERE singleton = 1 AND version = ${Number(journal.version)}) AS journal`
|
|
121
|
+
: ''}`)
|
|
122
|
+
.get();
|
|
123
|
+
if (!row || typeof row.main !== 'number' || typeof row.temp !== 'string')
|
|
124
|
+
return { journal: false };
|
|
125
|
+
return { epoch: `${row.main}.${row.fk}\n${row.temp}`, journal: row.journal === 1 };
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return { journal: false };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** The schema and whether a store's meta row says its version, in one statement; undefined when the store is not there. */
|
|
132
|
+
export function storeEpoch(db, meta) {
|
|
133
|
+
try {
|
|
134
|
+
const row = db
|
|
135
|
+
.prepare(`SELECT ${SCHEMA_EPOCH},
|
|
136
|
+
(SELECT count(*) FROM main."${meta.table}" WHERE singleton = 1 AND version = ?) AS meta`)
|
|
137
|
+
.get(meta.version);
|
|
138
|
+
return row && row.meta === 1 && typeof row.main === 'number' && typeof row.temp === 'string' ? `${row.main}\n${row.temp}` : undefined;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
interface ProcessStatement {
|
|
2
|
+
file: string;
|
|
3
|
+
/** The statement to prepare: the bounded wrap, when `bounded`. */
|
|
4
|
+
text: string;
|
|
5
|
+
/** What runs when the wrapped text does not prepare. */
|
|
6
|
+
fallback: string;
|
|
7
|
+
bounded: boolean;
|
|
8
|
+
limit: number;
|
|
9
|
+
/** Listen with SQLite's authorizer and answer `reserved` instead of rows. */
|
|
10
|
+
refuseReserved: boolean;
|
|
11
|
+
/** The statement's bound values, for one the adapter compiled (sqliteCostlyReads.ts). */
|
|
12
|
+
params?: unknown[];
|
|
13
|
+
}
|
|
14
|
+
interface ProcessAnswer {
|
|
15
|
+
columns: string[];
|
|
16
|
+
/** Each column's declared type, null for an expression (see sqliteDecimals.ts). */
|
|
17
|
+
types: Array<string | null>;
|
|
18
|
+
rows: unknown[][];
|
|
19
|
+
wrapped: boolean;
|
|
20
|
+
/** Set instead of rows when the statement reads one of tablewalk's own tables. */
|
|
21
|
+
reserved?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run one read in a child process, stopped when `capMs` runs out or when
|
|
25
|
+
* `signal` aborts. The engine's own errors come back as errors with the
|
|
26
|
+
* engine's words, as they would in-process.
|
|
27
|
+
*/
|
|
28
|
+
export declare function runInStatementProcess(job: ProcessStatement, capMs: number, signal: AbortSignal): Promise<ProcessAnswer>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A raw SQLite read, run in a process of its own so that it can be stopped.
|
|
3
|
+
*
|
|
4
|
+
* node:sqlite runs a statement synchronously on the thread that asked and
|
|
5
|
+
* offers neither an interrupt nor a progress handler, so an aggregate over a
|
|
6
|
+
* cross join holds the whole server until it finishes — its cancel included,
|
|
7
|
+
* which cannot even be read while the thread is busy. A worker thread would
|
|
8
|
+
* not help: terminating one waits for the native call to return. A process
|
|
9
|
+
* can be killed. So a read whose caller may stop it is handed to a child
|
|
10
|
+
* with its own read-only handle on the same file, and killed at its cap or
|
|
11
|
+
* on cancel. The cost is a process start per statement, which a statement
|
|
12
|
+
* someone typed can afford; the cap counts from when the child is ready.
|
|
13
|
+
*
|
|
14
|
+
* The child's program is plain JavaScript run with `node -e`, so it needs no
|
|
15
|
+
* build step and no loader, under tsx or from dist alike. It answers raw rows
|
|
16
|
+
* (BigInts, bytes) over an advanced-serialization channel, and the adapter
|
|
17
|
+
* makes them JSON-safe the way it does its own.
|
|
18
|
+
*/
|
|
19
|
+
import { spawn } from 'node:child_process';
|
|
20
|
+
import { RUNTIME_TABLE_PREFIXES } from '../shared/runtimeTables.js';
|
|
21
|
+
import { onCancel, StatementStopped } from './statementControl.js';
|
|
22
|
+
/* How long the child may take to start before the statement's own cap. */
|
|
23
|
+
const STARTUP_MS = 10_000;
|
|
24
|
+
/* The child. SQLITE_OK and SQLITE_READ are the C API's authorizer codes. The
|
|
25
|
+
rows stop one past the limit, so an unwrapped statement is not read whole
|
|
26
|
+
to learn that there was more. */
|
|
27
|
+
const CHILD = `
|
|
28
|
+
const { DatabaseSync } = process.getBuiltinModule('node:sqlite');
|
|
29
|
+
const SQLITE_OK = 0, SQLITE_READ = 20;
|
|
30
|
+
process.once('message', (job) => {
|
|
31
|
+
let answer;
|
|
32
|
+
try {
|
|
33
|
+
const db = new DatabaseSync(job.file, { readOnly: true });
|
|
34
|
+
try { db.exec('PRAGMA busy_timeout = 5000'); } catch {}
|
|
35
|
+
let reserved;
|
|
36
|
+
const prepare = (text) => {
|
|
37
|
+
if (!job.refuseReserved || typeof db.setAuthorizer !== 'function') return db.prepare(text);
|
|
38
|
+
db.setAuthorizer((action, table) => {
|
|
39
|
+
if (action === SQLITE_READ && typeof table === 'string' && job.prefixes.some((prefix) => table.toLowerCase().startsWith(prefix))) reserved ??= table;
|
|
40
|
+
return SQLITE_OK;
|
|
41
|
+
});
|
|
42
|
+
try { return db.prepare(text); } finally { db.setAuthorizer(null); }
|
|
43
|
+
};
|
|
44
|
+
let wrapped = job.bounded;
|
|
45
|
+
let statement;
|
|
46
|
+
try { statement = prepare(job.text); }
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (!job.bounded) throw error;
|
|
49
|
+
wrapped = false;
|
|
50
|
+
statement = prepare(job.fallback);
|
|
51
|
+
}
|
|
52
|
+
if (reserved !== undefined) answer = { reserved };
|
|
53
|
+
else {
|
|
54
|
+
statement.setReturnArrays(true);
|
|
55
|
+
statement.setReadBigInts(true);
|
|
56
|
+
const described = statement.columns();
|
|
57
|
+
const columns = described.map((c) => c.name ?? c.column ?? '?');
|
|
58
|
+
const types = described.map((c) => c.type ?? null);
|
|
59
|
+
const rows = [];
|
|
60
|
+
for (const row of statement.iterate(...(job.params || []))) {
|
|
61
|
+
rows.push(row);
|
|
62
|
+
if (rows.length > job.limit) break;
|
|
63
|
+
}
|
|
64
|
+
answer = { columns, types, rows, wrapped };
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
answer = { error: String((error && error.message) || error) };
|
|
68
|
+
}
|
|
69
|
+
process.send(answer, () => process.exit(0));
|
|
70
|
+
});
|
|
71
|
+
process.send({ ready: true });
|
|
72
|
+
`;
|
|
73
|
+
/**
|
|
74
|
+
* Run one read in a child process, stopped when `capMs` runs out or when
|
|
75
|
+
* `signal` aborts. The engine's own errors come back as errors with the
|
|
76
|
+
* engine's words, as they would in-process.
|
|
77
|
+
*/
|
|
78
|
+
export function runInStatementProcess(job, capMs, signal) {
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
if (signal.aborted) {
|
|
81
|
+
reject(new StatementStopped('cancelled'));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const child = spawn(process.execPath, ['-e', CHILD], {
|
|
85
|
+
stdio: ['ignore', 'ignore', 'pipe', 'ipc'],
|
|
86
|
+
serialization: 'advanced',
|
|
87
|
+
/* Electron's binary is Node only when told so; plain Node ignores it. */
|
|
88
|
+
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
|
|
89
|
+
windowsHide: true,
|
|
90
|
+
});
|
|
91
|
+
let stderr = '';
|
|
92
|
+
child.stderr?.on('data', (chunk) => {
|
|
93
|
+
stderr = (stderr + chunk.toString()).slice(-2_000);
|
|
94
|
+
});
|
|
95
|
+
let settled = false;
|
|
96
|
+
let timer;
|
|
97
|
+
let disarm = () => { };
|
|
98
|
+
const settle = (outcome) => {
|
|
99
|
+
if (settled)
|
|
100
|
+
return;
|
|
101
|
+
settled = true;
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
disarm();
|
|
104
|
+
outcome();
|
|
105
|
+
};
|
|
106
|
+
const stop = (reason) => settle(() => {
|
|
107
|
+
child.kill('SIGKILL');
|
|
108
|
+
reject(new StatementStopped(reason, capMs));
|
|
109
|
+
});
|
|
110
|
+
timer = setTimeout(() => stop('timeout'), STARTUP_MS + capMs);
|
|
111
|
+
disarm = onCancel(signal, () => stop('cancelled'));
|
|
112
|
+
child.on('message', (message) => {
|
|
113
|
+
if (message.ready) {
|
|
114
|
+
/* The cap is the statement's, not the process start's. */
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
timer = setTimeout(() => stop('timeout'), capMs);
|
|
117
|
+
child.send({ ...job, prefixes: RUNTIME_TABLE_PREFIXES });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
settle(() => {
|
|
121
|
+
if (message.error !== undefined)
|
|
122
|
+
reject(new Error(message.error));
|
|
123
|
+
else
|
|
124
|
+
resolve(message);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
child.once('error', (error) => settle(() => reject(error)));
|
|
128
|
+
child.once('exit', (code, killedBy) => settle(() => reject(new Error(`The SQLite statement process ended without an answer (${killedBy ?? `exit ${code}`}).` +
|
|
129
|
+
(stderr.trim() ? ` ${stderr.trim()}` : '')))));
|
|
130
|
+
});
|
|
131
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** The cap every read statement runs under unless a caller lowers it. */
|
|
2
|
+
export declare const STATEMENT_TIMEOUT_MS = 30000;
|
|
3
|
+
/**
|
|
4
|
+
* The cap for one statement: the caller's, when it gave one, held between
|
|
5
|
+
* the floor and the default. Politeness only lowers.
|
|
6
|
+
*/
|
|
7
|
+
export declare function statementCap(asked?: number): number;
|
|
8
|
+
/** A read stopped before it finished: the caller cancelled it, or its cap ran out. */
|
|
9
|
+
export declare class StatementStopped extends Error {
|
|
10
|
+
readonly reason: 'cancelled' | 'timeout';
|
|
11
|
+
readonly capMs?: number | undefined;
|
|
12
|
+
constructor(reason: 'cancelled' | 'timeout', capMs?: number | undefined, options?: ErrorOptions);
|
|
13
|
+
}
|
|
14
|
+
/** Run `work` so that every read it starts can be stopped by `signal`. */
|
|
15
|
+
export declare function withCancellation<T>(signal: AbortSignal, work: () => Promise<T>): Promise<T>;
|
|
16
|
+
/** Shared acquisition belongs to its host, not the first request that opens
|
|
17
|
+
* it. Explicitly detach inherited cancellation, including async descendants. */
|
|
18
|
+
export declare function withoutCancellation<T>(work: () => T): T;
|
|
19
|
+
/** The stop signal of the call this code runs for, when there is one. */
|
|
20
|
+
export declare function cancellation(): AbortSignal | undefined;
|
|
21
|
+
/** @throws StatementStopped when the call has been cancelled. */
|
|
22
|
+
export declare function throwIfCancelled(signal?: AbortSignal | undefined): void;
|
|
23
|
+
/**
|
|
24
|
+
* Run `stop` once if `signal` aborts before the returned disarm is called:
|
|
25
|
+
* an adapter's "cancel the statement I just started". An already aborted
|
|
26
|
+
* signal stops at once.
|
|
27
|
+
*/
|
|
28
|
+
export declare function onCancel(signal: AbortSignal | undefined, stop: () => void): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Whether a failure is a stopped statement, and why: a StatementStopped, or
|
|
31
|
+
* an engine saying its own cap ran out, in the words each one uses —
|
|
32
|
+
* Postgres's statement_timeout.
|
|
33
|
+
*/
|
|
34
|
+
export declare function stoppedReason(error: unknown): 'cancelled' | 'timeout' | undefined;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How long one read statement may run, and how the caller of a read stops it.
|
|
3
|
+
*
|
|
4
|
+
* The cap is one number for every engine: the Postgres pools
|
|
5
|
+
* open with it, `sql` may lower it for a single statement, and
|
|
6
|
+
* nothing raises it. The stop is a signal the caller owns — an MCP client's
|
|
7
|
+
* cancel — and it reaches the adapters ambiently, through
|
|
8
|
+
* AsyncLocalStorage, because a tool call gets to the driver through shared
|
|
9
|
+
* read services (readRecords, readCount, readView) whose signatures are
|
|
10
|
+
* about rows, not about who may abandon them. Each adapter decides what
|
|
11
|
+
* stopping means for its engine: Postgres cancels the backend, SQLite kills the process a raw statement runs in and checks
|
|
12
|
+
* between the statements it runs itself.
|
|
13
|
+
*
|
|
14
|
+
* Only reads are stopped. A write that has started runs to its end, so its
|
|
15
|
+
* outcome is known rather than guessed.
|
|
16
|
+
*/
|
|
17
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
18
|
+
/** The cap every read statement runs under unless a caller lowers it. */
|
|
19
|
+
export const STATEMENT_TIMEOUT_MS = 30_000;
|
|
20
|
+
/** Below this a cap loses races to the fast path, so a caller cannot ask for less. */
|
|
21
|
+
const STATEMENT_TIMEOUT_FLOOR_MS = 100;
|
|
22
|
+
/**
|
|
23
|
+
* The cap for one statement: the caller's, when it gave one, held between
|
|
24
|
+
* the floor and the default. Politeness only lowers.
|
|
25
|
+
*/
|
|
26
|
+
export function statementCap(asked) {
|
|
27
|
+
if (asked === undefined || !Number.isFinite(asked))
|
|
28
|
+
return STATEMENT_TIMEOUT_MS;
|
|
29
|
+
return Math.max(STATEMENT_TIMEOUT_FLOOR_MS, Math.min(STATEMENT_TIMEOUT_MS, Math.floor(asked)));
|
|
30
|
+
}
|
|
31
|
+
/** A read stopped before it finished: the caller cancelled it, or its cap ran out. */
|
|
32
|
+
export class StatementStopped extends Error {
|
|
33
|
+
reason;
|
|
34
|
+
capMs;
|
|
35
|
+
constructor(reason, capMs, options) {
|
|
36
|
+
super(reason === 'cancelled'
|
|
37
|
+
? 'The statement was cancelled and stopped.'
|
|
38
|
+
: `The statement ran past its ${capMs ?? STATEMENT_TIMEOUT_MS} ms cap and was stopped.`, options);
|
|
39
|
+
this.reason = reason;
|
|
40
|
+
this.capMs = capMs;
|
|
41
|
+
this.name = 'StatementStopped';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const calls = new AsyncLocalStorage();
|
|
45
|
+
/** Run `work` so that every read it starts can be stopped by `signal`. */
|
|
46
|
+
export function withCancellation(signal, work) {
|
|
47
|
+
return calls.run(signal, work);
|
|
48
|
+
}
|
|
49
|
+
/** Shared acquisition belongs to its host, not the first request that opens
|
|
50
|
+
* it. Explicitly detach inherited cancellation, including async descendants. */
|
|
51
|
+
export function withoutCancellation(work) {
|
|
52
|
+
return calls.exit(work);
|
|
53
|
+
}
|
|
54
|
+
/** The stop signal of the call this code runs for, when there is one. */
|
|
55
|
+
export function cancellation() {
|
|
56
|
+
return calls.getStore();
|
|
57
|
+
}
|
|
58
|
+
/** @throws StatementStopped when the call has been cancelled. */
|
|
59
|
+
export function throwIfCancelled(signal = cancellation()) {
|
|
60
|
+
if (signal?.aborted)
|
|
61
|
+
throw new StatementStopped('cancelled');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Run `stop` once if `signal` aborts before the returned disarm is called:
|
|
65
|
+
* an adapter's "cancel the statement I just started". An already aborted
|
|
66
|
+
* signal stops at once.
|
|
67
|
+
*/
|
|
68
|
+
export function onCancel(signal, stop) {
|
|
69
|
+
if (!signal)
|
|
70
|
+
return () => { };
|
|
71
|
+
if (signal.aborted) {
|
|
72
|
+
stop();
|
|
73
|
+
return () => { };
|
|
74
|
+
}
|
|
75
|
+
signal.addEventListener('abort', stop, { once: true });
|
|
76
|
+
return () => signal.removeEventListener('abort', stop);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Whether a failure is a stopped statement, and why: a StatementStopped, or
|
|
80
|
+
* an engine saying its own cap ran out, in the words each one uses —
|
|
81
|
+
* Postgres's statement_timeout.
|
|
82
|
+
*/
|
|
83
|
+
export function stoppedReason(error) {
|
|
84
|
+
if (error instanceof StatementStopped)
|
|
85
|
+
return error.reason;
|
|
86
|
+
const message = error instanceof Error ? error.message : '';
|
|
87
|
+
return /canceling statement due to statement timeout|maximum statement execution time exceeded|max_statement_time exceeded/i.test(message)
|
|
88
|
+
? 'timeout'
|
|
89
|
+
: undefined;
|
|
90
|
+
}
|