@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,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What was written, and how to put it back.
|
|
3
|
+
*
|
|
4
|
+
* Transactions protect a call from failing *halfway*. They do nothing at all
|
|
5
|
+
* about a call that succeeded and should not have — which is the failure mode
|
|
6
|
+
* that actually happens when an agent has write access: nothing errored,
|
|
7
|
+
* nothing rolled back, and the row is simply wrong now. Every destructive
|
|
8
|
+
* label in the tool surface warns about that and none of them helped after
|
|
9
|
+
* the fact.
|
|
10
|
+
*
|
|
11
|
+
* So every write that lands is recorded with what it would take to undo it,
|
|
12
|
+
* and `revert` undoes the last one. The browser has had an undo for its own
|
|
13
|
+
* edits since write mode shipped; this is the same idea one door out, covering
|
|
14
|
+
* the writes an agent makes as well, and covering inserts and deletes, which
|
|
15
|
+
* that one never did.
|
|
16
|
+
*
|
|
17
|
+
* Three things it deliberately does not do.
|
|
18
|
+
*
|
|
19
|
+
* It is **not persisted**. The browser's undo stack makes this argument and it
|
|
20
|
+
* is the right one: a stack that outlives the process invites undoing
|
|
21
|
+
* something from an hour ago, by which time the row has very likely moved on
|
|
22
|
+
* and the "undo" is an overwrite wearing a friendly name. In-session is the
|
|
23
|
+
* honest scope.
|
|
24
|
+
*
|
|
25
|
+
* It **checks before it writes**. Putting the old value back over a newer one
|
|
26
|
+
* is not an undo, it is a silent overwrite — so the row is re-read first and
|
|
27
|
+
* the revert refused if it no longer holds what this journal put there. An
|
|
28
|
+
* undo that can quietly destroy someone else's edit is worse than no undo.
|
|
29
|
+
*
|
|
30
|
+
* And it **does not pretend about SQL**. A `runSql` write is recorded so the
|
|
31
|
+
* history is complete, and marked unrevertible with the reason: arbitrary SQL
|
|
32
|
+
* has no general inverse, and guessing one is how a safety net becomes the
|
|
33
|
+
* thing that cut you.
|
|
34
|
+
*/
|
|
35
|
+
import { Refusal, TransactionOutcomeUnknown, WriteConflict, } from '../adapters/adapter.js';
|
|
36
|
+
import { snapshotScopedData } from '../adapters/scoped/scopedReads.js';
|
|
37
|
+
/** Enough to walk back a mistake, not a session. Matches the browser's depth. */
|
|
38
|
+
const DEPTH = 50;
|
|
39
|
+
/* Per connection: a write on staging is not undoable on production, and a
|
|
40
|
+
single stack would offer exactly that. */
|
|
41
|
+
const journals = new Map();
|
|
42
|
+
let nextId = 1;
|
|
43
|
+
const entriesFor = (connection) => {
|
|
44
|
+
if (!journals.has(connection))
|
|
45
|
+
journals.set(connection, []);
|
|
46
|
+
return journals.get(connection);
|
|
47
|
+
};
|
|
48
|
+
/** Record a write that landed. Returns the entry, mostly for tests. */
|
|
49
|
+
export function recordWrite(connection, entry) {
|
|
50
|
+
const full = {
|
|
51
|
+
id: nextId++,
|
|
52
|
+
connection,
|
|
53
|
+
at: new Date().toISOString(),
|
|
54
|
+
...entry,
|
|
55
|
+
};
|
|
56
|
+
const list = entriesFor(connection);
|
|
57
|
+
list.push(full);
|
|
58
|
+
if (list.length > DEPTH)
|
|
59
|
+
list.shift();
|
|
60
|
+
return full;
|
|
61
|
+
}
|
|
62
|
+
/** The most recent first, which is the order anyone asks about them in. */
|
|
63
|
+
export function history(connection, limit = 10) {
|
|
64
|
+
return [...entriesFor(connection)].reverse().slice(0, Math.max(1, limit));
|
|
65
|
+
}
|
|
66
|
+
/** The newest write that could still be undone, if there is one. */
|
|
67
|
+
export function lastRevertible(connection) {
|
|
68
|
+
return latestRevertible([...entriesFor(connection)].reverse());
|
|
69
|
+
}
|
|
70
|
+
/** Entries are newest first. Never silently step past an unresolved Undo. */
|
|
71
|
+
export function latestRevertible(entries) {
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
if (entry.blocksUndo || entry.undoState === 'pending' || entry.undoState === 'unknown')
|
|
74
|
+
return undefined;
|
|
75
|
+
if (entry.revertible)
|
|
76
|
+
return entry;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
export function forget(connection, id) {
|
|
81
|
+
const list = entriesFor(connection);
|
|
82
|
+
const at = list.findIndex((e) => e.id === id);
|
|
83
|
+
if (at !== -1)
|
|
84
|
+
list.splice(at, 1);
|
|
85
|
+
}
|
|
86
|
+
/** Testing seam: a fresh process is the normal state, and tests want it too. */
|
|
87
|
+
export function clearJournal(connection) {
|
|
88
|
+
if (connection === undefined)
|
|
89
|
+
journals.clear();
|
|
90
|
+
else
|
|
91
|
+
journals.delete(connection);
|
|
92
|
+
}
|
|
93
|
+
/** Fail closed without publishing another entry (or consulting a clock). The
|
|
94
|
+
* caller supplies already verified ownership; no record values are introduced. */
|
|
95
|
+
export function quarantineHistory(connection, owner) {
|
|
96
|
+
for (const entry of journals.get(connection) ?? []) {
|
|
97
|
+
if (owner && (entry.principal !== owner.principal || entry.app !== owner.app))
|
|
98
|
+
continue;
|
|
99
|
+
entry.revertible = false;
|
|
100
|
+
entry.undoState = 'unknown';
|
|
101
|
+
entry.reason = 'Newer write history could not be confirmed. Refresh and reconcile before further editing.';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const keyFilter = (key) => ({
|
|
105
|
+
groups: [
|
|
106
|
+
Object.entries(key).map(([column, value]) => ({
|
|
107
|
+
column,
|
|
108
|
+
op: '=',
|
|
109
|
+
value: value,
|
|
110
|
+
})),
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
/** The row as it stands now, or undefined if it is gone. */
|
|
114
|
+
async function currentRow(adapter, table, key) {
|
|
115
|
+
const result = await adapter.query({ table, filter: keyFilter(key), limit: 1, offset: 0 });
|
|
116
|
+
return result.rows[0];
|
|
117
|
+
}
|
|
118
|
+
/* Compared as strings, because a value that went through the database and came
|
|
119
|
+
back may be a different JavaScript type than the one that went in — SQLite
|
|
120
|
+
hands back an integer for a boolean, and a driver may widen a numeric. The
|
|
121
|
+
question is "is this still the value we wrote", not "is this the same
|
|
122
|
+
object". */
|
|
123
|
+
const same = (a, b) => a === b || (a ?? null) === (b ?? null) || String(a ?? '') === String(b ?? '');
|
|
124
|
+
/**
|
|
125
|
+
* Undo one recorded write.
|
|
126
|
+
*
|
|
127
|
+
* Every step is checked against the database before anything is written, and
|
|
128
|
+
* the whole revert is refused if any of them has moved on. Half an undo is
|
|
129
|
+
* worse than none: it leaves the row in a state neither the write nor the
|
|
130
|
+
* revert intended, and nothing recorded that it happened.
|
|
131
|
+
*/
|
|
132
|
+
export async function revert(adapter, connection, entry, errorMessage = (error) => error.message) {
|
|
133
|
+
// HTTP may pass a logical-resource projection, not the actual journal object.
|
|
134
|
+
// Gate by the canonical entry so stale copies cannot start a second attempt.
|
|
135
|
+
const canonical = entriesFor(connection).find((item) => item.id === entry.id);
|
|
136
|
+
if (!canonical || canonical.connection !== entry.connection) {
|
|
137
|
+
return { reverted: false, outcome: 'not_applied', entry, errors: ['This write is no longer available to undo.'] };
|
|
138
|
+
}
|
|
139
|
+
if (canonical.undoState) {
|
|
140
|
+
return {
|
|
141
|
+
reverted: false,
|
|
142
|
+
outcome: 'unknown',
|
|
143
|
+
entry,
|
|
144
|
+
errors: [canonical.undoState === 'pending' ? 'This Undo is already in progress. Do not retry it.' : undoUncertain],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (canonical.blocksUndo || entry.blocksUndo || !canonical.revertible || !entry.revertible) {
|
|
148
|
+
return { reverted: false, outcome: 'not_applied', entry, errors: [canonical.reason ?? entry.reason ?? 'That write cannot be undone.'] };
|
|
149
|
+
}
|
|
150
|
+
if (!adapter.update || !adapter.insert || !adapter.remove || !adapter.transaction) {
|
|
151
|
+
return { reverted: false, outcome: 'not_applied', entry, errors: ['This connection cannot safely undo writes in one transaction.'] };
|
|
152
|
+
}
|
|
153
|
+
let owned;
|
|
154
|
+
try {
|
|
155
|
+
owned = snapshotScopedData(entry);
|
|
156
|
+
// Logical-resource projections may rename tables, but cannot weaken the
|
|
157
|
+
// canonical inverse contract by dropping its comparison markers.
|
|
158
|
+
if (canonical.steps.some((step) => step.wholeRow || step.exactFields)) {
|
|
159
|
+
if (owned.kind !== canonical.kind || owned.steps.length !== canonical.steps.length) {
|
|
160
|
+
throw new Refusal('This write has no complete inverse projection.');
|
|
161
|
+
}
|
|
162
|
+
owned.steps.forEach((step, index) => {
|
|
163
|
+
if (canonical.steps[index].wholeRow)
|
|
164
|
+
step.wholeRow = true;
|
|
165
|
+
if (canonical.steps[index].exactFields)
|
|
166
|
+
step.exactFields = true;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return { reverted: false, outcome: 'not_applied', entry, errors: [errorMessage(error)] };
|
|
172
|
+
}
|
|
173
|
+
canonical.undoState = 'pending';
|
|
174
|
+
try {
|
|
175
|
+
const result = await revertOwned(adapter, connection, owned, errorMessage);
|
|
176
|
+
if (result.outcome === 'unknown') {
|
|
177
|
+
canonical.undoState = 'unknown';
|
|
178
|
+
canonical.revertible = false;
|
|
179
|
+
canonical.reason = undoUncertain;
|
|
180
|
+
Object.assign(owned, { undoState: 'unknown', revertible: false, reason: undoUncertain });
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
// Mutation failures are classified in revertOwned. This is a preflight
|
|
186
|
+
// read failure: no inverse operation has entered its transaction yet.
|
|
187
|
+
return { reverted: false, outcome: 'not_applied', entry, errors: [errorMessage(error)] };
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
if (canonical.undoState === 'pending')
|
|
191
|
+
delete canonical.undoState;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const undoUncertain = 'The Undo outcome could not be confirmed. Refresh and reconcile the records; do not retry this Undo.';
|
|
195
|
+
function scalarImage(image) {
|
|
196
|
+
// A display label might now be real text. Even SQL cannot recover the
|
|
197
|
+
// original type from that journal image, so refuse the ambiguous label too.
|
|
198
|
+
return Boolean(image &&
|
|
199
|
+
Object.keys(image).length &&
|
|
200
|
+
Object.values(image).every((value) => value === null ||
|
|
201
|
+
typeof value === 'boolean' ||
|
|
202
|
+
(typeof value === 'string' && !/^<\d+ bytes>$/.test(value)) ||
|
|
203
|
+
(typeof value === 'number' && Number.isFinite(value) && (!Number.isInteger(value) || Number.isSafeInteger(value)))));
|
|
204
|
+
}
|
|
205
|
+
const imagePredicates = (image) => Object.entries(image).map(([column, value]) => value === null ? { column, op: 'isNull' } : { column, op: '=', value });
|
|
206
|
+
function returnedImageMatches(current, image) {
|
|
207
|
+
return (current.rows.length === 1 &&
|
|
208
|
+
Object.keys(current.rows[0]).length === Object.keys(image).length &&
|
|
209
|
+
current.columns.length === Object.keys(image).length &&
|
|
210
|
+
Object.entries(image).every(([column, value]) => Object.hasOwn(current.rows[0], column) && current.columns.includes(column) && current.rows[0][column] === value));
|
|
211
|
+
}
|
|
212
|
+
/** Call on the fenced writer BOTH when capturing an image and when undoing it.
|
|
213
|
+
* SQL equality detects lossy driver conversions (e.g. submillisecond dates);
|
|
214
|
+
* strict scalar comparison also rejects NULL/empty and collation-equivalent
|
|
215
|
+
* text changes. Capture-time validation is essential: a later rounded value
|
|
216
|
+
* could match an image whose original precision was already lost.
|
|
217
|
+
* Permission wrappers must expose complete raw fields before marking wholeRow.
|
|
218
|
+
* This proves one scalar row, not trigger/cascade side effects or DDL history. */
|
|
219
|
+
export async function journalImageMatches(tx, table, image) {
|
|
220
|
+
if (!scalarImage(image))
|
|
221
|
+
return false;
|
|
222
|
+
const filter = { groups: [imagePredicates(image)] };
|
|
223
|
+
const current = await tx.query({ table, filter, limit: 2, offset: 0 });
|
|
224
|
+
return returnedImageMatches(current, image);
|
|
225
|
+
}
|
|
226
|
+
/** The touched-field counterpart to journalImageMatches. Call under lockRecord
|
|
227
|
+
* before and after a shared update to establish lossless history, and around
|
|
228
|
+
* its inverse to detect races and restore coercion. Untouched fields need no
|
|
229
|
+
* projection or inverse permission. A successful capture is not a guarantee
|
|
230
|
+
* that generic type coercion will restore it; inverse readback must still pass. */
|
|
231
|
+
export async function journalFieldsMatch(tx, table, key, values) {
|
|
232
|
+
if (!scalarImage(values) ||
|
|
233
|
+
!key ||
|
|
234
|
+
!Object.keys(key).length ||
|
|
235
|
+
Object.values(key).some((value) => typeof value !== 'string' && !(typeof value === 'number' && Number.isFinite(value))))
|
|
236
|
+
return false;
|
|
237
|
+
const filter = { groups: [...keyFilter(key).groups.map((group) => [...group, ...imagePredicates(values)])] };
|
|
238
|
+
const current = await tx.query({ table, columns: Object.keys(values), filter, limit: 2, offset: 0 });
|
|
239
|
+
return returnedImageMatches(current, values);
|
|
240
|
+
}
|
|
241
|
+
async function completeImageMatches(tx, step, image) {
|
|
242
|
+
if (!image ||
|
|
243
|
+
!step.key ||
|
|
244
|
+
!Object.keys(step.key).length ||
|
|
245
|
+
Object.entries(step.key).some(([column, value]) => !Object.hasOwn(image, column) || image[column] !== value))
|
|
246
|
+
return false;
|
|
247
|
+
return journalImageMatches(tx, step.table, image);
|
|
248
|
+
}
|
|
249
|
+
async function revertOwned(adapter, connection, entry, errorMessage) {
|
|
250
|
+
/* An insert is undone by removing what it added, and a delete by putting it
|
|
251
|
+
back — so a graph's steps are reversed, children before parents or the
|
|
252
|
+
other way round depending on which it was. The order a graph went in is
|
|
253
|
+
the order it must come out of, backwards. */
|
|
254
|
+
const steps = entry.kind === 'insert_graph' || entry.kind === 'delete_graph' ? [...entry.steps].reverse() : entry.steps;
|
|
255
|
+
const undoing = entry.kind === 'insert' || entry.kind === 'insert_graph'
|
|
256
|
+
? 'remove'
|
|
257
|
+
: entry.kind === 'delete' || entry.kind === 'delete_graph'
|
|
258
|
+
? 'restore'
|
|
259
|
+
: 'put back';
|
|
260
|
+
/* Checked first, all of it, before anything is written. */
|
|
261
|
+
const problems = [];
|
|
262
|
+
for (const step of steps) {
|
|
263
|
+
// An outside read is neither the complete image nor a lock. New bounded
|
|
264
|
+
// inverses do all validation below, after acquiring the transaction fence.
|
|
265
|
+
if (step.wholeRow || step.exactFields)
|
|
266
|
+
continue;
|
|
267
|
+
if (!step.key) {
|
|
268
|
+
problems.push(`A ${step.table} row in this write has no key, so it cannot be found again.`);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const row = await currentRow(adapter, step.table, step.key);
|
|
272
|
+
if (undoing === 'restore') {
|
|
273
|
+
/* The row was deleted; putting it back is only honest if nothing has
|
|
274
|
+
taken its key since. */
|
|
275
|
+
if (row)
|
|
276
|
+
problems.push(`${step.table} ${describe(step.key)} exists again, so restoring it would overwrite something.`);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (!row) {
|
|
280
|
+
problems.push(`${step.table} ${describe(step.key)} is gone, so there is nothing to undo.`);
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const moved = Object.entries(step.after ?? {}).filter(([column, value]) => !same(row[column], value));
|
|
284
|
+
if (moved.length) {
|
|
285
|
+
problems.push(`${step.table} ${describe(step.key)} has changed since — "${moved[0][0]}" is no longer what this write left. ` +
|
|
286
|
+
'Undoing would overwrite that.');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (problems.length)
|
|
290
|
+
return { reverted: false, outcome: 'not_applied', entry, errors: problems };
|
|
291
|
+
const done = [];
|
|
292
|
+
/* The steps go back as one transaction where the adapter offers one, so a
|
|
293
|
+
revert that fails on its third row leaves the first two as they were:
|
|
294
|
+
half an undo is the state neither the write nor the revert intended.
|
|
295
|
+
Legacy preflight stays on the read handle. Bounded single-row images are
|
|
296
|
+
checked inside the writer, after a fence: a shared handle alone does not
|
|
297
|
+
exclude concurrent PG writers. No nontransactional fallback. */
|
|
298
|
+
const undo = async (tx) => {
|
|
299
|
+
for (const step of steps) {
|
|
300
|
+
if ((step.wholeRow || step.exactFields) &&
|
|
301
|
+
(!step.key ||
|
|
302
|
+
!Object.keys(step.key).length ||
|
|
303
|
+
!tx.lockRecord ||
|
|
304
|
+
(step.wholeRow && !['insert', 'delete'].includes(entry.kind)) ||
|
|
305
|
+
(step.exactFields && entry.kind !== 'update'))) {
|
|
306
|
+
throw new Refusal('This connection cannot fence a complete single-row inverse.');
|
|
307
|
+
}
|
|
308
|
+
if (step.key && tx.lockRecord)
|
|
309
|
+
await tx.lockRecord({ table: step.table, key: step.key });
|
|
310
|
+
}
|
|
311
|
+
for (const step of steps) {
|
|
312
|
+
if (undoing === 'remove') {
|
|
313
|
+
if (step.wholeRow && !(await completeImageMatches(tx, step, step.after)))
|
|
314
|
+
throw new WriteConflict();
|
|
315
|
+
const removed = await tx.remove({ table: step.table, key: step.key });
|
|
316
|
+
if (step.wholeRow && removed.affected !== 1)
|
|
317
|
+
throw new WriteConflict();
|
|
318
|
+
done.push({ table: step.table, key: { ...step.key }, action: 'removed' });
|
|
319
|
+
}
|
|
320
|
+
else if (undoing === 'restore') {
|
|
321
|
+
if (step.wholeRow && (await currentRow(tx, step.table, step.key)))
|
|
322
|
+
throw new WriteConflict();
|
|
323
|
+
// An absent-row read does not reserve a PK. The transaction insert
|
|
324
|
+
// contract MUST reject every uniqueness conflict, including SQLite
|
|
325
|
+
// schema REPLACE policies, so a racing occupant cannot be overwritten.
|
|
326
|
+
// Trigger/cascade side effects remain the adapter's row-only boundary.
|
|
327
|
+
await tx.insert({
|
|
328
|
+
table: step.table,
|
|
329
|
+
values: (step.before ?? {}),
|
|
330
|
+
});
|
|
331
|
+
if (step.wholeRow && !(await completeImageMatches(tx, step, step.before)))
|
|
332
|
+
throw new WriteConflict();
|
|
333
|
+
done.push({ table: step.table, key: { ...step.key }, action: 'restored' });
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
if (step.exactFields &&
|
|
337
|
+
(!scalarImage(step.before) ||
|
|
338
|
+
!scalarImage(step.after) ||
|
|
339
|
+
Object.keys(step.before).length !== Object.keys(step.after).length ||
|
|
340
|
+
Object.keys(step.before).some((column) => !Object.hasOwn(step.after, column)) ||
|
|
341
|
+
!(await journalFieldsMatch(tx, step.table, step.key, step.after))))
|
|
342
|
+
throw new WriteConflict();
|
|
343
|
+
const updated = await tx.update({
|
|
344
|
+
table: step.table,
|
|
345
|
+
key: step.key,
|
|
346
|
+
values: (step.before ?? {}),
|
|
347
|
+
expected: (step.after ?? {}),
|
|
348
|
+
// Returning to the recorded before-image is not a new transition.
|
|
349
|
+
restore: true,
|
|
350
|
+
});
|
|
351
|
+
if (step.exactFields && (updated.affected !== 1 || !(await journalFieldsMatch(tx, step.table, step.key, step.before))))
|
|
352
|
+
throw new WriteConflict();
|
|
353
|
+
done.push({ table: step.table, key: { ...step.key }, action: 'put back' });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
try {
|
|
358
|
+
await adapter.transaction((tx) => undo(tx));
|
|
359
|
+
}
|
|
360
|
+
catch (err) {
|
|
361
|
+
if (err instanceof TransactionOutcomeUnknown) {
|
|
362
|
+
return { reverted: false, outcome: 'unknown', entry, errors: [undoUncertain] };
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
reverted: false,
|
|
366
|
+
outcome: 'not_applied',
|
|
367
|
+
entry,
|
|
368
|
+
steps: [],
|
|
369
|
+
errors: [`${errorMessage(err)}${done.length ? ' — nothing was changed; the whole undo rolled back.' : ''}`],
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
forget(connection, entry.id);
|
|
373
|
+
return { reverted: true, outcome: 'applied', entry, steps: done };
|
|
374
|
+
}
|
|
375
|
+
const describe = (key) => {
|
|
376
|
+
const parts = Object.entries(key);
|
|
377
|
+
return parts.length === 1 ? String(parts[0][1]) : parts.map(([c, v]) => `${c}=${v}`).join(',');
|
|
378
|
+
};
|
|
379
|
+
/** A sentence for the history, in the words someone would use about it. */
|
|
380
|
+
export function summarise(kind, steps, detail) {
|
|
381
|
+
const table = steps[0]?.table ?? 'something';
|
|
382
|
+
const n = steps.length;
|
|
383
|
+
switch (kind) {
|
|
384
|
+
case 'update':
|
|
385
|
+
return `Updated ${table} ${steps[0]?.key ? describe(steps[0].key) : ''}`.trim();
|
|
386
|
+
// Many rows of one table in one insert entry is an import (recordedImport).
|
|
387
|
+
case 'insert':
|
|
388
|
+
return n > 1 ? `Imported ${n} rows into ${table}` : `Inserted into ${table}`;
|
|
389
|
+
case 'delete':
|
|
390
|
+
return `Deleted ${table} ${steps[0]?.key ? describe(steps[0].key) : ''}`.trim();
|
|
391
|
+
case 'insert_graph':
|
|
392
|
+
return `Inserted ${n} row${n === 1 ? '' : 's'} as one graph`;
|
|
393
|
+
case 'delete_graph':
|
|
394
|
+
return `Deleted ${n} row${n === 1 ? '' : 's'} as one graph`;
|
|
395
|
+
default:
|
|
396
|
+
return detail ? `Ran SQL: ${detail}` : 'Ran a SQL write';
|
|
397
|
+
}
|
|
398
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The query bar's side of paging by key (shared/keysetPage.ts): which order a
|
|
3
|
+
* read pages in, the continuation a step asks for, and the page's boundaries
|
|
4
|
+
* for the next step. A table read and a view read the bar falls through to
|
|
5
|
+
* each get the same three answers, one over columns and one over paths.
|
|
6
|
+
*
|
|
7
|
+
* A boundary needs every order column in the row. A list that sorts by one
|
|
8
|
+
* it does not show (`show name sort created_at`) asks for it too, and it is
|
|
9
|
+
* taken out of the rows before they are sent: the reader may sort by it, so
|
|
10
|
+
* they may read it, but the list did not ask to show it.
|
|
11
|
+
*/
|
|
12
|
+
import type { Filter } from '../adapters/adapter.js';
|
|
13
|
+
import { type DatabaseSchema, type Order, type TableMeta } from '../shared/schema.js';
|
|
14
|
+
import type { ViewDef } from '../shared/viewPaths.js';
|
|
15
|
+
import { type PageBounds, type PageStep } from '../shared/keysetPage.js';
|
|
16
|
+
import type { RecordsContinuation, ViewContinuation } from './resourceReadOperations.js';
|
|
17
|
+
type Row = Record<string, unknown>;
|
|
18
|
+
interface RecordsPaging {
|
|
19
|
+
order: Order[];
|
|
20
|
+
/** The columns to read: the request's, with any order column it left out. */
|
|
21
|
+
columns?: string[];
|
|
22
|
+
continuation?: RecordsContinuation;
|
|
23
|
+
/** Read for the boundary only, and taken out of the rows. */
|
|
24
|
+
extra: string[];
|
|
25
|
+
}
|
|
26
|
+
/** How a table read pages, or undefined when it can only page by offset. */
|
|
27
|
+
export declare function recordsPaging(table: TableMeta, dialect: DatabaseSchema['dialect'], orderBy: Order[] | undefined, columns: string[] | undefined, filter: Filter | undefined, step: PageStep | undefined): RecordsPaging | undefined;
|
|
28
|
+
export interface ViewPaging {
|
|
29
|
+
/** The view as it is read: its order made total, and any order column it left out asked for. */
|
|
30
|
+
view: ViewDef;
|
|
31
|
+
order: Order[];
|
|
32
|
+
continuation?: ViewContinuation;
|
|
33
|
+
extra: string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* How a view read pages. Only an order over the base table's own columns
|
|
37
|
+
* pages by key: a path through a reference, an aggregate's alias, a distance
|
|
38
|
+
* or byte-ordered text keep the offset. Its order is made total with the key,
|
|
39
|
+
* as a table read's is (withKey), on every page, so the first page and the
|
|
40
|
+
* next agree about ties.
|
|
41
|
+
*/
|
|
42
|
+
export declare function viewPaging(schema: DatabaseSchema, table: TableMeta, view: ViewDef, step: PageStep | undefined): ViewPaging | undefined;
|
|
43
|
+
/** The page's boundaries, then the rows and columns without what was read only for them. */
|
|
44
|
+
export declare function settlePage(order: readonly Order[], extra: readonly string[], result: {
|
|
45
|
+
rows: Row[];
|
|
46
|
+
columns: string[];
|
|
47
|
+
}, name?: (column: string) => string): {
|
|
48
|
+
bounds?: PageBounds;
|
|
49
|
+
rows: Row[];
|
|
50
|
+
columns: string[];
|
|
51
|
+
};
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { defaultOrder, resolveOrder, withKey } from '../shared/schema.js';
|
|
2
|
+
import { continueGroups, keysetAfter, keysetOrder, pageBounds, reversedOrder, } from '../shared/keysetPage.js';
|
|
3
|
+
/** The groups past (or, read the other way, before) a step's boundary; undefined when it names no exact boundary. */
|
|
4
|
+
function continuationGroups(table, order, step, dialect) {
|
|
5
|
+
if ('end' in step)
|
|
6
|
+
return { reverse: true, groups: undefined };
|
|
7
|
+
const reverse = 'before' in step;
|
|
8
|
+
const tail = keysetAfter(table, reverse ? reversedOrder(order) : order, reverse ? step.before : step.after, dialect);
|
|
9
|
+
return tail && { reverse, groups: tail };
|
|
10
|
+
}
|
|
11
|
+
/** How a table read pages, or undefined when it can only page by offset. */
|
|
12
|
+
export function recordsPaging(table, dialect, orderBy, columns, filter, step) {
|
|
13
|
+
const { order } = resolveOrder(table, orderBy);
|
|
14
|
+
if (!keysetOrder(table, order, dialect))
|
|
15
|
+
return undefined;
|
|
16
|
+
const extra = columns?.length ? order.map((o) => o.column).filter((column) => !columns.includes(column)) : [];
|
|
17
|
+
const planned = step && continuationGroups(table, order, step, dialect);
|
|
18
|
+
if (step && !planned)
|
|
19
|
+
return { order, extra: [] };
|
|
20
|
+
return {
|
|
21
|
+
order,
|
|
22
|
+
extra,
|
|
23
|
+
...(extra.length ? { columns: [...columns, ...extra] } : {}),
|
|
24
|
+
...(planned
|
|
25
|
+
? {
|
|
26
|
+
continuation: { reverse: planned.reverse, ...(planned.groups ? { groups: continueGroups(filter?.groups, planned.groups) } : {}) },
|
|
27
|
+
}
|
|
28
|
+
: {}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* How a view read pages. Only an order over the base table's own columns
|
|
33
|
+
* pages by key: a path through a reference, an aggregate's alias, a distance
|
|
34
|
+
* or byte-ordered text keep the offset. Its order is made total with the key,
|
|
35
|
+
* as a table read's is (withKey), on every page, so the first page and the
|
|
36
|
+
* next agree about ties.
|
|
37
|
+
*/
|
|
38
|
+
export function viewPaging(schema, table, view, step) {
|
|
39
|
+
const given = view.orderBy ?? [];
|
|
40
|
+
if (given.some((o) => o.alias || o.near !== undefined || o.collation !== undefined || !table.columns.some((c) => c.name === o.path)))
|
|
41
|
+
return undefined;
|
|
42
|
+
const order = given.length
|
|
43
|
+
? withKey(table, given.map((o) => ({ column: o.path, direction: o.direction })))
|
|
44
|
+
: defaultOrder(table);
|
|
45
|
+
if (!keysetOrder(table, order, schema.dialect))
|
|
46
|
+
return undefined;
|
|
47
|
+
// No columns is every column of the base table, the order's among them.
|
|
48
|
+
const shown = new Set(view.columns.map((c) => c.path));
|
|
49
|
+
const extra = view.columns.length ? order.map((o) => o.column).filter((column) => !shown.has(column)) : [];
|
|
50
|
+
const read = {
|
|
51
|
+
...view,
|
|
52
|
+
orderBy: order.map((o) => ({ path: o.column, direction: o.direction })),
|
|
53
|
+
...(extra.length ? { columns: [...view.columns, ...extra.map((path) => ({ path }))] } : {}),
|
|
54
|
+
};
|
|
55
|
+
const planned = step && continuationGroups(table, order, step, schema.dialect);
|
|
56
|
+
if (step && !planned)
|
|
57
|
+
return { view: read, order, extra };
|
|
58
|
+
const toPaths = (groups) => groups.map((group) => group.map(({ column, op, value }) => ({ path: column, op, ...(value === undefined ? {} : { value }) })));
|
|
59
|
+
return {
|
|
60
|
+
view: read,
|
|
61
|
+
order,
|
|
62
|
+
extra,
|
|
63
|
+
...(planned
|
|
64
|
+
? {
|
|
65
|
+
continuation: {
|
|
66
|
+
reverse: planned.reverse,
|
|
67
|
+
orderBy: planned.reverse ? reversedOrder(order).map((o) => ({ path: o.column, direction: o.direction })) : read.orderBy,
|
|
68
|
+
...(planned.groups ? { groups: continueGroups(view.filter?.groups, toPaths(planned.groups)) } : {}),
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
: {}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** The page's boundaries, then the rows and columns without what was read only for them. */
|
|
75
|
+
export function settlePage(order, extra, result, name = (column) => column) {
|
|
76
|
+
const bounds = pageBounds(order, result.rows, name);
|
|
77
|
+
if (!extra.length)
|
|
78
|
+
return { ...(bounds ? { bounds } : {}), rows: result.rows, columns: result.columns };
|
|
79
|
+
const dropped = new Set(extra.map(name));
|
|
80
|
+
return {
|
|
81
|
+
...(bounds ? { bounds } : {}),
|
|
82
|
+
rows: result.rows.map((row) => Object.fromEntries(Object.entries(row).filter(([key]) => !dropped.has(key)))),
|
|
83
|
+
columns: result.columns.filter((column) => !dropped.has(column)),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** One stored entry, as the client wrote it. Opaque here on purpose: the
|
|
2
|
+
store round-trips any JSON value — layout objects, filter lists. */
|
|
3
|
+
export type StoredLayout = unknown;
|
|
4
|
+
/** connection id → table id → layout. */
|
|
5
|
+
type LayoutFile = Record<string, Record<string, StoredLayout>>;
|
|
6
|
+
/**
|
|
7
|
+
* Saved pages live in a sibling file with the same shape — connection id,
|
|
8
|
+
* then page id. The same shape because it earns the same machinery: pages
|
|
9
|
+
* were the one piece of built work that lived only in localStorage, so a
|
|
10
|
+
* page assembled in one browser was invisible to every other, while the
|
|
11
|
+
* record layout beside it travelled. Same store, same guarantees.
|
|
12
|
+
*/
|
|
13
|
+
export declare function pagesPath(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Saved list filters, the third sibling — connection id, then table id, to
|
|
16
|
+
* a list of `{name, query}`. The same argument as pages: a filter someone
|
|
17
|
+
* saved is work, and work that lives only in one browser's localStorage is
|
|
18
|
+
* work that vanishes with the browser.
|
|
19
|
+
*/
|
|
20
|
+
export declare function filtersPath(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Where a request's saved filters live, in that one file. An App without
|
|
23
|
+
* sign-in (and the plain browser) keeps one list per connection, shared. An
|
|
24
|
+
* App that signs people in keeps each account's own, in a section keyed by
|
|
25
|
+
* the connection and the account the verified session established — never
|
|
26
|
+
* by anything the client sends — so one account's list is a key no other
|
|
27
|
+
* account's request can name; the separator is a character no connection or
|
|
28
|
+
* account id carries. Null where nothing may be kept: no verified account,
|
|
29
|
+
* or rows scoped by a policy, whose principals write only through it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function filtersSection(connection: string, reader: {
|
|
32
|
+
signIn: boolean;
|
|
33
|
+
account?: string;
|
|
34
|
+
rowPolicy: boolean;
|
|
35
|
+
}): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Read every stored layout.
|
|
38
|
+
*
|
|
39
|
+
* A missing file is the normal case — most connections have never had a
|
|
40
|
+
* layout saved — and an unreadable one falls back to empty rather than
|
|
41
|
+
* refusing to serve the page. A record with its derived layout is a working
|
|
42
|
+
* page; a record that will not render because a preferences file has a stray
|
|
43
|
+
* comma in it is not.
|
|
44
|
+
*/
|
|
45
|
+
export declare function readLayouts(path?: string): Promise<LayoutFile>;
|
|
46
|
+
/** Every layout for one connection. */
|
|
47
|
+
export declare function layoutsFor(connection: string, path?: string): Promise<Record<string, StoredLayout>>;
|
|
48
|
+
export declare function writeLayout(connection: string, table: string, layout: StoredLayout | null, path?: string): Promise<void>;
|
|
49
|
+
export {};
|