@tearleads/client-sdk 0.1.65 → 0.1.66
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/data/persistence/container-contents/documentPurgePlacement.js +13 -0
- package/data/persistence/container-contents/documentPurgePlacement.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/stores/container-contents/containerContentsStore.js +3 -2
- package/stores/container-contents/containerContentsStore.js.map +1 -1
- package/stores/container-contents/index.d.ts +1 -1
- package/stores/container-contents/index.js.map +1 -1
- package/stores/container-contents/operations/purgeMoveSettlementOperation.js +71 -0
- package/stores/container-contents/operations/purgeMoveSettlementOperation.js.map +1 -0
- package/workflows/container-contents/container-state/moveIntentSync.js +43 -5
- package/workflows/container-contents/container-state/moveIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/purge/purgeMoveSettlement.js +119 -0
- package/workflows/container-contents/container-state/purge/purgeMoveSettlement.js.map +1 -0
- package/workflows/container-contents/container-state/purge/purgeProgress.d.ts +8 -0
- package/workflows/container-contents/container-state/purge/purgeProgress.js.map +1 -1
- package/workflows/container-contents/container-state/remote.js +1 -0
- package/workflows/container-contents/container-state/remote.js.map +1 -1
- package/workflows/container-contents/syncLane.d.ts +2 -0
- package/workflows/container-contents/syncLane.js +7 -0
- package/workflows/container-contents/syncLane.js.map +1 -1
- package/workflows/containers/child/move/index.d.ts +1 -0
- package/workflows/containers/child/move/index.js +1 -0
- package/workflows/containers/child/move/index.js.map +1 -1
- package/workflows/containers/child/mutationSubmit.js +3 -1
- package/workflows/containers/child/mutationSubmit.js.map +1 -1
|
@@ -12,4 +12,17 @@ export async function hasUnsettledDocumentPlacement(execSql, localId) {
|
|
|
12
12
|
.limit(1);
|
|
13
13
|
return intent !== undefined;
|
|
14
14
|
}
|
|
15
|
+
/** Every queued placement on this device; purge narrows it to its scope. */
|
|
16
|
+
export async function listDocumentPlacementIntentStates(execSql) {
|
|
17
|
+
await ensureSqlTables(execSql, documentPlacementIntentTables);
|
|
18
|
+
const rows = await getClientSQLitePersistenceRuntime(execSql)
|
|
19
|
+
.db.select({
|
|
20
|
+
lastAttemptedAt: localIntents.lastAttemptedAt,
|
|
21
|
+
localId: localIntents.localId,
|
|
22
|
+
syncStatus: localIntents.syncStatus,
|
|
23
|
+
})
|
|
24
|
+
.from(localIntents)
|
|
25
|
+
.where(inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement));
|
|
26
|
+
return rows.flatMap(({ localId, ...row }) => localId === null ? [] : [{ ...row, localId }]);
|
|
27
|
+
}
|
|
15
28
|
//# sourceMappingURL=documentPurgePlacement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentPurgePlacement.js","sourceRoot":"","sources":["documentPurgePlacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAgB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEvE,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAgB,EAChB,OAAe;IAEf,MAAM,eAAe,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAC9D,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,iCAAiC,CAAC,OAAO,CAAC;SAC9D,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC;SAClC,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CACJ,GAAG,CACD,iBAAiB,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,EACvD,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAClC,CACF;SACA,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,MAAM,KAAK,SAAS,CAAC;AAC9B,CAAC","sourcesContent":["import { and, eq } from \"drizzle-orm\";\nimport {\n documentPlacementIntentTables,\n inLocalIntentLane,\n LOCAL_INTENT_LANES,\n localIntents,\n} from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\n\n/** Even denied or unavailable placement intent belongs to the local user. */\nexport async function hasUnsettledDocumentPlacement(\n execSql: ExecSql,\n localId: string,\n): Promise<boolean> {\n await ensureSqlTables(execSql, documentPlacementIntentTables);\n const [intent] = await getClientSQLitePersistenceRuntime(execSql)\n .db.select({ id: localIntents.id })\n .from(localIntents)\n .where(\n and(\n inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement),\n eq(localIntents.localId, localId),\n ),\n )\n .limit(1);\n return intent !== undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentPurgePlacement.js","sourceRoot":"","sources":["documentPurgePlacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAgB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEvE,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAgB,EAChB,OAAe;IAEf,MAAM,eAAe,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAC9D,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,iCAAiC,CAAC,OAAO,CAAC;SAC9D,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC;SAClC,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CACJ,GAAG,CACD,iBAAiB,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,EACvD,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAClC,CACF;SACA,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,MAAM,KAAK,SAAS,CAAC;AAC9B,CAAC;AAQD,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,OAAgB;IAEhB,MAAM,eAAe,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,MAAM,iCAAiC,CAAC,OAAO,CAAC;SAC1D,EAAE,CAAC,MAAM,CAAC;QACT,eAAe,EAAE,YAAY,CAAC,eAAe;QAC7C,OAAO,EAAE,YAAY,CAAC,OAAO;QAC7B,UAAU,EAAE,YAAY,CAAC,UAAU;KACpC,CAAC;SACD,IAAI,CAAC,YAAY,CAAC;SAClB,KAAK,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,CAC1C,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC,CAC9C,CAAC;AACJ,CAAC","sourcesContent":["import { and, eq } from \"drizzle-orm\";\nimport {\n documentPlacementIntentTables,\n inLocalIntentLane,\n LOCAL_INTENT_LANES,\n localIntents,\n} from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\n\n/** Even denied or unavailable placement intent belongs to the local user. */\nexport async function hasUnsettledDocumentPlacement(\n execSql: ExecSql,\n localId: string,\n): Promise<boolean> {\n await ensureSqlTables(execSql, documentPlacementIntentTables);\n const [intent] = await getClientSQLitePersistenceRuntime(execSql)\n .db.select({ id: localIntents.id })\n .from(localIntents)\n .where(\n and(\n inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement),\n eq(localIntents.localId, localId),\n ),\n )\n .limit(1);\n return intent !== undefined;\n}\n\nexport interface DocumentPlacementIntentState {\n readonly lastAttemptedAt: string | null;\n readonly localId: string;\n readonly syncStatus: string;\n}\n\n/** Every queued placement on this device; purge narrows it to its scope. */\nexport async function listDocumentPlacementIntentStates(\n execSql: ExecSql,\n): Promise<DocumentPlacementIntentState[]> {\n await ensureSqlTables(execSql, documentPlacementIntentTables);\n const rows = await getClientSQLitePersistenceRuntime(execSql)\n .db.select({\n lastAttemptedAt: localIntents.lastAttemptedAt,\n localId: localIntents.localId,\n syncStatus: localIntents.syncStatus,\n })\n .from(localIntents)\n .where(inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement));\n return rows.flatMap(({ localId, ...row }) =>\n localId === null ? [] : [{ ...row, localId }],\n );\n}\n"]}
|
package/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ OrganizationPolicyHistory, OrganizationPolicyHistoryEntry, OrganizationProfile,
|
|
|
5
5
|
export { type BlobStoreFactory, Blobs, createBrowserLocalKeyring, createBrowserLocalKeyringManifestStore, createBrowserNetworkStatusSource, createContainerDocumentObjectSyncState, createDomainScope, createIndexedDbLocalKeyringManifestStore, createIndexedDbWrappingKeyKeystore, createLocalKeyring, createLocalStorageLocalKeyringManifestStore, createMemoryLocalKeyringManifestStore, createMemoryWrappingKeyKeystore, createPinCodeBrowserLocalKeyring, createPinCodeWrappingKeyKeystore, createRevenueCatPurchases, createUnavailableDirectCheckout, createUnavailablePurchases, createWebViewLocalKeyring, Database, DEFAULT_DOCUMENT_ID, type DirectCheckoutAppearance, type DirectCheckoutCapability, type DirectCheckoutConfirmation, type DirectCheckoutSession, DirectCheckoutUnavailableError, decodeLocalKeyringSqliteKey, Events, type EventsListener, type EventsSnapshot, encodeLocalKeyringSqliteKey, enqueueReconciliationForEvents, IDENTITY_KEY_PACKAGE_FORMAT, isPinCodeWrappedLocalSecretEnvelope, LOCAL_KEYRING_MANIFEST_FORMAT, localKeyringScopeKey, Network, normalizeLocalKeyringScope, type PrincipalHistoryKeyProvider, type PrincipalHistoryKeyScope, PurchaseAbortedError, PurchaseAlreadyOwnedError, PurchaseCancelledError, PurchaseIdentityPendingError, PurchaseProviderStalledError, type PurchasesCapability, PurchasesUnavailableError, PurgedOrganizationRecoveryBillingRequiredError, parseLocalKeyringManifest, type RevenueCatBackend, type RevenueCatCustomerInfo, type RevenueCatPackage, type RevenueCatPurchasesConfig, SyncBillingGate, type SyncBillingGateListener, type SyncPurchaseResult, type SyncSubscriptionOption, serializeLocalKeyringManifest, WRAPPED_LOCAL_SECRET_FORMAT, } from "./client/index.js";
|
|
6
6
|
export type { DiscoveredDocumentInput, DocumentAttachment, DocumentClientProjectionDefinition, DocumentClientProjectionDeleteInput, DocumentClientProjectionSaveInput, DocumentFieldValidationIssue, DocumentProjection, DocumentProjectorDefinition, DocumentProjectorInput, DocumentProjectorRegistry, DocumentProjectorRegistryInput, DocumentRow, DocumentRowSummary, DocumentSummary, StoredDocumentKind, StoredDocumentState, StructuredDocumentMap, StructuredDocumentShape, StructuredDocumentText, ValidatedDocumentFields, } from "./data/documents/index.js";
|
|
7
7
|
export { addDocumentAttachments, createDocumentProjectorRegistry, createDocumentSignerDeviceId, DEFAULT_DOCUMENT_ACCESS_EPOCH, DEFAULT_DOCUMENT_KIND, defaultDocumentProjectorRegistry, deriveStoredDocumentTitle, ensureDocumentAttachmentStructure, getDocumentAttachments, getDocumentClientProjectionTables, getStoredDocumentTypeLabel, getUntitledDocumentTitle, initializeStoredDocumentKind, projectStoredDocumentState, readStoredDocumentState, readStringDocumentField, resolveOpIdAttribution, sameDocumentAttachments, summarizeDocumentContributors, writerByPeerId, writeStoredDocumentFields, } from "./data/documents/index.js";
|
|
8
|
-
export type { ContainerContentsSnapshot, ContainerContentsStoreRuntime, ContainerContentsStoreState, ContainerContentsStoreSyncAgent, ContainerContentsStoreSyncState, ContainerState, PurgeOptions, PurgeProgress, } from "./stores/container-contents/index.js";
|
|
8
|
+
export type { ContainerContentsSnapshot, ContainerContentsStoreRuntime, ContainerContentsStoreState, ContainerContentsStoreSyncAgent, ContainerContentsStoreSyncState, ContainerState, PurgeMoveSettlement, PurgeOptions, PurgeProgress, } from "./stores/container-contents/index.js";
|
|
9
9
|
export { createContainerContentsStore, createContainerContentsStoreState, createContainerContentsStoreSyncAgent, getOrCreateContainerContentsStore, isSystemContainerNode, requestContainerContentsDocumentPriming, subscribeToContainerContentsStore, updateContainerContentsSnapshot, updateContainerContentsStoreRuntime, } from "./stores/container-contents/index.js";
|
|
10
10
|
export type { DocumentSnapshot, DocumentStoreFacade, DocumentStoreOpenOptions, DocumentStoreRelinkInput, DocumentStructuredFieldPatch, } from "./stores/documents/index.js";
|
|
11
11
|
export { createDocumentStore, discardRegisteredDocumentLocalState, getOrCreateDocumentStore, openDocumentStore, requestDomainDocumentSync, subscribeToPersistedDocuments, } from "./stores/documents/index.js";
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["// SDK: verified identity links, read-only pins and device-first handles.\n// Authority loaders take exact heads, including cached citations. Obsolete\n// adapters are excluded; authored policy journals survive restart. See workflows/README.md.\nexport {\n type ApiRequestCounts,\n type ApiRequestEndpointCounts,\n ApiRequestMetrics,\n type ApiRequestMetricsSnapshot,\n} from \"@tearleads/api-client\";\nexport type {\n AbandonOrganizationPolicyMutationInput,\n AddOrganizationGroupUserInput,\n BlobInfo,\n BlobInfoAttachmentKind,\n BlobInfoDocumentReference,\n BlobInfoInput,\n BlobInfoList,\n BlobInfoSort,\n BlobInfoSortDirection,\n BlobInfoSortKey,\n BrowserLocalKeyringOptions,\n ContainerContents,\n ContainerContentsContextValue,\n ContainerContentsStore,\n ContainerContentsStoreOptions,\n ContainerDocumentLinkInput,\n ContainerDocumentLinks,\n ContainerDocumentObjectSyncState,\n ContainerDocumentObjectSyncStatus,\n ContainerDocumentQueries,\n ContainerDocumentSidebarRow,\n ContainerInfo,\n ContainerInfoInput,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n ContainerNode,\n ContainerShareAccessLevel,\n CreateOrganizationOptions,\n DatabaseListener,\n DatabaseOptions,\n DatabaseSnapshot,\n DatabaseStatus,\n DeviceFirst,\n DeviceFirstContainerContents,\n DiscardUnreadableOrganizationPolicyMutationInput,\n DocumentAttachmentStatus,\n DocumentAttachmentUpload,\n DocumentAttributionRangesInput,\n DocumentAttributionRangesPage,\n DocumentContextValue,\n DocumentInfo,\n DocumentInfoInput,\n DocumentList,\n DocumentSort,\n DocumentSortDirection,\n DocumentSortKey,\n DocumentStore,\n DocumentSubscriptionOptions,\n Documents,\n DocumentsRuntime,\n DomainScope,\n FileSaver,\n Identity,\n IdentityGenerationResult,\n IdentityKeyPackage,\n IdentityListener,\n IdentityOptions,\n IdentitySnapshot,\n ImportedOrganizationUser,\n IndexedDbLocalKeyringManifestStoreOptions,\n IndexedDbWrappingKeyKeystoreOptions,\n LinkDocumentToContainerInput,\n ListDocumentsInput,\n LocalKeyPurpose,\n LocalKeyring,\n LocalKeyringManifest,\n LocalKeyringManifestFormat,\n LocalKeyringManifestStorage,\n LocalKeyringManifestStore,\n LocalKeyringOptions,\n LocalKeyringPinCode,\n LocalKeyringScope,\n LocalKeyringSession,\n LocalOrganizationSummary,\n LocalProjectionReconciledDelta,\n LocalProjectionSnapshot,\n LocalProjectionView,\n LocalSecretContext,\n LocalStorageLocalKeyringManifestStoreOptions,\n Logger,\n MergeDocumentSummary,\n MoveDocumentToContainerInput,\n NetworkListener,\n NetworkMode,\n NetworkStatusSource,\n NormalizedLocalKeyringScope,\n OpenContainerDocumentInput,\n OpenDocumentInput,\n OpenDocumentOptions,\n OrganizationBilling,\n OrganizationBillingHistory,\n OrganizationBillingHistoryEntry,\n OrganizationBillingManagementUrl,\n OrganizationBillingView,\n OrganizationContainerGrant,\n OrganizationContainerGrants,\n OrganizationDataUsage,\n OrganizationDirectory,\n OrganizationDirectoryAndGroups,\n OrganizationDirectoryUser,\n OrganizationGrantRef,\n OrganizationGroupContainer,\n OrganizationGroupContainers,\n OrganizationGroupDetails,\n OrganizationGroupMember,\n OrganizationGroupMembers,\n OrganizationGroupMutationReceipt,\n OrganizationGroupPolicyHistory,\n OrganizationGroupSummary,\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n /** Verified organization display page with an optional older-page cursor. */\n OrganizationPolicyHistory,\n OrganizationPolicyHistoryEntry,\n OrganizationProfile,\n Organizations,\n OrganizationUserDetail,\n PendingWriteQueueItem,\n PendingWriteQueueItemStatus,\n PendingWriteQueueObjectKind,\n PendingWriteQueueOperation,\n PendingWriteQueueOperationKind,\n PendingWriteQueueOperationStatus,\n // Persistence notifications distinguish placement changes from content saves.\n PersistedDocumentListener,\n PinCodeBrowserLocalKeyringOptions,\n PinCodeWrappingKeyKeystoreOptions,\n PurgeDocumentInput,\n PurgeDocumentResult,\n ReconciliationService,\n RemoveOrganizationGroupUserInput,\n ResolvedUserIdentity,\n SaveFileRequest,\n SecurityIncident,\n SecurityIncidentListener,\n SecurityIncidentObjectKind,\n SecurityIncidents,\n Session,\n SessionContext,\n SessionCreateOrganizationResult,\n SessionListener,\n SessionRecoverOrganizationResult,\n SessionRegistrationRefusal,\n SessionRegistrationResult,\n SessionSnapshot,\n SetActiveDocumentContainerInput,\n SetLinkedContainerIdsForDocument,\n UnlinkDocumentFromContainerInput,\n UnwrapLocalSecretInput,\n UserIdentities,\n UserSession,\n WrapLocalSecretInput,\n WrappedLocalSecretEnvelope,\n WrappedLocalSecretFormat,\n WrappingKeyHandle,\n WrappingKeyKeystore,\n WrappingKeyMaterialStorage,\n} from \"./client\";\nexport {\n type BlobStoreFactory,\n Blobs,\n createBrowserLocalKeyring,\n createBrowserLocalKeyringManifestStore,\n createBrowserNetworkStatusSource,\n createContainerDocumentObjectSyncState,\n createDomainScope,\n createIndexedDbLocalKeyringManifestStore,\n createIndexedDbWrappingKeyKeystore,\n createLocalKeyring,\n createLocalStorageLocalKeyringManifestStore,\n createMemoryLocalKeyringManifestStore,\n createMemoryWrappingKeyKeystore,\n createPinCodeBrowserLocalKeyring,\n createPinCodeWrappingKeyKeystore,\n createRevenueCatPurchases,\n createUnavailableDirectCheckout,\n createUnavailablePurchases,\n createWebViewLocalKeyring,\n Database,\n DEFAULT_DOCUMENT_ID,\n type DirectCheckoutAppearance,\n type DirectCheckoutCapability,\n type DirectCheckoutConfirmation,\n type DirectCheckoutSession,\n DirectCheckoutUnavailableError,\n decodeLocalKeyringSqliteKey,\n Events,\n type EventsListener,\n type EventsSnapshot,\n encodeLocalKeyringSqliteKey,\n enqueueReconciliationForEvents,\n IDENTITY_KEY_PACKAGE_FORMAT,\n isPinCodeWrappedLocalSecretEnvelope,\n LOCAL_KEYRING_MANIFEST_FORMAT,\n localKeyringScopeKey,\n Network,\n normalizeLocalKeyringScope,\n type PrincipalHistoryKeyProvider,\n type PrincipalHistoryKeyScope,\n PurchaseAbortedError,\n PurchaseAlreadyOwnedError,\n PurchaseCancelledError,\n PurchaseIdentityPendingError,\n PurchaseProviderStalledError,\n type PurchasesCapability,\n PurchasesUnavailableError,\n PurgedOrganizationRecoveryBillingRequiredError,\n parseLocalKeyringManifest,\n type RevenueCatBackend,\n type RevenueCatCustomerInfo,\n type RevenueCatPackage,\n type RevenueCatPurchasesConfig,\n SyncBillingGate,\n type SyncBillingGateListener,\n type SyncPurchaseResult,\n type SyncSubscriptionOption,\n serializeLocalKeyringManifest,\n WRAPPED_LOCAL_SECRET_FORMAT,\n} from \"./client\";\nexport type {\n DiscoveredDocumentInput,\n DocumentAttachment,\n DocumentClientProjectionDefinition,\n DocumentClientProjectionDeleteInput,\n DocumentClientProjectionSaveInput,\n DocumentFieldValidationIssue,\n DocumentProjection,\n DocumentProjectorDefinition,\n DocumentProjectorInput,\n DocumentProjectorRegistry,\n DocumentProjectorRegistryInput,\n DocumentRow,\n DocumentRowSummary,\n DocumentSummary,\n StoredDocumentKind,\n StoredDocumentState,\n StructuredDocumentMap,\n StructuredDocumentShape,\n StructuredDocumentText,\n ValidatedDocumentFields,\n} from \"./data/documents\";\nexport {\n addDocumentAttachments,\n createDocumentProjectorRegistry,\n createDocumentSignerDeviceId,\n DEFAULT_DOCUMENT_ACCESS_EPOCH,\n DEFAULT_DOCUMENT_KIND,\n defaultDocumentProjectorRegistry,\n deriveStoredDocumentTitle,\n ensureDocumentAttachmentStructure,\n getDocumentAttachments,\n getDocumentClientProjectionTables,\n getStoredDocumentTypeLabel,\n getUntitledDocumentTitle,\n initializeStoredDocumentKind,\n projectStoredDocumentState,\n readStoredDocumentState,\n readStringDocumentField,\n resolveOpIdAttribution,\n sameDocumentAttachments,\n summarizeDocumentContributors,\n writerByPeerId,\n writeStoredDocumentFields,\n} from \"./data/documents\";\nexport type {\n ContainerContentsSnapshot,\n ContainerContentsStoreRuntime,\n ContainerContentsStoreState,\n ContainerContentsStoreSyncAgent,\n ContainerContentsStoreSyncState,\n ContainerState,\n PurgeOptions,\n PurgeProgress,\n} from \"./stores/container-contents\";\nexport {\n createContainerContentsStore,\n createContainerContentsStoreState,\n createContainerContentsStoreSyncAgent,\n getOrCreateContainerContentsStore,\n isSystemContainerNode,\n requestContainerContentsDocumentPriming,\n subscribeToContainerContentsStore,\n updateContainerContentsSnapshot,\n updateContainerContentsStoreRuntime,\n} from \"./stores/container-contents\";\nexport type {\n DocumentSnapshot,\n DocumentStoreFacade,\n DocumentStoreOpenOptions,\n DocumentStoreRelinkInput,\n DocumentStructuredFieldPatch,\n} from \"./stores/documents\";\nexport {\n createDocumentStore,\n discardRegisteredDocumentLocalState,\n getOrCreateDocumentStore,\n openDocumentStore,\n requestDomainDocumentSync,\n subscribeToPersistedDocuments,\n} from \"./stores/documents\";\nexport { Tearleads } from \"./Tearleads\";\nexport type {\n TearleadsDatabaseOptions,\n TearleadsOptions,\n} from \"./TearleadsOptions\";\nexport type {\n BlobByteSource,\n BlobByteSourceInput,\n BlobBytes,\n BlobStore,\n EncryptedBlobStoreCipher,\n EncryptedBlobStoreKey,\n EncryptedBlobStoreOptions,\n WrapEncryptedBlobStoreOptions,\n} from \"./workflows/blobs\";\nexport {\n blobByteSourceInputLength,\n createBlobByteSource,\n createBlobStore,\n createEncryptedBlobStore,\n createLazyEncryptedBlobStore,\n createMemoryBlobStore,\n decryptDocumentAttachmentBlob,\n hydrateDocumentAttachmentBlobs,\n purgeOpfsBlobStore,\n readBlobByteSource,\n uploadDocumentAttachment,\n wrapEncryptedBlobStore,\n} from \"./workflows/blobs\";\nexport type {\n ContainerContentsRootAdopter,\n ContainerContentsRootAdoptionInput,\n ContainerContentsStoreWorkflowRuntime,\n ContainerContentsWorkflowRuntime,\n // Distinct from the canonical `ContainerDocumentLinkInput` (./client); the\n // documentQueries variant has a different shape, so it keeps a disambiguating\n // alias on the public surface.\n ContainerDocumentLinkInput as ContainerDocumentQueriesLinkInput,\n ContainerSystemSlotDefinition,\n PendingDownloadQueueItem,\n RecoveryFolder,\n} from \"./workflows/container-contents\";\nexport {\n createContainerContentsDocumentsRuntime,\n createContainerContentsProjectionUserKeyResolver,\n createContainerContentsStoreWorkflowRuntime,\n createContainerContentsSyncLane,\n createContainerContentsWorkflowRuntime,\n createContainerParentSyncLane,\n createInitializedContainerMetadataDocument,\n defaultContainerContentsPersistence,\n deriveContainerSystemSlot,\n initializeDocumentLinksSchema,\n listBlobInfo,\n listDocumentLinkedContainerIds,\n loadContainerInfo,\n loadContainerSyncWatermark,\n loadDocumentAttributionRanges,\n loadDocumentInfo,\n replaceDocumentLinks,\n saveContainerSyncWatermark,\n syncedContainerDocumentObjectSyncState,\n} from \"./workflows/container-contents\";\nexport type {\n AggregatedContainerKekLog,\n ContainerMutationAuthor,\n ContainerReciteApi,\n ContainerWriteRefusal,\n KeyringRebuildResult,\n MaterializedContainerRekeyPlan,\n} from \"./workflows/containers\";\nexport {\n buildMaterializedContainerRekeyPlan,\n buildRootContainerCreatePlan,\n ContainerAuthorAccessError,\n ContainerKekRepairInaccessibleError,\n ContainerKekRepairRequiredError,\n ContainerKeyringOverrideStaleError,\n ContainerPathTooDeepError,\n classifyContainerWriteRefusal,\n containerWriterProjectionFromRekeyPlan,\n createRemoteContainer,\n fetchContainerKekLog,\n GroupShareNameMismatchError,\n HistoricalWrapUnavailableError,\n type HistoricalWrapUnavailableReason,\n isProjectionVerificationCancelledError,\n moveRemoteContainer,\n rebuildKeyringEntriesFromLog,\n recoverKeyringEntryFromWraps,\n rekeyRemoteContainer,\n revokeRemoteContainer,\n rootContainerWriterProjectionFromCreatePlan,\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"./workflows/containers\";\nexport type {\n DocumentRecord,\n DocumentSyncContainerRekeyBuilder,\n DocumentSyncPullContinuation,\n DocumentSyncUpdateIsolationError,\n DocumentsPersistence,\n DocumentsWorkflowRuntime,\n DocumentsWorkflowRuntimeInput,\n IncomingDocumentSyncUpdateValidator,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n PendingUpdateInsert,\n PendingUpdateRecord,\n SyncRemoteDocumentInput,\n} from \"./workflows/documents\";\nexport {\n buildMaterializedDocumentCreatePlan,\n createDocumentProjectionUserKeyResolver,\n createDocumentsWorkflowRuntime,\n createRemoteDocument,\n DOCUMENT_SYNC_TRACE_FRAGMENT,\n DOCUMENT_SYNC_TRACE_PATTERN,\n DOCUMENTS_APP_KIND,\n DocumentRawHistoryUnavailableError,\n defaultDocumentsPersistence,\n deletePersistedDocument,\n isDatabaseUnavailableError,\n isDocumentSyncUpdateIsolationError,\n persistedDocumentCreateStateFromResponse,\n readPullContinuation,\n syncRemoteDocument,\n unwrapContainerKekPath,\n unwrapDocumentContentKeyTarget,\n validateDocumentSyncUpdateImports,\n} from \"./workflows/documents\";\n// Nominal identity constructors are available only through the testing subpath\n// for low-level runtime tests.\nexport type {\n AcknowledgedPrincipalCurrentInput,\n AcknowledgedPrincipalCurrentRetirement,\n AuthoredPrincipalMutation,\n OrganizationGroupPolicyHistoryEntry,\n OrganizationNativePurchaseEligibility,\n OrganizationPrincipalMemberChange,\n OrganizationPrincipalMemberChangeType,\n OrganizationPrincipalPolicyHistory,\n OrganizationPrincipalPolicyHistoryEntry,\n PrincipalMutationJournalContext,\n PrincipalMutationJournalScope,\n PrincipalMutationResponse,\n ReconcileOrganizationDataUsageInput,\n} from \"./workflows/organizations\";\nexport {\n abandonJournaledPrincipalMutation,\n addOrganizationGroupUser,\n buildInitialGroupPolicyRequest,\n buildInitialMemberGroupPolicyRequest,\n buildOrganizationGroupPolicyHistory,\n buildOrganizationProfileDocumentPatch,\n buildRosterProfileDocumentPatch,\n checkNativePurchaseEligibility,\n createInitializedRosterProfileDocument,\n createOrganizationGroup,\n DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME,\n deriveOrganizationMetadataContainerSystemSlot,\n deriveOrganizationRosterProfileContainerSystemSlot,\n discardUnreadableJournaledPrincipalMutation,\n GroupMembershipNameMismatchError,\n getOrganizationProfileDocumentLocalId,\n getRosterProfileDocumentLocalId,\n importOrganizationUser,\n loadLocalOrganizationDataUsage,\n loadLocalOrganizationDirectoryAndGroups,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n PendingPrincipalMutationError,\n PrincipalMutationOutcomeUnknownError,\n ROSTER_PROFILE_DOCUMENT_KIND,\n readJournaledPrincipalMutation,\n readOrganizationProfileName,\n reconcileOrganizationDataUsage,\n reconcileOrganizationDirectoryAndGroups,\n recoverJournaledPrincipalMutation,\n removeOrganizationGroupUser,\n resolveOrganizationBillingView,\n retainAcknowledgedPrincipalCurrents,\n revokeOrganizationContainerGrant,\n startOrganizationTrial,\n submitJournaledPrincipalMutation,\n subscribeOrganizationReadModelInvalidation,\n UnreadablePrincipalMutationError,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n} from \"./workflows/organizations\";\nexport type {\n AcknowledgedPrincipalPredecessor,\n CacheReferencedPrincipalPoliciesOptions,\n PrincipalHistoryProtectionLease,\n ProjectionPolicyHistoryRecoveryOptions,\n RecoveredPrincipalPolicyHistory,\n RecoveredScopedPrincipalPolicyHistory,\n RecoverPrincipalPolicyHistoryOptions,\n RecoverScopedPrincipalPolicyHistoryOptions,\n} from \"./workflows/principals\";\nexport {\n cacheReferencedPrincipalPolicies,\n captureAcknowledgedPrincipalPredecessor,\n PrincipalPolicyHistoryReadError,\n recoverPrincipalPolicyHistory,\n recoverProjectionPolicyHistory,\n recoverScopedPrincipalPolicyHistory,\n} from \"./workflows/principals\";\nexport type {\n InitialRootMetadataBootstrap,\n ProvisionedSystemContainerSpec,\n RegisterIdentityInput,\n RegistrationApi,\n} from \"./workflows/registration\";\nexport {\n bootstrapRootContainer,\n buildInitialOrganizationPolicyRequest,\n createInitialRootMetadataBootstrap,\n persistRegistrationBootstrap,\n registerIdentity,\n} from \"./workflows/registration\";\nexport type {\n RootIdentitiesApi,\n RootIdentitiesPage,\n RootIdentitiesQueryInput,\n RootIdentity,\n RootIdentityDetail,\n RootIdentityOrganization,\n RootIdentitySession,\n RootRequestOutcome,\n} from \"./workflows/root\";\nexport {\n listRootDataUsageReport,\n listRootIdentities,\n listRootIdentityOrganizations,\n listRootOrganizationIdentities,\n listRootOrganizations,\n loadRootIdentity,\n loadRootOrganization,\n loadRootOrganizationDataUsage,\n type RootDataUsageApi,\n type RootDataUsageReportPage,\n type RootOrganization,\n type RootOrganizationDetail,\n type RootOrganizationIdentitiesPage,\n type RootOrganizationIdentity,\n type RootOrganizationPageQueryInput,\n type RootOrganizationsApi,\n type RootOrganizationsPage,\n type RootOrganizationsQueryInput,\n} from \"./workflows/root\";\nexport type {\n ClearRemoteSyncStateResult,\n DomainSyncCoordinator,\n DomainSyncSnapshot,\n RemoteResetInput,\n RemoteResetReplacement,\n SyncIdleOptions,\n SyncLane,\n SyncLaneConfig,\n SyncLaneLastAction,\n SyncLanePhase,\n SyncLaneSnapshot,\n SyncLaneStatus,\n} from \"./workflows/sync\";\nexport {\n clearRemoteSyncState,\n getDomainSyncCoordinatorSnapshot,\n getOrCreateDomainSyncCoordinator,\n hasDomainSyncCoordinatorPendingWork,\n requestAllDomainSyncLanes,\n subscribeToDomainSyncCoordinator,\n waitForDomainSyncCoordinatorToSettle,\n} from \"./workflows/sync\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,2EAA2E;AAC3E,4FAA4F;AAC5F,OAAO,EAGL,iBAAiB,GAElB,MAAM,uBAAuB,CAAC;AAkK/B,OAAO,EAEL,KAAK,EACL,yBAAyB,EACzB,sCAAsC,EACtC,gCAAgC,EAChC,sCAAsC,EACtC,iBAAiB,EACjB,wCAAwC,EACxC,kCAAkC,EAClC,kBAAkB,EAClB,2CAA2C,EAC3C,qCAAqC,EACrC,+BAA+B,EAC/B,gCAAgC,EAChC,gCAAgC,EAChC,yBAAyB,EACzB,+BAA+B,EAC/B,0BAA0B,EAC1B,yBAAyB,EACzB,QAAQ,EACR,mBAAmB,EAKnB,8BAA8B,EAC9B,2BAA2B,EAC3B,MAAM,EAGN,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,mCAAmC,EACnC,6BAA6B,EAC7B,oBAAoB,EACpB,OAAO,EACP,0BAA0B,EAG1B,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,EAE5B,yBAAyB,EACzB,8CAA8C,EAC9C,yBAAyB,EAKzB,eAAe,EAIf,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,UAAU,CAAC;AAuBlB,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,4BAA4B,EAC5B,6BAA6B,EAC7B,qBAAqB,EACrB,gCAAgC,EAChC,yBAAyB,EACzB,iCAAiC,EACjC,sBAAsB,EACtB,iCAAiC,EACjC,0BAA0B,EAC1B,wBAAwB,EACxB,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,6BAA6B,EAC7B,cAAc,EACd,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAY1B,OAAO,EACL,4BAA4B,EAC5B,iCAAiC,EACjC,qCAAqC,EACrC,iCAAiC,EACjC,qBAAqB,EACrB,uCAAuC,EACvC,iCAAiC,EACjC,+BAA+B,EAC/B,mCAAmC,GACpC,MAAM,6BAA6B,CAAC;AAQrC,OAAO,EACL,mBAAmB,EACnB,mCAAmC,EACnC,wBAAwB,EACxB,iBAAiB,EACjB,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAexC,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,eAAe,EACf,wBAAwB,EACxB,4BAA4B,EAC5B,qBAAqB,EACrB,6BAA6B,EAC7B,8BAA8B,EAC9B,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAc3B,OAAO,EACL,uCAAuC,EACvC,gDAAgD,EAChD,2CAA2C,EAC3C,+BAA+B,EAC/B,sCAAsC,EACtC,6BAA6B,EAC7B,0CAA0C,EAC1C,mCAAmC,EACnC,yBAAyB,EACzB,6BAA6B,EAC7B,YAAY,EACZ,8BAA8B,EAC9B,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,sCAAsC,GACvC,MAAM,gCAAgC,CAAC;AASxC,OAAO,EACL,mCAAmC,EACnC,4BAA4B,EAC5B,0BAA0B,EAC1B,mCAAmC,EACnC,+BAA+B,EAC/B,kCAAkC,EAClC,yBAAyB,EACzB,6BAA6B,EAC7B,sCAAsC,EACtC,qBAAqB,EACrB,oBAAoB,EACpB,2BAA2B,EAC3B,8BAA8B,EAE9B,sCAAsC,EACtC,mBAAmB,EACnB,4BAA4B,EAC5B,4BAA4B,EAC5B,oBAAoB,EACpB,qBAAqB,EACrB,2CAA2C,EAC3C,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAgBhC,OAAO,EACL,mCAAmC,EACnC,uCAAuC,EACvC,8BAA8B,EAC9B,oBAAoB,EACpB,4BAA4B,EAC5B,2BAA2B,EAC3B,kBAAkB,EAClB,kCAAkC,EAClC,2BAA2B,EAC3B,uBAAuB,EACvB,0BAA0B,EAC1B,kCAAkC,EAClC,wCAAwC,EACxC,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,8BAA8B,EAC9B,iCAAiC,GAClC,MAAM,uBAAuB,CAAC;AAkB/B,OAAO,EACL,iCAAiC,EACjC,wBAAwB,EACxB,8BAA8B,EAC9B,oCAAoC,EACpC,mCAAmC,EACnC,qCAAqC,EACrC,+BAA+B,EAC/B,8BAA8B,EAC9B,sCAAsC,EACtC,uBAAuB,EACvB,0CAA0C,EAC1C,6CAA6C,EAC7C,kDAAkD,EAClD,2CAA2C,EAC3C,gCAAgC,EAChC,qCAAqC,EACrC,+BAA+B,EAC/B,sBAAsB,EACtB,8BAA8B,EAC9B,uCAAuC,EACvC,uBAAuB,EACvB,8BAA8B,EAC9B,oCAAoC,EACpC,oCAAoC,EACpC,kCAAkC,EAClC,0CAA0C,EAC1C,6BAA6B,EAC7B,oCAAoC,EACpC,4BAA4B,EAC5B,8BAA8B,EAC9B,2BAA2B,EAC3B,8BAA8B,EAC9B,uCAAuC,EACvC,iCAAiC,EACjC,2BAA2B,EAC3B,8BAA8B,EAC9B,mCAAmC,EACnC,gCAAgC,EAChC,sBAAsB,EACtB,gCAAgC,EAChC,0CAA0C,EAC1C,gCAAgC,EAChC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,2BAA2B,CAAC;AAWnC,OAAO,EACL,gCAAgC,EAChC,uCAAuC,EACvC,+BAA+B,EAC/B,6BAA6B,EAC7B,8BAA8B,EAC9B,mCAAmC,GACpC,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EACL,sBAAsB,EACtB,qCAAqC,EACrC,kCAAkC,EAClC,4BAA4B,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAWlC,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,6BAA6B,EAC7B,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,6BAA6B,GAW9B,MAAM,kBAAkB,CAAC;AAe1B,OAAO,EACL,oBAAoB,EACpB,gCAAgC,EAChC,gCAAgC,EAChC,mCAAmC,EACnC,yBAAyB,EACzB,gCAAgC,EAChC,oCAAoC,GACrC,MAAM,kBAAkB,CAAC","sourcesContent":["// SDK: verified identity links, read-only pins and device-first handles.\n// Authority loaders take exact heads, including cached citations. Obsolete\n// adapters are excluded; authored policy journals survive restart. See workflows/README.md.\nexport {\n type ApiRequestCounts,\n type ApiRequestEndpointCounts,\n ApiRequestMetrics,\n type ApiRequestMetricsSnapshot,\n} from \"@tearleads/api-client\";\nexport type {\n AbandonOrganizationPolicyMutationInput,\n AddOrganizationGroupUserInput,\n BlobInfo,\n BlobInfoAttachmentKind,\n BlobInfoDocumentReference,\n BlobInfoInput,\n BlobInfoList,\n BlobInfoSort,\n BlobInfoSortDirection,\n BlobInfoSortKey,\n BrowserLocalKeyringOptions,\n ContainerContents,\n ContainerContentsContextValue,\n ContainerContentsStore,\n ContainerContentsStoreOptions,\n ContainerDocumentLinkInput,\n ContainerDocumentLinks,\n ContainerDocumentObjectSyncState,\n ContainerDocumentObjectSyncStatus,\n ContainerDocumentQueries,\n ContainerDocumentSidebarRow,\n ContainerInfo,\n ContainerInfoInput,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n ContainerNode,\n ContainerShareAccessLevel,\n CreateOrganizationOptions,\n DatabaseListener,\n DatabaseOptions,\n DatabaseSnapshot,\n DatabaseStatus,\n DeviceFirst,\n DeviceFirstContainerContents,\n DiscardUnreadableOrganizationPolicyMutationInput,\n DocumentAttachmentStatus,\n DocumentAttachmentUpload,\n DocumentAttributionRangesInput,\n DocumentAttributionRangesPage,\n DocumentContextValue,\n DocumentInfo,\n DocumentInfoInput,\n DocumentList,\n DocumentSort,\n DocumentSortDirection,\n DocumentSortKey,\n DocumentStore,\n DocumentSubscriptionOptions,\n Documents,\n DocumentsRuntime,\n DomainScope,\n FileSaver,\n Identity,\n IdentityGenerationResult,\n IdentityKeyPackage,\n IdentityListener,\n IdentityOptions,\n IdentitySnapshot,\n ImportedOrganizationUser,\n IndexedDbLocalKeyringManifestStoreOptions,\n IndexedDbWrappingKeyKeystoreOptions,\n LinkDocumentToContainerInput,\n ListDocumentsInput,\n LocalKeyPurpose,\n LocalKeyring,\n LocalKeyringManifest,\n LocalKeyringManifestFormat,\n LocalKeyringManifestStorage,\n LocalKeyringManifestStore,\n LocalKeyringOptions,\n LocalKeyringPinCode,\n LocalKeyringScope,\n LocalKeyringSession,\n LocalOrganizationSummary,\n LocalProjectionReconciledDelta,\n LocalProjectionSnapshot,\n LocalProjectionView,\n LocalSecretContext,\n LocalStorageLocalKeyringManifestStoreOptions,\n Logger,\n MergeDocumentSummary,\n MoveDocumentToContainerInput,\n NetworkListener,\n NetworkMode,\n NetworkStatusSource,\n NormalizedLocalKeyringScope,\n OpenContainerDocumentInput,\n OpenDocumentInput,\n OpenDocumentOptions,\n OrganizationBilling,\n OrganizationBillingHistory,\n OrganizationBillingHistoryEntry,\n OrganizationBillingManagementUrl,\n OrganizationBillingView,\n OrganizationContainerGrant,\n OrganizationContainerGrants,\n OrganizationDataUsage,\n OrganizationDirectory,\n OrganizationDirectoryAndGroups,\n OrganizationDirectoryUser,\n OrganizationGrantRef,\n OrganizationGroupContainer,\n OrganizationGroupContainers,\n OrganizationGroupDetails,\n OrganizationGroupMember,\n OrganizationGroupMembers,\n OrganizationGroupMutationReceipt,\n OrganizationGroupPolicyHistory,\n OrganizationGroupSummary,\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n /** Verified organization display page with an optional older-page cursor. */\n OrganizationPolicyHistory,\n OrganizationPolicyHistoryEntry,\n OrganizationProfile,\n Organizations,\n OrganizationUserDetail,\n PendingWriteQueueItem,\n PendingWriteQueueItemStatus,\n PendingWriteQueueObjectKind,\n PendingWriteQueueOperation,\n PendingWriteQueueOperationKind,\n PendingWriteQueueOperationStatus,\n // Persistence notifications distinguish placement changes from content saves.\n PersistedDocumentListener,\n PinCodeBrowserLocalKeyringOptions,\n PinCodeWrappingKeyKeystoreOptions,\n PurgeDocumentInput,\n PurgeDocumentResult,\n ReconciliationService,\n RemoveOrganizationGroupUserInput,\n ResolvedUserIdentity,\n SaveFileRequest,\n SecurityIncident,\n SecurityIncidentListener,\n SecurityIncidentObjectKind,\n SecurityIncidents,\n Session,\n SessionContext,\n SessionCreateOrganizationResult,\n SessionListener,\n SessionRecoverOrganizationResult,\n SessionRegistrationRefusal,\n SessionRegistrationResult,\n SessionSnapshot,\n SetActiveDocumentContainerInput,\n SetLinkedContainerIdsForDocument,\n UnlinkDocumentFromContainerInput,\n UnwrapLocalSecretInput,\n UserIdentities,\n UserSession,\n WrapLocalSecretInput,\n WrappedLocalSecretEnvelope,\n WrappedLocalSecretFormat,\n WrappingKeyHandle,\n WrappingKeyKeystore,\n WrappingKeyMaterialStorage,\n} from \"./client\";\nexport {\n type BlobStoreFactory,\n Blobs,\n createBrowserLocalKeyring,\n createBrowserLocalKeyringManifestStore,\n createBrowserNetworkStatusSource,\n createContainerDocumentObjectSyncState,\n createDomainScope,\n createIndexedDbLocalKeyringManifestStore,\n createIndexedDbWrappingKeyKeystore,\n createLocalKeyring,\n createLocalStorageLocalKeyringManifestStore,\n createMemoryLocalKeyringManifestStore,\n createMemoryWrappingKeyKeystore,\n createPinCodeBrowserLocalKeyring,\n createPinCodeWrappingKeyKeystore,\n createRevenueCatPurchases,\n createUnavailableDirectCheckout,\n createUnavailablePurchases,\n createWebViewLocalKeyring,\n Database,\n DEFAULT_DOCUMENT_ID,\n type DirectCheckoutAppearance,\n type DirectCheckoutCapability,\n type DirectCheckoutConfirmation,\n type DirectCheckoutSession,\n DirectCheckoutUnavailableError,\n decodeLocalKeyringSqliteKey,\n Events,\n type EventsListener,\n type EventsSnapshot,\n encodeLocalKeyringSqliteKey,\n enqueueReconciliationForEvents,\n IDENTITY_KEY_PACKAGE_FORMAT,\n isPinCodeWrappedLocalSecretEnvelope,\n LOCAL_KEYRING_MANIFEST_FORMAT,\n localKeyringScopeKey,\n Network,\n normalizeLocalKeyringScope,\n type PrincipalHistoryKeyProvider,\n type PrincipalHistoryKeyScope,\n PurchaseAbortedError,\n PurchaseAlreadyOwnedError,\n PurchaseCancelledError,\n PurchaseIdentityPendingError,\n PurchaseProviderStalledError,\n type PurchasesCapability,\n PurchasesUnavailableError,\n PurgedOrganizationRecoveryBillingRequiredError,\n parseLocalKeyringManifest,\n type RevenueCatBackend,\n type RevenueCatCustomerInfo,\n type RevenueCatPackage,\n type RevenueCatPurchasesConfig,\n SyncBillingGate,\n type SyncBillingGateListener,\n type SyncPurchaseResult,\n type SyncSubscriptionOption,\n serializeLocalKeyringManifest,\n WRAPPED_LOCAL_SECRET_FORMAT,\n} from \"./client\";\nexport type {\n DiscoveredDocumentInput,\n DocumentAttachment,\n DocumentClientProjectionDefinition,\n DocumentClientProjectionDeleteInput,\n DocumentClientProjectionSaveInput,\n DocumentFieldValidationIssue,\n DocumentProjection,\n DocumentProjectorDefinition,\n DocumentProjectorInput,\n DocumentProjectorRegistry,\n DocumentProjectorRegistryInput,\n DocumentRow,\n DocumentRowSummary,\n DocumentSummary,\n StoredDocumentKind,\n StoredDocumentState,\n StructuredDocumentMap,\n StructuredDocumentShape,\n StructuredDocumentText,\n ValidatedDocumentFields,\n} from \"./data/documents\";\nexport {\n addDocumentAttachments,\n createDocumentProjectorRegistry,\n createDocumentSignerDeviceId,\n DEFAULT_DOCUMENT_ACCESS_EPOCH,\n DEFAULT_DOCUMENT_KIND,\n defaultDocumentProjectorRegistry,\n deriveStoredDocumentTitle,\n ensureDocumentAttachmentStructure,\n getDocumentAttachments,\n getDocumentClientProjectionTables,\n getStoredDocumentTypeLabel,\n getUntitledDocumentTitle,\n initializeStoredDocumentKind,\n projectStoredDocumentState,\n readStoredDocumentState,\n readStringDocumentField,\n resolveOpIdAttribution,\n sameDocumentAttachments,\n summarizeDocumentContributors,\n writerByPeerId,\n writeStoredDocumentFields,\n} from \"./data/documents\";\nexport type {\n ContainerContentsSnapshot,\n ContainerContentsStoreRuntime,\n ContainerContentsStoreState,\n ContainerContentsStoreSyncAgent,\n ContainerContentsStoreSyncState,\n ContainerState,\n PurgeMoveSettlement,\n PurgeOptions,\n PurgeProgress,\n} from \"./stores/container-contents\";\nexport {\n createContainerContentsStore,\n createContainerContentsStoreState,\n createContainerContentsStoreSyncAgent,\n getOrCreateContainerContentsStore,\n isSystemContainerNode,\n requestContainerContentsDocumentPriming,\n subscribeToContainerContentsStore,\n updateContainerContentsSnapshot,\n updateContainerContentsStoreRuntime,\n} from \"./stores/container-contents\";\nexport type {\n DocumentSnapshot,\n DocumentStoreFacade,\n DocumentStoreOpenOptions,\n DocumentStoreRelinkInput,\n DocumentStructuredFieldPatch,\n} from \"./stores/documents\";\nexport {\n createDocumentStore,\n discardRegisteredDocumentLocalState,\n getOrCreateDocumentStore,\n openDocumentStore,\n requestDomainDocumentSync,\n subscribeToPersistedDocuments,\n} from \"./stores/documents\";\nexport { Tearleads } from \"./Tearleads\";\nexport type {\n TearleadsDatabaseOptions,\n TearleadsOptions,\n} from \"./TearleadsOptions\";\nexport type {\n BlobByteSource,\n BlobByteSourceInput,\n BlobBytes,\n BlobStore,\n EncryptedBlobStoreCipher,\n EncryptedBlobStoreKey,\n EncryptedBlobStoreOptions,\n WrapEncryptedBlobStoreOptions,\n} from \"./workflows/blobs\";\nexport {\n blobByteSourceInputLength,\n createBlobByteSource,\n createBlobStore,\n createEncryptedBlobStore,\n createLazyEncryptedBlobStore,\n createMemoryBlobStore,\n decryptDocumentAttachmentBlob,\n hydrateDocumentAttachmentBlobs,\n purgeOpfsBlobStore,\n readBlobByteSource,\n uploadDocumentAttachment,\n wrapEncryptedBlobStore,\n} from \"./workflows/blobs\";\nexport type {\n ContainerContentsRootAdopter,\n ContainerContentsRootAdoptionInput,\n ContainerContentsStoreWorkflowRuntime,\n ContainerContentsWorkflowRuntime,\n // Distinct from the canonical `ContainerDocumentLinkInput` (./client); the\n // documentQueries variant has a different shape, so it keeps a disambiguating\n // alias on the public surface.\n ContainerDocumentLinkInput as ContainerDocumentQueriesLinkInput,\n ContainerSystemSlotDefinition,\n PendingDownloadQueueItem,\n RecoveryFolder,\n} from \"./workflows/container-contents\";\nexport {\n createContainerContentsDocumentsRuntime,\n createContainerContentsProjectionUserKeyResolver,\n createContainerContentsStoreWorkflowRuntime,\n createContainerContentsSyncLane,\n createContainerContentsWorkflowRuntime,\n createContainerParentSyncLane,\n createInitializedContainerMetadataDocument,\n defaultContainerContentsPersistence,\n deriveContainerSystemSlot,\n initializeDocumentLinksSchema,\n listBlobInfo,\n listDocumentLinkedContainerIds,\n loadContainerInfo,\n loadContainerSyncWatermark,\n loadDocumentAttributionRanges,\n loadDocumentInfo,\n replaceDocumentLinks,\n saveContainerSyncWatermark,\n syncedContainerDocumentObjectSyncState,\n} from \"./workflows/container-contents\";\nexport type {\n AggregatedContainerKekLog,\n ContainerMutationAuthor,\n ContainerReciteApi,\n ContainerWriteRefusal,\n KeyringRebuildResult,\n MaterializedContainerRekeyPlan,\n} from \"./workflows/containers\";\nexport {\n buildMaterializedContainerRekeyPlan,\n buildRootContainerCreatePlan,\n ContainerAuthorAccessError,\n ContainerKekRepairInaccessibleError,\n ContainerKekRepairRequiredError,\n ContainerKeyringOverrideStaleError,\n ContainerPathTooDeepError,\n classifyContainerWriteRefusal,\n containerWriterProjectionFromRekeyPlan,\n createRemoteContainer,\n fetchContainerKekLog,\n GroupShareNameMismatchError,\n HistoricalWrapUnavailableError,\n type HistoricalWrapUnavailableReason,\n isProjectionVerificationCancelledError,\n moveRemoteContainer,\n rebuildKeyringEntriesFromLog,\n recoverKeyringEntryFromWraps,\n rekeyRemoteContainer,\n revokeRemoteContainer,\n rootContainerWriterProjectionFromCreatePlan,\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"./workflows/containers\";\nexport type {\n DocumentRecord,\n DocumentSyncContainerRekeyBuilder,\n DocumentSyncPullContinuation,\n DocumentSyncUpdateIsolationError,\n DocumentsPersistence,\n DocumentsWorkflowRuntime,\n DocumentsWorkflowRuntimeInput,\n IncomingDocumentSyncUpdateValidator,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n PendingUpdateInsert,\n PendingUpdateRecord,\n SyncRemoteDocumentInput,\n} from \"./workflows/documents\";\nexport {\n buildMaterializedDocumentCreatePlan,\n createDocumentProjectionUserKeyResolver,\n createDocumentsWorkflowRuntime,\n createRemoteDocument,\n DOCUMENT_SYNC_TRACE_FRAGMENT,\n DOCUMENT_SYNC_TRACE_PATTERN,\n DOCUMENTS_APP_KIND,\n DocumentRawHistoryUnavailableError,\n defaultDocumentsPersistence,\n deletePersistedDocument,\n isDatabaseUnavailableError,\n isDocumentSyncUpdateIsolationError,\n persistedDocumentCreateStateFromResponse,\n readPullContinuation,\n syncRemoteDocument,\n unwrapContainerKekPath,\n unwrapDocumentContentKeyTarget,\n validateDocumentSyncUpdateImports,\n} from \"./workflows/documents\";\n// Nominal identity constructors are available only through the testing subpath\n// for low-level runtime tests.\nexport type {\n AcknowledgedPrincipalCurrentInput,\n AcknowledgedPrincipalCurrentRetirement,\n AuthoredPrincipalMutation,\n OrganizationGroupPolicyHistoryEntry,\n OrganizationNativePurchaseEligibility,\n OrganizationPrincipalMemberChange,\n OrganizationPrincipalMemberChangeType,\n OrganizationPrincipalPolicyHistory,\n OrganizationPrincipalPolicyHistoryEntry,\n PrincipalMutationJournalContext,\n PrincipalMutationJournalScope,\n PrincipalMutationResponse,\n ReconcileOrganizationDataUsageInput,\n} from \"./workflows/organizations\";\nexport {\n abandonJournaledPrincipalMutation,\n addOrganizationGroupUser,\n buildInitialGroupPolicyRequest,\n buildInitialMemberGroupPolicyRequest,\n buildOrganizationGroupPolicyHistory,\n buildOrganizationProfileDocumentPatch,\n buildRosterProfileDocumentPatch,\n checkNativePurchaseEligibility,\n createInitializedRosterProfileDocument,\n createOrganizationGroup,\n DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME,\n deriveOrganizationMetadataContainerSystemSlot,\n deriveOrganizationRosterProfileContainerSystemSlot,\n discardUnreadableJournaledPrincipalMutation,\n GroupMembershipNameMismatchError,\n getOrganizationProfileDocumentLocalId,\n getRosterProfileDocumentLocalId,\n importOrganizationUser,\n loadLocalOrganizationDataUsage,\n loadLocalOrganizationDirectoryAndGroups,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n PendingPrincipalMutationError,\n PrincipalMutationOutcomeUnknownError,\n ROSTER_PROFILE_DOCUMENT_KIND,\n readJournaledPrincipalMutation,\n readOrganizationProfileName,\n reconcileOrganizationDataUsage,\n reconcileOrganizationDirectoryAndGroups,\n recoverJournaledPrincipalMutation,\n removeOrganizationGroupUser,\n resolveOrganizationBillingView,\n retainAcknowledgedPrincipalCurrents,\n revokeOrganizationContainerGrant,\n startOrganizationTrial,\n submitJournaledPrincipalMutation,\n subscribeOrganizationReadModelInvalidation,\n UnreadablePrincipalMutationError,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n} from \"./workflows/organizations\";\nexport type {\n AcknowledgedPrincipalPredecessor,\n CacheReferencedPrincipalPoliciesOptions,\n PrincipalHistoryProtectionLease,\n ProjectionPolicyHistoryRecoveryOptions,\n RecoveredPrincipalPolicyHistory,\n RecoveredScopedPrincipalPolicyHistory,\n RecoverPrincipalPolicyHistoryOptions,\n RecoverScopedPrincipalPolicyHistoryOptions,\n} from \"./workflows/principals\";\nexport {\n cacheReferencedPrincipalPolicies,\n captureAcknowledgedPrincipalPredecessor,\n PrincipalPolicyHistoryReadError,\n recoverPrincipalPolicyHistory,\n recoverProjectionPolicyHistory,\n recoverScopedPrincipalPolicyHistory,\n} from \"./workflows/principals\";\nexport type {\n InitialRootMetadataBootstrap,\n ProvisionedSystemContainerSpec,\n RegisterIdentityInput,\n RegistrationApi,\n} from \"./workflows/registration\";\nexport {\n bootstrapRootContainer,\n buildInitialOrganizationPolicyRequest,\n createInitialRootMetadataBootstrap,\n persistRegistrationBootstrap,\n registerIdentity,\n} from \"./workflows/registration\";\nexport type {\n RootIdentitiesApi,\n RootIdentitiesPage,\n RootIdentitiesQueryInput,\n RootIdentity,\n RootIdentityDetail,\n RootIdentityOrganization,\n RootIdentitySession,\n RootRequestOutcome,\n} from \"./workflows/root\";\nexport {\n listRootDataUsageReport,\n listRootIdentities,\n listRootIdentityOrganizations,\n listRootOrganizationIdentities,\n listRootOrganizations,\n loadRootIdentity,\n loadRootOrganization,\n loadRootOrganizationDataUsage,\n type RootDataUsageApi,\n type RootDataUsageReportPage,\n type RootOrganization,\n type RootOrganizationDetail,\n type RootOrganizationIdentitiesPage,\n type RootOrganizationIdentity,\n type RootOrganizationPageQueryInput,\n type RootOrganizationsApi,\n type RootOrganizationsPage,\n type RootOrganizationsQueryInput,\n} from \"./workflows/root\";\nexport type {\n ClearRemoteSyncStateResult,\n DomainSyncCoordinator,\n DomainSyncSnapshot,\n RemoteResetInput,\n RemoteResetReplacement,\n SyncIdleOptions,\n SyncLane,\n SyncLaneConfig,\n SyncLaneLastAction,\n SyncLanePhase,\n SyncLaneSnapshot,\n SyncLaneStatus,\n} from \"./workflows/sync\";\nexport {\n clearRemoteSyncState,\n getDomainSyncCoordinatorSnapshot,\n getOrCreateDomainSyncCoordinator,\n hasDomainSyncCoordinatorPendingWork,\n requestAllDomainSyncLanes,\n subscribeToDomainSyncCoordinator,\n waitForDomainSyncCoordinatorToSettle,\n} from \"./workflows/sync\";\n"]}
|
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import { createChildContainer, deleteContainer, ensureSystemContainer, moveConta
|
|
|
5
5
|
import { emptyTrash } from "./operations/emptyTrashOperation.js";
|
|
6
6
|
import { prepareContainerGroupRewrap, verifyContainerGroupRewrapCurrent, } from "./operations/groupRewrapOperation.js";
|
|
7
7
|
import { purgeContainer } from "./operations/purgeContainerOperation.js";
|
|
8
|
+
import { chainPurgeAfterScopeMoves } from "./operations/purgeMoveSettlementOperation.js";
|
|
8
9
|
import { setContainerIcon } from "./operations/setContainerIconOperation.js";
|
|
9
10
|
import { shareContainerWithGroup, shareContainerWithUser, } from "./operations/shareOperations.js";
|
|
10
11
|
import { invalidateRemoteContainerWrites } from "./remoteWrites/remoteWriteGuards.js";
|
|
@@ -116,8 +117,8 @@ export function createContainerWriteMethods(state, syncAgent) {
|
|
|
116
117
|
...createContainerSharingMethods(state, syncAgent),
|
|
117
118
|
createChild: (parentId, name) => chainContainerWrite(state, (isCurrent) => createChildContainer(state, syncAgent, parentId, name, isCurrent), [parentId]),
|
|
118
119
|
deleteContainer: createDeleteContainerMethod(state, syncAgent),
|
|
119
|
-
purgeContainer: (containerId, options) =>
|
|
120
|
-
emptyTrash: (trashContainerId, options) =>
|
|
120
|
+
purgeContainer: (containerId, options) => chainPurgeAfterScopeMoves(state, syncAgent, containerId, options, (isCurrent) => purgeContainer(state, syncAgent, containerId, options, isCurrent)),
|
|
121
|
+
emptyTrash: (trashContainerId, options) => chainPurgeAfterScopeMoves(state, syncAgent, trashContainerId, options, (isCurrent) => emptyTrash(state, syncAgent, trashContainerId, options, isCurrent)),
|
|
121
122
|
ensureSystemContainer: createEnsureSystemContainerMethod(state, syncAgent),
|
|
122
123
|
moveContainer: (containerId, parentId) => chainContainerWrite(state, (isCurrent) => moveContainer(state, syncAgent, containerId, parentId, isCurrent), [containerId, parentId], containerId),
|
|
123
124
|
prepareGroupRewrap: createPrepareGroupRewrapMethod(state, syncAgent),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerContentsStore.js","sourceRoot":"","sources":["containerContentsStore.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport { getCachedContainerWriterProjection } from \"../../workflows/container-contents/container-state/projectionCache\";\nimport {\n type ContainerContentsPersistence,\n defaultContainerContentsPersistence,\n} from \"../../workflows/container-contents/containerPersistence\";\nimport { persistContainerState } from \"./containerState/containerStatePersistence\";\nimport {\n createChildContainer,\n deleteContainer,\n ensureSystemContainer,\n moveContainer,\n renameContainer,\n} from \"./operations\";\nimport { emptyTrash } from \"./operations/emptyTrashOperation\";\nimport {\n prepareContainerGroupRewrap,\n verifyContainerGroupRewrapCurrent,\n} from \"./operations/groupRewrapOperation\";\nimport { purgeContainer } from \"./operations/purgeContainerOperation\";\nimport { setContainerIcon } from \"./operations/setContainerIconOperation\";\nimport {\n shareContainerWithGroup,\n shareContainerWithUser,\n} from \"./operations/shareOperations\";\nimport { invalidateRemoteContainerWrites } from \"./remoteWrites/remoteWriteGuards\";\nimport { chainRemoteContainerTask } from \"./remoteWrites/remoteWriteQueue\";\nimport { captureContainerWriteGeneration } from \"./remoteWrites/writeGeneration\";\nimport {\n createContainerContentsStoreState,\n subscribeToContainerContentsStore,\n updateContainerContentsSnapshot,\n updateContainerContentsStorePersistence,\n updateContainerContentsStoreRuntime,\n} from \"./state\";\nimport {\n type ContainerContentsStoreRuntime,\n type ContainerContentsStoreSyncAgent,\n createContainerContentsStoreSyncAgent,\n} from \"./syncAgent\";\nimport { findRootContainerState } from \"./systemContainers/systemContainerLookup\";\nimport type {\n ContainerContentsStore,\n ContainerContentsStoreOptions,\n ContainerContentsStoreState,\n} from \"./types\";\n\nconst containerContentsStoresByScope = new WeakMap<\n DomainScope,\n ContainerContentsStoreEntry\n>();\n\ninterface ContainerContentsStoreEntry {\n requestDocumentPriming: () => void;\n store: ContainerContentsStore;\n updateOptions: (options: ContainerContentsStoreOptions) => void;\n}\n\nfunction applyContainerContentsStoreOptions(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n options: ContainerContentsStoreOptions,\n): void {\n if (\"logLabel\" in options) {\n state.logLabel = options.logLabel;\n }\n\n if (\"persistence\" in options) {\n updateContainerContentsStorePersistence(\n state,\n options.persistence ?? defaultContainerContentsPersistence,\n syncAgent,\n );\n }\n}\n\nfunction getCachedContainerWriterProjectionForStore(\n state: ContainerContentsStoreState,\n containerId: string,\n) {\n const containerState = state.containersById.get(containerId);\n return containerState\n ? getCachedContainerWriterProjection(containerState)\n : null;\n}\n\nfunction createContainerContentsStoreSyncHost(\n state: ContainerContentsStoreState,\n): Parameters<typeof createContainerContentsStoreSyncAgent>[0][\"host\"] {\n return {\n persistContainerState: (\n containerState,\n patch,\n updateView,\n saveOptions,\n mutationOptions,\n ) =>\n persistContainerState(state, containerState, {\n patch,\n updateView,\n saveOptions,\n ...mutationOptions,\n }),\n requestDocumentPriming: () => {\n state.documentStoresNeedPriming = true;\n },\n updateSnapshot: () => updateContainerContentsSnapshot(state),\n };\n}\n\n// null marks an unknown mutation scope; [] delegates invalidation to actual writes.\nfunction chainContainerWrite(\n state: ContainerContentsStoreState,\n work: (isCurrent: () => boolean) => ContainerContentsStoreState[\"writeChain\"],\n changedIds: readonly string[] | null = null,\n movedId?: string,\n): ContainerContentsStoreState[\"writeChain\"] {\n const isCurrent = captureContainerWriteGeneration(state);\n invalidateRemoteContainerWrites(state, changedIds, movedId);\n state.writeChain = state.writeChain\n .catch(() => null)\n .then(() => {\n if (!isCurrent()) return null;\n invalidateRemoteContainerWrites(state, changedIds, movedId);\n return work(isCurrent);\n })\n .then((node) => (isCurrent() ? node : null));\n return state.writeChain;\n}\n\ntype ContainerWriteMethods = Pick<\n ContainerContentsStore,\n | \"createChild\"\n | \"deleteContainer\"\n | \"emptyTrash\"\n | \"ensureSystemContainer\"\n | \"moveContainer\"\n | \"prepareGroupRewrap\"\n | \"purgeContainer\"\n | \"renameContainer\"\n | \"setContainerIcon\"\n | \"shareWithGroup\"\n | \"shareWithUser\"\n>;\n\n// The group-rewrap builder verifies any required existing grant before capturing\n// the container KEK, then returns a check/rewrap pair. A verified non-match is\n// distinct from an unavailable preparation so security-critical callers can\n// no-op unrelated groups without failing open for a real grant.\nfunction createPrepareGroupRewrapMethod(\n state: ContainerContentsStoreState,\n syncAgent: ReturnType<typeof createContainerContentsStoreSyncAgent>,\n): ContainerContentsStore[\"prepareGroupRewrap\"] {\n return async (containerId, groupId, accessLevel, options) => {\n const preparation = await chainRemoteContainerTask(\n state,\n syncAgent,\n null,\n (isCurrent) =>\n prepareContainerGroupRewrap(\n state,\n containerId,\n groupId,\n accessLevel,\n options,\n isCurrent,\n ),\n containerId,\n );\n return preparation?.status === \"prepared\"\n ? {\n isCurrent: (\n expectedGroupHead,\n expectedContainerId,\n expectedOrganizationId,\n ) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n verifyContainerGroupRewrapCurrent(\n state,\n containerId,\n groupId,\n accessLevel,\n expectedGroupHead,\n expectedContainerId,\n expectedOrganizationId,\n isCurrent,\n ),\n containerId,\n ),\n rewrap: () =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n shareContainerWithGroup(\n state,\n syncAgent,\n containerId,\n groupId,\n accessLevel,\n {\n ...options,\n knownContainerKeks: preparation.knownContainerKeks,\n // A prepared re-wrap is grant-preserving by definition, so\n // it never mints a grant and never needs the chosen name.\n requireExistingGrant: true,\n },\n isCurrent,\n ),\n containerId,\n { preserveResultOnLocalWrite: true },\n ),\n status: \"prepared\" as const,\n }\n : (preparation ?? null);\n };\n}\n\nfunction createContainerSharingMethods(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n): Pick<ContainerWriteMethods, \"shareWithUser\" | \"shareWithGroup\"> {\n return {\n shareWithUser: (containerId, userId) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n shareContainerWithUser(\n state,\n syncAgent,\n containerId,\n userId,\n isCurrent,\n ),\n containerId,\n { preserveResultOnLocalWrite: true },\n ),\n shareWithGroup: (containerId, groupId, accessLevel, options) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n shareContainerWithGroup(\n state,\n syncAgent,\n containerId,\n groupId,\n accessLevel,\n options,\n isCurrent,\n ),\n containerId,\n { preserveResultOnLocalWrite: true },\n ),\n };\n}\n\nfunction createDeleteContainerMethod(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n): ContainerContentsStore[\"deleteContainer\"] {\n return (containerId) => {\n const current = captureContainerWriteGeneration(state);\n const remoteDelete = () =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n null,\n (isCurrent) =>\n deleteContainer(state, syncAgent, containerId, isCurrent),\n containerId,\n ).then((node) => node !== null);\n if (state.containersById.get(containerId)?.record.documentId)\n return remoteDelete();\n let promoted = false;\n return chainContainerWrite(\n state,\n (isCurrent) => {\n // Promotion can win while this local operation was queued. Hand it to\n // the remote queue after releasing the local chain, before any HTTP I/O.\n promoted = Boolean(\n state.containersById.get(containerId)?.record.documentId,\n );\n return promoted\n ? Promise.resolve(null)\n : deleteContainer(state, syncAgent, containerId, isCurrent);\n },\n [containerId],\n ).then((node) => (promoted && current() ? remoteDelete() : node !== null));\n };\n}\n\nfunction createEnsureSystemContainerMethod(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n): ContainerContentsStore[\"ensureSystemContainer\"] {\n return (systemSlot, name, options) => {\n const work = (isCurrent: () => boolean) =>\n ensureSystemContainer(\n state,\n syncAgent,\n systemSlot,\n name,\n options,\n isCurrent,\n );\n const rootId = findRootContainerState(state)?.container.id;\n return options?.deferRemoteBootstrap\n ? chainContainerWrite(state, work, [])\n : chainRemoteContainerTask(\n state,\n syncAgent,\n null,\n work,\n rootId ? { rootId, systemSlot } : undefined,\n );\n };\n}\n\nexport function createContainerWriteMethods(\n state: ContainerContentsStoreState,\n syncAgent: ReturnType<typeof createContainerContentsStoreSyncAgent>,\n): ContainerWriteMethods {\n return {\n ...createContainerSharingMethods(state, syncAgent),\n createChild: (parentId, name) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n createChildContainer(state, syncAgent, parentId, name, isCurrent),\n [parentId],\n ),\n deleteContainer: createDeleteContainerMethod(state, syncAgent),\n purgeContainer: (containerId, options) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n purgeContainer(state, syncAgent, containerId, options, isCurrent),\n containerId,\n ),\n emptyTrash: (trashContainerId, options) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n emptyTrash(state, syncAgent, trashContainerId, options, isCurrent),\n trashContainerId,\n ),\n ensureSystemContainer: createEnsureSystemContainerMethod(state, syncAgent),\n moveContainer: (containerId, parentId) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n moveContainer(state, syncAgent, containerId, parentId, isCurrent),\n [containerId, parentId],\n containerId,\n ),\n prepareGroupRewrap: createPrepareGroupRewrapMethod(state, syncAgent),\n renameContainer: (containerId, name) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n renameContainer(state, syncAgent, containerId, name, isCurrent),\n [containerId],\n ),\n setContainerIcon: (containerId, icon) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n setContainerIcon(state, syncAgent, containerId, icon, isCurrent),\n [containerId],\n ),\n };\n}\n\nfunction createContainerContentsStoreEntry(\n initialRuntime: ContainerContentsStoreRuntime,\n persistence: ContainerContentsPersistence = defaultContainerContentsPersistence,\n options: ContainerContentsStoreOptions = {},\n): ContainerContentsStoreEntry {\n const state = createContainerContentsStoreState(\n initialRuntime,\n options.persistence ?? persistence,\n options.logLabel,\n );\n const syncAgent = createContainerContentsStoreSyncAgent({\n host: createContainerContentsStoreSyncHost(state),\n state,\n });\n const writeMethods = createContainerWriteMethods(state, syncAgent);\n\n return {\n requestDocumentPriming: () => {\n state.documentStoresNeedPriming = true;\n syncAgent.scheduleSync();\n },\n store: {\n ...writeMethods,\n refresh: () => syncAgent.refresh({ resetAllLaneWatermarks: true }),\n refreshRootLane: (options) => syncAgent.refreshRootLane(options),\n // Force an on-demand local SQLite re-read (see the interface doc): arm the\n // gate refreshLocalContainerStates otherwise requires, which the runtime\n // auto-arms only on a context transition an on-demand caller cannot rely on.\n refreshLocalContainers: () => {\n state.localContainersNeedRefresh = true;\n return syncAgent.refreshLocalContainers();\n },\n requestSync: () => syncAgent.scheduleSync(),\n getCachedContainerWriterProjection: (containerId) =>\n getCachedContainerWriterProjectionForStore(state, containerId),\n getSnapshot: () => state.snapshot,\n subscribe: (listener) =>\n subscribeToContainerContentsStore(state, listener),\n updateRuntime: (runtime) =>\n updateContainerContentsStoreRuntime(state, runtime, syncAgent),\n },\n updateOptions: (nextOptions) =>\n applyContainerContentsStoreOptions(state, syncAgent, nextOptions),\n };\n}\n\nexport function createContainerContentsStore(\n initialRuntime: ContainerContentsStoreRuntime,\n persistence: ContainerContentsPersistence = defaultContainerContentsPersistence,\n options: ContainerContentsStoreOptions = {},\n): ContainerContentsStore {\n return createContainerContentsStoreEntry(initialRuntime, persistence, options)\n .store;\n}\n\nexport function getOrCreateContainerContentsStore(\n domainScope: DomainScope,\n runtime: ContainerContentsStoreRuntime,\n options: ContainerContentsStoreOptions = {},\n): ContainerContentsStore {\n const existingEntry = containerContentsStoresByScope.get(domainScope);\n if (existingEntry) {\n existingEntry.updateOptions(options);\n return existingEntry.store;\n }\n\n const nextEntry = createContainerContentsStoreEntry(\n runtime,\n defaultContainerContentsPersistence,\n options,\n );\n containerContentsStoresByScope.set(domainScope, nextEntry);\n return nextEntry.store;\n}\n\n/**\n * Arm the next structural pass's document-priming scan for a domain scope.\n * Priming normally re-arms only on store creation and topology changes, so a\n * caller that just tore down a document's local state uses this to have the\n * still-listed server document re-created without waiting for an app\n * restart. Returns false when the scope has no container-contents store yet;\n * the startup priming pass covers that case.\n */\nexport function requestContainerContentsDocumentPriming(\n domainScope: DomainScope,\n): boolean {\n const entry = containerContentsStoresByScope.get(domainScope);\n if (!entry) {\n return false;\n }\n\n entry.requestDocumentPriming();\n return true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"containerContentsStore.js","sourceRoot":"","sources":["containerContentsStore.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport { getCachedContainerWriterProjection } from \"../../workflows/container-contents/container-state/projectionCache\";\nimport {\n type ContainerContentsPersistence,\n defaultContainerContentsPersistence,\n} from \"../../workflows/container-contents/containerPersistence\";\nimport { persistContainerState } from \"./containerState/containerStatePersistence\";\nimport {\n createChildContainer,\n deleteContainer,\n ensureSystemContainer,\n moveContainer,\n renameContainer,\n} from \"./operations\";\nimport { emptyTrash } from \"./operations/emptyTrashOperation\";\nimport {\n prepareContainerGroupRewrap,\n verifyContainerGroupRewrapCurrent,\n} from \"./operations/groupRewrapOperation\";\nimport { purgeContainer } from \"./operations/purgeContainerOperation\";\nimport { chainPurgeAfterScopeMoves } from \"./operations/purgeMoveSettlementOperation\";\nimport { setContainerIcon } from \"./operations/setContainerIconOperation\";\nimport {\n shareContainerWithGroup,\n shareContainerWithUser,\n} from \"./operations/shareOperations\";\nimport { invalidateRemoteContainerWrites } from \"./remoteWrites/remoteWriteGuards\";\nimport { chainRemoteContainerTask } from \"./remoteWrites/remoteWriteQueue\";\nimport { captureContainerWriteGeneration } from \"./remoteWrites/writeGeneration\";\nimport {\n createContainerContentsStoreState,\n subscribeToContainerContentsStore,\n updateContainerContentsSnapshot,\n updateContainerContentsStorePersistence,\n updateContainerContentsStoreRuntime,\n} from \"./state\";\nimport {\n type ContainerContentsStoreRuntime,\n type ContainerContentsStoreSyncAgent,\n createContainerContentsStoreSyncAgent,\n} from \"./syncAgent\";\nimport { findRootContainerState } from \"./systemContainers/systemContainerLookup\";\nimport type {\n ContainerContentsStore,\n ContainerContentsStoreOptions,\n ContainerContentsStoreState,\n} from \"./types\";\n\nconst containerContentsStoresByScope = new WeakMap<\n DomainScope,\n ContainerContentsStoreEntry\n>();\n\ninterface ContainerContentsStoreEntry {\n requestDocumentPriming: () => void;\n store: ContainerContentsStore;\n updateOptions: (options: ContainerContentsStoreOptions) => void;\n}\n\nfunction applyContainerContentsStoreOptions(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n options: ContainerContentsStoreOptions,\n): void {\n if (\"logLabel\" in options) {\n state.logLabel = options.logLabel;\n }\n\n if (\"persistence\" in options) {\n updateContainerContentsStorePersistence(\n state,\n options.persistence ?? defaultContainerContentsPersistence,\n syncAgent,\n );\n }\n}\n\nfunction getCachedContainerWriterProjectionForStore(\n state: ContainerContentsStoreState,\n containerId: string,\n) {\n const containerState = state.containersById.get(containerId);\n return containerState\n ? getCachedContainerWriterProjection(containerState)\n : null;\n}\n\nfunction createContainerContentsStoreSyncHost(\n state: ContainerContentsStoreState,\n): Parameters<typeof createContainerContentsStoreSyncAgent>[0][\"host\"] {\n return {\n persistContainerState: (\n containerState,\n patch,\n updateView,\n saveOptions,\n mutationOptions,\n ) =>\n persistContainerState(state, containerState, {\n patch,\n updateView,\n saveOptions,\n ...mutationOptions,\n }),\n requestDocumentPriming: () => {\n state.documentStoresNeedPriming = true;\n },\n updateSnapshot: () => updateContainerContentsSnapshot(state),\n };\n}\n\n// null marks an unknown mutation scope; [] delegates invalidation to actual writes.\nfunction chainContainerWrite(\n state: ContainerContentsStoreState,\n work: (isCurrent: () => boolean) => ContainerContentsStoreState[\"writeChain\"],\n changedIds: readonly string[] | null = null,\n movedId?: string,\n): ContainerContentsStoreState[\"writeChain\"] {\n const isCurrent = captureContainerWriteGeneration(state);\n invalidateRemoteContainerWrites(state, changedIds, movedId);\n state.writeChain = state.writeChain\n .catch(() => null)\n .then(() => {\n if (!isCurrent()) return null;\n invalidateRemoteContainerWrites(state, changedIds, movedId);\n return work(isCurrent);\n })\n .then((node) => (isCurrent() ? node : null));\n return state.writeChain;\n}\n\ntype ContainerWriteMethods = Pick<\n ContainerContentsStore,\n | \"createChild\"\n | \"deleteContainer\"\n | \"emptyTrash\"\n | \"ensureSystemContainer\"\n | \"moveContainer\"\n | \"prepareGroupRewrap\"\n | \"purgeContainer\"\n | \"renameContainer\"\n | \"setContainerIcon\"\n | \"shareWithGroup\"\n | \"shareWithUser\"\n>;\n\n// The group-rewrap builder verifies any required existing grant before capturing\n// the container KEK, then returns a check/rewrap pair. A verified non-match is\n// distinct from an unavailable preparation so security-critical callers can\n// no-op unrelated groups without failing open for a real grant.\nfunction createPrepareGroupRewrapMethod(\n state: ContainerContentsStoreState,\n syncAgent: ReturnType<typeof createContainerContentsStoreSyncAgent>,\n): ContainerContentsStore[\"prepareGroupRewrap\"] {\n return async (containerId, groupId, accessLevel, options) => {\n const preparation = await chainRemoteContainerTask(\n state,\n syncAgent,\n null,\n (isCurrent) =>\n prepareContainerGroupRewrap(\n state,\n containerId,\n groupId,\n accessLevel,\n options,\n isCurrent,\n ),\n containerId,\n );\n return preparation?.status === \"prepared\"\n ? {\n isCurrent: (\n expectedGroupHead,\n expectedContainerId,\n expectedOrganizationId,\n ) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n verifyContainerGroupRewrapCurrent(\n state,\n containerId,\n groupId,\n accessLevel,\n expectedGroupHead,\n expectedContainerId,\n expectedOrganizationId,\n isCurrent,\n ),\n containerId,\n ),\n rewrap: () =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n shareContainerWithGroup(\n state,\n syncAgent,\n containerId,\n groupId,\n accessLevel,\n {\n ...options,\n knownContainerKeks: preparation.knownContainerKeks,\n // A prepared re-wrap is grant-preserving by definition, so\n // it never mints a grant and never needs the chosen name.\n requireExistingGrant: true,\n },\n isCurrent,\n ),\n containerId,\n { preserveResultOnLocalWrite: true },\n ),\n status: \"prepared\" as const,\n }\n : (preparation ?? null);\n };\n}\n\nfunction createContainerSharingMethods(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n): Pick<ContainerWriteMethods, \"shareWithUser\" | \"shareWithGroup\"> {\n return {\n shareWithUser: (containerId, userId) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n shareContainerWithUser(\n state,\n syncAgent,\n containerId,\n userId,\n isCurrent,\n ),\n containerId,\n { preserveResultOnLocalWrite: true },\n ),\n shareWithGroup: (containerId, groupId, accessLevel, options) =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n shareContainerWithGroup(\n state,\n syncAgent,\n containerId,\n groupId,\n accessLevel,\n options,\n isCurrent,\n ),\n containerId,\n { preserveResultOnLocalWrite: true },\n ),\n };\n}\n\nfunction createDeleteContainerMethod(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n): ContainerContentsStore[\"deleteContainer\"] {\n return (containerId) => {\n const current = captureContainerWriteGeneration(state);\n const remoteDelete = () =>\n chainRemoteContainerTask(\n state,\n syncAgent,\n null,\n (isCurrent) =>\n deleteContainer(state, syncAgent, containerId, isCurrent),\n containerId,\n ).then((node) => node !== null);\n if (state.containersById.get(containerId)?.record.documentId)\n return remoteDelete();\n let promoted = false;\n return chainContainerWrite(\n state,\n (isCurrent) => {\n // Promotion can win while this local operation was queued. Hand it to\n // the remote queue after releasing the local chain, before any HTTP I/O.\n promoted = Boolean(\n state.containersById.get(containerId)?.record.documentId,\n );\n return promoted\n ? Promise.resolve(null)\n : deleteContainer(state, syncAgent, containerId, isCurrent);\n },\n [containerId],\n ).then((node) => (promoted && current() ? remoteDelete() : node !== null));\n };\n}\n\nfunction createEnsureSystemContainerMethod(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n): ContainerContentsStore[\"ensureSystemContainer\"] {\n return (systemSlot, name, options) => {\n const work = (isCurrent: () => boolean) =>\n ensureSystemContainer(\n state,\n syncAgent,\n systemSlot,\n name,\n options,\n isCurrent,\n );\n const rootId = findRootContainerState(state)?.container.id;\n return options?.deferRemoteBootstrap\n ? chainContainerWrite(state, work, [])\n : chainRemoteContainerTask(\n state,\n syncAgent,\n null,\n work,\n rootId ? { rootId, systemSlot } : undefined,\n );\n };\n}\n\nexport function createContainerWriteMethods(\n state: ContainerContentsStoreState,\n syncAgent: ReturnType<typeof createContainerContentsStoreSyncAgent>,\n): ContainerWriteMethods {\n return {\n ...createContainerSharingMethods(state, syncAgent),\n createChild: (parentId, name) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n createChildContainer(state, syncAgent, parentId, name, isCurrent),\n [parentId],\n ),\n deleteContainer: createDeleteContainerMethod(state, syncAgent),\n purgeContainer: (containerId, options) =>\n chainPurgeAfterScopeMoves(\n state,\n syncAgent,\n containerId,\n options,\n (isCurrent) =>\n purgeContainer(state, syncAgent, containerId, options, isCurrent),\n ),\n emptyTrash: (trashContainerId, options) =>\n chainPurgeAfterScopeMoves(\n state,\n syncAgent,\n trashContainerId,\n options,\n (isCurrent) =>\n emptyTrash(state, syncAgent, trashContainerId, options, isCurrent),\n ),\n ensureSystemContainer: createEnsureSystemContainerMethod(state, syncAgent),\n moveContainer: (containerId, parentId) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n moveContainer(state, syncAgent, containerId, parentId, isCurrent),\n [containerId, parentId],\n containerId,\n ),\n prepareGroupRewrap: createPrepareGroupRewrapMethod(state, syncAgent),\n renameContainer: (containerId, name) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n renameContainer(state, syncAgent, containerId, name, isCurrent),\n [containerId],\n ),\n setContainerIcon: (containerId, icon) =>\n chainContainerWrite(\n state,\n (isCurrent) =>\n setContainerIcon(state, syncAgent, containerId, icon, isCurrent),\n [containerId],\n ),\n };\n}\n\nfunction createContainerContentsStoreEntry(\n initialRuntime: ContainerContentsStoreRuntime,\n persistence: ContainerContentsPersistence = defaultContainerContentsPersistence,\n options: ContainerContentsStoreOptions = {},\n): ContainerContentsStoreEntry {\n const state = createContainerContentsStoreState(\n initialRuntime,\n options.persistence ?? persistence,\n options.logLabel,\n );\n const syncAgent = createContainerContentsStoreSyncAgent({\n host: createContainerContentsStoreSyncHost(state),\n state,\n });\n const writeMethods = createContainerWriteMethods(state, syncAgent);\n\n return {\n requestDocumentPriming: () => {\n state.documentStoresNeedPriming = true;\n syncAgent.scheduleSync();\n },\n store: {\n ...writeMethods,\n refresh: () => syncAgent.refresh({ resetAllLaneWatermarks: true }),\n refreshRootLane: (options) => syncAgent.refreshRootLane(options),\n // Force an on-demand local SQLite re-read (see the interface doc): arm the\n // gate refreshLocalContainerStates otherwise requires, which the runtime\n // auto-arms only on a context transition an on-demand caller cannot rely on.\n refreshLocalContainers: () => {\n state.localContainersNeedRefresh = true;\n return syncAgent.refreshLocalContainers();\n },\n requestSync: () => syncAgent.scheduleSync(),\n getCachedContainerWriterProjection: (containerId) =>\n getCachedContainerWriterProjectionForStore(state, containerId),\n getSnapshot: () => state.snapshot,\n subscribe: (listener) =>\n subscribeToContainerContentsStore(state, listener),\n updateRuntime: (runtime) =>\n updateContainerContentsStoreRuntime(state, runtime, syncAgent),\n },\n updateOptions: (nextOptions) =>\n applyContainerContentsStoreOptions(state, syncAgent, nextOptions),\n };\n}\n\nexport function createContainerContentsStore(\n initialRuntime: ContainerContentsStoreRuntime,\n persistence: ContainerContentsPersistence = defaultContainerContentsPersistence,\n options: ContainerContentsStoreOptions = {},\n): ContainerContentsStore {\n return createContainerContentsStoreEntry(initialRuntime, persistence, options)\n .store;\n}\n\nexport function getOrCreateContainerContentsStore(\n domainScope: DomainScope,\n runtime: ContainerContentsStoreRuntime,\n options: ContainerContentsStoreOptions = {},\n): ContainerContentsStore {\n const existingEntry = containerContentsStoresByScope.get(domainScope);\n if (existingEntry) {\n existingEntry.updateOptions(options);\n return existingEntry.store;\n }\n\n const nextEntry = createContainerContentsStoreEntry(\n runtime,\n defaultContainerContentsPersistence,\n options,\n );\n containerContentsStoresByScope.set(domainScope, nextEntry);\n return nextEntry.store;\n}\n\n/**\n * Arm the next structural pass's document-priming scan for a domain scope.\n * Priming normally re-arms only on store creation and topology changes, so a\n * caller that just tore down a document's local state uses this to have the\n * still-listed server document re-created without waiting for an app\n * restart. Returns false when the scope has no container-contents store yet;\n * the startup priming pass covers that case.\n */\nexport function requestContainerContentsDocumentPriming(\n domainScope: DomainScope,\n): boolean {\n const entry = containerContentsStoresByScope.get(domainScope);\n if (!entry) {\n return false;\n }\n\n entry.requestDocumentPriming();\n return true;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { PurgeOptions, PurgeProgress, } from "../../workflows/container-contents/container-state/purge/purgeProgress.js";
|
|
1
|
+
export type { PurgeMoveSettlement, PurgeOptions, PurgeProgress, } from "../../workflows/container-contents/container-state/purge/purgeProgress.js";
|
|
2
2
|
export * from "./containerContentsStore.js";
|
|
3
3
|
export { isAutomaticRootCatchupContainerNode, isForeignSystemContainerNode, isReconcilableContainerNode, isRemoteBackedContainerNode, isSystemContainerNode, } from "./containerState/reconcilableContainer.js";
|
|
4
4
|
export * from "./state.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAKA,cAAc,0BAA0B,CAAC;AACzC,OAAO,EACL,mCAAmC,EACnC,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,wCAAwC,CAAC;AAChD,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC","sourcesContent":["export type {\n PurgeMoveSettlement,\n PurgeOptions,\n PurgeProgress,\n} from \"../../workflows/container-contents/container-state/purge/purgeProgress\";\nexport * from \"./containerContentsStore\";\nexport {\n isAutomaticRootCatchupContainerNode,\n isForeignSystemContainerNode,\n isReconcilableContainerNode,\n isRemoteBackedContainerNode,\n isSystemContainerNode,\n} from \"./containerState/reconcilableContainer\";\nexport * from \"./state\";\nexport * from \"./syncAgent\";\nexport * from \"./types\";\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { settlePurgeScopeMoves } from "../../../workflows/container-contents/container-state/purge/purgeMoveSettlement.js";
|
|
2
|
+
import { readContainerContentsSyncLane } from "../../../workflows/container-contents/syncLane.js";
|
|
3
|
+
import { trackRemoteContainerWrite } from "../remoteWrites/remoteWriteGuards.js";
|
|
4
|
+
import { chainRemoteContainerTask } from "../remoteWrites/remoteWriteQueue.js";
|
|
5
|
+
import { captureContainerWriteGeneration, } from "../remoteWrites/writeGeneration.js";
|
|
6
|
+
function reportPurgeMoveSettlement(state, message, error) {
|
|
7
|
+
const { log, logError } = state.runtime.util;
|
|
8
|
+
try {
|
|
9
|
+
// A host logger that throws or rejects must not change the purge result.
|
|
10
|
+
if (logError)
|
|
11
|
+
void Promise.resolve(logError(message, error)).catch(() => { });
|
|
12
|
+
else
|
|
13
|
+
log(message);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Hosts may throw synchronously or return a rejected promise.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Delete Forever and Empty Trash often follow a Move to Trash within seconds,
|
|
21
|
+
* before its sync pass reaches the server. Wait for the scope's queued moves
|
|
22
|
+
* before joining the remote write queue, so the wait holds up no other remote
|
|
23
|
+
* task. The purge keeps its own readiness and online gates.
|
|
24
|
+
*
|
|
25
|
+
* The purge's own guards start only when it runs, so the selection is guarded
|
|
26
|
+
* from the click instead: a local edit in the subtree, or a new identity or
|
|
27
|
+
* database, cancels the purge, and it starts only while the selected folder
|
|
28
|
+
* still sits where it was selected, whichever device moved it.
|
|
29
|
+
*/
|
|
30
|
+
export async function chainPurgeAfterScopeMoves(state, syncAgent, containerId, options, purge) {
|
|
31
|
+
const runtime = state.runtime;
|
|
32
|
+
if (runtime.infra.dbStatus !== "ready" ||
|
|
33
|
+
!state.snapshot.ready ||
|
|
34
|
+
!runtime.auth.isAuthenticated ||
|
|
35
|
+
!runtime.state.online ||
|
|
36
|
+
!state.containersById.has(containerId)) {
|
|
37
|
+
return chainRemoteContainerTask(state, syncAgent, false, purge, containerId);
|
|
38
|
+
}
|
|
39
|
+
const writeCurrent = captureContainerWriteGeneration(state);
|
|
40
|
+
const tracked = trackRemoteContainerWrite(state, containerId);
|
|
41
|
+
const selectedParentId = state.containersById.get(containerId)?.container.parentId;
|
|
42
|
+
const selectionCurrent = () => writeCurrent() && !tracked.changed();
|
|
43
|
+
const placementCurrent = () => state.containersById.get(containerId)?.container.parentId ===
|
|
44
|
+
selectedParentId;
|
|
45
|
+
try {
|
|
46
|
+
const domainScope = runtime.state.domainScope;
|
|
47
|
+
const settlement = await settlePurgeScopeMoves({
|
|
48
|
+
containersById: state.containersById,
|
|
49
|
+
execSql: runtime.infra.execSql,
|
|
50
|
+
lane: {
|
|
51
|
+
read: () => readContainerContentsSyncLane(domainScope),
|
|
52
|
+
request: () => syncAgent.scheduleSync(),
|
|
53
|
+
},
|
|
54
|
+
onMoveSettlement: options?.onMoveSettlement,
|
|
55
|
+
persistence: state.persistence,
|
|
56
|
+
report: (message, error) => reportPurgeMoveSettlement(state, message, error),
|
|
57
|
+
rootContainerId: containerId,
|
|
58
|
+
signal: options?.signal,
|
|
59
|
+
stillCurrent: () => selectionCurrent() && placementCurrent(),
|
|
60
|
+
});
|
|
61
|
+
if (settlement !== "settled" || !selectionCurrent())
|
|
62
|
+
return false;
|
|
63
|
+
return await chainRemoteContainerTask(state, syncAgent, false, (isCurrent) => selectionCurrent() && placementCurrent()
|
|
64
|
+
? purge(() => isCurrent() && selectionCurrent())
|
|
65
|
+
: Promise.resolve(false), containerId);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
tracked.dispose();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=purgeMoveSettlementOperation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purgeMoveSettlementOperation.js","sourceRoot":"","sources":["purgeMoveSettlementOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import { settlePurgeScopeMoves } from \"../../../workflows/container-contents/container-state/purge/purgeMoveSettlement\";\nimport type { PurgeOptions } from \"../../../workflows/container-contents/container-state/purge/purgeProgress\";\nimport { readContainerContentsSyncLane } from \"../../../workflows/container-contents/syncLane\";\nimport { trackRemoteContainerWrite } from \"../remoteWrites/remoteWriteGuards\";\nimport { chainRemoteContainerTask } from \"../remoteWrites/remoteWriteQueue\";\nimport {\n type ContainerWriteGuard,\n captureContainerWriteGeneration,\n} from \"../remoteWrites/writeGeneration\";\nimport type { ContainerContentsStoreSyncAgent } from \"../syncAgent\";\nimport type { ContainerContentsStoreState } from \"../types\";\n\nfunction reportPurgeMoveSettlement(\n state: ContainerContentsStoreState,\n message: string,\n error: Error,\n): void {\n const { log, logError } = state.runtime.util;\n try {\n // A host logger that throws or rejects must not change the purge result.\n if (logError)\n void Promise.resolve(logError(message, error)).catch(() => {});\n else log(message);\n } catch {\n // Hosts may throw synchronously or return a rejected promise.\n }\n}\n\n/**\n * Delete Forever and Empty Trash often follow a Move to Trash within seconds,\n * before its sync pass reaches the server. Wait for the scope's queued moves\n * before joining the remote write queue, so the wait holds up no other remote\n * task. The purge keeps its own readiness and online gates.\n *\n * The purge's own guards start only when it runs, so the selection is guarded\n * from the click instead: a local edit in the subtree, or a new identity or\n * database, cancels the purge, and it starts only while the selected folder\n * still sits where it was selected, whichever device moved it.\n */\nexport async function chainPurgeAfterScopeMoves(\n state: ContainerContentsStoreState,\n syncAgent: ContainerContentsStoreSyncAgent,\n containerId: string,\n options: PurgeOptions | undefined,\n purge: (isCurrent: ContainerWriteGuard) => Promise<boolean>,\n): Promise<boolean> {\n const runtime = state.runtime;\n if (\n runtime.infra.dbStatus !== \"ready\" ||\n !state.snapshot.ready ||\n !runtime.auth.isAuthenticated ||\n !runtime.state.online ||\n !state.containersById.has(containerId)\n ) {\n return chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n purge,\n containerId,\n );\n }\n const writeCurrent = captureContainerWriteGeneration(state);\n const tracked = trackRemoteContainerWrite(state, containerId);\n const selectedParentId =\n state.containersById.get(containerId)?.container.parentId;\n const selectionCurrent = () => writeCurrent() && !tracked.changed();\n const placementCurrent = () =>\n state.containersById.get(containerId)?.container.parentId ===\n selectedParentId;\n try {\n const domainScope = runtime.state.domainScope;\n const settlement = await settlePurgeScopeMoves({\n containersById: state.containersById,\n execSql: runtime.infra.execSql,\n lane: {\n read: () => readContainerContentsSyncLane(domainScope),\n request: () => syncAgent.scheduleSync(),\n },\n onMoveSettlement: options?.onMoveSettlement,\n persistence: state.persistence,\n report: (message, error) =>\n reportPurgeMoveSettlement(state, message, error),\n rootContainerId: containerId,\n signal: options?.signal,\n stillCurrent: () => selectionCurrent() && placementCurrent(),\n });\n if (settlement !== \"settled\" || !selectionCurrent()) return false;\n return await chainRemoteContainerTask(\n state,\n syncAgent,\n false,\n (isCurrent) =>\n selectionCurrent() && placementCurrent()\n ? purge(() => isCurrent() && selectionCurrent())\n : Promise.resolve(false),\n containerId,\n );\n } finally {\n tracked.dispose();\n }\n}\n"]}
|
|
@@ -8,6 +8,38 @@ import { moveRemoteContainer } from "./remote.js";
|
|
|
8
8
|
function currentMoveResult(isCurrent, result) {
|
|
9
9
|
return isCurrent() ? result : "abandoned";
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The server accepted a move this pass did not settle, so the intent stays
|
|
13
|
+
* queued: a later pass re-posts it and a purge of its subtree waits. Fixed
|
|
14
|
+
* messages only; the error's call site names the path.
|
|
15
|
+
*/
|
|
16
|
+
function reportUnsettledAcceptedMove(state, message, error) {
|
|
17
|
+
try {
|
|
18
|
+
const report = state.runtime.util.logError;
|
|
19
|
+
if (report)
|
|
20
|
+
void Promise.resolve(report(message, error)).catch(() => { });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// A host logger must not change the replay result.
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function reportStaleAcceptedMove(state, error) {
|
|
27
|
+
reportUnsettledAcceptedMove(state, "Container contents: a stale sync pass dropped an accepted container move", error);
|
|
28
|
+
}
|
|
29
|
+
function reportFailedAcceptedMove(state, error) {
|
|
30
|
+
if (!(error instanceof Error))
|
|
31
|
+
return;
|
|
32
|
+
reportUnsettledAcceptedMove(state, "Container contents: an accepted container move failed to settle", error);
|
|
33
|
+
}
|
|
34
|
+
/** persistAcceptedMoveIntent already asked to reconcile a stale result. */
|
|
35
|
+
function unpersistedMoveResult(syncInput) {
|
|
36
|
+
if (!syncInput.isCurrent()) {
|
|
37
|
+
reportStaleAcceptedMove(syncInput.state, new Error("Stale pass dropped a persisting container move"));
|
|
38
|
+
return "abandoned";
|
|
39
|
+
}
|
|
40
|
+
reportUnsettledAcceptedMove(syncInput.state, "Container contents: an accepted container move did not persist", new Error("Accepted container move did not persist"));
|
|
41
|
+
return "failed";
|
|
42
|
+
}
|
|
11
43
|
async function recordPendingMoveIntentError(input) {
|
|
12
44
|
if (!input.isCurrent()) {
|
|
13
45
|
return false;
|
|
@@ -170,6 +202,7 @@ async function movePendingRemoteContainer(input) {
|
|
|
170
202
|
let remoteParentId = intent.parentContainerId;
|
|
171
203
|
const abandonAppliedMove = () => {
|
|
172
204
|
if (remoteMoveApplied) {
|
|
205
|
+
reportStaleAcceptedMove(state, new Error("Stale pass dropped an accepted container move"));
|
|
173
206
|
syncInput.requestRemoteReconciliation(remoteParentId);
|
|
174
207
|
}
|
|
175
208
|
return "abandoned";
|
|
@@ -177,6 +210,9 @@ async function movePendingRemoteContainer(input) {
|
|
|
177
210
|
try {
|
|
178
211
|
const moved = await moveRemoteContainer({
|
|
179
212
|
containerId: intent.containerId,
|
|
213
|
+
onStaleAcceptance: () => {
|
|
214
|
+
remoteMoveApplied = true;
|
|
215
|
+
},
|
|
180
216
|
parentContainerId: intent.parentContainerId,
|
|
181
217
|
resolveProjectionUserKey: state.resolveProjectionUserKey,
|
|
182
218
|
runtime: state.runtime,
|
|
@@ -184,8 +220,9 @@ async function movePendingRemoteContainer(input) {
|
|
|
184
220
|
});
|
|
185
221
|
if (!moved) {
|
|
186
222
|
if (!syncInput.isCurrent()) {
|
|
187
|
-
|
|
188
|
-
|
|
223
|
+
if (!remoteMoveApplied)
|
|
224
|
+
syncInput.requestRemoteReconciliation(intent.parentContainerId);
|
|
225
|
+
return abandonAppliedMove();
|
|
189
226
|
}
|
|
190
227
|
await recordPendingMoveIntentError({
|
|
191
228
|
containerId: intent.containerId,
|
|
@@ -209,9 +246,8 @@ async function movePendingRemoteContainer(input) {
|
|
|
209
246
|
requestRemoteReconciliation: syncInput.requestRemoteReconciliation,
|
|
210
247
|
state,
|
|
211
248
|
});
|
|
212
|
-
if (!persisted)
|
|
213
|
-
return
|
|
214
|
-
}
|
|
249
|
+
if (!persisted)
|
|
250
|
+
return unpersistedMoveResult(syncInput);
|
|
215
251
|
state.runtime.util.log(`Container contents: synced queued container move ${intent.containerId}`);
|
|
216
252
|
return "moved";
|
|
217
253
|
}
|
|
@@ -230,6 +266,8 @@ async function movePendingRemoteContainer(input) {
|
|
|
230
266
|
if (!syncInput.isCurrent()) {
|
|
231
267
|
return abandonAppliedMove();
|
|
232
268
|
}
|
|
269
|
+
if (remoteMoveApplied)
|
|
270
|
+
reportFailedAcceptedMove(state, error);
|
|
233
271
|
await recordPendingMoveIntentError({
|
|
234
272
|
containerId: intent.containerId,
|
|
235
273
|
expectedIntentId: intent.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moveIntentSync.js","sourceRoot":"","sources":["moveIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadata/metadataStateIsolation\";\nimport type { ContainerState, RemoteContainer } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { moveRemoteContainer } from \"./remote\";\nimport type {\n ContainerMoveIntentSyncHost,\n ContainerMoveIntentSyncInput,\n ContainerMoveIntentSyncState,\n} from \"./types\";\n\ntype MoveIntentSyncResult = \"abandoned\" | \"blocked\" | \"failed\" | \"moved\";\n\nfunction currentMoveResult<\n Result extends Exclude<MoveIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function recordPendingMoveIntentError(input: {\n blocked?: boolean | undefined;\n containerId: string;\n expectedIntentId: string;\n expectedUpdatedAt: string;\n isCurrent: () => boolean;\n message: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n if (!input.isCurrent()) {\n return false;\n }\n const execSql = input.state.runtime.infra.execSql;\n await input.state.persistence.recordMoveIntentError(execSql, {\n blocked: input.blocked,\n containerId: input.containerId,\n expectedIntentId: input.expectedIntentId,\n expectedUpdatedAt: input.expectedUpdatedAt,\n message: input.message,\n stillCurrent: input.isCurrent,\n });\n return input.isCurrent();\n}\n\nasync function resolveMoveIntentLocalUpdatedAt(input: {\n containerId: string;\n isCurrent: () => boolean;\n remoteUpdatedAt: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<string | null> {\n if (!input.isCurrent()) {\n return null;\n }\n const previousLocalUpdatedAt =\n input.state.containersById.get(input.containerId)?.container\n .localUpdatedAt ?? null;\n if (\n !previousLocalUpdatedAt ||\n previousLocalUpdatedAt.localeCompare(input.remoteUpdatedAt) <= 0\n ) {\n return input.remoteUpdatedAt;\n }\n\n const execSql = input.state.runtime.infra.execSql;\n const containersWithPendingMetadataUpdates =\n await input.state.persistence.listContainerIdsWithPendingUpdates(execSql, [\n input.containerId,\n ]);\n if (!input.isCurrent()) {\n return null;\n }\n\n return containersWithPendingMetadataUpdates.includes(input.containerId)\n ? previousLocalUpdatedAt\n : input.remoteUpdatedAt;\n}\n\nexport async function persistAcceptedMoveIntent(input: {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerMoveIntentSyncInput[\"intent\"];\n moved: RemoteContainer;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n const { host, intent, moved, state } = input;\n const abandon = () => {\n input.requestRemoteReconciliation(moved.parentId);\n return false;\n };\n if (!input.isCurrent()) return abandon();\n const containerState = state.containersById.get(intent.containerId);\n if (!containerState) {\n return false;\n }\n\n await createRuntimePrincipalPolicyWarmer(state.runtime)({\n organizationId: moved.organizationId,\n references: moved.metadataReferencedPrincipals,\n stillCurrent: input.isCurrent,\n });\n if (!input.isCurrent()) {\n return abandon();\n }\n const localUpdatedAt = await resolveMoveIntentLocalUpdatedAt({\n containerId: intent.containerId,\n isCurrent: input.isCurrent,\n remoteUpdatedAt: moved.updatedAt,\n state,\n });\n if (!input.isCurrent() || localUpdatedAt === null) {\n return abandon();\n }\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) {\n return abandon();\n }\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: moved.createdAt,\n serverCreatedAt: moved.createdAt,\n serverUpdatedAt: moved.updatedAt,\n updatedAt: moved.updatedAt,\n };\n const persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: moved.metadataAccessEpoch,\n accessStateHash: moved.metadataAccessStateHash,\n documentId: moved.metadataDocumentId,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n systemSlot: moved.systemSlot ?? null,\n },\n false,\n {\n localUpdatedAt,\n serverTimestamps: {\n createdAt: moved.createdAt,\n updatedAt: moved.updatedAt,\n },\n },\n {\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n moveIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n },\n },\n );\n if (!input.isCurrent() || persistenceResult.status !== \"persisted\") {\n return abandon();\n }\n if (persistenceResult.moveIntentSettled !== true) {\n throw new Error(\n \"Container move persistence must settle the intent atomically\",\n );\n }\n if (!input.isCurrent()) return abandon();\n const { record: nextRecord } = persistenceResult;\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n };\n return true;\n}\n\n/**\n * A move refused for path length never succeeds; the queue-time check saw only\n * the descendants this device holds. Drop the queued move and restore the\n * previous parent together: the server row never changed, so no listing would\n * ever put the folder back.\n */\nasync function abandonTooDeepMove(\n syncInput: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { host, intent, state } = syncInput;\n const previousParentId = intent.previousParentContainerId;\n if (previousParentId === null) {\n throw new Error(\"A queued container move must name its previous parent\");\n }\n const abandoned = await state.persistence.abandonMoveIntentRevision(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n previousParentContainerId: previousParentId,\n stillCurrent: syncInput.isCurrent,\n },\n );\n if (!syncInput.isCurrent()) return \"abandoned\";\n // A newer local move superseded this revision; it replays on its own.\n if (!abandoned) return \"failed\";\n const containerState = state.containersById.get(intent.containerId);\n if (containerState) {\n containerState.container = {\n ...containerState.container,\n parentId: previousParentId,\n };\n }\n host.updateSnapshot();\n state.runtime.util.log(\n `Container contents: abandoned queued move of ${intent.containerId}; its path would exceed the maximum depth`,\n );\n return \"failed\";\n}\n\nasync function movePendingRemoteContainer(input: {\n parentState: ContainerState;\n syncInput: ContainerMoveIntentSyncInput;\n}): Promise<MoveIntentSyncResult> {\n const { parentState, syncInput } = input;\n const { host, intent, state } = syncInput;\n let remoteMoveApplied = false;\n let remoteParentId: string | null = intent.parentContainerId;\n const abandonAppliedMove = () => {\n if (remoteMoveApplied) {\n syncInput.requestRemoteReconciliation(remoteParentId);\n }\n return \"abandoned\" as const;\n };\n try {\n const moved = await moveRemoteContainer({\n containerId: intent.containerId,\n parentContainerId: intent.parentContainerId,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n if (!moved) {\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: \"Remote container move was rejected or unavailable\",\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n remoteMoveApplied = true;\n remoteParentId = moved.parentId;\n if (!syncInput.isCurrent()) return abandonAppliedMove();\n\n const persisted = await persistAcceptedMoveIntent({\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n moved,\n requestRemoteReconciliation: syncInput.requestRemoteReconciliation,\n state,\n });\n if (!persisted) {\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n state.runtime.util.log(\n `Container contents: synced queued container move ${intent.containerId}`,\n );\n return \"moved\";\n } catch (error: unknown) {\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (error instanceof ContainerPathTooDeepError)\n return abandonTooDeepMove(syncInput);\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.move.replay\",\n organizationId: parentState.container.organizationId,\n },\n );\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: `Failed to sync container move: ${errorMessage(error)}`,\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n}\n\nasync function trySyncPendingContainerMoveIntent(\n input: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move intent references a missing local container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (!parentState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message:\n \"Container move intent references a missing destination parent container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (input.isRemoteSyncBlocked(containerState.container.organizationId)) {\n return \"blocked\";\n }\n if (\n !hasRemoteContainerMetadataState(containerState) ||\n input.isCreatePending(intent.containerId)\n ) {\n // Source not synced yet is TRANSIENT, exactly like the destination case\n // below: the source's own create intent syncs first (createIntentSync runs\n // before moveIntentSync in a pass), but if that create fails on this pass\n // the source still lacks remote metadata here. Keep the intent 'pending'\n // (not 'blocked') so the queue reports a retryable failure rather than a\n // missing-dependency block; either way listUnsyncedMoveIntents replays it\n // once the create lands.\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move source is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(intent.parentContainerId)\n ) {\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move destination parent is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n\n return movePendingRemoteContainer({ parentState, syncInput: input });\n}\n\nexport async function syncPendingContainerMoveIntents(input: {\n host: ContainerMoveIntentSyncHost;\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listUnsyncedMoveIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n let movedCount = 0;\n\n for (const intent of pendingIntents) {\n if (!input.isCurrent()) {\n return movedCount;\n }\n const result = await trySyncPendingContainerMoveIntent({\n host,\n isCurrent: input.isCurrent,\n isCreatePending: input.isCreatePending,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n });\n if (result === \"abandoned\") {\n return movedCount;\n }\n\n if (result === \"moved\") {\n movedCount += 1;\n }\n }\n\n return movedCount;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"moveIntentSync.js","sourceRoot":"","sources":["moveIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadata/metadataStateIsolation\";\nimport type { ContainerState, RemoteContainer } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { moveRemoteContainer } from \"./remote\";\nimport type {\n ContainerMoveIntentSyncHost,\n ContainerMoveIntentSyncInput,\n ContainerMoveIntentSyncState,\n} from \"./types\";\n\ntype MoveIntentSyncResult = \"abandoned\" | \"blocked\" | \"failed\" | \"moved\";\n\nfunction currentMoveResult<\n Result extends Exclude<MoveIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\n/**\n * The server accepted a move this pass did not settle, so the intent stays\n * queued: a later pass re-posts it and a purge of its subtree waits. Fixed\n * messages only; the error's call site names the path.\n */\nfunction reportUnsettledAcceptedMove(\n state: ContainerMoveIntentSyncState,\n message: string,\n error: Error,\n): void {\n try {\n const report = state.runtime.util.logError;\n if (report) void Promise.resolve(report(message, error)).catch(() => {});\n } catch {\n // A host logger must not change the replay result.\n }\n}\n\nfunction reportStaleAcceptedMove(\n state: ContainerMoveIntentSyncState,\n error: Error,\n): void {\n reportUnsettledAcceptedMove(\n state,\n \"Container contents: a stale sync pass dropped an accepted container move\",\n error,\n );\n}\n\nfunction reportFailedAcceptedMove(\n state: ContainerMoveIntentSyncState,\n error: unknown,\n): void {\n if (!(error instanceof Error)) return;\n reportUnsettledAcceptedMove(\n state,\n \"Container contents: an accepted container move failed to settle\",\n error,\n );\n}\n\n/** persistAcceptedMoveIntent already asked to reconcile a stale result. */\nfunction unpersistedMoveResult(\n syncInput: ContainerMoveIntentSyncInput,\n): MoveIntentSyncResult {\n if (!syncInput.isCurrent()) {\n reportStaleAcceptedMove(\n syncInput.state,\n new Error(\"Stale pass dropped a persisting container move\"),\n );\n return \"abandoned\";\n }\n reportUnsettledAcceptedMove(\n syncInput.state,\n \"Container contents: an accepted container move did not persist\",\n new Error(\"Accepted container move did not persist\"),\n );\n return \"failed\";\n}\n\nasync function recordPendingMoveIntentError(input: {\n blocked?: boolean | undefined;\n containerId: string;\n expectedIntentId: string;\n expectedUpdatedAt: string;\n isCurrent: () => boolean;\n message: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n if (!input.isCurrent()) {\n return false;\n }\n const execSql = input.state.runtime.infra.execSql;\n await input.state.persistence.recordMoveIntentError(execSql, {\n blocked: input.blocked,\n containerId: input.containerId,\n expectedIntentId: input.expectedIntentId,\n expectedUpdatedAt: input.expectedUpdatedAt,\n message: input.message,\n stillCurrent: input.isCurrent,\n });\n return input.isCurrent();\n}\n\nasync function resolveMoveIntentLocalUpdatedAt(input: {\n containerId: string;\n isCurrent: () => boolean;\n remoteUpdatedAt: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<string | null> {\n if (!input.isCurrent()) {\n return null;\n }\n const previousLocalUpdatedAt =\n input.state.containersById.get(input.containerId)?.container\n .localUpdatedAt ?? null;\n if (\n !previousLocalUpdatedAt ||\n previousLocalUpdatedAt.localeCompare(input.remoteUpdatedAt) <= 0\n ) {\n return input.remoteUpdatedAt;\n }\n\n const execSql = input.state.runtime.infra.execSql;\n const containersWithPendingMetadataUpdates =\n await input.state.persistence.listContainerIdsWithPendingUpdates(execSql, [\n input.containerId,\n ]);\n if (!input.isCurrent()) {\n return null;\n }\n\n return containersWithPendingMetadataUpdates.includes(input.containerId)\n ? previousLocalUpdatedAt\n : input.remoteUpdatedAt;\n}\n\nexport async function persistAcceptedMoveIntent(input: {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerMoveIntentSyncInput[\"intent\"];\n moved: RemoteContainer;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n const { host, intent, moved, state } = input;\n const abandon = () => {\n input.requestRemoteReconciliation(moved.parentId);\n return false;\n };\n if (!input.isCurrent()) return abandon();\n const containerState = state.containersById.get(intent.containerId);\n if (!containerState) {\n return false;\n }\n\n await createRuntimePrincipalPolicyWarmer(state.runtime)({\n organizationId: moved.organizationId,\n references: moved.metadataReferencedPrincipals,\n stillCurrent: input.isCurrent,\n });\n if (!input.isCurrent()) {\n return abandon();\n }\n const localUpdatedAt = await resolveMoveIntentLocalUpdatedAt({\n containerId: intent.containerId,\n isCurrent: input.isCurrent,\n remoteUpdatedAt: moved.updatedAt,\n state,\n });\n if (!input.isCurrent() || localUpdatedAt === null) {\n return abandon();\n }\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) {\n return abandon();\n }\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: moved.createdAt,\n serverCreatedAt: moved.createdAt,\n serverUpdatedAt: moved.updatedAt,\n updatedAt: moved.updatedAt,\n };\n const persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: moved.metadataAccessEpoch,\n accessStateHash: moved.metadataAccessStateHash,\n documentId: moved.metadataDocumentId,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n systemSlot: moved.systemSlot ?? null,\n },\n false,\n {\n localUpdatedAt,\n serverTimestamps: {\n createdAt: moved.createdAt,\n updatedAt: moved.updatedAt,\n },\n },\n {\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n moveIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n },\n },\n );\n if (!input.isCurrent() || persistenceResult.status !== \"persisted\") {\n return abandon();\n }\n if (persistenceResult.moveIntentSettled !== true) {\n throw new Error(\n \"Container move persistence must settle the intent atomically\",\n );\n }\n if (!input.isCurrent()) return abandon();\n const { record: nextRecord } = persistenceResult;\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n };\n return true;\n}\n\n/**\n * A move refused for path length never succeeds; the queue-time check saw only\n * the descendants this device holds. Drop the queued move and restore the\n * previous parent together: the server row never changed, so no listing would\n * ever put the folder back.\n */\nasync function abandonTooDeepMove(\n syncInput: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { host, intent, state } = syncInput;\n const previousParentId = intent.previousParentContainerId;\n if (previousParentId === null) {\n throw new Error(\"A queued container move must name its previous parent\");\n }\n const abandoned = await state.persistence.abandonMoveIntentRevision(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n previousParentContainerId: previousParentId,\n stillCurrent: syncInput.isCurrent,\n },\n );\n if (!syncInput.isCurrent()) return \"abandoned\";\n // A newer local move superseded this revision; it replays on its own.\n if (!abandoned) return \"failed\";\n const containerState = state.containersById.get(intent.containerId);\n if (containerState) {\n containerState.container = {\n ...containerState.container,\n parentId: previousParentId,\n };\n }\n host.updateSnapshot();\n state.runtime.util.log(\n `Container contents: abandoned queued move of ${intent.containerId}; its path would exceed the maximum depth`,\n );\n return \"failed\";\n}\n\nasync function movePendingRemoteContainer(input: {\n parentState: ContainerState;\n syncInput: ContainerMoveIntentSyncInput;\n}): Promise<MoveIntentSyncResult> {\n const { parentState, syncInput } = input;\n const { host, intent, state } = syncInput;\n let remoteMoveApplied = false;\n let remoteParentId: string | null = intent.parentContainerId;\n const abandonAppliedMove = () => {\n if (remoteMoveApplied) {\n reportStaleAcceptedMove(\n state,\n new Error(\"Stale pass dropped an accepted container move\"),\n );\n syncInput.requestRemoteReconciliation(remoteParentId);\n }\n return \"abandoned\" as const;\n };\n try {\n const moved = await moveRemoteContainer({\n containerId: intent.containerId,\n onStaleAcceptance: () => {\n remoteMoveApplied = true;\n },\n parentContainerId: intent.parentContainerId,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n if (!moved) {\n if (!syncInput.isCurrent()) {\n if (!remoteMoveApplied)\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return abandonAppliedMove();\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: \"Remote container move was rejected or unavailable\",\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n remoteMoveApplied = true;\n remoteParentId = moved.parentId;\n if (!syncInput.isCurrent()) return abandonAppliedMove();\n\n const persisted = await persistAcceptedMoveIntent({\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n moved,\n requestRemoteReconciliation: syncInput.requestRemoteReconciliation,\n state,\n });\n if (!persisted) return unpersistedMoveResult(syncInput);\n state.runtime.util.log(\n `Container contents: synced queued container move ${intent.containerId}`,\n );\n return \"moved\";\n } catch (error: unknown) {\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (error instanceof ContainerPathTooDeepError)\n return abandonTooDeepMove(syncInput);\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.move.replay\",\n organizationId: parentState.container.organizationId,\n },\n );\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (remoteMoveApplied) reportFailedAcceptedMove(state, error);\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: `Failed to sync container move: ${errorMessage(error)}`,\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n}\n\nasync function trySyncPendingContainerMoveIntent(\n input: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move intent references a missing local container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (!parentState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message:\n \"Container move intent references a missing destination parent container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (input.isRemoteSyncBlocked(containerState.container.organizationId)) {\n return \"blocked\";\n }\n if (\n !hasRemoteContainerMetadataState(containerState) ||\n input.isCreatePending(intent.containerId)\n ) {\n // Source not synced yet is TRANSIENT, exactly like the destination case\n // below: the source's own create intent syncs first (createIntentSync runs\n // before moveIntentSync in a pass), but if that create fails on this pass\n // the source still lacks remote metadata here. Keep the intent 'pending'\n // (not 'blocked') so the queue reports a retryable failure rather than a\n // missing-dependency block; either way listUnsyncedMoveIntents replays it\n // once the create lands.\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move source is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(intent.parentContainerId)\n ) {\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move destination parent is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n\n return movePendingRemoteContainer({ parentState, syncInput: input });\n}\n\nexport async function syncPendingContainerMoveIntents(input: {\n host: ContainerMoveIntentSyncHost;\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listUnsyncedMoveIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n let movedCount = 0;\n\n for (const intent of pendingIntents) {\n if (!input.isCurrent()) {\n return movedCount;\n }\n const result = await trySyncPendingContainerMoveIntent({\n host,\n isCurrent: input.isCurrent,\n isCreatePending: input.isCreatePending,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n });\n if (result === \"abandoned\") {\n return movedCount;\n }\n\n if (result === \"moved\") {\n movedCount += 1;\n }\n }\n\n return movedCount;\n}\n"]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { listDocumentPlacementIntentStates } from "../../../../data/persistence/container-contents/documentPurgePlacement.js";
|
|
2
|
+
import { listDocumentsByContainerIdsOrDocumentIds } from "../../../../data/persistence/documents/documentsPersistence.js";
|
|
3
|
+
import { collectSubtreeLeafFirst } from "./purgeTreeCollection.js";
|
|
4
|
+
// A pass replays pending and blocked moves. A denied placement waits for the
|
|
5
|
+
// next store generation and an unavailable one never replays, so waiting on
|
|
6
|
+
// either would only reach the ceiling.
|
|
7
|
+
const REPLAYED_STATUSES = new Set(["pending", "blocked"]);
|
|
8
|
+
const DEFAULT_TIMING = { pollMs: 200, timeoutMs: 30_000 };
|
|
9
|
+
function delay(ms, signal) {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
const timer = setTimeout(done, ms);
|
|
12
|
+
function done() {
|
|
13
|
+
clearTimeout(timer);
|
|
14
|
+
signal?.removeEventListener("abort", done);
|
|
15
|
+
resolve();
|
|
16
|
+
}
|
|
17
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function createScopeReader(input) {
|
|
21
|
+
const containerIds = new Set(collectSubtreeLeafFirst(input.containersById, input.rootContainerId).map((containerState) => containerState.container.id));
|
|
22
|
+
let documentLocalIds = null;
|
|
23
|
+
// Listing the subtree's documents is the costly read, so it runs only once
|
|
24
|
+
// some document placement is queued anywhere on this device.
|
|
25
|
+
const readDocumentLocalIds = () => {
|
|
26
|
+
documentLocalIds ??= listDocumentsByContainerIdsOrDocumentIds(input.execSql, { containerIds: [...containerIds], documentIds: [] }).then((documents) => new Set(documents.map((document) => document.id)));
|
|
27
|
+
return documentLocalIds;
|
|
28
|
+
};
|
|
29
|
+
return async () => {
|
|
30
|
+
const moves = await input.persistence.listUnsyncedMoveIntents(input.execSql);
|
|
31
|
+
const placements = await listDocumentPlacementIntentStates(input.execSql);
|
|
32
|
+
const scoped = moves.filter((move) => containerIds.has(move.containerId));
|
|
33
|
+
if (placements.length === 0)
|
|
34
|
+
return scoped;
|
|
35
|
+
const localIds = await readDocumentLocalIds();
|
|
36
|
+
return [
|
|
37
|
+
...scoped,
|
|
38
|
+
...placements.filter((placement) => localIds.has(placement.localId)),
|
|
39
|
+
];
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const isParked = (intent) => !REPLAYED_STATUSES.has(intent.syncStatus);
|
|
43
|
+
/** Why a wait that began at `startedAt` must stop, or null to keep polling. */
|
|
44
|
+
function stopReason(input) {
|
|
45
|
+
const { intents, lane, startedAt } = input;
|
|
46
|
+
if (intents.some(isParked))
|
|
47
|
+
return {
|
|
48
|
+
error: new Error("Purge scope move was parked"),
|
|
49
|
+
message: "Container contents: a move in the purge scope was parked",
|
|
50
|
+
};
|
|
51
|
+
if (startedAt !== null &&
|
|
52
|
+
intents.some(({ lastAttemptedAt }) => lastAttemptedAt !== null && lastAttemptedAt >= startedAt))
|
|
53
|
+
return {
|
|
54
|
+
error: new Error("Purge scope move failed to sync"),
|
|
55
|
+
message: "Container contents: a move in the purge scope failed to sync",
|
|
56
|
+
};
|
|
57
|
+
if (startedAt !== null && lane && !lane.running && !lane.requested)
|
|
58
|
+
return {
|
|
59
|
+
error: new Error("Purge scope move stayed queued"),
|
|
60
|
+
message: "Container contents: a sync pass left a purge scope move queued",
|
|
61
|
+
};
|
|
62
|
+
if (Date.now() >= input.deadline)
|
|
63
|
+
return {
|
|
64
|
+
error: new Error("Purge scope move wait timed out"),
|
|
65
|
+
message: "Container contents: purge timed out waiting for a move",
|
|
66
|
+
};
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The purge scope refuses a subtree whose moves the server has not accepted,
|
|
71
|
+
* so ask for a pass that replays them and wait for its verdict. The scope's
|
|
72
|
+
* own checks still run afterwards; this only gives the moves time to land.
|
|
73
|
+
* It ends unsettled once a pass requested here has tried and left one queued.
|
|
74
|
+
*/
|
|
75
|
+
export async function settlePurgeScopeMoves(input) {
|
|
76
|
+
const timing = input.timing ?? DEFAULT_TIMING;
|
|
77
|
+
const cancelled = () => input.signal?.aborted === true || !input.stillCurrent();
|
|
78
|
+
const unsettled = (reason) => {
|
|
79
|
+
input.report(reason.message, reason.error);
|
|
80
|
+
input.onMoveSettlement?.("unsettled");
|
|
81
|
+
return "unsettled";
|
|
82
|
+
};
|
|
83
|
+
const readScope = createScopeReader(input);
|
|
84
|
+
let intents = await readScope();
|
|
85
|
+
if (cancelled())
|
|
86
|
+
return "cancelled";
|
|
87
|
+
if (intents.length === 0)
|
|
88
|
+
return "settled";
|
|
89
|
+
if (intents.some(isParked))
|
|
90
|
+
return unsettled({
|
|
91
|
+
error: new Error("Purge scope holds a parked move"),
|
|
92
|
+
message: "Container contents: purge scope holds a parked move",
|
|
93
|
+
});
|
|
94
|
+
input.onMoveSettlement?.("waiting");
|
|
95
|
+
const runCountAtRequest = input.lane.read()?.runCount ?? 0;
|
|
96
|
+
input.lane.request();
|
|
97
|
+
const deadline = Date.now() + timing.timeoutMs;
|
|
98
|
+
let startedAt = null;
|
|
99
|
+
while (true) {
|
|
100
|
+
await delay(timing.pollMs, input.signal);
|
|
101
|
+
if (cancelled())
|
|
102
|
+
return "cancelled";
|
|
103
|
+
// Read the lane first: a row still queued after a pass it shows finished
|
|
104
|
+
// survived that pass, while one read before could have settled since.
|
|
105
|
+
const lane = input.lane.read();
|
|
106
|
+
intents = await readScope();
|
|
107
|
+
if (cancelled())
|
|
108
|
+
return "cancelled";
|
|
109
|
+
if (intents.length === 0)
|
|
110
|
+
return "settled";
|
|
111
|
+
// Only a pass that starts after the request answers it.
|
|
112
|
+
if (lane && lane.runCount > runCountAtRequest)
|
|
113
|
+
startedAt ??= lane.lastStartedAt;
|
|
114
|
+
const reason = stopReason({ deadline, intents, lane, startedAt });
|
|
115
|
+
if (reason)
|
|
116
|
+
return unsettled(reason);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=purgeMoveSettlement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purgeMoveSettlement.js","sourceRoot":"","sources":["purgeMoveSettlement.ts"],"names":[],"mappings":"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","sourcesContent":["import { listDocumentPlacementIntentStates } from \"../../../../data/persistence/container-contents/documentPurgePlacement\";\nimport { listDocumentsByContainerIdsOrDocumentIds } from \"../../../../data/persistence/documents/documentsPersistence\";\nimport type { ExecSql } from \"../../../../data/sqlite/sqlSchema\";\nimport type { ContainerContentsPersistence } from \"../../containerPersistence\";\nimport type { ContainerState } from \"../../remoteHydration\";\nimport type { PurgeMoveSettlement } from \"./purgeProgress\";\nimport { collectSubtreeLeafFirst } from \"./purgeTreeCollection\";\n\n/** The container-contents lane replays queued container and document moves. */\nexport interface PurgeMoveSyncLane {\n readonly read: () => {\n readonly lastStartedAt: string | null;\n readonly requested: boolean;\n readonly runCount: number;\n readonly running: boolean;\n } | null;\n readonly request: () => void;\n}\n\ninterface ScopedIntent {\n readonly lastAttemptedAt: string | null;\n readonly syncStatus: string;\n}\n\ninterface SettlePurgeScopeMovesInput {\n readonly containersById: ReadonlyMap<string, ContainerState>;\n readonly execSql: ExecSql;\n readonly lane: PurgeMoveSyncLane;\n readonly onMoveSettlement?:\n | ((settlement: PurgeMoveSettlement) => void)\n | undefined;\n readonly persistence: Pick<\n ContainerContentsPersistence,\n \"listUnsyncedMoveIntents\"\n >;\n /** Fixed messages only: the error's call site names the outcome. */\n readonly report: (message: string, error: Error) => void;\n readonly rootContainerId: string;\n readonly signal?: AbortSignal | undefined;\n readonly stillCurrent: () => boolean;\n readonly timing?: { pollMs: number; timeoutMs: number } | undefined;\n}\n\n// A pass replays pending and blocked moves. A denied placement waits for the\n// next store generation and an unavailable one never replays, so waiting on\n// either would only reach the ceiling.\nconst REPLAYED_STATUSES = new Set([\"pending\", \"blocked\"]);\nconst DEFAULT_TIMING = { pollMs: 200, timeoutMs: 30_000 };\n\nfunction delay(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(done, ms);\n function done() {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", done);\n resolve();\n }\n signal?.addEventListener(\"abort\", done, { once: true });\n });\n}\n\nfunction createScopeReader(input: SettlePurgeScopeMovesInput) {\n const containerIds = new Set(\n collectSubtreeLeafFirst(input.containersById, input.rootContainerId).map(\n (containerState) => containerState.container.id,\n ),\n );\n let documentLocalIds: Promise<Set<string>> | null = null;\n // Listing the subtree's documents is the costly read, so it runs only once\n // some document placement is queued anywhere on this device.\n const readDocumentLocalIds = () => {\n documentLocalIds ??= listDocumentsByContainerIdsOrDocumentIds(\n input.execSql,\n { containerIds: [...containerIds], documentIds: [] },\n ).then((documents) => new Set(documents.map((document) => document.id)));\n return documentLocalIds;\n };\n return async (): Promise<ScopedIntent[]> => {\n const moves = await input.persistence.listUnsyncedMoveIntents(\n input.execSql,\n );\n const placements = await listDocumentPlacementIntentStates(input.execSql);\n const scoped: ScopedIntent[] = moves.filter((move) =>\n containerIds.has(move.containerId),\n );\n if (placements.length === 0) return scoped;\n const localIds = await readDocumentLocalIds();\n return [\n ...scoped,\n ...placements.filter((placement) => localIds.has(placement.localId)),\n ];\n };\n}\n\ntype LaneRun = ReturnType<PurgeMoveSyncLane[\"read\"]>;\n\nconst isParked = (intent: ScopedIntent) =>\n !REPLAYED_STATUSES.has(intent.syncStatus);\n\n/** Why a wait that began at `startedAt` must stop, or null to keep polling. */\nfunction stopReason(input: {\n deadline: number;\n intents: readonly ScopedIntent[];\n lane: LaneRun;\n startedAt: string | null;\n}): { error: Error; message: string } | null {\n const { intents, lane, startedAt } = input;\n if (intents.some(isParked))\n return {\n error: new Error(\"Purge scope move was parked\"),\n message: \"Container contents: a move in the purge scope was parked\",\n };\n if (\n startedAt !== null &&\n intents.some(\n ({ lastAttemptedAt }) =>\n lastAttemptedAt !== null && lastAttemptedAt >= startedAt,\n )\n )\n return {\n error: new Error(\"Purge scope move failed to sync\"),\n message: \"Container contents: a move in the purge scope failed to sync\",\n };\n if (startedAt !== null && lane && !lane.running && !lane.requested)\n return {\n error: new Error(\"Purge scope move stayed queued\"),\n message: \"Container contents: a sync pass left a purge scope move queued\",\n };\n if (Date.now() >= input.deadline)\n return {\n error: new Error(\"Purge scope move wait timed out\"),\n message: \"Container contents: purge timed out waiting for a move\",\n };\n return null;\n}\n\n/**\n * The purge scope refuses a subtree whose moves the server has not accepted,\n * so ask for a pass that replays them and wait for its verdict. The scope's\n * own checks still run afterwards; this only gives the moves time to land.\n * It ends unsettled once a pass requested here has tried and left one queued.\n */\nexport async function settlePurgeScopeMoves(\n input: SettlePurgeScopeMovesInput,\n): Promise<\"cancelled\" | \"settled\" | \"unsettled\"> {\n const timing = input.timing ?? DEFAULT_TIMING;\n const cancelled = () =>\n input.signal?.aborted === true || !input.stillCurrent();\n const unsettled = (reason: { error: Error; message: string }) => {\n input.report(reason.message, reason.error);\n input.onMoveSettlement?.(\"unsettled\");\n return \"unsettled\" as const;\n };\n const readScope = createScopeReader(input);\n let intents = await readScope();\n if (cancelled()) return \"cancelled\";\n if (intents.length === 0) return \"settled\";\n if (intents.some(isParked))\n return unsettled({\n error: new Error(\"Purge scope holds a parked move\"),\n message: \"Container contents: purge scope holds a parked move\",\n });\n\n input.onMoveSettlement?.(\"waiting\");\n const runCountAtRequest = input.lane.read()?.runCount ?? 0;\n input.lane.request();\n const deadline = Date.now() + timing.timeoutMs;\n let startedAt: string | null = null;\n while (true) {\n await delay(timing.pollMs, input.signal);\n if (cancelled()) return \"cancelled\";\n // Read the lane first: a row still queued after a pass it shows finished\n // survived that pass, while one read before could have settled since.\n const lane = input.lane.read();\n intents = await readScope();\n if (cancelled()) return \"cancelled\";\n if (intents.length === 0) return \"settled\";\n // Only a pass that starts after the request answers it.\n if (lane && lane.runCount > runCountAtRequest)\n startedAt ??= lane.lastStartedAt;\n const reason = stopReason({ deadline, intents, lane, startedAt });\n if (reason) return unsettled(reason);\n }\n}\n"]}
|
|
@@ -3,7 +3,15 @@ export interface PurgeProgress {
|
|
|
3
3
|
readonly failedCount: number;
|
|
4
4
|
readonly totalCount: number;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* A purge first waits for moves this device queued inside its scope: until the
|
|
8
|
+
* server holds them, the scope cannot prove what it would destroy. "waiting"
|
|
9
|
+
* reports the wait; "unsettled" means it ended before every move reached the
|
|
10
|
+
* server, and nothing was deleted.
|
|
11
|
+
*/
|
|
12
|
+
export type PurgeMoveSettlement = "waiting" | "unsettled";
|
|
6
13
|
export interface PurgeOptions {
|
|
14
|
+
onMoveSettlement?: ((settlement: PurgeMoveSettlement) => void) | undefined;
|
|
7
15
|
onProgress?: ((progress: PurgeProgress) => void) | undefined;
|
|
8
16
|
signal?: AbortSignal | undefined;
|
|
9
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"purgeProgress.js","sourceRoot":"","sources":["purgeProgress.ts"],"names":[],"mappings":"","sourcesContent":["// Progress + cancellation contract shared by the recursive purge engine and its\n// store wrappers (\"Delete Forever\" and \"Empty Trash\"). onProgress reports\n// ABSOLUTE counts (not deltas) so a determinate progress bar can render\n// completed/total directly; a fresh object is emitted each tick so a\n// referential-equality state setter never drops an update. signal cancels at the\n// next unit boundary — between whole documents / whole containers, never\n// mid-remote-call — so a cancelled run always stops on a consistent prefix that\n// re-running can safely resume.\nexport interface PurgeProgress {\n readonly completedCount: number;\n readonly failedCount: number;\n readonly totalCount: number;\n}\n\nexport interface PurgeOptions {\n onProgress?: ((progress: PurgeProgress) => void) | undefined;\n signal?: AbortSignal | undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"purgeProgress.js","sourceRoot":"","sources":["purgeProgress.ts"],"names":[],"mappings":"","sourcesContent":["// Progress + cancellation contract shared by the recursive purge engine and its\n// store wrappers (\"Delete Forever\" and \"Empty Trash\"). onProgress reports\n// ABSOLUTE counts (not deltas) so a determinate progress bar can render\n// completed/total directly; a fresh object is emitted each tick so a\n// referential-equality state setter never drops an update. signal cancels at the\n// next unit boundary — between whole documents / whole containers, never\n// mid-remote-call — so a cancelled run always stops on a consistent prefix that\n// re-running can safely resume.\nexport interface PurgeProgress {\n readonly completedCount: number;\n readonly failedCount: number;\n readonly totalCount: number;\n}\n\n/**\n * A purge first waits for moves this device queued inside its scope: until the\n * server holds them, the scope cannot prove what it would destroy. \"waiting\"\n * reports the wait; \"unsettled\" means it ended before every move reached the\n * server, and nothing was deleted.\n */\nexport type PurgeMoveSettlement = \"waiting\" | \"unsettled\";\n\nexport interface PurgeOptions {\n onMoveSettlement?: ((settlement: PurgeMoveSettlement) => void) | undefined;\n onProgress?: ((progress: PurgeProgress) => void) | undefined;\n signal?: AbortSignal | undefined;\n}\n"]}
|
|
@@ -116,6 +116,7 @@ export async function moveRemoteContainer(input) {
|
|
|
116
116
|
containerId: input.containerId,
|
|
117
117
|
destinationParentContainerId: input.parentContainerId,
|
|
118
118
|
execSql,
|
|
119
|
+
onStaleAcceptance: input.onStaleAcceptance,
|
|
119
120
|
resolveProjectionUserKey: input.resolveProjectionUserKey,
|
|
120
121
|
stillCurrent: input.stillCurrent,
|
|
121
122
|
targetSecretKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.js","sourceRoot":"","sources":["remote.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport {\n moveRemoteContainer as moveRemoteContainerMutation,\n readContainerMutationMetadataDocumentId,\n referencedPrincipalHeadsFromContainerMutationResponse,\n shareRemoteContainer as shareRemoteContainerMutation,\n} from \"../../containers\";\nimport { createRuntimeCurrentGroupShare } from \"../../containers/child/share/runtimeCurrentGroupShare\";\nimport { resolveDocumentCreateAuthor } from \"../../documents\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadata/groupMetadataRuntime\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n type ContainerAlreadyCommitted,\n createRemoteContainerWithMetadataDocument,\n} from \"./create/createWithMetadata\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n RemoteContainer,\n SharedRemoteContainerState,\n} from \"./types\";\n\n/**\n * Resolve the author, api client, executor, and encapsulation secret a remote\n * container mutation needs, logging a skip for the given operation when the\n * writer context is unavailable.\n */\nfunction resolveContainerWriterContext(\n runtime: ContainerWorkflowRuntime,\n operation:\n | \"container create\"\n | \"container group share\"\n | \"container move\"\n | \"container share\",\n) {\n const author = resolveDocumentCreateAuthor(runtime);\n const secretKey = runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !secretKey) {\n runtime.util.log(\n `Container contents: skipped ${operation} because the writer context is unavailable.`,\n );\n return null;\n }\n\n return {\n apiClient: runtime.apiClient,\n author,\n execSql: runtime.infra.execSql,\n secretKey,\n };\n}\n\nexport async function createRemoteContainer(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n return createRemoteContainerWithMetadataDocument(input);\n}\n\nfunction sharedRemoteContainerStateFromMutation(\n previousProjection: ContainerWriterProjectionResponse,\n response: ContainerMutationResponse,\n): SharedRemoteContainerState {\n if (\n response.containerId !== previousProjection.containerId ||\n response.organizationId !== previousProjection.organizationId\n )\n throw new Error(\"Container mutation response projection mismatch\");\n return {\n accessManifestHash: response.manifestHead.manifestHash,\n accessEpoch: response.manifestHead.epoch,\n createdAt: response.createdAt,\n metadataDocumentId: readContainerMutationMetadataDocumentId({ response }),\n referencedPrincipalHeads:\n referencedPrincipalHeadsFromContainerMutationResponse({ response }),\n updatedAt: response.updatedAt,\n // The next read obtains the post-commit proof. A failed read cannot undo\n // acknowledgement of this successful mutation.\n writerProjection: null,\n };\n}\n\nexport async function shareRemoteContainer(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n previousProjection: ContainerWriterProjectionResponse;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shared = await shareRemoteContainerMutation({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n previousProjection: input.previousProjection,\n recipientUserId: input.recipientUserId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\nexport async function shareRemoteContainerWithGroup(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n expectedGroupName?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection: ContainerWriterProjectionResponse;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container group share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shareWithGroup = createRuntimeCurrentGroupShare(input.runtime);\n if (!shareWithGroup)\n throw new ProjectionDependencyUnavailableError(\n \"Group sharing requires private paged recovery\",\n );\n const shared = await shareWithGroup({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n expectedGroupName: input.expectedGroupName ?? null,\n readEncryptedName: (bundle) =>\n createRuntimeGroupMetadataAccess(\n input.runtime,\n author.organizationId,\n input.stillCurrent,\n ).readName(bundle),\n knownContainerKeks: input.knownContainerKeks,\n previousProjection: input.previousProjection,\n recipientGroupId: input.recipientGroupId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n signingKeyPair: input.runtime.crypto.signingKeyPair,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\nexport async function moveRemoteContainer(input: {\n containerId: string;\n parentContainerId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<RemoteContainer | null> {\n const writer = resolveContainerWriterContext(input.runtime, \"container move\");\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const moved = await moveRemoteContainerMutation({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n apiClient,\n author,\n containerId: input.containerId,\n destinationParentContainerId: input.parentContainerId,\n execSql,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!moved) {\n return null;\n }\n\n return {\n createdAt: moved.response.createdAt,\n effectiveAccessLevel: \"admin\",\n id: moved.response.containerId,\n organizationId: moved.response.organizationId,\n parentId: moved.response.parentId,\n metadataDocumentId: readContainerMutationMetadataDocumentId({\n response: moved.response,\n }),\n metadataAccessEpoch: moved.response.manifestHead.epoch,\n metadataAccessStateHash: moved.response.manifestHead.manifestHash,\n metadataReferencedPrincipals:\n referencedPrincipalHeadsFromContainerMutationResponse({\n response: moved.response,\n }),\n updatedAt: moved.response.updatedAt,\n };\n}\n\nexport async function deleteRemoteContainer(input: {\n containerId: string;\n organizationId: string;\n requiredAncestorId?: string | undefined;\n runtime: ContainerWorkflowRuntime;\n}): Promise<{ deletedAt: string } | null> {\n const deleteResult = await input.runtime.apiClient.deleteContainerResult(\n input.containerId,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n requiredAncestorId: input.requiredAncestorId,\n },\n );\n if (!deleteResult.ok && !isContainerNotFoundFailure(deleteResult)) {\n deleteResult.report();\n return null;\n }\n\n if (!deleteResult.ok) {\n // A 404 proves this immutable id is permanently absent, but it does not\n // carry the server deletion time. A maximal fence prevents an older\n // in-flight listing page from resurrecting it.\n return { deletedAt: \"9999-12-31T23:59:59.999Z\" };\n }\n\n return { deletedAt: deleteResult.data.deletedAt };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["remote.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport {\n moveRemoteContainer as moveRemoteContainerMutation,\n readContainerMutationMetadataDocumentId,\n referencedPrincipalHeadsFromContainerMutationResponse,\n shareRemoteContainer as shareRemoteContainerMutation,\n} from \"../../containers\";\nimport { createRuntimeCurrentGroupShare } from \"../../containers/child/share/runtimeCurrentGroupShare\";\nimport { resolveDocumentCreateAuthor } from \"../../documents\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadata/groupMetadataRuntime\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n type ContainerAlreadyCommitted,\n createRemoteContainerWithMetadataDocument,\n} from \"./create/createWithMetadata\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n RemoteContainer,\n SharedRemoteContainerState,\n} from \"./types\";\n\n/**\n * Resolve the author, api client, executor, and encapsulation secret a remote\n * container mutation needs, logging a skip for the given operation when the\n * writer context is unavailable.\n */\nfunction resolveContainerWriterContext(\n runtime: ContainerWorkflowRuntime,\n operation:\n | \"container create\"\n | \"container group share\"\n | \"container move\"\n | \"container share\",\n) {\n const author = resolveDocumentCreateAuthor(runtime);\n const secretKey = runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !secretKey) {\n runtime.util.log(\n `Container contents: skipped ${operation} because the writer context is unavailable.`,\n );\n return null;\n }\n\n return {\n apiClient: runtime.apiClient,\n author,\n execSql: runtime.infra.execSql,\n secretKey,\n };\n}\n\nexport async function createRemoteContainer(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n return createRemoteContainerWithMetadataDocument(input);\n}\n\nfunction sharedRemoteContainerStateFromMutation(\n previousProjection: ContainerWriterProjectionResponse,\n response: ContainerMutationResponse,\n): SharedRemoteContainerState {\n if (\n response.containerId !== previousProjection.containerId ||\n response.organizationId !== previousProjection.organizationId\n )\n throw new Error(\"Container mutation response projection mismatch\");\n return {\n accessManifestHash: response.manifestHead.manifestHash,\n accessEpoch: response.manifestHead.epoch,\n createdAt: response.createdAt,\n metadataDocumentId: readContainerMutationMetadataDocumentId({ response }),\n referencedPrincipalHeads:\n referencedPrincipalHeadsFromContainerMutationResponse({ response }),\n updatedAt: response.updatedAt,\n // The next read obtains the post-commit proof. A failed read cannot undo\n // acknowledgement of this successful mutation.\n writerProjection: null,\n };\n}\n\nexport async function shareRemoteContainer(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n previousProjection: ContainerWriterProjectionResponse;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shared = await shareRemoteContainerMutation({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n previousProjection: input.previousProjection,\n recipientUserId: input.recipientUserId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\nexport async function shareRemoteContainerWithGroup(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n expectedGroupName?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection: ContainerWriterProjectionResponse;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container group share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shareWithGroup = createRuntimeCurrentGroupShare(input.runtime);\n if (!shareWithGroup)\n throw new ProjectionDependencyUnavailableError(\n \"Group sharing requires private paged recovery\",\n );\n const shared = await shareWithGroup({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n expectedGroupName: input.expectedGroupName ?? null,\n readEncryptedName: (bundle) =>\n createRuntimeGroupMetadataAccess(\n input.runtime,\n author.organizationId,\n input.stillCurrent,\n ).readName(bundle),\n knownContainerKeks: input.knownContainerKeks,\n previousProjection: input.previousProjection,\n recipientGroupId: input.recipientGroupId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n signingKeyPair: input.runtime.crypto.signingKeyPair,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\nexport async function moveRemoteContainer(input: {\n containerId: string;\n onStaleAcceptance?: (() => void) | undefined;\n parentContainerId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<RemoteContainer | null> {\n const writer = resolveContainerWriterContext(input.runtime, \"container move\");\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const moved = await moveRemoteContainerMutation({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n apiClient,\n author,\n containerId: input.containerId,\n destinationParentContainerId: input.parentContainerId,\n execSql,\n onStaleAcceptance: input.onStaleAcceptance,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!moved) {\n return null;\n }\n\n return {\n createdAt: moved.response.createdAt,\n effectiveAccessLevel: \"admin\",\n id: moved.response.containerId,\n organizationId: moved.response.organizationId,\n parentId: moved.response.parentId,\n metadataDocumentId: readContainerMutationMetadataDocumentId({\n response: moved.response,\n }),\n metadataAccessEpoch: moved.response.manifestHead.epoch,\n metadataAccessStateHash: moved.response.manifestHead.manifestHash,\n metadataReferencedPrincipals:\n referencedPrincipalHeadsFromContainerMutationResponse({\n response: moved.response,\n }),\n updatedAt: moved.response.updatedAt,\n };\n}\n\nexport async function deleteRemoteContainer(input: {\n containerId: string;\n organizationId: string;\n requiredAncestorId?: string | undefined;\n runtime: ContainerWorkflowRuntime;\n}): Promise<{ deletedAt: string } | null> {\n const deleteResult = await input.runtime.apiClient.deleteContainerResult(\n input.containerId,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n requiredAncestorId: input.requiredAncestorId,\n },\n );\n if (!deleteResult.ok && !isContainerNotFoundFailure(deleteResult)) {\n deleteResult.report();\n return null;\n }\n\n if (!deleteResult.ok) {\n // A 404 proves this immutable id is permanently absent, but it does not\n // carry the server deletion time. A maximal fence prevents an older\n // in-flight listing page from resurrecting it.\n return { deletedAt: \"9999-12-31T23:59:59.999Z\" };\n }\n\n return { deletedAt: deleteResult.data.deletedAt };\n}\n"]}
|
|
@@ -10,3 +10,5 @@ export declare function registerContainerContentsSyncLane(input: {
|
|
|
10
10
|
readonly logError?: ((message: string, error: unknown) => void) | undefined;
|
|
11
11
|
readonly run: () => Promise<void>;
|
|
12
12
|
}): ContainerContentsSyncLane;
|
|
13
|
+
/** The lane's run counters, for work that waits on a pass it requested. */
|
|
14
|
+
export declare function readContainerContentsSyncLane(domainScope: DomainScope): import("../sync/index.js").SyncLaneSnapshot | null;
|
|
@@ -17,4 +17,11 @@ export function registerContainerContentsSyncLane(input) {
|
|
|
17
17
|
shouldIgnoreError: isDatabaseUnavailableError,
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
+
/** The lane's run counters, for work that waits on a pass it requested. */
|
|
21
|
+
export function readContainerContentsSyncLane(domainScope) {
|
|
22
|
+
return (getOrCreateDomainSyncCoordinator(domainScope)
|
|
23
|
+
.getSnapshot()
|
|
24
|
+
.lanes.find((lane) => lane.key === CONTAINER_CONTENTS_SYNC_LANE_KEY) ??
|
|
25
|
+
null);
|
|
26
|
+
}
|
|
20
27
|
//# sourceMappingURL=syncLane.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncLane.js","sourceRoot":"","sources":["syncLane.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAE3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,4EAA4E;AAC5E,+EAA+E;AAC/E,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,iCAAiC,CAAC;AAGzC,MAAM,CAAC,MAAM,gCAAgC,GAAG,oBAAoB,CAAC;AAErE,MAAM,UAAU,iCAAiC,CAAC,KAKjD;IACC,OAAO,gCAAgC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,YAAY,CACrE,gCAAgC,EAChC;QACE,KAAK,EAAE,oBAAoB;QAC3B,KAAK,EAAE,YAAY;QACnB,qEAAqE;QACrE,sEAAsE;QACtE,yEAAyE;QACzE,mDAAmD;QACnD,qBAAqB,EAAE,CAAC,KAAK,EAAE,EAAE,CAC/B,KAAK,CAAC,QAAQ,EAAE,CAAC,sCAAsC,EAAE,KAAK,CAAC;QACjE,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,iBAAiB,EAAE,0BAA0B;KAC9C,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport {\n getOrCreateDomainSyncCoordinator,\n isDatabaseUnavailableError,\n type SyncLane,\n} from \"../../data/sync/syncCoordinator\";\n\nexport { sequenceUnchanged } from \"../../data/sync/sequence\";\n// Facade re-exports: container-contents stores must reach these shared sync\n// helpers through this workflow boundary, not by importing data/sync directly.\nexport {\n didRegainSyncPrerequisites,\n isDatabaseUnavailableError,\n} from \"../../data/sync/syncCoordinator\";\n\nexport type ContainerContentsSyncLane = SyncLane;\nexport const CONTAINER_CONTENTS_SYNC_LANE_KEY = \"container-contents\";\n\nexport function registerContainerContentsSyncLane(input: {\n readonly domainScope: DomainScope;\n /** Host diagnostics sink; bare runtimes do not structure errors. */\n readonly logError?: ((message: string, error: unknown) => void) | undefined;\n readonly run: () => Promise<void>;\n}): ContainerContentsSyncLane {\n return getOrCreateDomainSyncCoordinator(input.domainScope).registerLane(\n CONTAINER_CONTENTS_SYNC_LANE_KEY,\n {\n label: \"Container contents\",\n phase: \"structural\",\n // Fixed literal: no container or identity id may reach a report. The\n // mapped stack identifies which lane body threw. Returning the host's\n // result hands a rejection to the lane reporter's wrapper; discarding it\n // would surface as an unhandled rejection instead.\n reportUnexpectedError: (error) =>\n input.logError?.(\"Container contents: sync lane failed\", error),\n run: input.run,\n shouldIgnoreError: isDatabaseUnavailableError,\n },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"syncLane.js","sourceRoot":"","sources":["syncLane.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAE3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,4EAA4E;AAC5E,+EAA+E;AAC/E,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,iCAAiC,CAAC;AAGzC,MAAM,CAAC,MAAM,gCAAgC,GAAG,oBAAoB,CAAC;AAErE,MAAM,UAAU,iCAAiC,CAAC,KAKjD;IACC,OAAO,gCAAgC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,YAAY,CACrE,gCAAgC,EAChC;QACE,KAAK,EAAE,oBAAoB;QAC3B,KAAK,EAAE,YAAY;QACnB,qEAAqE;QACrE,sEAAsE;QACtE,yEAAyE;QACzE,mDAAmD;QACnD,qBAAqB,EAAE,CAAC,KAAK,EAAE,EAAE,CAC/B,KAAK,CAAC,QAAQ,EAAE,CAAC,sCAAsC,EAAE,KAAK,CAAC;QACjE,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,iBAAiB,EAAE,0BAA0B;KAC9C,CACF,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,6BAA6B,CAAC,WAAwB;IACpE,OAAO,CACL,gCAAgC,CAAC,WAAW,CAAC;SAC1C,WAAW,EAAE;SACb,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,gCAAgC,CAAC;QACtE,IAAI,CACL,CAAC;AACJ,CAAC","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport {\n getOrCreateDomainSyncCoordinator,\n isDatabaseUnavailableError,\n type SyncLane,\n} from \"../../data/sync/syncCoordinator\";\n\nexport { sequenceUnchanged } from \"../../data/sync/sequence\";\n// Facade re-exports: container-contents stores must reach these shared sync\n// helpers through this workflow boundary, not by importing data/sync directly.\nexport {\n didRegainSyncPrerequisites,\n isDatabaseUnavailableError,\n} from \"../../data/sync/syncCoordinator\";\n\nexport type ContainerContentsSyncLane = SyncLane;\nexport const CONTAINER_CONTENTS_SYNC_LANE_KEY = \"container-contents\";\n\nexport function registerContainerContentsSyncLane(input: {\n readonly domainScope: DomainScope;\n /** Host diagnostics sink; bare runtimes do not structure errors. */\n readonly logError?: ((message: string, error: unknown) => void) | undefined;\n readonly run: () => Promise<void>;\n}): ContainerContentsSyncLane {\n return getOrCreateDomainSyncCoordinator(input.domainScope).registerLane(\n CONTAINER_CONTENTS_SYNC_LANE_KEY,\n {\n label: \"Container contents\",\n phase: \"structural\",\n // Fixed literal: no container or identity id may reach a report. The\n // mapped stack identifies which lane body threw. Returning the host's\n // result hands a rejection to the lane reporter's wrapper; discarding it\n // would surface as an unhandled rejection instead.\n reportUnexpectedError: (error) =>\n input.logError?.(\"Container contents: sync lane failed\", error),\n run: input.run,\n shouldIgnoreError: isDatabaseUnavailableError,\n },\n );\n}\n\n/** The lane's run counters, for work that waits on a pass it requested. */\nexport function readContainerContentsSyncLane(domainScope: DomainScope) {\n return (\n getOrCreateDomainSyncCoordinator(domainScope)\n .getSnapshot()\n .lanes.find((lane) => lane.key === CONTAINER_CONTENTS_SYNC_LANE_KEY) ??\n null\n );\n}\n"]}
|
|
@@ -11,6 +11,7 @@ export declare function moveRemoteContainer(input: {
|
|
|
11
11
|
destinationParentContainerId: string;
|
|
12
12
|
eventId?: string | undefined;
|
|
13
13
|
execSql: ExecSql;
|
|
14
|
+
onStaleAcceptance?: (() => void) | undefined;
|
|
14
15
|
resolveProjectionUserKey: ProjectionUserKeyResolver;
|
|
15
16
|
signedAt?: string | undefined;
|
|
16
17
|
stillCurrent?: (() => boolean) | undefined;
|
|
@@ -246,6 +246,7 @@ export async function moveRemoteContainer(input) {
|
|
|
246
246
|
},
|
|
247
247
|
containerKey: materializedPlan.containerKey,
|
|
248
248
|
execSql: input.execSql,
|
|
249
|
+
onStaleAcceptance: input.onStaleAcceptance,
|
|
249
250
|
plan: materializedPlan.plan,
|
|
250
251
|
stillCurrent: input.stillCurrent,
|
|
251
252
|
submit: (carried) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccessEvent,\n AccessManifest,\n ContainerAccessManifestState,\n ContainerKekKeyring,\n ContainerKekPredecessorBridge,\n ContainerKeyEpoch,\n ContainerKeyWrap,\n ContainerMoveAccessEventBody,\n ContainerUserRecipientKey,\n VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWire,\n ContainerMutationRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n ContainerKekResponse,\n ContainerRotationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertContainerAuthorAccess } from \"../../../../data/containers/shared/authorAccess\";\nimport { assertContainerChildPathFits } from \"../../../../data/containers/shared/containerPathLimits\";\nimport {\n asContainerManifestBundle,\n containerManifestRef,\n getTargetContainerContext,\n readContainerState,\n uniqueSortedManifestHashes,\n} from \"../../../../data/containers/shared/projection\";\nimport type {\n BuildMaterializedContainerMovePlanInput,\n ContainerMoveApi,\n ContainerMovePlan,\n ContainerMutationAuthor,\n MaterializedContainerMovePlan,\n} from \"../../../../data/containers/shared/types\";\nimport { unwrapContainerKekPath } from \"../../../../data/documents/shared/projection\";\nimport { projectionVerificationOptions } from \"../../../../data/documents/shared/types\";\nimport { readCanonicalRecord } from \"../../../../data/keying/canonicalJson\";\nimport {\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../../../data/keyingProjectionVerification\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../../data/sqlite/sqlSchema\";\nimport {\n containerMutationRequestCore,\n previousPathRequestFields,\n} from \"../mutationRequestCore\";\nimport {\n submitAcknowledgedContainerMutation,\n submitContainerRotation,\n} from \"../mutationSubmit\";\nimport { containerWriterProjectionFromRotationPlan } from \"../rekey/rekeyProjection\";\nimport {\n requireUnwrappedKek,\n type SignedRotationTarget,\n signedRotationTarget,\n} from \"../rotation/rotationContext\";\nimport {\n buildMoveRotationWithBody,\n deriveMoveManifestArtifacts,\n} from \"./moveArtifacts\";\nimport {\n buildContainerMoveWraps,\n collectContainerMovePrincipalPolicies,\n} from \"./moveWraps\";\n\nfunction buildContainerMoveRequest(input: {\n body: ContainerMoveAccessEventBody;\n destinationParentKek: ContainerKekResponse;\n destinationParentProjection: ContainerWriterProjectionResponse;\n event: AccessEvent;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n previousProjection: ContainerWriterProjectionResponse;\n predecessorBridge: ContainerKekPredecessorBridge;\n principalPolicies: readonly PrincipalPolicyCurrentEvidence[];\n userRecipientKeys: readonly ContainerUserRecipientKey[];\n wraps: readonly ContainerKeyWrap[];\n}): ContainerMutationRequest {\n return {\n ...containerMutationRequestCore(\"move\", input),\n ...previousPathRequestFields(\n input.previousManifest,\n input.previousProjection,\n ),\n destinationParentContainerPathRefs:\n input.destinationParentProjection.path.map(containerManifestRef),\n predecessorBridge: readCanonicalRecord(\n input.predecessorBridge,\n \"Container move predecessor bridge\",\n ),\n keyring: readCanonicalRecord(input.keyring, \"Container move keyring\"),\n parentKekState: readCanonicalRecord(\n input.destinationParentKek,\n \"Container move destination parent KEK state\",\n ),\n };\n}\n\nasync function unwrapMoveContainerKeys(input: {\n destinationParentProjection: ContainerWriterProjectionResponse;\n execSql: ExecSql;\n previousProjection: ContainerWriterProjectionResponse;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n destinationParent: ReturnType<typeof getTargetContainerContext>;\n source: SignedRotationTarget;\n}> {\n const verifiedByHash = new Map<string, VerifiedContainerAccessManifest>();\n const keksByEpochId = await unwrapContainerKekPath({\n execSql: input.execSql,\n projection: input.previousProjection,\n secretKey: input.targetSecretKey,\n verifiedByHash,\n ...projectionVerificationOptions(input),\n });\n const source = signedRotationTarget(input.previousProjection, verifiedByHash);\n const containerKey = requireUnwrappedKek(\n keksByEpochId,\n source.kek,\n \"Container move source\",\n );\n\n const destinationKeksByEpochId = await unwrapContainerKekPath({\n execSql: input.execSql,\n projection: input.destinationParentProjection,\n secretKey: input.targetSecretKey,\n ...projectionVerificationOptions(input),\n });\n const destinationParent = getTargetContainerContext(\n input.destinationParentProjection,\n );\n requireUnwrappedKek(\n destinationKeksByEpochId,\n destinationParent.kek,\n \"Container move destination parent\",\n );\n\n return { containerKey, destinationParent, source };\n}\n\nfunction assertContainerMoveOrganizations(input: {\n authorOrganizationId: string;\n destinationState: ContainerAccessManifestState;\n previousState: ContainerAccessManifestState;\n}): void {\n if (input.previousState.organizationId !== input.authorOrganizationId) {\n throw new Error(\"Container move author organization mismatch\");\n }\n if (input.destinationState.organizationId !== input.authorOrganizationId) {\n throw new Error(\"Container move destination organization mismatch\");\n }\n}\n\nfunction readContainerMoveStates(input: {\n authorOrganizationId: string;\n destinationParent: ReturnType<typeof getTargetContainerContext>;\n source: ReturnType<typeof getTargetContainerContext>;\n}) {\n const previousState = readContainerState(input.source.manifest);\n const destinationState = readContainerState(input.destinationParent.manifest);\n assertContainerMoveOrganizations({\n authorOrganizationId: input.authorOrganizationId,\n destinationState,\n previousState,\n });\n return { destinationState, previousState };\n}\n\nfunction containerMoveDependencyManifestHashes(input: {\n destinationParentProjection: ContainerWriterProjectionResponse;\n previousProjection: ContainerWriterProjectionResponse;\n}): string[] {\n return [\n ...uniqueSortedManifestHashes(input.previousProjection.path),\n ...uniqueSortedManifestHashes(input.destinationParentProjection.path),\n ];\n}\n\nfunction buildContainerMovePlanResult(input: {\n body: ContainerMoveAccessEventBody;\n containerId: string;\n containerKey: Uint8Array;\n containerKeyEpochId: string;\n destinationParentKek: ContainerKekResponse;\n destinationParentProjection: ContainerWriterProjectionResponse;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n previousProjection: ContainerWriterProjectionResponse;\n predecessorBridge: ContainerKekPredecessorBridge;\n principalPolicies: readonly PrincipalPolicyCurrentEvidence[];\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}): MaterializedContainerMovePlan {\n const plan: ContainerMovePlan = {\n body: input.body,\n containerId: input.containerId,\n containerKeyEpochId: input.containerKeyEpochId,\n event: input.event,\n eventHash: input.eventHash,\n keyEpoch: input.keyEpoch,\n keyring: input.keyring,\n manifest: input.manifest,\n manifestHash: input.manifestHash,\n previousManifest: input.previousManifest,\n request: buildContainerMoveRequest({\n body: input.body,\n destinationParentKek: input.destinationParentKek,\n destinationParentProjection: input.destinationParentProjection,\n event: input.event,\n keyEpoch: input.keyEpoch,\n keyring: input.keyring,\n manifest: input.manifest,\n manifestHash: input.manifestHash,\n previousManifest: input.previousManifest,\n previousProjection: input.previousProjection,\n predecessorBridge: input.predecessorBridge,\n principalPolicies: input.principalPolicies,\n userRecipientKeys: input.userRecipientKeys,\n wraps: input.wraps,\n }),\n state: input.state,\n wraps: input.wraps,\n };\n\n return { containerKey: input.containerKey, plan };\n}\n\ntype MaterializedContainerMoveInput =\n BuildMaterializedContainerMovePlanInput & {\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n stillCurrent?: (() => boolean) | undefined;\n warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n };\n\nasync function collectAuthorizedMovePolicies(\n input: MaterializedContainerMoveInput,\n) {\n const principalPolicies = await collectContainerMovePrincipalPolicies({\n ...input,\n resolveUserKey: input.resolveProjectionUserKey,\n });\n assertContainerAuthorAccess({\n author: input.author,\n projection: input.previousProjection,\n principalPolicies,\n minimumAccess: \"admin\",\n });\n assertContainerAuthorAccess({\n author: input.author,\n projection: input.destinationParentProjection,\n principalPolicies,\n minimumAccess: \"write\",\n });\n return principalPolicies;\n}\n\nasync function buildMaterializedContainerMovePlan(\n input: MaterializedContainerMoveInput,\n): Promise<MaterializedContainerMovePlan> {\n const {\n containerKey: predecessorContainerKey,\n destinationParent,\n source,\n } = await unwrapMoveContainerKeys({\n destinationParentProjection: input.destinationParentProjection,\n execSql: input.execSql,\n previousProjection: input.previousProjection,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // Only a verified path is a final depth refusal; a padded unverified path\n // must fail verification (an incident), never look like an honest refusal.\n assertContainerChildPathFits(input.destinationParentProjection.path);\n const { destinationState, previousState } = readContainerMoveStates({\n authorOrganizationId: input.author.organizationId,\n destinationParent,\n source,\n });\n const principalPolicies = await collectAuthorizedMovePolicies(input);\n const {\n body,\n containerKey,\n containerKeyEpochId,\n keyring,\n predecessorBridge,\n } = await buildMoveRotationWithBody({\n destinationParent,\n destinationState,\n override: input.containerKeyEpochId,\n predecessorContainerKey,\n previousState,\n source,\n });\n const { event, eventHash, keyEpoch, manifest, manifestHash, state } =\n await deriveMoveManifestArtifacts({\n body,\n containerKeyEpochId,\n destinationParent,\n previousState,\n signing: {\n author: input.author,\n dependencyManifestHashes: containerMoveDependencyManifestHashes(input),\n eventId: input.eventId,\n signedAt: input.signedAt,\n },\n source,\n });\n const { userRecipientKeys, wraps } = await buildContainerMoveWraps({\n principalPolicies,\n containerKey,\n containerKeyEpochId,\n destinationParentKek: destinationParent.kek,\n destinationParentProjection: input.destinationParentProjection,\n execSql: input.execSql,\n manifestHash,\n previousProjection: input.previousProjection,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n state,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n\n return buildContainerMovePlanResult({\n body,\n containerKey,\n containerId: previousState.containerId,\n containerKeyEpochId,\n destinationParentKek: destinationParent.kek,\n destinationParentProjection: input.destinationParentProjection,\n event,\n eventHash,\n keyEpoch,\n keyring,\n manifest,\n manifestHash,\n previousManifest: asContainerManifestBundle(source.manifest),\n previousProjection: input.previousProjection,\n predecessorBridge,\n principalPolicies,\n state,\n userRecipientKeys,\n wraps,\n });\n}\n\nexport async function moveRemoteContainer(input: {\n reportSecurityIncident: SecurityIncidentReporter;\n apiClient: ContainerMoveApi;\n author: ContainerMutationAuthor;\n containerId: string;\n destinationParentContainerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n plan: ContainerMovePlan;\n response: ContainerRotationResponse;\n} | null> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container move\",\n );\n const [previousProjection, destinationParentProjection] = await Promise.all([\n input.apiClient.getContainerWriterProjection(input.containerId),\n input.apiClient.getContainerWriterProjection(\n input.destinationParentContainerId,\n ),\n ]);\n if (!previousProjection || !destinationParentProjection) {\n return null;\n }\n\n const materializedPlan = await nullOnProjectionVerificationCancellation(() =>\n buildMaterializedContainerMovePlan({\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n previousProjection,\n destinationParentProjection,\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n );\n if (!materializedPlan) return null;\n return submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: [],\n apiClient: input.apiClient,\n author: input.author,\n carriedRekeys: {\n planning: {\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n knownContainerKeks: new Map([\n [\n materializedPlan.plan.containerKeyEpochId,\n materializedPlan.containerKey,\n ],\n ]),\n resolveProjectionUserKey: resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n },\n rotated: () =>\n containerWriterProjectionFromRotationPlan({\n ancestors: destinationParentProjection,\n plan: materializedPlan.plan,\n previousProjection,\n }),\n },\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: (carried) => {\n const request = carried.length\n ? { ...materializedPlan.plan.request, containerRekeys: [...carried] }\n : materializedPlan.plan.request;\n const options = {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n };\n const { moveContainerResult } = input.apiClient;\n return submitContainerRotation({\n plain: () =>\n input.apiClient.moveContainer(input.containerId, request, options),\n result: moveContainerResult\n ? () =>\n moveContainerResult.call(\n input.apiClient,\n input.containerId,\n request,\n { ...options, reportErrors: false },\n )\n : undefined,\n });\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccessEvent,\n AccessManifest,\n ContainerAccessManifestState,\n ContainerKekKeyring,\n ContainerKekPredecessorBridge,\n ContainerKeyEpoch,\n ContainerKeyWrap,\n ContainerMoveAccessEventBody,\n ContainerUserRecipientKey,\n VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWire,\n ContainerMutationRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n ContainerKekResponse,\n ContainerRotationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertContainerAuthorAccess } from \"../../../../data/containers/shared/authorAccess\";\nimport { assertContainerChildPathFits } from \"../../../../data/containers/shared/containerPathLimits\";\nimport {\n asContainerManifestBundle,\n containerManifestRef,\n getTargetContainerContext,\n readContainerState,\n uniqueSortedManifestHashes,\n} from \"../../../../data/containers/shared/projection\";\nimport type {\n BuildMaterializedContainerMovePlanInput,\n ContainerMoveApi,\n ContainerMovePlan,\n ContainerMutationAuthor,\n MaterializedContainerMovePlan,\n} from \"../../../../data/containers/shared/types\";\nimport { unwrapContainerKekPath } from \"../../../../data/documents/shared/projection\";\nimport { projectionVerificationOptions } from \"../../../../data/documents/shared/types\";\nimport { readCanonicalRecord } from \"../../../../data/keying/canonicalJson\";\nimport {\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../../../data/keyingProjectionVerification\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../../data/sqlite/sqlSchema\";\nimport {\n containerMutationRequestCore,\n previousPathRequestFields,\n} from \"../mutationRequestCore\";\nimport {\n submitAcknowledgedContainerMutation,\n submitContainerRotation,\n} from \"../mutationSubmit\";\nimport { containerWriterProjectionFromRotationPlan } from \"../rekey/rekeyProjection\";\nimport {\n requireUnwrappedKek,\n type SignedRotationTarget,\n signedRotationTarget,\n} from \"../rotation/rotationContext\";\nimport {\n buildMoveRotationWithBody,\n deriveMoveManifestArtifacts,\n} from \"./moveArtifacts\";\nimport {\n buildContainerMoveWraps,\n collectContainerMovePrincipalPolicies,\n} from \"./moveWraps\";\n\nfunction buildContainerMoveRequest(input: {\n body: ContainerMoveAccessEventBody;\n destinationParentKek: ContainerKekResponse;\n destinationParentProjection: ContainerWriterProjectionResponse;\n event: AccessEvent;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n previousProjection: ContainerWriterProjectionResponse;\n predecessorBridge: ContainerKekPredecessorBridge;\n principalPolicies: readonly PrincipalPolicyCurrentEvidence[];\n userRecipientKeys: readonly ContainerUserRecipientKey[];\n wraps: readonly ContainerKeyWrap[];\n}): ContainerMutationRequest {\n return {\n ...containerMutationRequestCore(\"move\", input),\n ...previousPathRequestFields(\n input.previousManifest,\n input.previousProjection,\n ),\n destinationParentContainerPathRefs:\n input.destinationParentProjection.path.map(containerManifestRef),\n predecessorBridge: readCanonicalRecord(\n input.predecessorBridge,\n \"Container move predecessor bridge\",\n ),\n keyring: readCanonicalRecord(input.keyring, \"Container move keyring\"),\n parentKekState: readCanonicalRecord(\n input.destinationParentKek,\n \"Container move destination parent KEK state\",\n ),\n };\n}\n\nasync function unwrapMoveContainerKeys(input: {\n destinationParentProjection: ContainerWriterProjectionResponse;\n execSql: ExecSql;\n previousProjection: ContainerWriterProjectionResponse;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n destinationParent: ReturnType<typeof getTargetContainerContext>;\n source: SignedRotationTarget;\n}> {\n const verifiedByHash = new Map<string, VerifiedContainerAccessManifest>();\n const keksByEpochId = await unwrapContainerKekPath({\n execSql: input.execSql,\n projection: input.previousProjection,\n secretKey: input.targetSecretKey,\n verifiedByHash,\n ...projectionVerificationOptions(input),\n });\n const source = signedRotationTarget(input.previousProjection, verifiedByHash);\n const containerKey = requireUnwrappedKek(\n keksByEpochId,\n source.kek,\n \"Container move source\",\n );\n\n const destinationKeksByEpochId = await unwrapContainerKekPath({\n execSql: input.execSql,\n projection: input.destinationParentProjection,\n secretKey: input.targetSecretKey,\n ...projectionVerificationOptions(input),\n });\n const destinationParent = getTargetContainerContext(\n input.destinationParentProjection,\n );\n requireUnwrappedKek(\n destinationKeksByEpochId,\n destinationParent.kek,\n \"Container move destination parent\",\n );\n\n return { containerKey, destinationParent, source };\n}\n\nfunction assertContainerMoveOrganizations(input: {\n authorOrganizationId: string;\n destinationState: ContainerAccessManifestState;\n previousState: ContainerAccessManifestState;\n}): void {\n if (input.previousState.organizationId !== input.authorOrganizationId) {\n throw new Error(\"Container move author organization mismatch\");\n }\n if (input.destinationState.organizationId !== input.authorOrganizationId) {\n throw new Error(\"Container move destination organization mismatch\");\n }\n}\n\nfunction readContainerMoveStates(input: {\n authorOrganizationId: string;\n destinationParent: ReturnType<typeof getTargetContainerContext>;\n source: ReturnType<typeof getTargetContainerContext>;\n}) {\n const previousState = readContainerState(input.source.manifest);\n const destinationState = readContainerState(input.destinationParent.manifest);\n assertContainerMoveOrganizations({\n authorOrganizationId: input.authorOrganizationId,\n destinationState,\n previousState,\n });\n return { destinationState, previousState };\n}\n\nfunction containerMoveDependencyManifestHashes(input: {\n destinationParentProjection: ContainerWriterProjectionResponse;\n previousProjection: ContainerWriterProjectionResponse;\n}): string[] {\n return [\n ...uniqueSortedManifestHashes(input.previousProjection.path),\n ...uniqueSortedManifestHashes(input.destinationParentProjection.path),\n ];\n}\n\nfunction buildContainerMovePlanResult(input: {\n body: ContainerMoveAccessEventBody;\n containerId: string;\n containerKey: Uint8Array;\n containerKeyEpochId: string;\n destinationParentKek: ContainerKekResponse;\n destinationParentProjection: ContainerWriterProjectionResponse;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n previousProjection: ContainerWriterProjectionResponse;\n predecessorBridge: ContainerKekPredecessorBridge;\n principalPolicies: readonly PrincipalPolicyCurrentEvidence[];\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}): MaterializedContainerMovePlan {\n const plan: ContainerMovePlan = {\n body: input.body,\n containerId: input.containerId,\n containerKeyEpochId: input.containerKeyEpochId,\n event: input.event,\n eventHash: input.eventHash,\n keyEpoch: input.keyEpoch,\n keyring: input.keyring,\n manifest: input.manifest,\n manifestHash: input.manifestHash,\n previousManifest: input.previousManifest,\n request: buildContainerMoveRequest({\n body: input.body,\n destinationParentKek: input.destinationParentKek,\n destinationParentProjection: input.destinationParentProjection,\n event: input.event,\n keyEpoch: input.keyEpoch,\n keyring: input.keyring,\n manifest: input.manifest,\n manifestHash: input.manifestHash,\n previousManifest: input.previousManifest,\n previousProjection: input.previousProjection,\n predecessorBridge: input.predecessorBridge,\n principalPolicies: input.principalPolicies,\n userRecipientKeys: input.userRecipientKeys,\n wraps: input.wraps,\n }),\n state: input.state,\n wraps: input.wraps,\n };\n\n return { containerKey: input.containerKey, plan };\n}\n\ntype MaterializedContainerMoveInput =\n BuildMaterializedContainerMovePlanInput & {\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n stillCurrent?: (() => boolean) | undefined;\n warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n };\n\nasync function collectAuthorizedMovePolicies(\n input: MaterializedContainerMoveInput,\n) {\n const principalPolicies = await collectContainerMovePrincipalPolicies({\n ...input,\n resolveUserKey: input.resolveProjectionUserKey,\n });\n assertContainerAuthorAccess({\n author: input.author,\n projection: input.previousProjection,\n principalPolicies,\n minimumAccess: \"admin\",\n });\n assertContainerAuthorAccess({\n author: input.author,\n projection: input.destinationParentProjection,\n principalPolicies,\n minimumAccess: \"write\",\n });\n return principalPolicies;\n}\n\nasync function buildMaterializedContainerMovePlan(\n input: MaterializedContainerMoveInput,\n): Promise<MaterializedContainerMovePlan> {\n const {\n containerKey: predecessorContainerKey,\n destinationParent,\n source,\n } = await unwrapMoveContainerKeys({\n destinationParentProjection: input.destinationParentProjection,\n execSql: input.execSql,\n previousProjection: input.previousProjection,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // Only a verified path is a final depth refusal; a padded unverified path\n // must fail verification (an incident), never look like an honest refusal.\n assertContainerChildPathFits(input.destinationParentProjection.path);\n const { destinationState, previousState } = readContainerMoveStates({\n authorOrganizationId: input.author.organizationId,\n destinationParent,\n source,\n });\n const principalPolicies = await collectAuthorizedMovePolicies(input);\n const {\n body,\n containerKey,\n containerKeyEpochId,\n keyring,\n predecessorBridge,\n } = await buildMoveRotationWithBody({\n destinationParent,\n destinationState,\n override: input.containerKeyEpochId,\n predecessorContainerKey,\n previousState,\n source,\n });\n const { event, eventHash, keyEpoch, manifest, manifestHash, state } =\n await deriveMoveManifestArtifacts({\n body,\n containerKeyEpochId,\n destinationParent,\n previousState,\n signing: {\n author: input.author,\n dependencyManifestHashes: containerMoveDependencyManifestHashes(input),\n eventId: input.eventId,\n signedAt: input.signedAt,\n },\n source,\n });\n const { userRecipientKeys, wraps } = await buildContainerMoveWraps({\n principalPolicies,\n containerKey,\n containerKeyEpochId,\n destinationParentKek: destinationParent.kek,\n destinationParentProjection: input.destinationParentProjection,\n execSql: input.execSql,\n manifestHash,\n previousProjection: input.previousProjection,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n state,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n\n return buildContainerMovePlanResult({\n body,\n containerKey,\n containerId: previousState.containerId,\n containerKeyEpochId,\n destinationParentKek: destinationParent.kek,\n destinationParentProjection: input.destinationParentProjection,\n event,\n eventHash,\n keyEpoch,\n keyring,\n manifest,\n manifestHash,\n previousManifest: asContainerManifestBundle(source.manifest),\n previousProjection: input.previousProjection,\n predecessorBridge,\n principalPolicies,\n state,\n userRecipientKeys,\n wraps,\n });\n}\n\nexport async function moveRemoteContainer(input: {\n reportSecurityIncident: SecurityIncidentReporter;\n apiClient: ContainerMoveApi;\n author: ContainerMutationAuthor;\n containerId: string;\n destinationParentContainerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n onStaleAcceptance?: (() => void) | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n plan: ContainerMovePlan;\n response: ContainerRotationResponse;\n} | null> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container move\",\n );\n const [previousProjection, destinationParentProjection] = await Promise.all([\n input.apiClient.getContainerWriterProjection(input.containerId),\n input.apiClient.getContainerWriterProjection(\n input.destinationParentContainerId,\n ),\n ]);\n if (!previousProjection || !destinationParentProjection) {\n return null;\n }\n\n const materializedPlan = await nullOnProjectionVerificationCancellation(() =>\n buildMaterializedContainerMovePlan({\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n previousProjection,\n destinationParentProjection,\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n );\n if (!materializedPlan) return null;\n return submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: [],\n apiClient: input.apiClient,\n author: input.author,\n carriedRekeys: {\n planning: {\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n knownContainerKeks: new Map([\n [\n materializedPlan.plan.containerKeyEpochId,\n materializedPlan.containerKey,\n ],\n ]),\n resolveProjectionUserKey: resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n },\n rotated: () =>\n containerWriterProjectionFromRotationPlan({\n ancestors: destinationParentProjection,\n plan: materializedPlan.plan,\n previousProjection,\n }),\n },\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n onStaleAcceptance: input.onStaleAcceptance,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: (carried) => {\n const request = carried.length\n ? { ...materializedPlan.plan.request, containerRekeys: [...carried] }\n : materializedPlan.plan.request;\n const options = {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n };\n const { moveContainerResult } = input.apiClient;\n return submitContainerRotation({\n plain: () =>\n input.apiClient.moveContainer(input.containerId, request, options),\n result: moveContainerResult\n ? () =>\n moveContainerResult.call(\n input.apiClient,\n input.containerId,\n request,\n { ...options, reportErrors: false },\n )\n : undefined,\n });\n },\n });\n}\n"]}
|
|
@@ -89,8 +89,10 @@ export async function submitAcknowledgedContainerMutation(input) {
|
|
|
89
89
|
responses: [response, ...(response.containerRekeys ?? [])],
|
|
90
90
|
stillCurrent: input.stillCurrent,
|
|
91
91
|
});
|
|
92
|
-
if (!acknowledged || input.stillCurrent?.() === false)
|
|
92
|
+
if (!acknowledged || input.stillCurrent?.() === false) {
|
|
93
|
+
input.onStaleAcceptance?.();
|
|
93
94
|
return null;
|
|
95
|
+
}
|
|
94
96
|
try {
|
|
95
97
|
rememberVerifiedContainerHeads({
|
|
96
98
|
execSql: input.execSql,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./rekey/carriedDescendantRekeys\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n /** Session lifetime for best-effort work after durable acknowledgement. */\n recitationStillCurrent?: (() => boolean) | undefined;\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) return null;\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./rekey/carriedDescendantRekeys\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n /** Called when the server accepted but a stale caller dropped the result. */\n onStaleAcceptance?: (() => void) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n recitationStillCurrent?: (() => boolean) | undefined;\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) {\n input.onStaleAcceptance?.();\n return null;\n }\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
|