@substrat-run/adapter-cloudflare 0.148.0 → 0.149.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/control-plane-do.d.ts +87 -27
- package/dist/control-plane-do.d.ts.map +1 -1
- package/dist/control-plane-do.js +135 -52
- package/dist/control-plane-do.js.map +1 -1
- package/dist/host.d.ts +40 -11
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +274 -85
- package/dist/host.js.map +1 -1
- package/dist/route-resolver.js +2 -2
- package/dist/route-resolver.js.map +1 -1
- package/dist/scope-do.d.ts +7 -0
- package/dist/scope-do.d.ts.map +1 -1
- package/dist/scope-do.js +121 -17
- package/dist/scope-do.js.map +1 -1
- package/package.json +9 -9
package/dist/route-resolver.js
CHANGED
|
@@ -10,8 +10,8 @@ function scopeStoresOf(json) {
|
|
|
10
10
|
if (typeof entry !== 'object' || entry === null)
|
|
11
11
|
return [];
|
|
12
12
|
const binding = Reflect.get(entry, 'binding');
|
|
13
|
-
const
|
|
14
|
-
return typeof binding === 'string' && typeof
|
|
13
|
+
const driver = Reflect.get(entry, 'driver');
|
|
14
|
+
return typeof binding === 'string' && typeof driver === 'string' ? [{ binding, driver }] : [];
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-resolver.js","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,qBAAqB,GAGtB,MAAM,yBAAyB,CAAC;AAiDjC,SAAS,aAAa,CAAC,IAA+B;IACpD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC9C,MAAM,
|
|
1
|
+
{"version":3,"file":"route-resolver.js","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/scope-do.d.ts
CHANGED
|
@@ -32,6 +32,13 @@ export interface ScopeDoEnv {
|
|
|
32
32
|
* worker, stamps NULL.
|
|
33
33
|
*/
|
|
34
34
|
SUBSTRAT_VERSION_ID?: string;
|
|
35
|
+
/**
|
|
36
|
+
* The migration set digest of the version this script serves (#2349), injected at upload
|
|
37
|
+
* beside `SUBSTRAT_VERSION_ID` for a version whose migrations the control plane stores. A pass
|
|
38
|
+
* with migrations pending applies none unless its registered set matches. Optional: an unheld
|
|
39
|
+
* version, a script uploaded before the binding, or a test worker compares nothing.
|
|
40
|
+
*/
|
|
41
|
+
SUBSTRAT_MIGRATIONS_DIGEST?: string;
|
|
35
42
|
}
|
|
36
43
|
/** #2016: how a tenant reads against a scope's record (`ScopeDO.tenantVerdict`). */
|
|
37
44
|
export type TenantVerdict = 'recorded' | 'inferred' | 'foreign' | 'unknown';
|
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;AA8DnD,OAAO,EA2DL,KAAK,SAAS,EAsBd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"scope-do.d.ts","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA8DnD,OAAO,EA2DL,KAAK,SAAS,EAsBd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EA2GtB,MAAM,sBAAsB,CAAC;AAoD9B,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAwBL,kBAAkB,EA4EnB,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;IAC7B;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAoFD,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAqkB5E;;;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,CAywO7E"}
|
package/dist/scope-do.js
CHANGED
|
@@ -2,13 +2,13 @@ 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
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
|
-
import { ulid, 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';
|
|
5
|
+
import { ulid, 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, migrationSetDivergence, migrationSteps, planMigrations, listQuery, cursorOf, searchLimit, searchMatchExpression, searchQuery, ATTACHMENT_TEXT_DDL, ATTACHMENT_CONDEMNED_DDL, condemnOrphanAttachments, refuseCondemnedAttachment, refuseCondemnedInDump, rowlessAttachmentIds, 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, LIVE_CLOSE, LIVE_SOCKETS_PER_PRINCIPAL, 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, UPLOAD_LINK_DDL, createAttachmentVerbs, inspectUploadLink, redeemUploadLinkInTransaction, 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, ENTITY_UNBIND_OPERATION, allowedFor, unbindEntityHolderBounded, capabilityAttachmentWriteRefused, createCapabilityVerbs, createEntityEdgeVerbs, createEntityStateVerbs, createTrashedReads, CONTINUATION_POSITION_CAP, visibleContinuation, searchStateWhere, uncheckedView, addStatePlans, addUpdatedStampPlans, watchUpdatedStamps, assertNoCallerPurge, isUnreachableParent, PURGE_BATCH, heldPurgePass, lifecycleRefusal, purgeHeldBy, purgeDueOf, purgeOnlyKeysOf, runPurgePass, refuseTrashedTarget, assertBoundOperations, 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';
|
|
10
|
+
import { actorOf, admitPeer, boundToPeerDeclarations, collectPeers, switchPeer, peerSubjectRef, subjectGrantState, assertNoSecret, CAPABILITY_DDL, UPLOAD_LINK_DDL, createAttachmentVerbs, inspectUploadLink, redeemUploadLinkInTransaction, 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, ENTITY_UNBIND_OPERATION, allowedFor, unbindEntityHolderBounded, capabilityAttachmentWriteRefused, createCapabilityVerbs, createEntityEdgeVerbs, createEntityStateVerbs, createTrashedReads, CONTINUATION_POSITION_CAP, visibleContinuation, searchStateWhere, uncheckedView, addStatePlans, addUpdatedStampPlans, watchUpdatedStamps, assertNoCallerPurge, isUnreachableParent, PURGE_BATCH, heldPurgePass, lifecycleRefusal, purgeHeldBy, purgeDueOf, purgeOnlyKeysOf, runPurgePass, refuseTrashedTarget, assertBoundOperations, 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, orphanSweepVersionRefusal } from '@substrat-run/kernel';
|
|
12
12
|
import { createDoTupleChecker, createLocalControlPlaneReader, scopeTupleReader } from './checker.js';
|
|
13
13
|
import { settlePlatformRequestIn } from '@substrat-run/kernel';
|
|
14
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';
|
|
@@ -352,6 +352,9 @@ const KERNEL_DDL = `
|
|
|
352
352
|
-- #1575: attachment text and its FTS5 index, shared from @substrat-run/kernel. After
|
|
353
353
|
-- _substrat_attachments, whose delete trigger it adds.
|
|
354
354
|
${ATTACHMENT_TEXT_DDL}
|
|
355
|
+
-- #2314: the orphan sweep's tombstones, shared from @substrat-run/kernel. An id here
|
|
356
|
+
-- never takes an attachment row again: the insert path refuses it.
|
|
357
|
+
${ATTACHMENT_CONDEMNED_DDL}
|
|
355
358
|
-- #901: an entity's version is the ULID of the last event about it (a state move
|
|
356
359
|
-- excepted, #2191), so the newest id per (entity_type, entity_id) is the read. The id
|
|
357
360
|
-- column sits last so SQLite walks the matched range backwards instead of aggregating.
|
|
@@ -844,7 +847,9 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
844
847
|
if (highest)
|
|
845
848
|
this.mintEventId.seedFrom(highest);
|
|
846
849
|
const controlPlane = this.controlPlaneReader();
|
|
847
|
-
|
|
850
|
+
// #2263: a peer holds only what this code's declaration names, whatever the tuples say. The
|
|
851
|
+
// union is this class's code-time module set, so a promote (new code) is a new union.
|
|
852
|
+
this.checker = boundToPeerDeclarations(createDoTupleChecker({ scopeSql: this.sql, controlPlane }), () => this.peers);
|
|
848
853
|
}
|
|
849
854
|
// -- module registration (port of SqliteScopeHost.registerModule) ---------
|
|
850
855
|
registerModule(registration) {
|
|
@@ -2852,14 +2857,87 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
2852
2857
|
* writing an attachment a link never paid for. The write is checked as `record.createdBy`,
|
|
2853
2858
|
* which the kernel holds to the link's minter inside the transaction.
|
|
2854
2859
|
*/
|
|
2855
|
-
attachmentRedeemUploadLinkReply(record, secret, tenantId, scopeId) {
|
|
2856
|
-
return replyOf(() => this.addAttachment(record, record.createdBy, tenantId, scopeId, undefined,
|
|
2860
|
+
attachmentRedeemUploadLinkReply(record, secret, tenantId, scopeId, idempotencyKey) {
|
|
2861
|
+
return replyOf(() => this.addAttachment(record, record.createdBy, tenantId, scopeId, undefined, {
|
|
2862
|
+
secret,
|
|
2863
|
+
idempotencyKey,
|
|
2864
|
+
}));
|
|
2865
|
+
}
|
|
2866
|
+
/**
|
|
2867
|
+
* #2314: the scope side of one orphan-sweep pass over `ids`. With `condemn`, the ids no row
|
|
2868
|
+
* names are tombstoned in one transaction, which the attachment insert refuses from then on,
|
|
2869
|
+
* and only they may be deleted; without it (a dry run), they are only read.
|
|
2870
|
+
*
|
|
2871
|
+
* Only the copy that holds the scope's rows may judge them, so this refuses, before anything
|
|
2872
|
+
* is migrated: a reaped store, a scope whose delivered lifecycle is not active, a scope not
|
|
2873
|
+
* provisioned here for `tenantId`, a store that holds nothing (an object this namespace never
|
|
2874
|
+
* held, woken by this call), a copy a carry wiped or kept, and a fork or snapshot. Each of
|
|
2875
|
+
* those would read every object as an orphan. Any doubt refuses.
|
|
2876
|
+
*/
|
|
2877
|
+
orphanAttachmentsReply(ids, now, tenantId, condemn,
|
|
2878
|
+
// Whether the coordinator's directory named this scope a primary of `tenantId`. Only that
|
|
2879
|
+
// stands in for a missing receipt: a scope provisioned on a host with a directory holds none.
|
|
2880
|
+
vouched = false,
|
|
2881
|
+
// The version the platform routed this pass to, judged against the version this script is
|
|
2882
|
+
// deployed as: this object shares the script's env, so it reads the binding the upload sets.
|
|
2883
|
+
expectedVersionId) {
|
|
2884
|
+
return replyOf(async () => {
|
|
2885
|
+
const misrouted = orphanSweepVersionRefusal(this.env.SUBSTRAT_VERSION_ID ?? null, expectedVersionId, condemn);
|
|
2886
|
+
if (misrouted)
|
|
2887
|
+
throw misrouted;
|
|
2888
|
+
await this.refuseOrphanJudgement(tenantId, vouched);
|
|
2889
|
+
// The verdict alone (no ids, the host's first call) changes nothing: no migration, no repair.
|
|
2890
|
+
if (ids.length === 0)
|
|
2891
|
+
return [];
|
|
2892
|
+
await this.ensureMigrations();
|
|
2893
|
+
return this.queue.enqueue(async () => {
|
|
2894
|
+
await this.refuseOrphanJudgement(tenantId, vouched);
|
|
2895
|
+
if (!condemn)
|
|
2896
|
+
return rowlessAttachmentIds(doSpineSql(this.sql), ids);
|
|
2897
|
+
return this.revision.transaction(async () => condemnOrphanAttachments(doSpineSql(this.sql), ids, now));
|
|
2898
|
+
});
|
|
2899
|
+
});
|
|
2900
|
+
}
|
|
2901
|
+
/**
|
|
2902
|
+
* #2314: what the orphan sweep's fence needs from this storage, read without migrating: the
|
|
2903
|
+
* tenant its provision receipt names (or null), and whether it holds any attachment row.
|
|
2904
|
+
*/
|
|
2905
|
+
async sweepFenceFacts() {
|
|
2906
|
+
return {
|
|
2907
|
+
tenant: this.provisionedFor(),
|
|
2908
|
+
holdsAttachments: this.hasTable('_substrat_attachments') &&
|
|
2909
|
+
this.sql.exec('SELECT 1 FROM _substrat_attachments LIMIT 1').toArray().length > 0,
|
|
2910
|
+
};
|
|
2911
|
+
}
|
|
2912
|
+
/** #2314: why this copy may not judge which attachment bytes are orphans, as a refusal. */
|
|
2913
|
+
async refuseOrphanJudgement(tenantId, vouched) {
|
|
2914
|
+
// First, and before any table is read: a reaped store holds none.
|
|
2915
|
+
if (await this.isReaped()) {
|
|
2916
|
+
throw substratError('conflict', 'refused: this scope copy may not judge orphan attachments, because its storage was reaped');
|
|
2917
|
+
}
|
|
2918
|
+
const { verdict } = this.tenantVerdict(tenantId);
|
|
2919
|
+
const lifecycle = readLifecycle(this.switchSql());
|
|
2920
|
+
const why = lifecycle && (lifecycle.scope !== 'active' || lifecycle.tenant !== 'active')
|
|
2921
|
+
? `its lifecycle is not active (scope ${lifecycle.scope}, tenant ${lifecycle.tenant})`
|
|
2922
|
+
: verdict === 'foreign' || (verdict !== 'recorded' && !vouched)
|
|
2923
|
+
? `it holds no provision receipt for tenant ${tenantId} (${verdict})`
|
|
2924
|
+
: verdict === 'unknown' && !this.holdsData()
|
|
2925
|
+
? 'it holds nothing: this namespace does not hold the scope'
|
|
2926
|
+
: this.carriedAwayCopy
|
|
2927
|
+
? 'it is a copy a carry wiped'
|
|
2928
|
+
: this.hasTable('_substrat_meta') && this.metaValue(KEPT_DIVERGENT_KEY)
|
|
2929
|
+
? 'it is a kept copy'
|
|
2930
|
+
: this.hasTable('_substrat_copy_origin') && this.isCopy()
|
|
2931
|
+
? 'it is a fork or a snapshot'
|
|
2932
|
+
: null;
|
|
2933
|
+
if (why)
|
|
2934
|
+
throw substratError('conflict', `refused: this scope copy may not judge orphan attachments, because ${why}`);
|
|
2857
2935
|
}
|
|
2858
2936
|
/** Look an upload link up without spending it — what the route judges a body against. */
|
|
2859
|
-
uploadLinkInspectReply(secret, _tenantId, _scopeId) {
|
|
2937
|
+
uploadLinkInspectReply(secret, _tenantId, _scopeId, target, idempotencyKey) {
|
|
2860
2938
|
return replyOf(async () => {
|
|
2861
2939
|
await this.ensureMigrations();
|
|
2862
|
-
return await this.queue.enqueue(() => inspectUploadLink({ sql: doSpineSql(this.sql), now: instant.parse(new Date().toISOString()) }, secret));
|
|
2940
|
+
return await this.queue.enqueue(() => inspectUploadLink({ sql: doSpineSql(this.sql), now: instant.parse(new Date().toISOString()) }, secret, target, idempotencyKey));
|
|
2863
2941
|
});
|
|
2864
2942
|
}
|
|
2865
2943
|
attachmentListReply(...args) {
|
|
@@ -2888,8 +2966,9 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
2888
2966
|
// #476: when set, the gate is checked as this CONNECTION (not `principal`, which is
|
|
2889
2967
|
// then only the ctx.principal placeholder the connector door passes).
|
|
2890
2968
|
connectionId,
|
|
2891
|
-
// An upload-link redemption: the link is spent in this same transaction
|
|
2892
|
-
|
|
2969
|
+
// An upload-link redemption: the link is spent in this same transaction, recording the
|
|
2970
|
+
// hash of the request's idempotency key (#2315).
|
|
2971
|
+
uploadLink) {
|
|
2893
2972
|
await this.ensureMigrations();
|
|
2894
2973
|
const parsed = attachmentRecord.parse(record);
|
|
2895
2974
|
const gate = this.attachmentGate(parsed.entity.entityType);
|
|
@@ -2902,6 +2981,8 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
2902
2981
|
await this.revision.transaction(async () => {
|
|
2903
2982
|
const ctx = this.operationContext(principal, tenantId, scopeId, undefined, connectionId, undefined, undefined, undefined, 'attachments.upload');
|
|
2904
2983
|
assertAllowed(await ctx.check(gate.write, parsed.entity));
|
|
2984
|
+
// #2314: an id the orphan sweep condemned takes no row, in this same transaction.
|
|
2985
|
+
refuseCondemnedAttachment(doSpineSql(this.sql), parsed.id);
|
|
2905
2986
|
this.sql.exec(`INSERT INTO _substrat_attachments
|
|
2906
2987
|
(id, entity_type, entity_id, filename, content_type, size, sha256,
|
|
2907
2988
|
visibility, created_by, created_at)
|
|
@@ -2916,12 +2997,12 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
2916
2997
|
// #1575: queue its text extraction in the same transaction — a `pending` row
|
|
2917
2998
|
// and a job run. Nothing is extracted here, so nothing here can fail the upload.
|
|
2918
2999
|
enqueueAttachmentText(doSpineSql(this.sql), parsed.id, ulid(), new Date().toISOString());
|
|
2919
|
-
if (
|
|
3000
|
+
if (uploadLink !== undefined) {
|
|
2920
3001
|
await redeemUploadLinkInTransaction({
|
|
2921
3002
|
sql: doSpineSql(this.sql),
|
|
2922
3003
|
now: instant.parse(new Date().toISOString()),
|
|
2923
3004
|
emit: (event) => kernelEmit(ctx, event),
|
|
2924
|
-
},
|
|
3005
|
+
}, uploadLink.secret, parsed, uploadLink.idempotencyKey);
|
|
2925
3006
|
}
|
|
2926
3007
|
});
|
|
2927
3008
|
}
|
|
@@ -3642,7 +3723,7 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
3642
3723
|
* unqueued read as the line above: nothing here decides a write.
|
|
3643
3724
|
*/
|
|
3644
3725
|
async peerGrantsStatus() {
|
|
3645
|
-
return peerGrantsStatus(this.switchSql(), new Date().toISOString());
|
|
3726
|
+
return peerGrantsStatus(this.switchSql(), new Date().toISOString(), this.peers);
|
|
3646
3727
|
}
|
|
3647
3728
|
/**
|
|
3648
3729
|
* The exchange (#1672) — a capability's secret traded for a session, or for the
|
|
@@ -3799,7 +3880,14 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
3799
3880
|
* the scope that received the call, whatever this says. A wrong one fails closed, since the
|
|
3800
3881
|
* module's grant is seated on this scope's node and not on the one named.
|
|
3801
3882
|
*/
|
|
3802
|
-
scopeId, systemDoorInstance
|
|
3883
|
+
scopeId, systemDoorInstance,
|
|
3884
|
+
/**
|
|
3885
|
+
* #2192: the schedule run this pass belongs to. Every purge in it runs under that id, so its
|
|
3886
|
+
* events, denials and deliveries join the run's own line. LAST and optional for the
|
|
3887
|
+
* positional-RPC reason `recordExecutorAttempt` gives; a coordinator without it gets a fresh
|
|
3888
|
+
* id per purge, as before.
|
|
3889
|
+
*/
|
|
3890
|
+
runInvocationId) {
|
|
3803
3891
|
await this.ensureMigrations();
|
|
3804
3892
|
const schedule = this.purgeSchedules.get(operation);
|
|
3805
3893
|
if (!schedule)
|
|
@@ -3820,7 +3908,7 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
3820
3908
|
return heldPurgePass(held);
|
|
3821
3909
|
const due = purgeDueOf(doSpineSql(this.sql), this.statePlans, this.operationTarget, operation, schedule.entityType, new Date().toISOString(), PURGE_BATCH);
|
|
3822
3910
|
return runPurgePass(operation, due, async (entityId) => {
|
|
3823
|
-
await this.#invokeOrThrow(operation, { [due.idFrom]: entityId }, schedule.moduleId, tenantId, scopeId, undefined, undefined, schedule.moduleId, { invocationId: ulid() }, undefined, undefined, undefined, systemDoorInstance, true);
|
|
3911
|
+
await this.#invokeOrThrow(operation, { [due.idFrom]: entityId }, schedule.moduleId, tenantId, scopeId, undefined, undefined, schedule.moduleId, { invocationId: runInvocationId ?? ulid() }, undefined, undefined, undefined, systemDoorInstance, true);
|
|
3824
3912
|
}, (write) => write(doSpineSql(this.sql)));
|
|
3825
3913
|
}
|
|
3826
3914
|
/**
|
|
@@ -4229,6 +4317,15 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
4229
4317
|
await this.queue.enqueue(async () => this.repairDerived());
|
|
4230
4318
|
return false;
|
|
4231
4319
|
}
|
|
4320
|
+
// #2349: before the bookmark and before any SQL, the registered set is held to the one
|
|
4321
|
+
// stored for the version this script serves. Only here, so a scope with nothing pending
|
|
4322
|
+
// never computes it.
|
|
4323
|
+
const unstored = await migrationSetDivergence(this.modules.values(), this.env.SUBSTRAT_MIGRATIONS_DIGEST);
|
|
4324
|
+
if (unstored) {
|
|
4325
|
+
const key = `${pending[0].moduleId}@${pending[0].migration.version}`;
|
|
4326
|
+
this.lastFailure = { version: key, error: unstored };
|
|
4327
|
+
throw migrationFailedError(key, unstored);
|
|
4328
|
+
}
|
|
4232
4329
|
this.migrationRuns += 1;
|
|
4233
4330
|
await this.queue.enqueue(async () => {
|
|
4234
4331
|
// #286: bookmark the instant before an UPGRADE migrates live data — the
|
|
@@ -4283,9 +4380,10 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
4283
4380
|
let steps;
|
|
4284
4381
|
this.revisionSuspended = true;
|
|
4285
4382
|
try {
|
|
4286
|
-
|
|
4383
|
+
// #115: an authored one is also held to the data-loss fence, inside this transaction.
|
|
4384
|
+
steps = runMigrationStatements(doSpineSql(this.sql), migration, (stmt) => {
|
|
4287
4385
|
this.sql.exec(stmt);
|
|
4288
|
-
});
|
|
4386
|
+
}, { key, authored });
|
|
4289
4387
|
// #2090: the state columns this migration must have left, and after the last of
|
|
4290
4388
|
// the pass, the triggers and indexes a create-copy-rename rebuild dropped.
|
|
4291
4389
|
const last = i === pending.length - 1;
|
|
@@ -4934,6 +5032,9 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
4934
5032
|
// #2009: the copy classification on a scope DO built before it (NULL reads as a copy;
|
|
4935
5033
|
// see `COPY_ORIGIN_DDL`).
|
|
4936
5034
|
'ALTER TABLE _substrat_copy_origin ADD COLUMN is_copy INTEGER',
|
|
5035
|
+
// #2315: the hash of the key a redemption carried, on a scope DO built before it. NULL = the
|
|
5036
|
+
// spending request carried none, the honest reading of every link already spent.
|
|
5037
|
+
'ALTER TABLE _substrat_upload_links ADD COLUMN redeemed_key_hash TEXT',
|
|
4937
5038
|
]) {
|
|
4938
5039
|
try {
|
|
4939
5040
|
this.sql.exec(alter);
|
|
@@ -5052,6 +5153,9 @@ export function defineScopeDO(modules, bareOps) {
|
|
|
5052
5153
|
// #2016: this store's own tenant receipt, read before the drops take it. A load never
|
|
5053
5154
|
// changes which tenant the scope belongs to: the platform's word for it (`provisionedFor`)
|
|
5054
5155
|
// must agree with the receipt held, and is refused before the first drop if it does not.
|
|
5156
|
+
// #2314: a row for an id the orphan sweep condemned here is refused, as the insert refuses it.
|
|
5157
|
+
// Judged on `replayable`, the very tables whose rows the replay below inserts.
|
|
5158
|
+
refuseCondemnedInDump(doSpineSql(this.sql), replayable);
|
|
5055
5159
|
const receiptBefore = this.provisionedFor();
|
|
5056
5160
|
if (provisionedFor !== undefined && receiptBefore !== null && receiptBefore !== provisionedFor) {
|
|
5057
5161
|
const refused = substratError('conflict', tenantReceiptRefusal(receiptBefore, provisionedFor));
|