@substrat-run/adapter-cloudflare 0.140.0 → 0.141.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.
@@ -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
@@ -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;AA2DnD,OAAO,EA6DL,KAAK,SAAS,EAsBd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EAqGtB,MAAM,sBAAsB,CAAC;AA6C9B,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAkBL,kBAAkB,EAgEnB,MAAM,sBAAsB,CAAC;AAyB9B;;;;;;;;;;;;;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;AAkjB5E;;;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,CA2yNjE"}
1
+ {"version":3,"file":"scope-do.d.ts","sourceRoot":"","sources":["../src/scope-do.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA2DnD,OAAO,EA6DL,KAAK,SAAS,EAsBd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EAqGtB,MAAM,sBAAsB,CAAC;AA6C9B,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAkBL,kBAAkB,EAgEnB,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,CA2zN7E"}
package/dist/scope-do.js CHANGED
@@ -8,6 +8,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
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';
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) };
@@ -4632,6 +4636,8 @@ export function defineScopeDO(modules, bareOps) {
4632
4636
  // #2066: the rows already there get the legacy mark below, never a digest.
4633
4637
  'ALTER TABLE _substrat_migrations ADD COLUMN sql_digest TEXT',
4634
4638
  'ALTER TABLE _substrat_tuples ADD COLUMN revoked_at TEXT',
4639
+ // #2126: NULL keeps every existing capability's attachment behavior unchanged.
4640
+ 'ALTER TABLE _substrat_capabilities ADD COLUMN attachments TEXT',
4635
4641
  // #1632: legacy runs retain an unknown subject; no content-based backfill.
4636
4642
  'ALTER TABLE _substrat_job_runs ADD COLUMN subject_id TEXT',
4637
4643
  // #2034: the lease. NULL = nobody holds the run, which is right for every row already there.
@@ -4762,7 +4768,7 @@ export function defineScopeDO(modules, bareOps) {
4762
4768
  this.sql.exec(stmt);
4763
4769
  });
4764
4770
  }
4765
- async importDump(tables, destScopeId, { switchOff, sourceScopeId, exact, loadStamp, expect, resolveKept, markCopy, provisionedFor, } = {}) {
4771
+ async importDump(tables, destScopeId, { switchOff, sourceScopeId, exact, loadStamp, expect, resolveKept, markCopy, provisionedFor, fence, } = {}) {
4766
4772
  // The WHOLE drop-then-replay runs under deferred foreign keys, in one transaction.
4767
4773
  //
4768
4774
  // Two distinct FK hazards, and both need the deferral — the second is why it cannot
@@ -4798,6 +4804,13 @@ export function defineScopeDO(modules, bareOps) {
4798
4804
  throw substratError('validation_failed', 'restore refused: `exact` needs the scope the dump came from');
4799
4805
  }
4800
4806
  const switched = await this.revision.transaction(async () => {
4807
+ // #1722: first, before any read: a store a reap has since emptied must refuse the late load
4808
+ // too, and the check is against this store's clock, inside the load's own transaction.
4809
+ if (fence && copyRestoreFenceLapsed(fence, Date.now())) {
4810
+ const lapsed = substratError('precondition_failed', COPY_RESTORE_FENCE_LAPSED);
4811
+ fenceRefusals.add(lapsed);
4812
+ throw lapsed;
4813
+ }
4801
4814
  const before = this.loadMarker();
4802
4815
  // #1713: the lifecycle the platform delivered here, read before the drops take it.
4803
4816
  const lifecycleBefore = readLifecycle(this.switchSql());
@@ -5002,6 +5015,8 @@ export function defineScopeDO(modules, bareOps) {
5002
5015
  return { refused: false, switchedOff: await this.importDump(tables, destScopeId, opts) };
5003
5016
  }
5004
5017
  catch (e) {
5018
+ if (e instanceof Error && fenceRefusals.has(e))
5019
+ return { refused: 'lapsed' };
5005
5020
  const code = errorCodeOf(e);
5006
5021
  if (code === 'precondition_failed')
5007
5022
  return { refused: 'changed' };