@substrat-run/adapter-sqlite 0.121.0 → 0.122.0
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/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +156 -44
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { type BlobStoreHandle, type ImportBatch, type ImportResult, type PeerCoverage, type VerticalCaller, type CapabilityExchange, type ConnectionId, type ModuleId, type DomainEvent, type PlatformRequestId, type PlatformRequest, type PlatformRequestFilter, type PlatformRequestStatus, type PlatformRequestFailure, type ProjectedConnectionGrant, type PermissionKey, type PlatformActorId, type PrincipalId, type ScopeDump, type ScopeId, type ImpersonationSessionId, type TenantId, type TenantStoreHandle } from '@substrat-run/contracts';
|
|
2
2
|
import { type FreshnessReport, type FreshnessRegistration, type BlobStoreProvisionInput, type ScopeAttachments, type ExecutorDeadLetter, type ExecutorDrainReport, type MigrateScopeOutcome, type MigrationFrontier, type ExecutorHandler, type ExecutorRetryPolicy, type ConnectorHandler, type ConnectorOptions, type Clock, type FetchLike, type SecretBox, type HostAdmin, type ModuleRegistration, type OperationHandler, type PermissionChecker, type ProvisionScopeInput, type ScheduleRegistration, type ScheduleRunReport, type ScopeHost, type ScopeStub, type ScopeStubOptions, type TenantRelationalStore, type TenantStoreProvisionInput, type JobDriveReport, type JobHandler, type JobRun, type JobRunFilter, type StartJobRunInput, type ConnectorCallRecorder } from '@substrat-run/kernel';
|
|
3
|
+
/**
|
|
4
|
+
* A fault in the database itself (full, corrupt, I/O), as opposed to one statement failing.
|
|
5
|
+
* The #1764 backfill logs and opens past a failed batch, but never past one of these.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isStorageFault(err: unknown): boolean;
|
|
3
8
|
export interface SqliteScopeHostOptions {
|
|
4
9
|
/** Directory holding one SQLite file per scope plus the directory database. */
|
|
5
10
|
dir: string;
|
|
@@ -305,6 +310,14 @@ export declare class SqliteScopeHost implements ScopeHost {
|
|
|
305
310
|
* `undefined` when the registry has no such version (under `slug`, when one is named).
|
|
306
311
|
*/
|
|
307
312
|
private manifestJsonOf;
|
|
313
|
+
/**
|
|
314
|
+
* #1756: the bind gate's question for one install (`bindExportBreaksOf`), from the directory.
|
|
315
|
+
* The serving pointer is read only when the scope is on a serving script before or after the
|
|
316
|
+
* move, the one case it decides anything.
|
|
317
|
+
*/
|
|
318
|
+
private bindBreaks;
|
|
319
|
+
/** What one version of `slug` imports, from the registry; `not_found` for a version it does not know. */
|
|
320
|
+
private versionImports;
|
|
308
321
|
/** #1705 PR 3: the promote gate's question, over two stored versions (`exportBreaksOf`). */
|
|
309
322
|
private exportBreaksBetween;
|
|
310
323
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAcL,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import Database from 'better-sqlite3';
|
|
4
|
-
import { accessLogEntry, adminLogEntry, opsFailureEntry, opsFailureFingerprint, issueEntry, FRESHNESS_HEARTBEAT_MINUTES, sweepRunEntry, modelUsageEntry, ATTACHMENT_ADDED, ATTACHMENT_REMOVED, attachmentRecord, createTenantInput, domainEvent, domainEventInput, exportReadInput, importBatch, importCursorMove, exportsOfManifestJson, importsOfManifestJson, entitlementGrant, entitlementGrantInput, eventId, meterReading, platformRequestInput, platformRequestId, MAX_PENDING_PLATFORM_REQUESTS, identityLink, identityPool, instant, connection, capabilityGrant, connectionGrant, connectionGrantRecord, connectionSecret, systemGrant, systemSwitch, systemSwitchRecord, peerSwitch, verticalCaller, verticalSlug as verticalSlugOf, subjectRef, requestFingerprint, createConnectionInput, projectedConnectionGrant, projectedConnectionKey, moduleManifest, createOrgInput, promotionAcknowledgement, bindHostnameInput, channelHistoryEntry, hostnameBinding, publishVersionInput, AUTO_ADMISSION_NOTE, routeTarget, registerVerticalInput, vertical as verticalSchema, verticalChannel, verticalVersion, objectRef, grantRefFromProof, org as orgSchema, orgMembership, principalId, resolvedIdentity, identityMembership, roleDefinition, scope as scopeSchema, tenant as tenantSchema, tenantRole, subjectShredReceipt, SCOPE_TABLE_PAGE_DEFAULT, SCOPE_TABLE_PAGE_MAX, SCOPE_QUERY_ROW_MAX, verticalServingState, callsOfManifestJson, outboundOfManifestJson, listLimitOf, substratError, assertReplayableDump, delegatedReadRecord, redrainEventsInput, REDRAIN_BATCH, } from '@substrat-run/contracts';
|
|
5
|
-
import { actorOf, asPrincipal, assertAllowed, assertNoSecret, assertPermissionKey, CAPABILITY_DDL, CAPABILITY_EXCHANGE_OPERATION, capabilityAttachmentWriteRefused, capabilityTokenHash, createCapabilityVerbs, exchangeCapability as exchangeCapabilitySecret, guardSecrets, mintBecomeCapability, plausibleSessionToken, redactSecrets, resolveCapabilitySession, revokeCapabilityAsPlatform, assertReadOnlyQuery, attachmentBlobKey, entitlementDenial, foldMeterReading, guardSpine, guardSqlLimits, parseValidationRecords, resolveScopeRecord, ulid, ISSUE_RETENTION_DAYS, OPS_FAILURE_RETENTION_DAYS, SWEEP_RUN_RETENTION_DAYS, SWEEP_RUNS_INTENT_INDEX, sweepRunsIntentHasKind, MODEL_USAGE_RETENTION_DAYS, foldModelUsage, backoffAt, platformRequestHistoryQuery, platformRequestOf, PLATFORM_REQUEST_COLUMNS, PLATFORM_REQUEST_REDACTION_SQL, platformRequestRedactionParams, platformRequestRedactionQuery, intentPayloadCarriesSubject, redactSubjectJobRuns, JOB_RUN_PATCH_SQL, JOB_STEP_RECORD_SQL, DELIVERY_ERROR_REDACTION_SQL, REDACTED_DELIVERY_NOTE, seatScopeTuple, switchSystemSchedules, admitPeer, collectPeers, peerSeats, resolveVerticalInstanceFrom, switchPeer, peerGrantsStatus, systemGrantsStatus, systemScheduleState, systemSwitchedOff, systemSwitchedOffMessage, SYSTEM_SWITCHES_BACKFILL_SQL, SYSTEM_SWITCHES_DDL, forgetSystemSwitchesOf, listSystemSwitchRecords, recordSystemSwitchedOff, recordSystemSwitchedOn, restoreSystemSwitchRecord, switchedOffModulesOf, systemSwitchRecordsOf, systemSwitchesTableExists, withRecorded, denialListQuery, denialSummaryQuery, denialTotalsQuery, DENIAL_WINDOW_QUERY, mapDenialRow, mapDenialSummaryBuckets, IMPERSONATION_COLUMNS, IMPERSONATION_DDL, ImpersonationRefused, assertImpersonationWrites, assertModuleEnqueueableKind, assertSessionUsable, impersonationByIdQuery, impersonationListQuery, impersonationRowValues, impersonationStampOf, mapImpersonationRow, newImpersonationSession, resolveRetryPolicy, isSecretBoxConfigured, unconfiguredSecretBox, createSubjectKeys, generateSealingKeyPair, noSealingKeyMessage, openSealed, sealTo, ConnectionSealingKeyUnavailableError, PermissionDenied, createAtomic, NotSearchable, NotListable, listIndexMigrations, listIndexPlans, listQuery, cursorOf, moduleMigrations, isSearchIndexTable, searchIndexDdl, searchIndexMigrations, searchIndexPlans, searchLimit, searchMatchExpression, searchQuery, entityVersionQuery, entityVersionOf, assertIfMatch, OUTBOX_ENTITY_INDEX, SCHEDULE_STATE_DDL, SCHEDULE_STATE_REBUILD, scheduleStateHasKind, VERTICAL_EVENTS_DDL, EXPORT_HOPS_SQL, IMPORT_CURSORS_SQL, IMPORT_CURSOR_OF_SQL, OUTBOX_MARK_SQL, exportedSinceQuery, IMPORT_CURSOR_ADVANCE_SQL, IMPORT_RECORD_SQL, moveImportCursor, importCursorSourceOf, exportBreaksOf, exportBreakRefusal, CrossVerticalRegistry, exportReadPlan, exportReadQuery, planExportBatch, withheldNote, JOB_RUN_DDL, jobRunListLimit, jobRunOf, runDueJobRuns, startJobRun, IDEMPOTENCY_DDL, assertIdempotencyKey, idempotencyLookupQuery, idempotencyPruneStatement, idempotencyRecordStatement, idempotencyOptedOutMessage, replayFor, globalFetch, createUlid, facetEvents, readHistory, walkEventCause, walkEventEffects, assertRedrainWindow, readInvocation, readDeadLetters, domainEventOf, readUndrainedOutbox, undrainedEventsOf, connectorCallRecord, noopConnectorCallRecorder, recordConnectorCall, settleConnectionUse, } from '@substrat-run/kernel';
|
|
4
|
+
import { accessLogEntry, adminLogEntry, opsFailureEntry, opsFailureFingerprint, issueEntry, FRESHNESS_HEARTBEAT_MINUTES, sweepRunEntry, modelUsageEntry, ATTACHMENT_ADDED, ATTACHMENT_REMOVED, attachmentRecord, createTenantInput, domainEvent, domainEventInput, exportReadInput, importBatch, importCursorMove, exportsOfManifestJson, importsOfManifestJson, entitlementGrant, entitlementGrantInput, eventId, meterReading, platformRequestInput, platformRequestId, MAX_PENDING_PLATFORM_REQUESTS, identityLink, identityPool, instant, connection, capabilityGrant, connectionGrant, connectionGrantRecord, connectionSecret, systemGrant, systemSwitch, systemSwitchRecord, peerSwitch, verticalCaller, verticalSlug as verticalSlugOf, subjectRef, requestFingerprint, createConnectionInput, projectedConnectionGrant, projectedConnectionKey, moduleManifest, createOrgInput, promotionAcknowledgement, bindAcknowledgement, bindHostnameInput, channelHistoryEntry, hostnameBinding, publishVersionInput, AUTO_ADMISSION_NOTE, routeTarget, registerVerticalInput, vertical as verticalSchema, verticalChannel, verticalVersion, objectRef, grantRefFromProof, org as orgSchema, orgMembership, principalId, resolvedIdentity, identityMembership, roleDefinition, scope as scopeSchema, tenant as tenantSchema, tenantRole, subjectShredReceipt, SCOPE_TABLE_PAGE_DEFAULT, SCOPE_TABLE_PAGE_MAX, SCOPE_QUERY_ROW_MAX, verticalServingState, callsOfManifestJson, outboundOfManifestJson, listLimitOf, substratError, assertReplayableDump, delegatedReadRecord, redrainEventsInput, REDRAIN_BATCH, } from '@substrat-run/contracts';
|
|
5
|
+
import { actorOf, asPrincipal, assertAllowed, assertNoSecret, assertPermissionKey, CAPABILITY_DDL, CAPABILITY_EXCHANGE_OPERATION, capabilityAttachmentWriteRefused, capabilityTokenHash, createCapabilityVerbs, exchangeCapability as exchangeCapabilitySecret, guardSecrets, mintBecomeCapability, plausibleSessionToken, redactSecrets, resolveCapabilitySession, revokeCapabilityAsPlatform, assertReadOnlyQuery, attachmentBlobKey, entitlementDenial, foldMeterReading, guardSpine, guardSqlLimits, parseValidationRecords, resolveScopeRecord, ulid, ISSUE_RETENTION_DAYS, OPS_FAILURE_RETENTION_DAYS, SWEEP_RUN_RETENTION_DAYS, SWEEP_RUNS_INTENT_INDEX, sweepRunsIntentHasKind, MODEL_USAGE_RETENTION_DAYS, foldModelUsage, backoffAt, platformRequestHistoryQuery, platformRequestOf, PLATFORM_REQUEST_COLUMNS, PLATFORM_REQUEST_REDACTION_SQL, platformRequestRedactionParams, platformRequestRedactionQuery, intentPayloadCarriesSubject, redactSubjectJobRuns, JOB_RUN_PATCH_SQL, JOB_STEP_RECORD_SQL, DELIVERY_ERROR_REDACTION_SQL, REDACTED_DELIVERY_NOTE, seatScopeTuple, switchSystemSchedules, admitPeer, collectPeers, peerSeats, resolveVerticalInstanceFrom, switchPeer, peerGrantsStatus, systemGrantsStatus, systemScheduleState, systemSwitchedOff, systemSwitchedOffMessage, SYSTEM_SWITCHES_BACKFILL_SQL, SYSTEM_SWITCHES_DDL, forgetSystemSwitchesOf, listSystemSwitchRecords, recordSystemSwitchedOff, recordSystemSwitchedOn, restoreSystemSwitchRecord, switchedOffModulesOf, systemSwitchRecordsOf, systemSwitchesTableExists, withRecorded, VERSION_MIGRATIONS_DDL, splitManifestMigrations, splitVersionMigrationsBatch, versionMigrationsOf, writeVersionMigrations, denialListQuery, denialSummaryQuery, denialTotalsQuery, DENIAL_WINDOW_QUERY, mapDenialRow, mapDenialSummaryBuckets, IMPERSONATION_COLUMNS, IMPERSONATION_DDL, ImpersonationRefused, assertImpersonationWrites, assertModuleEnqueueableKind, assertSessionUsable, impersonationByIdQuery, impersonationListQuery, impersonationRowValues, impersonationStampOf, mapImpersonationRow, newImpersonationSession, resolveRetryPolicy, isSecretBoxConfigured, unconfiguredSecretBox, createSubjectKeys, generateSealingKeyPair, noSealingKeyMessage, openSealed, sealTo, ConnectionSealingKeyUnavailableError, PermissionDenied, createAtomic, NotSearchable, NotListable, listIndexMigrations, listIndexPlans, listQuery, cursorOf, moduleMigrations, isSearchIndexTable, searchIndexDdl, searchIndexMigrations, searchIndexPlans, searchLimit, searchMatchExpression, searchQuery, entityVersionQuery, entityVersionOf, assertIfMatch, OUTBOX_ENTITY_INDEX, SCHEDULE_STATE_DDL, SCHEDULE_STATE_REBUILD, scheduleStateHasKind, VERTICAL_EVENTS_DDL, EXPORT_HOPS_SQL, IMPORT_CURSORS_SQL, IMPORT_CURSOR_OF_SQL, OUTBOX_MARK_SQL, exportedSinceQuery, IMPORT_CURSOR_ADVANCE_SQL, IMPORT_RECORD_SQL, moveImportCursor, importCursorSourceOf, exportBreaksOf, exportBreakRefusal, bindExportBreaksOf, bindExportBreakRefusal, CrossVerticalRegistry, exportReadPlan, exportReadQuery, planExportBatch, withheldNote, JOB_RUN_DDL, jobRunListLimit, jobRunOf, runDueJobRuns, startJobRun, IDEMPOTENCY_DDL, assertIdempotencyKey, idempotencyLookupQuery, idempotencyPruneStatement, idempotencyRecordStatement, idempotencyOptedOutMessage, replayFor, globalFetch, createUlid, facetEvents, readHistory, walkEventCause, walkEventEffects, assertRedrainWindow, readInvocation, readDeadLetters, domainEventOf, readUndrainedOutbox, undrainedEventsOf, connectorCallRecord, noopConnectorCallRecorder, recordConnectorCall, settleConnectionUse, } from '@substrat-run/kernel';
|
|
6
6
|
import { ScopeActor } from './actor.js';
|
|
7
7
|
import { createTupleChecker } from './checker.js';
|
|
8
|
+
/**
|
|
9
|
+
* A fault in the database itself (full, corrupt, I/O), as opposed to one statement failing.
|
|
10
|
+
* The #1764 backfill logs and opens past a failed batch, but never past one of these.
|
|
11
|
+
*/
|
|
12
|
+
export function isStorageFault(err) {
|
|
13
|
+
const code = err?.code;
|
|
14
|
+
return typeof code === 'string' && /^SQLITE_(FULL|CORRUPT|IOERR|NOTADB)/.test(code);
|
|
15
|
+
}
|
|
8
16
|
/** The kernel's schedule-switch SQL (#1666), over one scope's database handle. */
|
|
9
17
|
const switchSqlOf = (db) => ({
|
|
10
18
|
all: (sql, ...params) => db.prepare(sql).all(...params),
|
|
@@ -723,10 +731,16 @@ export class SqliteScopeHost {
|
|
|
723
731
|
admission_note TEXT,
|
|
724
732
|
-- The pushed DeployManifest (JSON) — what a serve rebuilds upload metadata
|
|
725
733
|
-- from (#286). NULL = pre-#286 push, archivable but never served in place.
|
|
734
|
+
-- Stored WITHOUT its SQL migrations, which live in vertical_version_migrations (#1764).
|
|
726
735
|
manifest_json TEXT,
|
|
736
|
+
-- How many migration rows the version stored. NULL = it carries no SQL to show.
|
|
737
|
+
migration_count INTEGER,
|
|
738
|
+
-- 1 once the SQL is out of manifest_json. NULL = stored before #1764, not yet backfilled.
|
|
739
|
+
migrations_split INTEGER,
|
|
727
740
|
created_at TEXT NOT NULL,
|
|
728
741
|
UNIQUE (vertical_slug, version)
|
|
729
742
|
);
|
|
743
|
+
${VERSION_MIGRATIONS_DDL}
|
|
730
744
|
-- Channels (#31 step 2): a named pointer per vertical. Promotion moves it,
|
|
731
745
|
-- and promotion is where the migration and permission diffs fire — the
|
|
732
746
|
-- moment a change reaches anyone, rather than the moment it was typed.
|
|
@@ -1116,10 +1130,33 @@ export class SqliteScopeHost {
|
|
|
1116
1130
|
ensureDirectorySchema() {
|
|
1117
1131
|
this.directory.transaction(() => {
|
|
1118
1132
|
const switchRecordIsNew = !systemSwitchesTableExists(switchSqlOf(this.directory));
|
|
1133
|
+
// #1764: `VERSION_MIGRATIONS_DDL` indexes these two columns, so a directory created
|
|
1134
|
+
// before them needs them before `applyDirectorySchema` reaches that statement.
|
|
1135
|
+
if (this.directory.prepare('PRAGMA table_info(vertical_versions)').all().length > 0) {
|
|
1136
|
+
this.ensureColumn(this.directory, 'vertical_versions', 'migration_count', 'migration_count INTEGER');
|
|
1137
|
+
this.ensureColumn(this.directory, 'vertical_versions', 'migrations_split', 'migrations_split INTEGER');
|
|
1138
|
+
}
|
|
1119
1139
|
this.applyDirectorySchema();
|
|
1120
1140
|
if (switchRecordIsNew)
|
|
1121
1141
|
this.directory.exec(SYSTEM_SWITCHES_BACKFILL_SQL);
|
|
1122
1142
|
})();
|
|
1143
|
+
// #1764: move the SQL out of every version stored before the split. A batch per
|
|
1144
|
+
// transaction, the same resumable step the Durable-Object adapter runs per alarm. This
|
|
1145
|
+
// adapter has no constructor budget to protect, so it runs them all on open. A batch that
|
|
1146
|
+
// fails is logged and the rest left for the next open: the host must still open, and a
|
|
1147
|
+
// version the backfill has not reached reads from its manifest.
|
|
1148
|
+
const sql = switchSqlOf(this.directory);
|
|
1149
|
+
try {
|
|
1150
|
+
while (this.directory.transaction(() => splitVersionMigrationsBatch(sql))().more)
|
|
1151
|
+
;
|
|
1152
|
+
}
|
|
1153
|
+
catch (err) {
|
|
1154
|
+
// The directory's own storage failing is not a backfill problem, and must not be
|
|
1155
|
+
// opened past as one.
|
|
1156
|
+
if (isStorageFault(err))
|
|
1157
|
+
throw err;
|
|
1158
|
+
console.error('substrat: version-migrations backfill failed; unsplit versions read from their manifests', err);
|
|
1159
|
+
}
|
|
1123
1160
|
}
|
|
1124
1161
|
registerExecutor(id, eventType, handler, retry) {
|
|
1125
1162
|
if (this.executors.has(id))
|
|
@@ -2472,6 +2509,37 @@ export class SqliteScopeHost {
|
|
|
2472
2509
|
.get(versionId, slug));
|
|
2473
2510
|
return row ? row.manifest_json : undefined;
|
|
2474
2511
|
}
|
|
2512
|
+
/**
|
|
2513
|
+
* #1756: the bind gate's question for one install (`bindExportBreaksOf`), from the directory.
|
|
2514
|
+
* The serving pointer is read only when the scope is on a serving script before or after the
|
|
2515
|
+
* move, the one case it decides anything.
|
|
2516
|
+
*/
|
|
2517
|
+
bindBreaks(actor, scope, incoming, servingRef) {
|
|
2518
|
+
const vertical = scope.vertical && (scope.servingRef || servingRef)
|
|
2519
|
+
? this.directory
|
|
2520
|
+
.prepare('SELECT serving_ref, serving_version_id FROM verticals WHERE slug = ?')
|
|
2521
|
+
.get(scope.vertical)
|
|
2522
|
+
: undefined;
|
|
2523
|
+
return bindExportBreaksOf({
|
|
2524
|
+
admin: this.admin,
|
|
2525
|
+
actor,
|
|
2526
|
+
scope,
|
|
2527
|
+
incoming: { id: incoming.id, verticalSlug: incoming.verticalSlug },
|
|
2528
|
+
...(servingRef !== undefined ? { servingRef } : {}),
|
|
2529
|
+
serving: vertical?.serving_ref && vertical.serving_version_id
|
|
2530
|
+
? { ref: vertical.serving_ref, versionId: vertical.serving_version_id }
|
|
2531
|
+
: null,
|
|
2532
|
+
readExports: async (versionId) => exportsOfManifestJson(this.manifestJsonOf(versionId) ?? null),
|
|
2533
|
+
readImports: async (slug, versionId) => this.versionImports(slug, versionId),
|
|
2534
|
+
});
|
|
2535
|
+
}
|
|
2536
|
+
/** What one version of `slug` imports, from the registry; `not_found` for a version it does not know. */
|
|
2537
|
+
versionImports(slug, versionId) {
|
|
2538
|
+
const manifest = this.manifestJsonOf(versionId, slug);
|
|
2539
|
+
if (manifest === undefined)
|
|
2540
|
+
throw substratError('not_found', `unknown version ${versionId} for vertical '${slug}'`);
|
|
2541
|
+
return importsOfManifestJson(manifest);
|
|
2542
|
+
}
|
|
2475
2543
|
/** #1705 PR 3: the promote gate's question, over two stored versions (`exportBreaksOf`). */
|
|
2476
2544
|
exportBreaksBetween(actor, producer, outgoingId, incomingId) {
|
|
2477
2545
|
return exportBreaksOf({
|
|
@@ -2480,12 +2548,7 @@ export class SqliteScopeHost {
|
|
|
2480
2548
|
producer,
|
|
2481
2549
|
outgoing: exportsOfManifestJson(this.manifestJsonOf(outgoingId)),
|
|
2482
2550
|
incoming: exportsOfManifestJson(this.manifestJsonOf(incomingId)),
|
|
2483
|
-
readImports: async (slug, versionId) =>
|
|
2484
|
-
const manifest = this.manifestJsonOf(versionId, slug);
|
|
2485
|
-
if (manifest === undefined)
|
|
2486
|
-
throw substratError('not_found', `unknown version ${versionId} for vertical '${slug}'`);
|
|
2487
|
-
return importsOfManifestJson(manifest);
|
|
2488
|
-
},
|
|
2551
|
+
readImports: async (slug, versionId) => this.versionImports(slug, versionId),
|
|
2489
2552
|
});
|
|
2490
2553
|
}
|
|
2491
2554
|
/**
|
|
@@ -2687,8 +2750,9 @@ export class SqliteScopeHost {
|
|
|
2687
2750
|
const observed = new Map();
|
|
2688
2751
|
for (const row of rt.db
|
|
2689
2752
|
.prepare(`SELECT type, MAX(occurred_at) AS at FROM _substrat_outbox
|
|
2690
|
-
WHERE type IN (
|
|
2691
|
-
|
|
2753
|
+
WHERE type IN (SELECT value FROM json_each(?)) GROUP BY type`)
|
|
2754
|
+
// One JSON array, the shape the DO twin needs for its 100-parameter limit (#1776).
|
|
2755
|
+
.all(JSON.stringify(types))) {
|
|
2692
2756
|
if (row.at !== null)
|
|
2693
2757
|
observed.set(row.type, row.at);
|
|
2694
2758
|
}
|
|
@@ -4087,6 +4151,28 @@ export class SqliteScopeHost {
|
|
|
4087
4151
|
archivedAt: r.archived_at ?? null,
|
|
4088
4152
|
createdAt: r.created_at,
|
|
4089
4153
|
});
|
|
4154
|
+
// The (version, scope) pair a bind and its impact read both start from, and the refusals
|
|
4155
|
+
// that come before any export-break question, in the order the bind makes them (#1756).
|
|
4156
|
+
const bindTarget = (tenantId, scopeId, versionId) => {
|
|
4157
|
+
const v = readVersion(versionId);
|
|
4158
|
+
if (!v)
|
|
4159
|
+
throw substratError('not_found', `unknown version ${versionId}`);
|
|
4160
|
+
const scope = this.directory.prepare('SELECT * FROM scopes WHERE scope_id = ?').get(scopeId);
|
|
4161
|
+
if (!scope || scope.tenant_id !== tenantId) {
|
|
4162
|
+
throw substratError('not_found', `unknown scope ${scopeId} in tenant ${tenantId}`);
|
|
4163
|
+
}
|
|
4164
|
+
// The refusal this registry exists for. Without it, "a push lands pending"
|
|
4165
|
+
// is a convention, and D-30's argument is that we cannot afford conventions
|
|
4166
|
+
// where lockstep upgrades are the failure mode. Scoped to a SERVING bind, though:
|
|
4167
|
+
// a PREVIEW fork serves no install (the builder's own tenant's data, non-canonical
|
|
4168
|
+
// URL), so it may run pending PR code — the own-tenant blast radius that lets a
|
|
4169
|
+
// private vertical self-admit, and what lets a LISTED vertical's builder keep
|
|
4170
|
+
// previewing their own new code (issue #509 ask (d)).
|
|
4171
|
+
if (v.admission !== 'admitted' && scope.kind !== 'preview') {
|
|
4172
|
+
throw new Error(`version ${versionId} is ${v.admission}, not admitted — it cannot be bound to a scope`);
|
|
4173
|
+
}
|
|
4174
|
+
return { v, scope };
|
|
4175
|
+
};
|
|
4090
4176
|
// Scope lifecycle transition (control-plane.md §4.2): validate ownership,
|
|
4091
4177
|
// enforce the legal transition graph (fail closed on an illegal one), flip
|
|
4092
4178
|
// the status, and audit before/after. un-archive is just another entry here
|
|
@@ -4979,13 +5065,19 @@ export class SqliteScopeHost {
|
|
|
4979
5065
|
// The manifest is retained for the serving upload (#286), not audited — a whole
|
|
4980
5066
|
// manifest per publish would drown the admin log in bundle metadata.
|
|
4981
5067
|
const { manifestJson, origin, ...audited } = parsed;
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
5068
|
+
// The SQL migrations are stored apart from the manifest (#1764), so no read of the
|
|
5069
|
+
// version but the promote review's carries them.
|
|
5070
|
+
const split = splitManifestMigrations(manifestJson ?? null, 'push');
|
|
5071
|
+
this.directory.transaction(() => {
|
|
5072
|
+
this.directory
|
|
5073
|
+
.prepare(`INSERT INTO vertical_versions
|
|
5074
|
+
(id, vertical_slug, version, manifest_digest, permission_digest,
|
|
5075
|
+
migration_digest, deployment_ref, admission, admission_note, manifest_json,
|
|
5076
|
+
origin_json, migration_count, migrations_split, created_at)
|
|
5077
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`)
|
|
5078
|
+
.run(audited.id, audited.verticalSlug, audited.version, audited.manifestDigest, audited.permissionDigest, audited.migrationDigest, audited.deploymentRef, selfAdmits ? 'admitted' : 'pending', selfAdmits ? AUTO_ADMISSION_NOTE : null, split.manifestJson, origin ? JSON.stringify(origin) : null, split.migrations?.length ?? null, new Date().toISOString());
|
|
5079
|
+
writeVersionMigrations(switchSqlOf(this.directory), audited.id, split.migrations);
|
|
5080
|
+
})();
|
|
4989
5081
|
this.recordAdmin(actor, 'publishVersion', { tenantId: null }, null, {
|
|
4990
5082
|
...audited,
|
|
4991
5083
|
...(origin ? { origin } : {}),
|
|
@@ -5091,6 +5183,10 @@ export class SqliteScopeHost {
|
|
|
5091
5183
|
// cleanup script (#248), never destroyed alongside a registry row.
|
|
5092
5184
|
this.directory.prepare('DELETE FROM vertical_channels WHERE vertical_slug = ?').run(slug);
|
|
5093
5185
|
this.directory.prepare('DELETE FROM vertical_channel_history WHERE vertical_slug = ?').run(slug);
|
|
5186
|
+
this.directory
|
|
5187
|
+
.prepare(`DELETE FROM vertical_version_migrations
|
|
5188
|
+
WHERE version_id IN (SELECT id FROM vertical_versions WHERE vertical_slug = ?)`)
|
|
5189
|
+
.run(slug);
|
|
5094
5190
|
this.directory.prepare('DELETE FROM vertical_versions WHERE vertical_slug = ?').run(slug);
|
|
5095
5191
|
this.directory.prepare('DELETE FROM verticals WHERE slug = ?').run(slug);
|
|
5096
5192
|
this.recordAdmin(actor, 'deleteVertical', { tenantId: null }, { slug, source: existing.source, ownerTenant: existing.ownerTenant }, null);
|
|
@@ -5288,25 +5384,21 @@ export class SqliteScopeHost {
|
|
|
5288
5384
|
at: r.at,
|
|
5289
5385
|
}));
|
|
5290
5386
|
},
|
|
5387
|
+
bindingImpact: async (actor, tenantId, scopeId, versionId, opts) => {
|
|
5388
|
+
const { v, scope } = bindTarget(tenantId, scopeId, versionId);
|
|
5389
|
+
const breaks = await this.bindBreaks(actor, mapScope(scope), v, opts?.servingRef);
|
|
5390
|
+
this.recordAccess(actor, 'bindingImpact', { tenantId, scopeId }, { versionId, ...opts }, breaks.length);
|
|
5391
|
+
return breaks;
|
|
5392
|
+
},
|
|
5291
5393
|
bindScopeVersion: async (actor, tenantId, scopeId, versionId, opts) => {
|
|
5292
|
-
const v =
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
.
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
}
|
|
5301
|
-
// The refusal this registry exists for. Without it, "a push lands pending"
|
|
5302
|
-
// is a convention, and D-30's argument is that we cannot afford conventions
|
|
5303
|
-
// where lockstep upgrades are the failure mode. Scoped to a SERVING bind, though:
|
|
5304
|
-
// a PREVIEW fork serves no install (the builder's own tenant's data, non-canonical
|
|
5305
|
-
// URL), so it may run pending PR code — the own-tenant blast radius that lets a
|
|
5306
|
-
// private vertical self-admit, and what lets a LISTED vertical's builder keep
|
|
5307
|
-
// previewing their own new code (issue #509 ask (d)).
|
|
5308
|
-
if (v.admission !== 'admitted' && scope.kind !== 'preview') {
|
|
5309
|
-
throw new Error(`version ${versionId} is ${v.admission}, not admitted — it cannot be bound to a scope`);
|
|
5394
|
+
const { v, scope } = bindTarget(tenantId, scopeId, versionId);
|
|
5395
|
+
const ack = bindAcknowledgement.parse(opts?.acknowledge ?? {});
|
|
5396
|
+
// #1756: an export an app in this tenant imports, dropped or re-versioned by what this
|
|
5397
|
+
// scope would run. Before the snapshot, so a refused bind leaves nothing behind.
|
|
5398
|
+
if (!ack.exportBreak) {
|
|
5399
|
+
const breaks = await this.bindBreaks(actor, mapScope(scope), v);
|
|
5400
|
+
if (breaks.length > 0)
|
|
5401
|
+
throw substratError('precondition_failed', bindExportBreakRefusal(breaks));
|
|
5310
5402
|
}
|
|
5311
5403
|
// Fork-before-promote (§4): snapshot the pre-migration data if this rebind
|
|
5312
5404
|
// crosses a migration boundary. Gated on a real digest change — a code-only
|
|
@@ -5324,6 +5416,7 @@ export class SqliteScopeHost {
|
|
|
5324
5416
|
versionId,
|
|
5325
5417
|
vertical: v.verticalSlug,
|
|
5326
5418
|
version: v.version,
|
|
5419
|
+
...(ack.exportBreak ? { acknowledged: ack } : {}),
|
|
5327
5420
|
});
|
|
5328
5421
|
},
|
|
5329
5422
|
/**
|
|
@@ -5381,17 +5474,32 @@ export class SqliteScopeHost {
|
|
|
5381
5474
|
this.recordAccess(actor, 'versionManifest', {}, { verticalSlug, versionId }, v.manifest_json ? 1 : 0);
|
|
5382
5475
|
return v.manifest_json;
|
|
5383
5476
|
},
|
|
5384
|
-
|
|
5385
|
-
const
|
|
5386
|
-
|
|
5387
|
-
|
|
5477
|
+
versionMigrations: async (actor, verticalSlug, versionId) => {
|
|
5478
|
+
const v = versionMigrationsOf(switchSqlOf(this.directory), versionId);
|
|
5479
|
+
if (!v || v.verticalSlug !== verticalSlug) {
|
|
5480
|
+
throw substratError('not_found', `unknown version ${versionId} for vertical '${verticalSlug}'`);
|
|
5481
|
+
}
|
|
5482
|
+
this.recordAccess(actor, 'versionMigrations', {}, { verticalSlug, versionId }, v.migrations?.length ?? 0);
|
|
5483
|
+
return v.migrations;
|
|
5484
|
+
},
|
|
5485
|
+
setScopeServingRef: async (actor, tenantId, scopeId, servingRef, opts) => {
|
|
5486
|
+
const scope = this.directory.prepare('SELECT * FROM scopes WHERE scope_id = ?').get(scopeId);
|
|
5388
5487
|
if (!scope || scope.tenant_id !== tenantId) {
|
|
5389
5488
|
throw substratError('not_found', `unknown scope ${scopeId} in tenant ${tenantId}`);
|
|
5390
5489
|
}
|
|
5490
|
+
const ack = bindAcknowledgement.parse(opts?.acknowledge ?? {});
|
|
5491
|
+
// #1756: onto (or off) a serving script, the scope runs other code before its pointer
|
|
5492
|
+
// moves. Judged here, so no caller that routes first and binds second passes unasked.
|
|
5493
|
+
const bound = scope.vertical_version_id ? readVersion(scope.vertical_version_id) : undefined;
|
|
5494
|
+
if (!ack.exportBreak && bound) {
|
|
5495
|
+
const breaks = await this.bindBreaks(actor, mapScope(scope), bound, servingRef);
|
|
5496
|
+
if (breaks.length > 0)
|
|
5497
|
+
throw substratError('precondition_failed', bindExportBreakRefusal(breaks));
|
|
5498
|
+
}
|
|
5391
5499
|
this.directory
|
|
5392
5500
|
.prepare('UPDATE scopes SET serving_ref = ? WHERE scope_id = ?')
|
|
5393
5501
|
.run(servingRef, scopeId);
|
|
5394
|
-
this.recordAdmin(actor, 'setScopeServingRef', { tenantId, scopeId }, { servingRef: scope.serving_ref }, { servingRef });
|
|
5502
|
+
this.recordAdmin(actor, 'setScopeServingRef', { tenantId, scopeId }, { servingRef: scope.serving_ref }, { servingRef, ...(ack.exportBreak ? { acknowledged: ack } : {}) });
|
|
5395
5503
|
},
|
|
5396
5504
|
setScopeExpiresAt: async (actor, tenantId, scopeId, expiresAt) => {
|
|
5397
5505
|
const scope = this.directory
|
|
@@ -5826,8 +5934,9 @@ export class SqliteScopeHost {
|
|
|
5826
5934
|
// than degenerating into an unfiltered read of the whole fleet.
|
|
5827
5935
|
if (statuses.length === 0)
|
|
5828
5936
|
return [];
|
|
5829
|
-
|
|
5830
|
-
|
|
5937
|
+
// One JSON array, the shape the DO twin needs for its 100-parameter limit (#1776).
|
|
5938
|
+
where.push('status IN (SELECT value FROM json_each(?))');
|
|
5939
|
+
params.push(JSON.stringify(statuses));
|
|
5831
5940
|
}
|
|
5832
5941
|
if (filter?.vertical) {
|
|
5833
5942
|
where.push('vertical = ?');
|
|
@@ -6879,8 +6988,9 @@ export class SqliteScopeHost {
|
|
|
6879
6988
|
const actions = Array.isArray(filter.action) ? filter.action : [filter.action];
|
|
6880
6989
|
if (actions.length === 0)
|
|
6881
6990
|
return []; // no action is acceptable — match nothing
|
|
6882
|
-
|
|
6883
|
-
|
|
6991
|
+
// One JSON array, the shape the DO twin needs for its 100-parameter limit (#1776).
|
|
6992
|
+
where.push('action IN (SELECT value FROM json_each(?))');
|
|
6993
|
+
params.push(JSON.stringify(actions));
|
|
6884
6994
|
}
|
|
6885
6995
|
if (filter?.since) {
|
|
6886
6996
|
where.push('at >= ?');
|
|
@@ -7374,6 +7484,8 @@ export class SqliteScopeHost {
|
|
|
7374
7484
|
this.ensureColumn(this.directory, 'vertical_versions', 'manifest_json', 'manifest_json TEXT');
|
|
7375
7485
|
// Push provenance (git CI vs a terminal) — null for a pre-tracking push.
|
|
7376
7486
|
this.ensureColumn(this.directory, 'vertical_versions', 'origin_json', 'origin_json TEXT');
|
|
7487
|
+
// #1764's `migration_count` and `migrations_split` are added in `ensureDirectorySchema`,
|
|
7488
|
+
// BEFORE the DDL, because `VERSION_MIGRATIONS_DDL` indexes one of them.
|
|
7377
7489
|
// #33: the SKU flag learns to express a plan. All nullable — a legacy row
|
|
7378
7490
|
// reads as a perpetual boolean flag, exactly its pre-widening semantics.
|
|
7379
7491
|
for (const [col, ddl] of [
|