@substrat-run/adapter-cloudflare 0.140.0 → 0.142.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/connector-calls.d.ts +74 -7
- package/dist/connector-calls.d.ts.map +1 -1
- package/dist/connector-calls.js +56 -6
- package/dist/connector-calls.js.map +1 -1
- package/dist/control-plane-do.d.ts +55 -5
- package/dist/control-plane-do.d.ts.map +1 -1
- package/dist/control-plane-do.js +208 -13
- package/dist/control-plane-do.js.map +1 -1
- package/dist/host.d.ts +26 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +164 -23
- package/dist/host.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/scope-do.d.ts +1 -1
- package/dist/scope-do.d.ts.map +1 -1
- package/dist/scope-do.js +69 -4
- package/dist/scope-do.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -27,6 +27,6 @@ export { createD1TenantStores, d1TenantRelationalStore, tenantStoreDatabaseName,
|
|
|
27
27
|
export { blobStoreBucketName, createR2BlobStores, r2TenantBlobStore, } from './r2.js';
|
|
28
28
|
export { createRouteResolver } from './route-resolver.js';
|
|
29
29
|
export { cloudflareClientContext, cloudflareGeo } from './client-context.js';
|
|
30
|
-
// #1978:
|
|
30
|
+
// #1978: moved here from the kernel — the hosted connector-call recorder.
|
|
31
31
|
export { analyticsEngineConnectorCallRecorder, CONNECTOR_CALL_DATA_POINT_LAYOUT, connectorCallDataPoint, } from './connector-calls.js';
|
|
32
32
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAWhD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,6FAA6F;AAC7F,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,6BAA6B,GAK9B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAQjF,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAWhD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,6FAA6F;AAC7F,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,6BAA6B,GAK9B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAQjF,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7E,0EAA0E;AAC1E,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
|
package/dist/scope-do.d.ts
CHANGED
|
@@ -74,5 +74,5 @@ export type CapabilityAttachmentReply<T> = DoReply<T>;
|
|
|
74
74
|
export declare function switchSqlOver(sql: SqlStorage): SwitchSql;
|
|
75
75
|
/** The splitter both adapters run migrations through — the kernel's, re-exported for this package's callers. */
|
|
76
76
|
export { splitSqlStatements };
|
|
77
|
-
export declare function defineScopeDO(modules: ModuleRegistration[], bareOps: Record<string, OperationHandler<never, unknown>>): new (ctx: DurableObjectState, env: ScopeDoEnv) => DurableObject
|
|
77
|
+
export declare function defineScopeDO(modules: ModuleRegistration[], bareOps: Record<string, OperationHandler<never, unknown>>): new (ctx: DurableObjectState, env: ScopeDoEnv) => DurableObject<ScopeDoEnv>;
|
|
78
78
|
//# sourceMappingURL=scope-do.d.ts.map
|
package/dist/scope-do.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-do.d.ts","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"scope-do.d.ts","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA4DnD,OAAO,EA6DL,KAAK,SAAS,EAsBd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EAqGtB,MAAM,sBAAsB,CAAC;AAiD9B,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAkBL,kBAAkB,EAqEnB,MAAM,sBAAsB,CAAC;AA0B9B;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAoFD,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAqjB5E;;;GAGG;AACH,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAmBtD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAOxD;AAED,gHAAgH;AAChH,OAAO,EAAE,kBAAkB,EAAE,CAAC;AA2B9B,wBAAgB,aAAa,CAC3B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,GACxD,KAAK,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,KAAK,aAAa,CAAC,UAAU,CAAC,CAo5N7E"}
|
package/dist/scope-do.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { REWIND_REFUSED } from './rewind-refusal.js';
|
|
2
2
|
import { SYSTEM_DOOR_MOVED } from './system-door.js';
|
|
3
3
|
import { DurableObject } from 'cloudflare:workers';
|
|
4
|
-
import { ATTACHMENT_ADDED, ATTACHMENT_REMOVED, attachmentRecord, domainEvent, domainEventInput, eventId, instant, objectRef, entityObjectRef, assertModuleEmittableType, assertKernelAuthoredType, toWireFailure, grantRefFromProof, principalId, scopeId as scopeIdOf, tenantId as tenantIdOf, platformRequestInput, platformRequestId, MAX_PENDING_PLATFORM_REQUESTS, MAX_PENDING_SWEEP_RUNS, SWEEP_RUNS_KIND, SCOPE_TABLE_PAGE_MAX, SCOPE_QUERY_ROW_MAX, listLimitOf, pageOf, countedPageOf, requestFingerprint, substratError, errorCodeOf, assertReplayableDump, REDRAIN_BATCH, } from '@substrat-run/contracts';
|
|
4
|
+
import { ATTACHMENT_ADDED, ATTACHMENT_REMOVED, attachmentRecord, domainEvent, domainEventInput, eventId, instant, objectRef, entityObjectRef, assertModuleEmittableType, assertKernelAuthoredType, toWireFailure, grantRefFromProof, principalId, principalBecomeCapabilityInput, scopeId as scopeIdOf, tenantId as tenantIdOf, platformRequestInput, platformRequestId, MAX_PENDING_PLATFORM_REQUESTS, MAX_PENDING_SWEEP_RUNS, SWEEP_RUNS_KIND, SCOPE_TABLE_PAGE_MAX, SCOPE_QUERY_ROW_MAX, listLimitOf, pageOf, countedPageOf, requestFingerprint, substratError, errorCodeOf, assertReplayableDump, REDRAIN_BATCH, } from '@substrat-run/contracts';
|
|
5
5
|
import { ulid, LIVE_CLOSE, LIVE_SOCKETS_PER_PRINCIPAL, DO_SQL_LIMITS, unknownRoleError, createUlid, assertAllowed, ConnectionSealingKeyUnavailableError, noSealingKeyMessage, sealTo, assertReadOnlyQuery, entitlementDenial, platformRequestHistoryQuery, platformRequestOf, PLATFORM_REQUEST_COLUMNS, PLATFORM_REQUEST_REDACTION_SQL, platformRequestRedactionParams, platformRequestRedactionQuery, intentPayloadCarriesSubject, redactSubjectJobRuns, eraseSubjectFromModules, moduleErasurePlan, redactSubjectScopeText, assertRowLimit, assertRowOffset, JOB_RUN_PATCH_SQL, JOB_RUN_CLAIM_SQL, JOB_RUN_RENEW_SQL, JOB_RUN_BEGIN_SQL, JOB_RUN_MISS_SQL, JOB_RUN_MISS_SETTLE_SQL, admissionMissOutcome, JOB_LEASE_EXPIRED_NOTE, JOB_STEP_RECORD_SQL, DELIVERY_ERROR_REDACTION_SQL, REDACTED_DELIVERY_NOTE, seatScopeTuple, delegatedRevokeSql, writeExplicitTupleIn, grantEntityShapeIn, topUpEntityGrantShapes, applyScopeRoleChange, changeScopeRole, revokeScopeRoles, scopeRoleHolders, effectiveRoleGrantQuery, switchRecordedOff, switchSystemSchedules, peerGrantsStatus, systemGrantsStatus, systemScheduleState, systemSwitchedOff, denialListQuery, refusalListQuery, mapRefusalRow, denialSummaryQuery, denialTotalsQuery, DENIAL_WINDOW_QUERY, mapDenialRow, mapDenialSummaryBuckets, PermissionDenied, assertImpersonationWrites, assertModuleEnqueueableKind, impersonationStampOf, createAtomic, NotSearchable, isSearchIndexTable, searchIndexPlans, NotListable, listIndexPlans, moduleMigrations, MIGRATION_DIGEST_FENCE_DDL, MIGRATION_DIGEST_MARK_LEGACY, assertJournalDumpCoherent, assertMigrationSql, migrationDivergence, migrationFailedError, migrationSteps, planMigrations, listQuery, cursorOf, searchLimit, searchMatchExpression, searchQuery, ATTACHMENT_TEXT_DDL, attachmentRecordOfRow, enqueueAttachmentText, reconcileAttachmentText, queueAttachmentTextBackfill, startAttachmentTextBackfill, recordAttachmentText, searchAttachments, IDEMPOTENCY_DDL, REFUSALS_TABLE_DDL, REFUSALS_INDEX, refusalInsert, refusalOf, markGuardRefusal, REFUSALS_REBUILD, refusalsAdmitGuards, assertIdempotencyKey, assertPermissionKey, idempotencyLookupQuery, idempotencyPruneStatement, idempotencyRecordStatement, idempotencyOptedOutMessage, replayFor, entityVersionQuery, entityVersionOf, assertIfMatch, OUTBOX_ENTITY_INDEX, SCHEDULE_STATE_DDL, SCHEDULE_STATE_REBUILD, scheduleStateHasKind, VERTICAL_EVENTS_DDL, EXPORT_HOPS_SQL, emptyImportResult, IMPORT_CURSORS_SQL, IMPORT_CURSOR_OF_SQL, OUTBOX_MARK_SQL, exportedSinceQuery, emittedSinceQuery, emittedReportOf, EMITTED_REPORT_CAP, IMPORT_CURSOR_ADVANCE_SQL, IMPORT_RECORD_SQL, moveImportCursor, CrossVerticalRegistry, exportReadPlan, exportReadQuery, planExportBatch, withheldNote, JOB_RUN_DDL, JOB_RUN_DUE_AT, jobRunListLimit, SYSTEM_DOOR_WAIT, ancestorsWithin, } from '@substrat-run/kernel';
|
|
6
6
|
import { isUpgradeRequest, readSubscription, LIVE_DECIDE_ATTEMPTS, LIVE_FANOUT_LIMIT, LIVE_MODE_HEADER, LIVE_PRINCIPAL_HEADER, LIVE_SCOPE_HEADER, LIVE_SUBSCRIBE_PATH, LIVE_TENANT_HEADER, LIVE_WITHIN_HEADER, LIVE_EXPIRES_HEADER, decodeLiveWithin, liveInstant, } from './live-reads.js';
|
|
7
7
|
import { replyOf } from './do-reply.js';
|
|
8
8
|
import { OperationQueue } from './serialization.js';
|
|
9
9
|
import { assertNoWorkerdStorage, doScopedSql, doBuiltColumnsOf, doRedactionSql, doSpineSql } from './sql.js';
|
|
10
|
-
import { actorOf, admitPeer, collectPeers, switchPeer, peerSubjectRef, subjectGrantState, assertNoSecret, CAPABILITY_DDL, COPY_ORIGIN_DDL, ENTITY_STATE_MOVES_DDL, SWITCH_FENCES_DDL, TABLE_OWNERS_DDL, assertMigrationLeavesLedgerAlone, recordOwnershipSteps, runMigrationStatements, splitSqlStatements, executableSqlStatements, blankSqlComments, CAPABILITY_EXCHANGE_OPERATION, capabilityAttachmentWriteRefused, createCapabilityVerbs, createEntityEdgeVerbs, createEntityStateVerbs, createTrashedReads, CONTINUATION_POSITION_CAP, visibleContinuation, searchStateWhere, uncheckedView, addStatePlans, assertNoCallerPurge, isUnreachableParent, PURGE_BATCH, heldPurgePass, lifecycleRefusal, purgeHeldBy, purgeDueOf, purgeOnlyKeysOf, runPurgePass, refuseTrashedTarget, registerTrashTargets, withheldKeysFor, statefulTablesOf, afterMigration, afterRuntimeDdl, derivesAnything, repairDerivedObjects, StateColumnLost, exchangeCapability, guardSecrets, mintBecomeCapability, redactSecrets, redactSecretText, moduleLog, asyncInvocationId, asyncLinePass, resolveCapabilitySession, revokeCapabilityAsPlatform, readCapabilityPage, domainEventOf, facetEvents, readDeadLetters, readLifecycleFlow, readOperationSeries, readHistory, readInvocation, readUndrainedOutbox, walkEventCause, walkEventEffects, } from '@substrat-run/kernel';
|
|
10
|
+
import { actorOf, admitPeer, collectPeers, switchPeer, peerSubjectRef, subjectGrantState, assertNoSecret, CAPABILITY_DDL, COPY_ORIGIN_DDL, ENTITY_STATE_MOVES_DDL, SWITCH_FENCES_DDL, TABLE_OWNERS_DDL, assertMigrationLeavesLedgerAlone, recordOwnershipSteps, runMigrationStatements, splitSqlStatements, executableSqlStatements, blankSqlComments, CAPABILITY_EXCHANGE_OPERATION, CAPABILITY_BECOME_MINT_OPERATION, becomeMintCheck, mintBecomeCapabilityAsPrincipal, revokeBecomeCapabilityAsPrincipal, readBecomeLinkStates, capabilityAttachmentWriteRefused, createCapabilityVerbs, createEntityEdgeVerbs, createEntityStateVerbs, createTrashedReads, CONTINUATION_POSITION_CAP, visibleContinuation, searchStateWhere, uncheckedView, addStatePlans, assertNoCallerPurge, isUnreachableParent, PURGE_BATCH, heldPurgePass, lifecycleRefusal, purgeHeldBy, purgeDueOf, purgeOnlyKeysOf, runPurgePass, refuseTrashedTarget, registerTrashTargets, withheldKeysFor, statefulTablesOf, afterMigration, afterRuntimeDdl, derivesAnything, repairDerivedObjects, StateColumnLost, exchangeCapability, guardSecrets, mintBecomeCapability, redactSecrets, redactSecretText, moduleLog, asyncInvocationId, asyncLinePass, resolveCapabilitySession, revokeCapabilityAsPlatform, readCapabilityPage, domainEventOf, facetEvents, readDeadLetters, readLifecycleFlow, readOperationSeries, readHistory, readInvocation, readUndrainedOutbox, walkEventCause, walkEventEffects, } from '@substrat-run/kernel';
|
|
11
|
+
import { COPY_RESTORE_FENCE_LAPSED, copyRestoreFenceLapsed } from '@substrat-run/kernel';
|
|
11
12
|
import { createDoTupleChecker, createLocalControlPlaneReader, scopeTupleReader } from './checker.js';
|
|
12
13
|
import { settlePlatformRequestIn } from '@substrat-run/kernel';
|
|
13
14
|
import { CARRIED_AWAY_KEY, COPY_MARK_CLEARED_KEY, KEPT_COPY_REFUSAL, KEPT_DIVERGENT_KEY, LOAD_STAMP_KEY, STORE_LOCAL_META_KEYS, WRITE_REVISION_KEY, carriedAwayDump, isCopyMarkInsert, isWriteStatement, assertSpineTablesBuilt, capabilitiesForLoad, clearCopyMarker, dumpRowsInsert, isSpineTable, markCopyOrigin, repointScopeGrants, settleCopiedWork, emittedHere, IS_COPY_SQL, isCopyLoad, isLifecycleWrite, readLifecycle, settleLifecycleAfterLoad, writeLifecycle, spineColumnAdditions } from '@substrat-run/kernel';
|
|
@@ -39,6 +40,9 @@ const foreignTenant = (held, tenantId) => held !== null
|
|
|
39
40
|
: `refused: this scope holds role rows for another tenant and none for ${tenantId}`;
|
|
40
41
|
/** #2016: the load refusals `tenantReceiptRefusal` raised, told apart by identity, not by text. */
|
|
41
42
|
const tenantRefusals = new WeakSet();
|
|
43
|
+
/** #1722: a load refused because its copy move's lease ran out (`CopyRestoreFence`), told apart
|
|
44
|
+
* from a store that moved, since the host must not read it as an applied retry. */
|
|
45
|
+
const fenceRefusals = new WeakSet();
|
|
42
46
|
/**
|
|
43
47
|
* The scope spine, as this adapter builds it — one of two hand-written copies (#969).
|
|
44
48
|
*
|
|
@@ -2982,7 +2986,7 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
2982
2986
|
return this.queue.enqueue(async () => {
|
|
2983
2987
|
let capability;
|
|
2984
2988
|
try {
|
|
2985
|
-
capability = resolveCapabilitySession(doSpineSql(this.sql), sessionHash, instant.parse(new Date().toISOString()), operation);
|
|
2989
|
+
capability = resolveCapabilitySession(doSpineSql(this.sql), sessionHash, instant.parse(new Date().toISOString()), operation, true);
|
|
2986
2990
|
}
|
|
2987
2991
|
catch (err) {
|
|
2988
2992
|
return { failure: toWireFailure(err) };
|
|
@@ -3500,6 +3504,9 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
3500
3504
|
// pseudo-operation name — the actor is the capability, as on every event it
|
|
3501
3505
|
// goes on to cause.
|
|
3502
3506
|
emit: (capability, event) => kernelEmit(this.operationContext(principalId.parse(ulid()), tenantId, scopeId, undefined, undefined, undefined, undefined, undefined, CAPABILITY_EXCHANGE_OPERATION, capability, [], now), event),
|
|
3507
|
+
holdings: this.checker.holdings
|
|
3508
|
+
? (principal) => this.checker.holdings({ kind: 'principal', id: principal }, { tenantId, scopeId })
|
|
3509
|
+
: undefined,
|
|
3503
3510
|
}, secret, mode);
|
|
3504
3511
|
});
|
|
3505
3512
|
if (outcome)
|
|
@@ -3507,6 +3514,49 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
3507
3514
|
return outcome;
|
|
3508
3515
|
});
|
|
3509
3516
|
}
|
|
3517
|
+
/**
|
|
3518
|
+
* A principal's `become` mint (#1686) — a member invite's link. The kernel's
|
|
3519
|
+
* `becomeMintCheck` and the write in ONE queued body and one storage transaction, so
|
|
3520
|
+
* nothing the target or the caller holds moves between the check and the mint; a refusal
|
|
3521
|
+
* writes nothing. On the spine as `capability.become-minted`, the caller its actor.
|
|
3522
|
+
*/
|
|
3523
|
+
async mintBecomeCapabilityBoundedFor(tenantId, scopeId, caller, input) {
|
|
3524
|
+
await this.ensureMigrations();
|
|
3525
|
+
const minter = principalId.parse(caller);
|
|
3526
|
+
const parsed = principalBecomeCapabilityInput.parse(input);
|
|
3527
|
+
return await this.queue.enqueue(async () => {
|
|
3528
|
+
const checked = await becomeMintCheck({ sql: doSpineSql(this.sql), checker: this.checker }, minter, parsed.principal, { tenantId, scopeId });
|
|
3529
|
+
if (!checked.ok)
|
|
3530
|
+
return checked;
|
|
3531
|
+
const liveSince = this.liveHighWaterMark();
|
|
3532
|
+
const now = instant.parse(new Date().toISOString());
|
|
3533
|
+
let minted;
|
|
3534
|
+
await this.revision.transaction(async () => {
|
|
3535
|
+
minted = await mintBecomeCapabilityAsPrincipal({
|
|
3536
|
+
sql: doSpineSql(this.sql),
|
|
3537
|
+
now,
|
|
3538
|
+
emit: (event) => kernelEmit(this.operationContext(minter, tenantId, scopeId, undefined, undefined, undefined, undefined, undefined, CAPABILITY_BECOME_MINT_OPERATION, undefined, [], now), event),
|
|
3539
|
+
}, minter, parsed, checked.targetDigest);
|
|
3540
|
+
});
|
|
3541
|
+
await this.settleCommitted(tenantId, scopeId, liveSince, null);
|
|
3542
|
+
return { ok: true, minted: minted };
|
|
3543
|
+
});
|
|
3544
|
+
}
|
|
3545
|
+
/** Where each named `become` link stands (#1686) — a pending-invite list's read. */
|
|
3546
|
+
async becomeLinkStatesFor(tenantId, scopeId, ids) {
|
|
3547
|
+
await this.ensureMigrations();
|
|
3548
|
+
return this.queue.enqueue(() => readBecomeLinkStates(doSpineSql(this.sql), ids, instant.parse(new Date().toISOString()), this.checker.holdings
|
|
3549
|
+
? (principal) => this.checker.holdings({ kind: 'principal', id: principal }, { tenantId, scopeId })
|
|
3550
|
+
: undefined));
|
|
3551
|
+
}
|
|
3552
|
+
/**
|
|
3553
|
+
* Revoke a `become` capability a principal minted (#1686) — withdrawing a member invite's
|
|
3554
|
+
* link, with `by` recorded as the revoker. False for any other capability.
|
|
3555
|
+
*/
|
|
3556
|
+
async revokeBecomeCapabilityFor(tenantId, scopeId, id, by) {
|
|
3557
|
+
await this.ensureMigrations();
|
|
3558
|
+
return await this.queue.enqueue(() => revokeBecomeCapabilityAsPrincipal({ sql: doSpineSql(this.sql), checker: this.checker, node: { tenantId, scopeId }, now: instant.parse(new Date().toISOString()) }, id, principalId.parse(by)));
|
|
3559
|
+
}
|
|
3510
3560
|
/**
|
|
3511
3561
|
* The platform's mint (#1672, `HostAdmin.mintCapability`) — a `become` capability,
|
|
3512
3562
|
* serialized on the queue with every other spine write. One INSERT, so it needs no
|
|
@@ -4632,6 +4682,12 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
4632
4682
|
// #2066: the rows already there get the legacy mark below, never a digest.
|
|
4633
4683
|
'ALTER TABLE _substrat_migrations ADD COLUMN sql_digest TEXT',
|
|
4634
4684
|
'ALTER TABLE _substrat_tuples ADD COLUMN revoked_at TEXT',
|
|
4685
|
+
// #2126: NULL keeps every existing capability's attachment behavior unchanged.
|
|
4686
|
+
'ALTER TABLE _substrat_capabilities ADD COLUMN attachments TEXT',
|
|
4687
|
+
// #1686: NULL on every row already there — none is a principal-minted become.
|
|
4688
|
+
'ALTER TABLE _substrat_capabilities ADD COLUMN target_digest TEXT',
|
|
4689
|
+
// #1686: why the kernel revoked a link itself; NULL for every revoke already there.
|
|
4690
|
+
'ALTER TABLE _substrat_capabilities ADD COLUMN revoked_reason TEXT',
|
|
4635
4691
|
// #1632: legacy runs retain an unknown subject; no content-based backfill.
|
|
4636
4692
|
'ALTER TABLE _substrat_job_runs ADD COLUMN subject_id TEXT',
|
|
4637
4693
|
// #2034: the lease. NULL = nobody holds the run, which is right for every row already there.
|
|
@@ -4762,7 +4818,7 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
4762
4818
|
this.sql.exec(stmt);
|
|
4763
4819
|
});
|
|
4764
4820
|
}
|
|
4765
|
-
async importDump(tables, destScopeId, { switchOff, sourceScopeId, exact, loadStamp, expect, resolveKept, markCopy, provisionedFor, } = {}) {
|
|
4821
|
+
async importDump(tables, destScopeId, { switchOff, sourceScopeId, exact, loadStamp, expect, resolveKept, markCopy, provisionedFor, fence, } = {}) {
|
|
4766
4822
|
// The WHOLE drop-then-replay runs under deferred foreign keys, in one transaction.
|
|
4767
4823
|
//
|
|
4768
4824
|
// Two distinct FK hazards, and both need the deferral — the second is why it cannot
|
|
@@ -4798,6 +4854,13 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
4798
4854
|
throw substratError('validation_failed', 'restore refused: `exact` needs the scope the dump came from');
|
|
4799
4855
|
}
|
|
4800
4856
|
const switched = await this.revision.transaction(async () => {
|
|
4857
|
+
// #1722: first, before any read: a store a reap has since emptied must refuse the late load
|
|
4858
|
+
// too, and the check is against this store's clock, inside the load's own transaction.
|
|
4859
|
+
if (fence && copyRestoreFenceLapsed(fence, Date.now())) {
|
|
4860
|
+
const lapsed = substratError('precondition_failed', COPY_RESTORE_FENCE_LAPSED);
|
|
4861
|
+
fenceRefusals.add(lapsed);
|
|
4862
|
+
throw lapsed;
|
|
4863
|
+
}
|
|
4801
4864
|
const before = this.loadMarker();
|
|
4802
4865
|
// #1713: the lifecycle the platform delivered here, read before the drops take it.
|
|
4803
4866
|
const lifecycleBefore = readLifecycle(this.switchSql());
|
|
@@ -5002,6 +5065,8 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
5002
5065
|
return { refused: false, switchedOff: await this.importDump(tables, destScopeId, opts) };
|
|
5003
5066
|
}
|
|
5004
5067
|
catch (e) {
|
|
5068
|
+
if (e instanceof Error && fenceRefusals.has(e))
|
|
5069
|
+
return { refused: 'lapsed' };
|
|
5005
5070
|
const code = errorCodeOf(e);
|
|
5006
5071
|
if (code === 'precondition_failed')
|
|
5007
5072
|
return { refused: 'changed' };
|