@tearleads/client-sdk 0.1.60 → 0.1.62
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/Tearleads.d.ts +8 -48
- package/Tearleads.js +18 -25
- package/Tearleads.js.map +1 -1
- package/TearleadsOptions.d.ts +49 -0
- package/TearleadsOptions.js +2 -0
- package/TearleadsOptions.js.map +1 -0
- package/client/containerContents/documentDiscovery.js +5 -5
- package/client/containerContents/documentDiscovery.js.map +1 -1
- package/client/containerContents/index.d.ts +7 -7
- package/client/containerContents/index.js +7 -7
- package/client/containerContents/index.js.map +1 -1
- package/client/containerContents/types.d.ts +6 -6
- package/client/containerContents/types.js.map +1 -1
- package/client/deviceFirst/index.js +2 -2
- package/client/deviceFirst/index.js.map +1 -1
- package/client/root/index.d.ts +1 -1
- package/client/root/index.js.map +1 -1
- package/client/runtime/workflowRuntime.d.ts +1 -1
- package/client/runtime/workflowRuntime.js.map +1 -1
- package/index.d.ts +2 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/stores/container-contents/containerStatePersistence.js +1 -1
- package/stores/container-contents/documentRecovery.js +2 -2
- package/stores/container-contents/documentRecovery.js.map +1 -1
- package/stores/container-contents/documentWork.js.map +1 -1
- package/stores/container-contents/localRefresh.js +2 -2
- package/stores/container-contents/localRefresh.js.map +1 -1
- package/stores/container-contents/operations.js +2 -2
- package/stores/container-contents/operations.js.map +1 -1
- package/stores/container-contents/remoteContainerIngestion.js +1 -1
- package/stores/container-contents/remoteEventSync.js +1 -1
- package/stores/container-contents/remoteHydrationRequest.js +1 -1
- package/stores/container-contents/setContainerIconOperation.js +2 -2
- package/stores/container-contents/setContainerIconOperation.js.map +1 -1
- package/stores/container-contents/shareOperations.js +1 -1
- package/stores/container-contents/startupHydration.js +1 -1
- package/stores/container-contents/syncAgent.d.ts +2 -2
- package/stores/container-contents/syncAgentTypes.d.ts +1 -1
- package/stores/container-contents/syncLaneIteration.js +2 -2
- package/stores/container-contents/syncLaneIteration.js.map +1 -1
- package/stores/container-contents/systemContainerIcon.js +1 -1
- package/stores/container-contents/systemContainerIcon.js.map +1 -1
- package/workflows/container-contents/{documentAttributionRanges.d.ts → attribution/documentAttributionRanges.d.ts} +1 -1
- package/workflows/container-contents/{documentCharacterBlame.js → attribution/documentCharacterBlame.js} +3 -3
- package/workflows/container-contents/attribution/documentCharacterBlame.js.map +1 -0
- package/workflows/container-contents/{documentFieldBlame.js → attribution/documentFieldBlame.js} +4 -4
- package/workflows/container-contents/attribution/documentFieldBlame.js.map +1 -0
- package/workflows/container-contents/container-state/createIntentSync.js +1 -1
- package/workflows/container-contents/container-state/createIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/moveIntentSync.js +1 -1
- package/workflows/container-contents/container-state/moveIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/purgeTree.js +2 -2
- package/workflows/container-contents/container-state/purgeTree.js.map +1 -1
- package/workflows/container-contents/container-state/sharePersistence.js +2 -2
- package/workflows/container-contents/container-state/sharePersistence.js.map +1 -1
- package/workflows/container-contents/{containerDocumentListing.js → documentDiscovery/containerDocumentListing.js} +1 -1
- package/workflows/container-contents/{documentDiscoveryApply.js → documentDiscovery/documentDiscoveryApply.js} +3 -3
- package/workflows/container-contents/documentDiscovery/documentDiscoveryApply.js.map +1 -0
- package/workflows/container-contents/{documentDiscoveryCandidates.js.map → documentDiscovery/documentDiscoveryCandidates.js.map} +1 -1
- package/workflows/container-contents/{documentDiscoveryEvidence.js → documentDiscovery/documentDiscoveryEvidence.js} +1 -1
- package/workflows/container-contents/documentDiscovery/documentDiscoveryEvidence.js.map +1 -0
- package/workflows/container-contents/{documentDiscoveryInputs.js → documentDiscovery/documentDiscoveryInputs.js} +2 -2
- package/workflows/container-contents/documentDiscovery/documentDiscoveryInputs.js.map +1 -0
- package/workflows/container-contents/documentDiscovery/documentDiscoveryLanes.js.map +1 -0
- package/workflows/container-contents/{documentDiscoveryTypes.d.ts → documentDiscovery/documentDiscoveryTypes.d.ts} +4 -4
- package/workflows/container-contents/documentDiscovery/documentDiscoveryTypes.js.map +1 -0
- package/workflows/container-contents/{documentDiscovery.d.ts → documentDiscovery/index.d.ts} +1 -1
- package/workflows/container-contents/{documentDiscovery.js → documentDiscovery/index.js} +5 -5
- package/workflows/container-contents/documentDiscovery/index.js.map +1 -0
- package/workflows/container-contents/{availableDocumentLinkIntent.js → documentLinks/availableDocumentLinkIntent.js} +1 -1
- package/workflows/container-contents/documentLinks/availableDocumentLinkIntent.js.map +1 -0
- package/workflows/container-contents/{deferredDocumentLinks.js → documentLinks/deferredDocumentLinks.js} +1 -1
- package/workflows/container-contents/documentLinks/deferredDocumentLinks.js.map +1 -0
- package/workflows/container-contents/{documentLinkIntent.js → documentLinks/documentLinkIntent.js} +4 -4
- package/workflows/container-contents/documentLinks/documentLinkIntent.js.map +1 -0
- package/workflows/container-contents/documentLinks/documentLocalRelink.js.map +1 -0
- package/workflows/container-contents/{documentLinks.d.ts → documentLinks/index.d.ts} +5 -5
- package/workflows/container-contents/{documentLinks.js → documentLinks/index.js} +10 -10
- package/workflows/container-contents/documentLinks/index.js.map +1 -0
- package/workflows/container-contents/documentMove/documentMoveDeniedReplay.js.map +1 -0
- package/workflows/container-contents/{documentMoveFailure.js → documentMove/documentMoveFailure.js} +1 -1
- package/workflows/container-contents/documentMove/documentMoveFailure.js.map +1 -0
- package/workflows/container-contents/{documentMoveIntent.js → documentMove/documentMoveIntent.js} +7 -7
- package/workflows/container-contents/documentMove/documentMoveIntent.js.map +1 -0
- package/workflows/container-contents/{documentMoveIntentErrors.js → documentMove/documentMoveIntentErrors.js} +1 -1
- package/workflows/container-contents/documentMove/documentMoveIntentErrors.js.map +1 -0
- package/workflows/container-contents/{documentMoveIntentSettlement.js → documentMove/documentMoveIntentSettlement.js} +4 -4
- package/workflows/container-contents/documentMove/documentMoveIntentSettlement.js.map +1 -0
- package/workflows/container-contents/{documentMoveIntentSync.js → documentMove/documentMoveIntentSync.js} +7 -7
- package/workflows/container-contents/documentMove/documentMoveIntentSync.js.map +1 -0
- package/workflows/container-contents/{documentMoveVanishedRefresh.js → documentMove/documentMoveVanishedRefresh.js} +3 -3
- package/workflows/container-contents/documentMove/documentMoveVanishedRefresh.js.map +1 -0
- package/workflows/container-contents/{documentHydrationProbe.js → documentPriming/documentHydrationProbe.js} +4 -4
- package/workflows/container-contents/documentPriming/documentHydrationProbe.js.map +1 -0
- package/workflows/container-contents/documentPriming/documentRuntimeTargetSync.js.map +1 -0
- package/workflows/container-contents/{documentPriming.js → documentPriming/index.js} +5 -5
- package/workflows/container-contents/documentPriming/index.js.map +1 -0
- package/workflows/container-contents/{documentStructure.d.ts → documentQueries/documentStructure.d.ts} +1 -1
- package/workflows/container-contents/{documentStructure.js → documentQueries/documentStructure.js} +4 -4
- package/workflows/container-contents/documentQueries/documentStructure.js.map +1 -0
- package/workflows/container-contents/{documentStructureTypes.d.ts → documentQueries/documentStructureTypes.d.ts} +4 -4
- package/workflows/container-contents/documentQueries/documentStructureTypes.js.map +1 -0
- package/workflows/container-contents/{documentSubtreeQueries.js → documentQueries/documentSubtreeQueries.js} +5 -5
- package/workflows/container-contents/documentQueries/documentSubtreeQueries.js.map +1 -0
- package/workflows/container-contents/{documentQueries.d.ts → documentQueries/index.d.ts} +8 -8
- package/workflows/container-contents/{documentQueries.js → documentQueries/index.js} +13 -13
- package/workflows/container-contents/documentQueries/index.js.map +1 -0
- package/workflows/container-contents/{orphanedDocumentSql.js → documentQueries/orphanedDocumentSql.js} +1 -1
- package/workflows/container-contents/documentQueries/orphanedDocumentSql.js.map +1 -0
- package/workflows/container-contents/{pendingDownloads.d.ts → documentQueries/pendingDownloads.d.ts} +1 -1
- package/workflows/container-contents/{pendingDownloads.js → documentQueries/pendingDownloads.js} +3 -3
- package/workflows/container-contents/documentQueries/pendingDownloads.js.map +1 -0
- package/workflows/container-contents/documentQueries/sql.js +1 -1
- package/workflows/container-contents/documentQueries/sql.js.map +1 -1
- package/workflows/container-contents/index.d.ts +13 -13
- package/workflows/container-contents/index.js +11 -11
- package/workflows/container-contents/index.js.map +1 -1
- package/workflows/container-contents/{blobInfo.d.ts → info/blobInfo.d.ts} +1 -1
- package/workflows/container-contents/{blobInfo.js → info/blobInfo.js} +4 -4
- package/workflows/container-contents/info/blobInfo.js.map +1 -0
- package/workflows/container-contents/{blobInfoTypes.d.ts → info/blobInfoTypes.d.ts} +1 -1
- package/workflows/container-contents/info/blobInfoTypes.js.map +1 -0
- package/workflows/container-contents/{containerInfo.d.ts → info/containerInfo.d.ts} +4 -4
- package/workflows/container-contents/{containerInfo.js → info/containerInfo.js} +5 -5
- package/workflows/container-contents/info/containerInfo.js.map +1 -0
- package/workflows/container-contents/{documentInfo.d.ts → info/documentInfo.d.ts} +3 -3
- package/workflows/container-contents/{documentInfo.js → info/documentInfo.js} +11 -11
- package/workflows/container-contents/info/documentInfo.js.map +1 -0
- package/workflows/container-contents/{documentInfoTypes.d.ts → info/documentInfoTypes.d.ts} +3 -3
- package/workflows/container-contents/info/documentInfoTypes.js.map +1 -0
- package/workflows/container-contents/{metadata.d.ts → metadata/index.d.ts} +2 -2
- package/workflows/container-contents/{metadata.js → metadata/index.js} +5 -5
- package/workflows/container-contents/metadata/index.js.map +1 -0
- package/workflows/container-contents/{metadataEvents.d.ts → metadata/metadataEvents.d.ts} +1 -1
- package/workflows/container-contents/{metadataEvents.js → metadata/metadataEvents.js} +1 -1
- package/workflows/container-contents/metadata/metadataEvents.js.map +1 -0
- package/workflows/container-contents/{metadataIncomingUpdateIsolation.js → metadata/metadataIncomingUpdateIsolation.js} +5 -5
- package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js.map +1 -0
- package/workflows/container-contents/{metadataMutationPreparation.d.ts → metadata/metadataMutationPreparation.d.ts} +7 -7
- package/workflows/container-contents/{metadataMutationPreparation.js → metadata/metadataMutationPreparation.js} +5 -5
- package/workflows/container-contents/metadata/metadataMutationPreparation.js.map +1 -0
- package/workflows/container-contents/{metadataPersistence.d.ts → metadata/metadataPersistence.d.ts} +2 -2
- package/workflows/container-contents/{metadataPersistence.js → metadata/metadataPersistence.js} +4 -4
- package/workflows/container-contents/metadata/metadataPersistence.js.map +1 -0
- package/workflows/container-contents/{metadataPullContinuationInvalidation.js → metadata/metadataPullContinuationInvalidation.js} +4 -4
- package/workflows/container-contents/metadata/metadataPullContinuationInvalidation.js.map +1 -0
- package/workflows/container-contents/{metadataReadState.d.ts → metadata/metadataReadState.d.ts} +1 -1
- package/workflows/container-contents/metadata/metadataReadState.js.map +1 -0
- package/workflows/container-contents/{metadataRecord.js → metadata/metadataRecord.js} +2 -2
- package/workflows/container-contents/metadata/metadataRecord.js.map +1 -0
- package/workflows/container-contents/{metadataRemoteSync.d.ts → metadata/metadataRemoteSync.d.ts} +5 -5
- package/workflows/container-contents/{metadataRemoteSync.js → metadata/metadataRemoteSync.js} +3 -3
- package/workflows/container-contents/metadata/metadataRemoteSync.js.map +1 -0
- package/workflows/container-contents/{metadataStateInstallation.d.ts → metadata/metadataStateInstallation.d.ts} +1 -1
- package/workflows/container-contents/metadata/metadataStateInstallation.js.map +1 -0
- package/workflows/container-contents/{metadataStateIsolation.js → metadata/metadataStateIsolation.js} +3 -3
- package/workflows/container-contents/metadata/metadataStateIsolation.js.map +1 -0
- package/workflows/container-contents/{metadataSyncErrors.js → metadata/metadataSyncErrors.js} +3 -3
- package/workflows/container-contents/metadata/metadataSyncErrors.js.map +1 -0
- package/workflows/container-contents/{metadataSyncSettlement.d.ts → metadata/metadataSyncSettlement.d.ts} +2 -2
- package/workflows/container-contents/{metadataSyncSettlement.js → metadata/metadataSyncSettlement.js} +3 -3
- package/workflows/container-contents/metadata/metadataSyncSettlement.js.map +1 -0
- package/workflows/container-contents/{metadataTypes.d.ts → metadata/metadataTypes.d.ts} +5 -5
- package/workflows/container-contents/metadata/metadataTypes.js.map +1 -0
- package/workflows/container-contents/pendingWrites/aggregation.js.map +1 -1
- package/workflows/container-contents/pendingWrites/deferredTails.js.map +1 -1
- package/workflows/container-contents/{pendingWrites.d.ts → pendingWrites/index.d.ts} +1 -1
- package/workflows/container-contents/{pendingWrites.js → pendingWrites/index.js} +12 -12
- package/workflows/container-contents/pendingWrites/index.js.map +1 -0
- package/workflows/container-contents/projectionGeneration.js.map +1 -1
- package/workflows/container-contents/projectionKeys.d.ts +1 -1
- package/workflows/container-contents/projectionKeys.js.map +1 -1
- package/workflows/container-contents/projectionView.js +1 -1
- package/workflows/container-contents/projectionView.js.map +1 -1
- package/workflows/container-contents/{folderRecovery.d.ts → recovery/folderRecovery.d.ts} +1 -1
- package/workflows/container-contents/{folderRecovery.js → recovery/folderRecovery.js} +4 -4
- package/workflows/container-contents/recovery/folderRecovery.js.map +1 -0
- package/workflows/container-contents/{staleRootRecovery.js → recovery/staleRootRecovery.js} +1 -1
- package/workflows/container-contents/recovery/staleRootRecovery.js.map +1 -0
- package/workflows/container-contents/remoteHydration/completeHydration.js +1 -1
- package/workflows/container-contents/remoteHydration/completeHydration.js.map +1 -1
- package/workflows/container-contents/remoteHydration/heldContainerRebind.js +1 -1
- package/workflows/container-contents/remoteHydration/heldContainerRebind.js.map +1 -1
- package/workflows/container-contents/{remoteHydration.d.ts → remoteHydration/index.d.ts} +2 -2
- package/workflows/container-contents/{remoteHydration.js → remoteHydration/index.js} +6 -6
- package/workflows/container-contents/remoteHydration/index.js.map +1 -0
- package/workflows/container-contents/{remoteContainerPageHydration.js → remoteHydration/remoteContainerPageHydration.js} +8 -8
- package/workflows/container-contents/remoteHydration/remoteContainerPageHydration.js.map +1 -0
- package/workflows/container-contents/{remoteContainerState.js → remoteHydration/remoteContainerState.js} +11 -11
- package/workflows/container-contents/remoteHydration/remoteContainerState.js.map +1 -0
- package/workflows/container-contents/remoteHydration/types.d.ts +1 -1
- package/workflows/container-contents/runtime.d.ts +1 -1
- package/workflows/container-contents/runtime.js.map +1 -1
- package/workflows/container-contents/{documentPurge.d.ts → tombstones/documentPurge.d.ts} +6 -6
- package/workflows/container-contents/{documentPurge.js → tombstones/documentPurge.js} +6 -6
- package/workflows/container-contents/tombstones/documentPurge.js.map +1 -0
- package/workflows/container-contents/{documentTombstoneEvidence.js → tombstones/documentTombstoneEvidence.js} +9 -9
- package/workflows/container-contents/tombstones/documentTombstoneEvidence.js.map +1 -0
- package/workflows/container-contents/{documentTombstoneGate.js → tombstones/documentTombstoneGate.js} +1 -1
- package/workflows/container-contents/tombstones/documentTombstoneGate.js.map +1 -0
- package/workflows/documents/projectionKeys.d.ts +1 -1
- package/workflows/documents/projectionKeys.js.map +1 -1
- package/workflows/documents/reportDocumentSyncQuarantine.js.map +1 -1
- package/workflows/documents/runtime.d.ts +1 -1
- package/workflows/documents/runtime.js.map +1 -1
- package/workflows/{runtimeInput.d.ts → shared/runtimeInput.d.ts} +6 -6
- package/workflows/shared/runtimeInput.js.map +1 -0
- package/workflows/container-contents/availableDocumentLinkIntent.js.map +0 -1
- package/workflows/container-contents/blobInfo.js.map +0 -1
- package/workflows/container-contents/blobInfoTypes.js.map +0 -1
- package/workflows/container-contents/containerInfo.js.map +0 -1
- package/workflows/container-contents/deferredDocumentLinks.js.map +0 -1
- package/workflows/container-contents/documentCharacterBlame.js.map +0 -1
- package/workflows/container-contents/documentDiscovery.js.map +0 -1
- package/workflows/container-contents/documentDiscoveryApply.js.map +0 -1
- package/workflows/container-contents/documentDiscoveryEvidence.js.map +0 -1
- package/workflows/container-contents/documentDiscoveryInputs.js.map +0 -1
- package/workflows/container-contents/documentDiscoveryLanes.js.map +0 -1
- package/workflows/container-contents/documentDiscoveryTypes.js.map +0 -1
- package/workflows/container-contents/documentFieldBlame.js.map +0 -1
- package/workflows/container-contents/documentHydrationProbe.js.map +0 -1
- package/workflows/container-contents/documentInfo.js.map +0 -1
- package/workflows/container-contents/documentInfoTypes.js.map +0 -1
- package/workflows/container-contents/documentLinkIntent.js.map +0 -1
- package/workflows/container-contents/documentLinks.js.map +0 -1
- package/workflows/container-contents/documentLocalRelink.js.map +0 -1
- package/workflows/container-contents/documentMoveDeniedReplay.js.map +0 -1
- package/workflows/container-contents/documentMoveFailure.js.map +0 -1
- package/workflows/container-contents/documentMoveIntent.js.map +0 -1
- package/workflows/container-contents/documentMoveIntentErrors.js.map +0 -1
- package/workflows/container-contents/documentMoveIntentSettlement.js.map +0 -1
- package/workflows/container-contents/documentMoveIntentSync.js.map +0 -1
- package/workflows/container-contents/documentMoveVanishedRefresh.js.map +0 -1
- package/workflows/container-contents/documentPriming.js.map +0 -1
- package/workflows/container-contents/documentPurge.js.map +0 -1
- package/workflows/container-contents/documentQueries.js.map +0 -1
- package/workflows/container-contents/documentRuntimeTargetSync.js.map +0 -1
- package/workflows/container-contents/documentStructure.js.map +0 -1
- package/workflows/container-contents/documentStructureTypes.js.map +0 -1
- package/workflows/container-contents/documentSubtreeQueries.js.map +0 -1
- package/workflows/container-contents/documentTombstoneEvidence.js.map +0 -1
- package/workflows/container-contents/documentTombstoneGate.js.map +0 -1
- package/workflows/container-contents/folderRecovery.js.map +0 -1
- package/workflows/container-contents/metadata.js.map +0 -1
- package/workflows/container-contents/metadataEvents.js.map +0 -1
- package/workflows/container-contents/metadataIncomingUpdateIsolation.js.map +0 -1
- package/workflows/container-contents/metadataMutationPreparation.js.map +0 -1
- package/workflows/container-contents/metadataPersistence.js.map +0 -1
- package/workflows/container-contents/metadataPullContinuationInvalidation.js.map +0 -1
- package/workflows/container-contents/metadataReadState.js.map +0 -1
- package/workflows/container-contents/metadataRecord.js.map +0 -1
- package/workflows/container-contents/metadataRemoteSync.js.map +0 -1
- package/workflows/container-contents/metadataStateInstallation.js.map +0 -1
- package/workflows/container-contents/metadataStateIsolation.js.map +0 -1
- package/workflows/container-contents/metadataSyncErrors.js.map +0 -1
- package/workflows/container-contents/metadataSyncSettlement.js.map +0 -1
- package/workflows/container-contents/metadataTypes.js.map +0 -1
- package/workflows/container-contents/orphanedDocumentSql.js.map +0 -1
- package/workflows/container-contents/pendingDownloads.js.map +0 -1
- package/workflows/container-contents/pendingWrites.js.map +0 -1
- package/workflows/container-contents/remoteContainerPageHydration.js.map +0 -1
- package/workflows/container-contents/remoteContainerState.js.map +0 -1
- package/workflows/container-contents/remoteHydration.js.map +0 -1
- package/workflows/container-contents/staleRootRecovery.js.map +0 -1
- package/workflows/runtimeInput.js.map +0 -1
- /package/workflows/container-contents/{documentAttributionRanges.js → attribution/documentAttributionRanges.js} +0 -0
- /package/workflows/container-contents/{documentAttributionRanges.js.map → attribution/documentAttributionRanges.js.map} +0 -0
- /package/workflows/container-contents/{containerDocumentListing.js.map → documentDiscovery/containerDocumentListing.js.map} +0 -0
- /package/workflows/container-contents/{documentDiscoveryCandidates.js → documentDiscovery/documentDiscoveryCandidates.js} +0 -0
- /package/workflows/container-contents/{documentDiscoveryLanes.js → documentDiscovery/documentDiscoveryLanes.js} +0 -0
- /package/workflows/container-contents/{documentDiscoveryTypes.js → documentDiscovery/documentDiscoveryTypes.js} +0 -0
- /package/workflows/container-contents/{documentHeadScope.js → documentDiscovery/documentHeadScope.js} +0 -0
- /package/workflows/container-contents/{documentHeadScope.js.map → documentDiscovery/documentHeadScope.js.map} +0 -0
- /package/workflows/container-contents/{documentLocalRelink.js → documentLinks/documentLocalRelink.js} +0 -0
- /package/workflows/container-contents/{documentMoveDeniedReplay.js → documentMove/documentMoveDeniedReplay.js} +0 -0
- /package/workflows/container-contents/{documentMoveUnlinkIds.js → documentMove/documentMoveUnlinkIds.js} +0 -0
- /package/workflows/container-contents/{documentMoveUnlinkIds.js.map → documentMove/documentMoveUnlinkIds.js.map} +0 -0
- /package/workflows/container-contents/{documentRuntimeTargetSync.js → documentPriming/documentRuntimeTargetSync.js} +0 -0
- /package/workflows/container-contents/{documentStructureTypes.js → documentQueries/documentStructureTypes.js} +0 -0
- /package/workflows/container-contents/{blobInfoRows.js → info/blobInfoRows.js} +0 -0
- /package/workflows/container-contents/{blobInfoRows.js.map → info/blobInfoRows.js.map} +0 -0
- /package/workflows/container-contents/{blobInfoTypes.js → info/blobInfoTypes.js} +0 -0
- /package/workflows/container-contents/{documentInfoTypes.js → info/documentInfoTypes.js} +0 -0
- /package/workflows/container-contents/{metadataReadState.js → metadata/metadataReadState.js} +0 -0
- /package/workflows/container-contents/{metadataStateInstallation.js → metadata/metadataStateInstallation.js} +0 -0
- /package/workflows/container-contents/{metadataSyncFollowup.js → metadata/metadataSyncFollowup.js} +0 -0
- /package/workflows/container-contents/{metadataSyncFollowup.js.map → metadata/metadataSyncFollowup.js.map} +0 -0
- /package/workflows/container-contents/{metadataSyncRegistrations.d.ts → metadata/metadataSyncRegistrations.d.ts} +0 -0
- /package/workflows/container-contents/{metadataSyncRegistrations.js → metadata/metadataSyncRegistrations.js} +0 -0
- /package/workflows/container-contents/{metadataSyncRegistrations.js.map → metadata/metadataSyncRegistrations.js.map} +0 -0
- /package/workflows/container-contents/{metadataTypes.js → metadata/metadataTypes.js} +0 -0
- /package/workflows/container-contents/{pendingWritesTypes.d.ts → pendingWrites/pendingWritesTypes.d.ts} +0 -0
- /package/workflows/container-contents/{pendingWritesTypes.js → pendingWrites/pendingWritesTypes.js} +0 -0
- /package/workflows/container-contents/{pendingWritesTypes.js.map → pendingWrites/pendingWritesTypes.js.map} +0 -0
- /package/workflows/container-contents/{remoteHydrationLog.js → remoteHydration/remoteHydrationLog.js} +0 -0
- /package/workflows/container-contents/{remoteHydrationLog.js.map → remoteHydration/remoteHydrationLog.js.map} +0 -0
- /package/workflows/{runtimeInput.js → shared/runtimeInput.js} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentHydrationProbe.js","sourceRoot":"","sources":["documentHydrationProbe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EACL,iCAAiC,EACjC,wBAAwB,EACxB,cAAc,GACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAM1E,OAAO,EAAE,sCAAsC,EAAE,MAAM,6BAA6B,CAAC;AAErF,MAAM,2CAA2C,GAAG,CAAC,CAAC;AACtD,MAAM,wCAAwC,GAAG,EAAE,CAAC;AAiBpD,SAAS,iBAAiB,CAAC,MAA8B;IACvD,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,SAAS,CAAC,MAA8B;IAC/C,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,eAAe,CAAC,GAAY;IACnC,0EAA0E;IAC1E,wEAAwE;IACxE,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,UAAU,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;IACxE,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC5D,IACE,OAAO,UAAU,KAAK,QAAQ;QAC9B,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,kBAAkB,KAAK,QAAQ,EACtC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO;QACL,UAAU;QACV,OAAO;QACP,yBAAyB,EAAE,oBAAoB,KAAK,kBAAkB;QACtE,kBAAkB;KACnB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,2CAA2C,CAAC,KAI1D;IACC,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAC5C;;iBAEa,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;+CA0BC,iBAAiB,CACtD,6BAA6B,CAC9B;;;;;;;;KAQJ,EACD;QACE,GAAG,KAAK,CAAC,YAAY;QACrB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,YAAY;QAClB,GAAG,6BAA6B;QAChC,wCAAwC;KACzC,CACF,CAAC;IACF,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,+BAA+B,CACtC,OAAgE;IAEhE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAqC,CAAC;IACtE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtD,IACE,QAAQ,KAAK,SAAS;gBACtB,CAAC,MAAM,CAAC,yBAAyB;oBAC/B,CAAC,QAAQ,CAAC,yBAAyB,CAAC;gBACtC,CAAC,MAAM,CAAC,yBAAyB;oBAC/B,QAAQ,CAAC,yBAAyB;oBAClC,MAAM,CAAC,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC,EAC1D,CAAC;gBACD,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC;SAClC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACpB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CACzE;SACA,KAAK,CAAC,CAAC,EAAE,wCAAwC,CAAC,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,4BAA4B,CAAC,KAI3C;IACC,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE;QACjD,GAAG,cAAc;QACjB,GAAG,wBAAwB;QAC3B,GAAG,iCAAiC;KACrC,CAAC,CAAC;IACH,MAAM,OAAO,GAAkC,EAAE,CAAC;IAClD,KAAK,MAAM,gBAAgB,IAAI,iCAAiC,CAC9D,YAAY,CACb,EAAE,CAAC;QACF,OAAO,CAAC,IAAI,CACV,MAAM,2CAA2C,CAAC;YAChD,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,YAAY,EAAE,gBAAgB;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,+BAA+B,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAW,KAMpE;IACC,MAAM,OAAO,GAAG,MAAM,4BAA4B,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAC/B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAC5D,CAAC;IACF,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAC9B,CAAC,EACD,2CAA2C,CAC5C,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,sCAAsC,CAAC;QAC7D,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO;KACR,CAAC,CAAC;IACH,MAAM,uBAAuB,GAAG,UAAU,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACnE,MAAM,mBAAmB,GACvB,OAAO,CAAC,MAAM,KAAK,wCAAwC,CAAC;IAC9D,MAAM,IAAI,GAAG,CAAC,uBAAuB,IAAI,CAAC,mBAAmB,CAAC;IAC9D,MAAM,gBAAgB,GAAG,uBAAuB;QAC9C,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnB,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,OAAO,IAAI,IAAI,CAAC;QAC7D,cAAc,EAAE,SAAS,CAAC,IAAI;KAC/B,CAAC;AACJ,CAAC","sourcesContent":["import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from \"../../data/documents/documentSummary\";\nimport {\n documentContainerProjectionTables,\n documentProjectionTables,\n documentTables,\n} from \"../../data/sqlite/schema\";\nimport { ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport { listContainerContentsSqlIdBatches } from \"./documentQueries/sql\";\nimport type {\n ContainerContentsDocumentRuntimeTarget,\n ContainerDocumentProbeHost,\n ContainerDocumentQueriesRuntime,\n} from \"./documentQueries/types\";\nimport { requestRemoteDocumentRuntimeTargetSync } from \"./documentRuntimeTargetSync\";\n\nconst DOCUMENT_HYDRATION_PROBE_REQUEST_BATCH_SIZE = 8;\nconst DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE = 64;\n\ninterface DocumentHydrationProbeBatchResult {\n readonly done: boolean;\n readonly nextCursor: string | null;\n readonly requestedCount: number;\n}\n\ntype RemoteDocumentProbeTarget = Omit<\n ContainerContentsDocumentRuntimeTarget,\n \"documentId\" | \"runtimeContainerId\"\n> & {\n readonly documentId: string;\n readonly preferredRuntimeContainer: boolean;\n readonly runtimeContainerId: string;\n};\n\nfunction valuePlaceholders(values: ReadonlyArray<unknown>): string {\n return values.map(() => \"?\").join(\", \");\n}\n\nfunction valueRows(values: ReadonlyArray<unknown>): string {\n return values.map(() => \"(?)\").join(\", \");\n}\n\nfunction readProbeTarget(row: unknown): RemoteDocumentProbeTarget {\n // These aliases are wholly internal SQL contracts; fail loudly if a query\n // edit violates them instead of silently skipping a persisted document.\n if (row === null || (typeof row !== \"object\" && typeof row !== \"function\")) {\n throw new Error(\"Document hydration probe returned an invalid target\");\n }\n const documentId = Reflect.get(row, \"document_id\");\n const localId = Reflect.get(row, \"local_id\");\n const projectedContainerId = Reflect.get(row, \"projected_container_id\");\n const runtimeContainerId = Reflect.get(row, \"container_id\");\n if (\n typeof documentId !== \"string\" ||\n typeof localId !== \"string\" ||\n typeof runtimeContainerId !== \"string\"\n ) {\n throw new Error(\"Document hydration probe returned an invalid target\");\n }\n return {\n documentId,\n localId,\n preferredRuntimeContainer: projectedContainerId === runtimeContainerId,\n runtimeContainerId,\n };\n}\n\nasync function listRemoteDocumentProbeBatchForContainerIds(input: {\n readonly afterLocalId: string | null;\n readonly containerIds: ReadonlyArray<string>;\n readonly runtime: ContainerDocumentQueriesRuntime;\n}): Promise<RemoteDocumentProbeTarget[]> {\n const rows = await input.runtime.infra.execSql(\n `\n WITH eligible_container_ids(container_id) AS (\n VALUES ${valueRows(input.containerIds)}\n )\n SELECT\n stored.local_id AS local_id,\n stored.document_id AS document_id,\n projection.container_id AS projected_container_id,\n COALESCE(\n projected_container.container_id,\n MIN(linked_container.container_id)\n ) AS container_id\n FROM documents stored\n INNER JOIN document_projection projection\n ON projection.local_id = stored.local_id\n LEFT JOIN eligible_container_ids projected_container\n ON projected_container.container_id = projection.container_id\n LEFT JOIN document_container_projection link\n ON link.document_id = stored.document_id\n LEFT JOIN eligible_container_ids linked_container\n ON linked_container.container_id = link.container_id\n WHERE stored.app_kind = 'documents'\n AND stored.document_id IS NOT NULL\n AND (? IS NULL OR stored.local_id > ?)\n AND (\n projected_container.container_id IS NOT NULL\n OR linked_container.container_id IS NOT NULL\n )\n AND projection.document_kind NOT IN (${valuePlaceholders(\n HIDDEN_DOCUMENT_SUMMARY_KINDS,\n )})\n GROUP BY\n stored.local_id,\n stored.document_id,\n projection.container_id,\n projected_container.container_id\n ORDER BY stored.local_id ASC\n LIMIT ?\n `,\n [\n ...input.containerIds,\n input.afterLocalId,\n input.afterLocalId,\n ...HIDDEN_DOCUMENT_SUMMARY_KINDS,\n DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE,\n ],\n );\n return rows.map(readProbeTarget);\n}\n\nfunction mergeRemoteDocumentProbeTargets(\n batches: ReadonlyArray<ReadonlyArray<RemoteDocumentProbeTarget>>,\n): RemoteDocumentProbeTarget[] {\n const targetsByLocalId = new Map<string, RemoteDocumentProbeTarget>();\n for (const batch of batches) {\n for (const target of batch) {\n const existing = targetsByLocalId.get(target.localId);\n if (\n existing === undefined ||\n (target.preferredRuntimeContainer &&\n !existing.preferredRuntimeContainer) ||\n (target.preferredRuntimeContainer ===\n existing.preferredRuntimeContainer &&\n target.runtimeContainerId < existing.runtimeContainerId)\n ) {\n targetsByLocalId.set(target.localId, target);\n }\n }\n }\n return [...targetsByLocalId.values()]\n .sort((left, right) =>\n left.localId < right.localId ? -1 : Number(left.localId > right.localId),\n )\n .slice(0, DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE);\n}\n\nasync function listRemoteDocumentProbeBatch(input: {\n readonly afterLocalId: string | null;\n readonly listedContainerIds: ReadonlySet<string>;\n readonly runtime: ContainerDocumentQueriesRuntime;\n}): Promise<RemoteDocumentProbeTarget[]> {\n const containerIds = [...input.listedContainerIds];\n if (containerIds.length === 0) {\n return [];\n }\n\n await ensureSqlTables(input.runtime.infra.execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentContainerProjectionTables,\n ]);\n const batches: RemoteDocumentProbeTarget[][] = [];\n for (const containerIdBatch of listContainerContentsSqlIdBatches(\n containerIds,\n )) {\n batches.push(\n await listRemoteDocumentProbeBatchForContainerIds({\n afterLocalId: input.afterLocalId,\n containerIds: containerIdBatch,\n runtime: input.runtime,\n }),\n );\n }\n return mergeRemoteDocumentProbeTargets(batches);\n}\n\n/**\n * Opens at most one bounded batch of visible, remote-backed local documents\n * linked to an authoritatively listed container but absent from every full\n * listing. Each store's ordinary sync pass owns its coded-404/403 verdict.\n */\nexport async function probeUndiscoveredRemoteDocumentBatch<TRuntime>(input: {\n readonly afterLocalId: string | null;\n readonly host: ContainerDocumentProbeHost<TRuntime>;\n readonly listedContainerIds: ReadonlySet<string>;\n readonly listedDocumentIds: ReadonlySet<string>;\n readonly runtime: ContainerDocumentQueriesRuntime;\n}): Promise<DocumentHydrationProbeBatchResult> {\n const scanned = await listRemoteDocumentProbeBatch(input);\n const candidates = scanned.filter(\n (target) => !input.listedDocumentIds.has(target.documentId),\n );\n const targets = candidates.slice(\n 0,\n DOCUMENT_HYDRATION_PROBE_REQUEST_BATCH_SIZE,\n );\n const requested = await requestRemoteDocumentRuntimeTargetSync({\n host: input.host,\n targets,\n });\n const hasUnrequestedCandidate = candidates.length > targets.length;\n const scanPageMayContinue =\n scanned.length === DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE;\n const done = !hasUnrequestedCandidate && !scanPageMayContinue;\n const nextCursorTarget = hasUnrequestedCandidate\n ? targets.at(-1)\n : scanned.at(-1);\n return {\n done,\n nextCursor: done ? null : (nextCursorTarget?.localId ?? null),\n requestedCount: requested.size,\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentInfo.js","sourceRoot":"","sources":["documentInfo.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { exportFullHistorySnapshot } from \"@tearleads/loro\";\nimport type {\n BlobAttachmentSummary,\n ContainerKeyingPathResponse,\n DocumentEditAttributionResponse,\n DocumentWriterProjectionResponse,\n ListDocumentAttachmentsResponse,\n} from \"@tearleads/validators/response\";\nimport { and, eq, isNull } from \"drizzle-orm\";\nimport { DEFAULT_DOCUMENT_KIND } from \"../../data/documents/documentConstants\";\nimport {\n type DocumentBlameRange,\n type DocumentCharacterBlameSummary,\n type DocumentContributor,\n type DocumentFieldBlame,\n summarizeDocumentContributors,\n} from \"../../data/documents/editAttribution\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\nimport {\n documentAttachmentBlobProjection,\n documentPendingAttachments,\n documentProjection,\n} from \"../../data/sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { loadPersistedDocumentContent } from \"../documents/historyContent\";\nimport { computeDocumentBlame } from \"./documentCharacterBlame\";\nimport { computeFieldBlame } from \"./documentFieldBlame\";\nimport type {\n DocumentInfo,\n DocumentInfoAttachment,\n DocumentInfoAuthorizingContainerPath,\n DocumentInfoLocalDetails,\n DocumentInfoRemoteAttachmentBinding,\n DocumentInfoRemoteDetails,\n DocumentInfoRemoteMode,\n} from \"./documentInfoTypes\";\n\nexport type {\n DocumentInfo,\n DocumentInfoAttachment,\n DocumentInfoAuthorizingContainerPath,\n DocumentInfoLocalDetails,\n DocumentInfoRemoteAttachmentBinding,\n DocumentInfoRemoteDetails,\n DocumentInfoRemoteMode,\n} from \"./documentInfoTypes\";\n\ninterface DocumentInfoApi {\n getDocumentEditAttribution: (\n documentId: string,\n requestKey?: string,\n ) => Promise<DocumentEditAttributionResponse | null>;\n getDocumentWriterProjection: (\n documentId: string,\n ) => Promise<DocumentWriterProjectionResponse | null>;\n listDocumentAttachments: (\n documentId: string,\n ) => Promise<ListDocumentAttachmentsResponse | null>;\n}\n\ninterface PendingAttachmentInfoRow {\n byteLength: number;\n createdAt: string;\n localId: string;\n mimeType: string | null;\n name: string;\n slotId: string;\n storageKey: string;\n}\n\ninterface LocalAttachmentInfoRow {\n blobId: string | null;\n byteLength: number;\n localId: string;\n mimeType: string | null;\n slotId: string;\n storageKey: string;\n updatedAt: string;\n}\n\nfunction readRecordString(value: unknown, key: string): string | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const nextValue = Reflect.get(value, key);\n return typeof nextValue === \"string\" && nextValue.length > 0\n ? nextValue\n : null;\n}\n\nfunction readRecordNumber(value: unknown, key: string): number | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const nextValue = Reflect.get(value, key);\n return typeof nextValue === \"number\" && Number.isFinite(nextValue)\n ? nextValue\n : null;\n}\n\nfunction readRecordArrayLength(value: unknown, key: string): number | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const nextValue = Reflect.get(value, key);\n return Array.isArray(nextValue) ? nextValue.length : null;\n}\n\nfunction readStoredManifestHash(\n value: string | null | undefined,\n): string | null {\n if (!value) {\n return null;\n }\n\n try {\n const parsed: unknown = JSON.parse(value);\n return readRecordString(parsed, \"manifestHash\");\n } catch {\n return null;\n }\n}\n\nfunction mapPendingAttachmentRow(\n row: PendingAttachmentInfoRow,\n): DocumentInfoAttachment {\n return {\n attachmentKind: \"pending\",\n blobId: null,\n byteLength: row.byteLength,\n createdAt: row.createdAt,\n localId: row.localId,\n mimeType: row.mimeType,\n name: row.name,\n slotId: row.slotId,\n storageKey: row.storageKey,\n updatedAt: null,\n };\n}\n\nfunction mapLocalAttachmentRow(\n row: LocalAttachmentInfoRow,\n): DocumentInfoAttachment {\n return {\n attachmentKind: \"local\",\n blobId: row.blobId,\n byteLength: row.byteLength,\n createdAt: null,\n localId: row.localId,\n mimeType: row.mimeType,\n name: null,\n slotId: row.slotId,\n storageKey: row.storageKey,\n updatedAt: row.updatedAt,\n };\n}\n\nasync function loadDocumentInfoAttachments(input: {\n execSql: ExecSql;\n localId: string;\n}): Promise<DocumentInfoAttachment[]> {\n const { db } = getClientSQLitePersistenceRuntime(input.execSql);\n const [pendingRows, localRows] = await Promise.all([\n db\n .select({\n byteLength: documentPendingAttachments.byteLength,\n createdAt: documentPendingAttachments.createdAt,\n localId: documentPendingAttachments.localId,\n mimeType: documentPendingAttachments.mimeType,\n name: documentPendingAttachments.name,\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n })\n .from(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, input.localId))\n .orderBy(\n documentPendingAttachments.createdAt,\n documentPendingAttachments.slotId,\n ),\n db\n .select({\n blobId: documentAttachmentBlobProjection.blobId,\n byteLength: documentAttachmentBlobProjection.byteLength,\n localId: documentAttachmentBlobProjection.localId,\n mimeType: documentAttachmentBlobProjection.mimeType,\n slotId: documentAttachmentBlobProjection.slotId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n updatedAt: documentAttachmentBlobProjection.updatedAt,\n })\n .from(documentAttachmentBlobProjection)\n .where(\n and(\n eq(documentAttachmentBlobProjection.localId, input.localId),\n // Unlinked slots keep their row as a pending-detach marker; the\n // document no longer has the attachment, so do not report it.\n isNull(documentAttachmentBlobProjection.detachedAt),\n ),\n )\n .orderBy(\n documentAttachmentBlobProjection.updatedAt,\n documentAttachmentBlobProjection.slotId,\n ),\n ]);\n\n return [\n ...pendingRows.map(mapPendingAttachmentRow),\n ...localRows.map(mapLocalAttachmentRow),\n ];\n}\n\nasync function loadLocalDocumentInfo(input: {\n execSql: ExecSql | null;\n localId: string;\n}): Promise<{\n attachments: DocumentInfoAttachment[];\n contentSnapshot: string | null;\n local: DocumentInfoLocalDetails;\n}> {\n const fallback = {\n attachments: [],\n contentSnapshot: null,\n local: {\n accessEpoch: null,\n accessStateHash: null,\n containerId: null,\n documentId: null,\n documentKind: null,\n hasContentKeyBundle: false,\n hasDocumentKekTargets: false,\n hasDocumentManifestBundle: false,\n lastCommitLsn: null,\n localDocumentManifestHash: null,\n localId: input.localId,\n pendingAttachmentByteLength: 0,\n pendingAttachmentCount: 0,\n pendingUpdateCount: 0,\n title: null,\n updatedAt: null,\n },\n };\n\n if (!input.execSql) {\n return fallback;\n }\n\n await sqlDocumentsPersistence.ensureSchema(input.execSql);\n const { db } = getClientSQLitePersistenceRuntime(input.execSql);\n const [document, pendingUpdates, attachments, projectionRows, contentDoc] =\n await Promise.all([\n sqlDocumentsPersistence.loadDocument(input.execSql, input.localId),\n sqlDocumentsPersistence.listPendingUpdates(input.execSql, input.localId),\n loadDocumentInfoAttachments({\n execSql: input.execSql,\n localId: input.localId,\n }),\n db\n .select({ updatedAt: documentProjection.updatedAt })\n .from(documentProjection)\n .where(eq(documentProjection.localId, input.localId))\n .limit(1),\n loadPersistedDocumentContent({\n execSql: input.execSql,\n localId: input.localId,\n persistence: sqlDocumentsPersistence,\n }).catch(() => null),\n ]);\n\n if (!document) {\n return fallback;\n }\n\n const pendingAttachments = attachments.filter(\n (attachment) => attachment.attachmentKind === \"pending\",\n );\n\n return {\n attachments,\n // Blame reads op-level provenance out of a serialized snapshot; export the\n // durable-history content for it. Degrades to null (blame unavailable)\n // rather than failing the Info panel.\n contentSnapshot: contentDoc\n ? bytesToBase64(exportFullHistorySnapshot(contentDoc))\n : null,\n local: {\n accessEpoch: document.accessEpoch,\n accessStateHash: document.accessStateHash ?? null,\n containerId: document.containerId,\n documentId: document.documentId,\n documentKind: document.documentKind ?? DEFAULT_DOCUMENT_KIND,\n hasContentKeyBundle: Boolean(document.contentKeyBundle),\n hasDocumentKekTargets: Boolean(document.documentKekTargets),\n hasDocumentManifestBundle: Boolean(document.documentManifestBundle),\n lastCommitLsn: document.lastCommitLsn ?? null,\n localDocumentManifestHash: readStoredManifestHash(\n document.documentManifestBundle,\n ),\n localId: document.id,\n pendingAttachmentByteLength: pendingAttachments.reduce(\n (total, attachment) => total + attachment.byteLength,\n 0,\n ),\n pendingAttachmentCount: pendingAttachments.length,\n pendingUpdateCount: pendingUpdates.length,\n title: document.title ?? null,\n updatedAt: projectionRows[0]?.updatedAt ?? null,\n },\n };\n}\n\nfunction shouldLoadRemoteDocumentInfo(input: {\n local: DocumentInfoLocalDetails;\n remoteInfoMode: DocumentInfoRemoteMode;\n}): boolean {\n return input.remoteInfoMode !== \"never\" && Boolean(input.local.documentId);\n}\n\nfunction mapAttachmentBinding(\n binding: BlobAttachmentSummary,\n): DocumentInfoRemoteAttachmentBinding {\n return {\n bindingId: binding.bindingId,\n blobId: binding.blobId,\n slotId: binding.slotId,\n };\n}\n\nfunction mapAuthorizingContainerPath(\n projection: ContainerKeyingPathResponse,\n): DocumentInfoAuthorizingContainerPath {\n const leafBundle = projection.path.at(-1);\n const leafKek = projection.containerKeks.at(-1);\n\n return {\n containerId: projection.containerId,\n containerKeyEpoch: leafKek?.containerKeyEpoch ?? null,\n containerKeyEpochId: leafKek?.containerKeyEpochId ?? null,\n leafManifestHash: leafBundle?.manifestHash ?? null,\n organizationId: projection.organizationId,\n pathLength: projection.path.length,\n };\n}\n\nfunction getDocumentInfoRemoteDetails(input: {\n attachmentBindings: ReadonlyArray<BlobAttachmentSummary>;\n attribution: DocumentEditAttributionResponse | null;\n blameRanges: DocumentBlameRange[] | null;\n characterBlame: DocumentCharacterBlameSummary | null;\n contributors: DocumentContributor[];\n fieldBlame: DocumentFieldBlame[] | null;\n projection: DocumentWriterProjectionResponse;\n}): DocumentInfoRemoteDetails {\n const {\n attachmentBindings,\n attribution,\n blameRanges,\n characterBlame,\n contributors,\n fieldBlame,\n projection,\n } = input;\n const manifestState = projection.documentManifest.state;\n const manifest = projection.documentManifest.manifest;\n\n return {\n activeAttachmentBindings: attachmentBindings.map(mapAttachmentBinding),\n attributionRevision: attribution?.attributionRevision ?? null,\n attributionStatus: attribution\n ? attribution.truncated\n ? \"truncated\"\n : \"available\"\n : \"unavailable\",\n attributionSegments: attribution?.segments ?? [],\n authorizingContainerPaths: projection.authorizingContainerPaths.map(\n mapAuthorizingContainerPath,\n ),\n blameRanges,\n characterBlame,\n fieldBlame,\n contentKeyEpoch: projection.contentKeyBundle.contentKeyEpoch,\n contentKeyTargetCount: projection.contentKeyBundle.targets.length,\n contentKeyTargetHash: projection.contentKeyBundle.targetHash,\n contributors,\n currentManifestHash: projection.documentManifest.manifestHash,\n documentContainerManifestHistoryCount:\n projection.documentContainerManifestHistory.length,\n documentKekTargetCount: projection.documentKekTargets.targets.length,\n documentKeyTargetHash: projection.documentKekTargets.documentKeyTargetHash,\n documentManifestContainerPathCount:\n projection.documentManifestContainerPaths.length,\n documentManifestHistoryCount: projection.documentManifestHistory.length,\n linkedContainerKeyEpochCount:\n projection.documentKekTargets.linkedContainerKeyEpochIds.length,\n linkedContainerManifestCount:\n projection.documentKekTargets.linkedContainerManifestHashes.length,\n linkSetManifestHash: projection.documentKekTargets.linkSetManifestHash,\n manifestEpoch: readRecordNumber(manifest, \"epoch\"),\n previousManifestHash: readRecordString(\n manifestState,\n \"previousManifestHash\",\n ),\n referencedPrincipalCount: readRecordArrayLength(\n manifest,\n \"referencedPrincipalHeads\",\n ),\n };\n}\n\nexport async function loadDocumentInfo(input: {\n apiClient: DocumentInfoApi;\n attributionRequestKey?: string | undefined;\n execSql?: ExecSql | null;\n localId: string;\n reportSecurityIncident: SecurityIncidentReporter;\n remoteInfoMode?: DocumentInfoRemoteMode | undefined;\n}): Promise<DocumentInfo> {\n const { attachments, contentSnapshot, local } = await loadLocalDocumentInfo({\n execSql: input.execSql ?? null,\n localId: input.localId,\n });\n\n if (\n !shouldLoadRemoteDocumentInfo({\n local,\n remoteInfoMode: input.remoteInfoMode ?? \"if-synced\",\n }) ||\n !local.documentId\n ) {\n return { attachments, local, remoteInfo: null };\n }\n\n const attributionPromise = input.apiClient\n .getDocumentEditAttribution(local.documentId, input.attributionRequestKey)\n .catch(async (error: unknown) => {\n await reportAndRethrowKeyingVerificationError(\n error,\n input.reportSecurityIncident,\n {\n objectId: local.documentId ?? input.localId,\n objectKind: \"document\",\n operation: \"document.info.attribution\",\n },\n );\n return null;\n });\n const [projection, attachmentBindings, attribution] = await Promise.all([\n input.apiClient.getDocumentWriterProjection(local.documentId),\n input.apiClient.listDocumentAttachments(local.documentId),\n // Attribution is supplementary: a rejection (network/server) must not block\n // the rest of the document-info load, so swallow it to null (no contributors).\n attributionPromise,\n ]);\n\n if (!projection) {\n throw new Error(\n `Document info projection was unavailable for local document ${input.localId} with remote document ${local.documentId}.`,\n );\n }\n\n const attributionComplete = attribution && !attribution.truncated;\n const attributionSegments = attribution?.segments ?? [];\n const blame = attributionComplete\n ? computeDocumentBlame(contentSnapshot, attributionSegments)\n : null;\n return {\n attachments,\n local,\n remoteInfo: getDocumentInfoRemoteDetails({\n attachmentBindings: attachmentBindings ?? [],\n attribution,\n blameRanges: blame?.blameRanges ?? null,\n characterBlame: blame?.characterBlame ?? null,\n contributors: attributionComplete\n ? summarizeDocumentContributors(attributionSegments)\n : [],\n fieldBlame: attributionComplete\n ? computeFieldBlame(contentSnapshot, attributionSegments)\n : null,\n projection,\n }),\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentInfoTypes.js","sourceRoot":"","sources":["documentInfoTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentEditAttributionResponse } from \"@tearleads/validators/response\";\nimport type { StoredDocumentKind } from \"../../data/documents/documentKinds\";\nimport type {\n DocumentBlameRange,\n DocumentCharacterBlameSummary,\n DocumentContributor,\n DocumentFieldBlame,\n} from \"../../data/documents/editAttribution\";\n\nexport type DocumentInfoRemoteMode = \"if-synced\" | \"never\";\n\nexport interface DocumentInfoLocalDetails {\n accessEpoch: number | null;\n accessStateHash: string | null;\n containerId: string | null;\n documentId: string | null;\n documentKind: StoredDocumentKind | null;\n hasContentKeyBundle: boolean;\n hasDocumentKekTargets: boolean;\n hasDocumentManifestBundle: boolean;\n lastCommitLsn: string | null;\n localDocumentManifestHash: string | null;\n localId: string;\n pendingAttachmentByteLength: number;\n pendingAttachmentCount: number;\n pendingUpdateCount: number;\n title: string | null;\n updatedAt: string | null;\n}\n\nexport interface DocumentInfoAttachment {\n attachmentKind: \"local\" | \"pending\";\n blobId: string | null;\n byteLength: number;\n createdAt: string | null;\n localId: string;\n mimeType: string | null;\n name: string | null;\n slotId: string;\n storageKey: string;\n updatedAt: string | null;\n}\n\nexport interface DocumentInfoRemoteAttachmentBinding {\n bindingId: string;\n blobId: string;\n slotId: string;\n}\n\nexport interface DocumentInfoAuthorizingContainerPath {\n containerId: string;\n containerKeyEpoch: number | null;\n containerKeyEpochId: string | null;\n leafManifestHash: string | null;\n organizationId: string;\n pathLength: number;\n}\n\nexport interface DocumentInfoRemoteDetails {\n activeAttachmentBindings: DocumentInfoRemoteAttachmentBinding[];\n attributionRevision: number | null;\n attributionStatus: \"available\" | \"truncated\" | \"unavailable\";\n attributionSegments: DocumentEditAttributionResponse[\"segments\"];\n authorizingContainerPaths: DocumentInfoAuthorizingContainerPath[];\n /**\n * Contiguous per-writer runs of the current prose — the read-only \"blame\"\n * view that tints each phrase by who wrote it. Shares its `null` conditions\n * (and its single snapshot reconstruction) with {@link characterBlame}.\n */\n blameRanges: DocumentBlameRange[] | null;\n /**\n * Per-writer live-character blame, or `null` when it could not be computed —\n * the document has no local snapshot, the snapshot is too large to extract\n * op ids from cheaply, or the snapshot was unreadable.\n */\n characterBlame: DocumentCharacterBlameSummary | null;\n /**\n * Per-field blame for a structured document (who last set each field), or\n * `null` when it could not be computed. A note yields `[]` (no fields).\n */\n fieldBlame: DocumentFieldBlame[] | null;\n contentKeyEpoch: number;\n contentKeyTargetCount: number;\n contentKeyTargetHash: string;\n contributors: DocumentContributor[];\n currentManifestHash: string;\n documentContainerManifestHistoryCount: number;\n documentKekTargetCount: number;\n documentKeyTargetHash: string;\n documentManifestContainerPathCount: number;\n documentManifestHistoryCount: number;\n linkedContainerKeyEpochCount: number;\n linkedContainerManifestCount: number;\n linkSetManifestHash: string;\n manifestEpoch: number | null;\n previousManifestHash: string | null;\n referencedPrincipalCount: number | null;\n}\n\nexport interface DocumentInfo {\n attachments: DocumentInfoAttachment[];\n local: DocumentInfoLocalDetails;\n remoteInfo: DocumentInfoRemoteDetails | null;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentLinkIntent.js","sourceRoot":"","sources":["documentLinkIntent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { uniqueSortedStrings } from \"../../data/documents/shared/readers\";\nimport { sqlDocumentMoveIntentPersistence } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { sqlDocumentContainerProjectionPersistence as links } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { defaultDocumentsPersistence } from \"../documents\";\nimport { relinkContainerDocumentLocally } from \"./documentLocalRelink\";\nimport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationLocalStore,\n DocumentStructuralMutationRuntime,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\nexport async function addDocumentLinkLocally<TRuntime>(input: {\n currentDocumentStore: DocumentStructuralMutationLocalStore<TRuntime>;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary & { documentId: string; containerId: string };\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { note, runtime, targetContainerId } = input;\n const persisted = await defaultDocumentsPersistence.loadDocument(\n runtime.infra.execSql,\n note.id,\n );\n if (!persisted) return null;\n const intentId = crypto.randomUUID();\n let linkedContainerIds: readonly string[] = [];\n const linkedNote = await relinkContainerDocumentLocally({\n ...input,\n accessEpoch: persisted.accessEpoch,\n requestSync: false,\n targetContainerId: note.containerId,\n commitSideEffect: async (execSql) => {\n const currentLinks = await links.listLinkedContainerIds(\n execSql,\n note.documentId,\n );\n linkedContainerIds = uniqueSortedStrings([\n ...currentLinks,\n note.containerId,\n targetContainerId,\n ]);\n await sqlDocumentMoveIntentPersistence.enqueueLinkIntent(execSql, {\n id: intentId,\n documentId: note.documentId,\n localId: note.id,\n sourceContainerId: note.containerId,\n targetContainerId,\n });\n await links.replaceDocumentLinks(\n execSql,\n note.documentId,\n linkedContainerIds,\n { moveIntentId: intentId },\n );\n },\n });\n if (!linkedNote) return null;\n input.setLinkedContainerIdsForDocument(note.documentId, linkedContainerIds);\n input.scheduleSync?.();\n runtime.util.log(\n `Container contents: queued note ${note.id} link to ${targetContainerId}`,\n );\n return linkedNote;\n}\n\nexport async function removeDocumentLinkLocally<TRuntime>(\n input: Omit<\n Parameters<typeof addDocumentLinkLocally<TRuntime>>[0],\n \"targetContainerId\"\n > & { removedContainerId: string },\n): Promise<DocumentSummary | null> {\n const { note, runtime, removedContainerId } = input;\n const execSql = runtime.infra.execSql;\n const persisted = await defaultDocumentsPersistence.loadDocument(\n execSql,\n note.id,\n );\n if (!persisted) return null;\n const currentLinks = await links.listLinkedContainerIds(\n execSql,\n note.documentId,\n );\n const remaining = currentLinks.filter((id) => id !== removedContainerId);\n const nextContainerId = remaining.includes(note.containerId)\n ? note.containerId\n : remaining[0];\n if (!nextContainerId || !currentLinks.includes(removedContainerId))\n return null;\n const intentId = crypto.randomUUID();\n let linkedContainerIds: readonly string[] = [];\n const unlinkedNote = await relinkContainerDocumentLocally({\n ...input,\n accessEpoch: persisted.accessEpoch,\n requestSync: false,\n targetContainerId: nextContainerId,\n commitSideEffect: async (transactionExecSql) => {\n linkedContainerIds = (\n await links.listLinkedContainerIds(transactionExecSql, note.documentId)\n ).filter((id) => id !== removedContainerId);\n if (!linkedContainerIds.includes(nextContainerId))\n throw new Error(\"Document placement changed before unlink\");\n await sqlDocumentMoveIntentPersistence.enqueueUnlinkIntent(\n transactionExecSql,\n {\n id: intentId,\n documentId: note.documentId,\n localId: note.id,\n removedContainerId,\n targetContainerId: nextContainerId,\n },\n );\n await links.replaceDocumentLinks(\n transactionExecSql,\n note.documentId,\n linkedContainerIds,\n { moveIntentId: intentId },\n );\n },\n });\n if (!unlinkedNote) return null;\n input.setLinkedContainerIdsForDocument(note.documentId, linkedContainerIds);\n input.scheduleSync?.();\n return unlinkedNote;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentLinks.js","sourceRoot":"","sources":["documentLinks.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VerifiedDocumentLinkSetManifest } from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n assertDocumentWriterProjectionConsistent,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"../../data/documents/shared/projection\";\nimport { persistedDocumentCreateStateFromWriterProjection } from \"../../data/documents/shared/responses\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { errorMessage } from \"../../data/shared/errorMessage\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { isDatabaseUnavailableError } from \"../../data/sync/databaseUnavailable\";\nimport {\n type DocumentLinkSetFailureHandler,\n type RelinkRemoteDocumentResult,\n relinkRemoteDocument,\n resolveDocumentCreateAuthor,\n} from \"../documents\";\nimport type { SubtreePurgeRoot } from \"../documents/subtreePurgeScope\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../principals/runtimePolicyWarmer\";\nimport { resolveContainerDocumentMoveUnlinkIds } from \"./documentMoveUnlinkIds\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\ntype ContainerDocumentLinkApi = Parameters<\n typeof relinkRemoteDocument\n>[0][\"apiClient\"];\ntype ContainerDocumentLinkOperation = Parameters<\n typeof relinkRemoteDocument\n>[0][\"operation\"];\ntype RemoteDocumentPersistedState =\n RelinkRemoteDocumentResult[\"persistedState\"];\n\n// A cold-cache denial must keep its HTTP status: collapsing a 403 to null\n// would leave an access-denied move routinely retriable instead of parking\n// it for the access-restored signal (row 7).\nasync function fetchMoveWriterProjection(input: {\n documentId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n runtime: ContainerDocumentLinkRuntime;\n}): Promise<Awaited<\n ReturnType<ContainerDocumentLinkApi[\"getDocumentWriterProjection\"]>\n> | null> {\n const { apiClient } = input.runtime;\n const result = await apiClient.getDocumentWriterProjectionResult(\n input.documentId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n result.report();\n input.onFailure?.({ message: result.message, status: result.status });\n return null;\n}\n\ninterface ContainerDocumentLinkRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n apiClient: ContainerDocumentLinkApi &\n Pick<\n ContainerContentsWorkflowRuntime[\"apiClient\"],\n \"getPrincipalPolicyPages\" | \"getProjectionPolicyHistoryPages\"\n >;\n}\n\ntype MoveRemoteContainerDocumentStatus = \"complete\" | \"partial\";\n\ninterface MoveRemoteContainerDocumentResult {\n accessEpoch: number | null;\n accessStateHash: string | null;\n linkedContainerIds: readonly string[];\n nextContainerId: string;\n remoteState: RemoteDocumentPersistedState | null;\n status: MoveRemoteContainerDocumentStatus;\n}\n\nexport type { RemoteDocumentPersistedState };\n\nexport async function initializeDocumentLinksSchema(\n execSql: ExecSql,\n): Promise<void> {\n await sqlDocumentContainerProjectionPersistence.ensureSchema(execSql);\n}\n\nexport async function listDocumentLinkedContainerIds(\n execSql: ExecSql,\n documentId: string,\n): Promise<ReadonlyArray<string>> {\n return sqlDocumentContainerProjectionPersistence.listLinkedContainerIds(\n execSql,\n documentId,\n );\n}\n\nexport async function replaceDocumentLinks(\n execSql: ExecSql,\n documentId: string,\n containerIds: ReadonlyArray<string>,\n): Promise<void> {\n await sqlDocumentContainerProjectionPersistence.replaceDocumentLinks(\n execSql,\n documentId,\n containerIds,\n );\n}\n\nfunction resolveActiveDocumentContainerId(\n linkedContainerIds: ReadonlyArray<string>,\n preferredContainerId: string,\n): string | null {\n if (linkedContainerIds.includes(preferredContainerId)) {\n return preferredContainerId;\n }\n\n return linkedContainerIds[0] ?? null;\n}\n\nfunction containerDocumentMoveResult(input: {\n document: RelinkRemoteDocumentResult;\n nextContainerId: string;\n status: MoveRemoteContainerDocumentStatus;\n}): MoveRemoteContainerDocumentResult {\n return {\n accessEpoch: input.document.plan.state.epoch,\n accessStateHash: input.document.response.accessManifest.manifestHash,\n linkedContainerIds: input.document.linkedContainerIds,\n nextContainerId: input.nextContainerId,\n remoteState: input.document.persistedState,\n status: input.status,\n };\n}\n\nasync function containerDocumentAlreadyMovedResult(input: {\n writerProjection: DocumentWriterProjectionResponse;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerDocumentLinkRuntime;\n isCurrent?: (() => boolean) | undefined;\n linkedContainerIds: readonly string[];\n nextContainerId: string;\n status: MoveRemoteContainerDocumentStatus;\n}): Promise<MoveRemoteContainerDocumentResult> {\n const verified: { head?: VerifiedDocumentLinkSetManifest | undefined } = {};\n await assertDocumentWriterProjectionConsistent(input.writerProjection, {\n execSql: input.runtime.infra.execSql,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.isCurrent,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n onVerifiedAuthorization: (authorization) => {\n verified.head = authorization.documentManifestByHash.get(\n input.writerProjection.documentManifest.manifestHash,\n );\n },\n });\n if (!verified.head)\n throw new Error(\"Move replay lacks a verified document head\");\n return {\n accessEpoch: verified.head.state.epoch,\n accessStateHash: verified.head.manifestHash,\n linkedContainerIds: input.linkedContainerIds,\n nextContainerId: input.nextContainerId,\n remoteState: persistedDocumentCreateStateFromWriterProjection(\n input.writerProjection,\n ),\n status: input.status,\n };\n}\n\n/**\n * Hand a link/unlink/move/purge failure to host diagnostics as a real `Error`.\n * The caller's string-only log line stays the fallback for a host without\n * `logError`, so this never logs a second copy of the same failure.\n */\nfunction reportDocumentLinkMutationFailure(\n util: ContainerDocumentLinkRuntime[\"util\"],\n error: unknown,\n): void {\n // `ApiClient` returns `RequestFailure` objects instead of throwing, so\n // offline and 403/404/409 already left through the `!result` branch: a status\n // filter here would be dead code. Only a database lost mid-flight stays quiet.\n if (!util.logError || isDatabaseUnavailableError(error)) return;\n try {\n // A host logger that throws or rejects must not replace the null result or\n // skip the failure handler below.\n void Promise.resolve(\n util.logError(\"Container contents: document link mutation failed\", error),\n ).catch(() => undefined);\n } catch {\n // Hosts may throw synchronously or return a rejected promise.\n }\n}\n\nexport async function relinkRemoteContainerDocument(input: {\n beforeSubmit?: (() => Promise<boolean>) | undefined;\n documentId: string;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n operation: ContainerDocumentLinkOperation;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot?: Uint8Array | undefined;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<RelinkRemoteDocumentResult | null> {\n const {\n documentId,\n noteId,\n operation,\n resolveProjectionUserKey,\n runtime,\n targetContainerId,\n } = input;\n const author = resolveDocumentCreateAuthor(runtime);\n const targetSecretKey = runtime.crypto.encapsulationKeyPair?.secretKey;\n const execSql = runtime.infra.execSql;\n if (input.isCurrent?.() === false) return null;\n if (!author || !targetSecretKey) {\n runtime.util.log(\n \"Container contents: document mutation skipped because the local key context is unavailable\",\n );\n input.onFailure?.({\n message: \"the local key context is unavailable\",\n status: null,\n });\n return null;\n }\n\n try {\n const result = await relinkRemoteDocument({\n beforeSubmit: input.beforeSubmit,\n apiClient: runtime.apiClient,\n author,\n documentId,\n expectedSubtreeRoot: input.expectedSubtreeRoot,\n execSql,\n onFailure: input.onFailure,\n operation,\n resolveProjectionUserKey,\n rotationSnapshot: input.rotationSnapshot,\n stillCurrent: input.isCurrent,\n targetContainerId,\n targetSecretKey,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!result) {\n runtime.util.log(\n `Container contents: failed to ${operation} note ${noteId} ${operation === \"link\" ? \"to\" : \"from\"} container ${targetContainerId}`,\n );\n return null;\n }\n if (input.isCurrent?.() === false) return null;\n\n await sqlDocumentContainerProjectionPersistence.replaceDocumentLinks(\n execSql,\n documentId,\n result.linkedContainerIds,\n { stillCurrent: input.isCurrent },\n );\n\n return result;\n } catch (error) {\n await reportAndRethrowKeyingVerificationError(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: documentId,\n objectKind: \"document\",\n operation: `document.${operation}`,\n },\n );\n const message = errorMessage(error);\n runtime.util.log(\n `Container contents: failed to ${operation} note ${noteId} ${operation === \"link\" ? \"to\" : \"from\"} container ${targetContainerId}: ${message}`,\n );\n // After the keying rethrow above, so a verification failure keeps its\n // security incident instead of being reported twice, and before the failure\n // handler, so a throwing caller callback cannot swallow the report.\n reportDocumentLinkMutationFailure(runtime.util, error);\n input.onFailure?.({ message, status: null });\n return null;\n }\n}\n\nasync function linkRemoteContainerDocument(input: {\n documentId: string;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<RelinkRemoteDocumentResult | null> {\n return relinkRemoteContainerDocument({\n ...input,\n operation: \"link\",\n });\n}\n\nexport async function unlinkRemoteContainerDocument(input: {\n beforeSubmit?: (() => Promise<boolean>) | undefined;\n documentId: string;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot: Uint8Array;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<RelinkRemoteDocumentResult | null> {\n return relinkRemoteContainerDocument({\n ...input,\n operation: \"unlink\",\n });\n}\n\nexport async function moveRemoteContainerDocument(input: {\n linkOnly?: boolean | undefined;\n additionalLinkContainerIds?: readonly string[] | undefined;\n removedLinkContainerIds?: readonly string[] | undefined;\n currentContainerId: string;\n documentId: string;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n replaceLinkedContainers?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot: Uint8Array;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<MoveRemoteContainerDocumentResult | null> {\n const {\n documentId,\n noteId,\n resolveProjectionUserKey,\n runtime,\n targetContainerId,\n } = input;\n if (input.isCurrent?.() === false) return null;\n const writerProjection = await fetchMoveWriterProjection({\n documentId,\n onFailure: input.onFailure,\n runtime,\n });\n if (!writerProjection || input.isCurrent?.() === false) {\n return null;\n }\n if (writerProjection.documentId !== documentId)\n throw new Error(\"Move replay document id mismatch\");\n const initialLinkedContainerIds =\n readLinkedContainerIdsFromDocumentManifest(writerProjection);\n\n let latestLinkedContainerIds: readonly string[] = initialLinkedContainerIds;\n let latestDocument: RelinkRemoteDocumentResult | null = null;\n for (const linkTarget of new Set([\n ...(input.linkOnly ? [] : [targetContainerId]),\n ...(input.additionalLinkContainerIds ?? []),\n ])) {\n if (latestLinkedContainerIds.includes(linkTarget)) continue;\n const linkedDocument = await linkRemoteContainerDocument({\n documentId,\n isCurrent: input.isCurrent,\n noteId,\n onFailure: input.onFailure,\n resolveProjectionUserKey,\n runtime,\n targetContainerId: linkTarget,\n });\n if (!linkedDocument || input.isCurrent?.() === false) {\n return null;\n }\n\n latestDocument = linkedDocument;\n latestLinkedContainerIds = linkedDocument.linkedContainerIds;\n }\n\n const unlinkContainerIds = resolveContainerDocumentMoveUnlinkIds({\n ...input,\n linkedContainerIds: latestLinkedContainerIds,\n });\n\n const unlinked = await unlinkMovedDocumentSources({\n ...input,\n latestDocument,\n latestLinkedContainerIds,\n unlinkContainerIds,\n });\n if (!unlinked) return null;\n latestDocument = unlinked.latestDocument;\n latestLinkedContainerIds = unlinked.latestLinkedContainerIds;\n\n const nextContainerId = resolveActiveDocumentContainerId(\n latestLinkedContainerIds,\n targetContainerId,\n );\n if (!nextContainerId) {\n return null;\n }\n\n const status =\n unlinked.failedUnlinkContainerIds.length > 0 ? \"partial\" : \"complete\";\n return latestDocument\n ? containerDocumentMoveResult({\n document: latestDocument,\n nextContainerId,\n status,\n })\n : containerDocumentAlreadyMovedResult({\n writerProjection,\n resolveProjectionUserKey,\n runtime,\n isCurrent: input.isCurrent,\n linkedContainerIds: latestLinkedContainerIds,\n nextContainerId,\n status,\n });\n}\n\n// The unlink half of a move: every source is attempted even when an earlier\n// one fails, so one dead source cannot strand the others; a failed unlink\n// leaves the move \"partial\" for the queue to retry.\nasync function unlinkMovedDocumentSources(input: {\n documentId: string;\n isCurrent?: (() => boolean) | undefined;\n latestDocument: RelinkRemoteDocumentResult | null;\n latestLinkedContainerIds: readonly string[];\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot: Uint8Array;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n unlinkContainerIds: readonly string[];\n}): Promise<{\n failedUnlinkContainerIds: readonly string[];\n latestDocument: RelinkRemoteDocumentResult | null;\n latestLinkedContainerIds: readonly string[];\n} | null> {\n const { noteId, runtime, targetContainerId } = input;\n let { latestDocument, latestLinkedContainerIds } = input;\n const failedUnlinkContainerIds: string[] = [];\n for (const unlinkContainerId of input.unlinkContainerIds) {\n if (input.isCurrent?.() === false) return null;\n const unlinkedDocument = await unlinkRemoteContainerDocument({\n documentId: input.documentId,\n isCurrent: input.isCurrent,\n noteId,\n onFailure: input.onFailure,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n rotationSnapshot: input.rotationSnapshot,\n runtime,\n targetContainerId: unlinkContainerId,\n });\n if (input.isCurrent?.() === false) return null;\n if (!unlinkedDocument) {\n failedUnlinkContainerIds.push(unlinkContainerId);\n runtime.util.log(\n `Container contents: note ${noteId} was linked to ${targetContainerId} but failed to unlink from ${unlinkContainerId}`,\n );\n continue;\n }\n\n latestDocument = unlinkedDocument;\n latestLinkedContainerIds = unlinkedDocument.linkedContainerIds;\n }\n return { failedUnlinkContainerIds, latestDocument, latestLinkedContainerIds };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentLocalRelink.js","sourceRoot":"","sources":["documentLocalRelink.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAW,MAW9D;IACC,MAAM,EACJ,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,IAAI,EACJ,IAAI,EACJ,WAAW,EACX,WAAW,EACX,OAAO,EACP,iBAAiB,GAClB,GAAG,MAAM,CAAC;IAEX,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC;QACrD,WAAW;QACX,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7D,WAAW,EAAE,iBAAiB;QAC9B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,GAAG,WAAW;QACd,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,OAAO,EAAE,IAAI,CAAC,EAAE;KACjB,CAAC,CAAC;IACH,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,GAAG,CACd,4BAA4B,IAAI,CAAC,EAAE,oDAAoD,CACxF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACxC,oBAAoB,CAAC,aAAa,CAChC,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAChD,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,oBAAoB,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport type { RemoteDocumentPersistedState } from \"./documentLinks\";\nimport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationLocalStore,\n DocumentStructuralMutationRelinkInput,\n DocumentStructuralMutationRuntime,\n} from \"./documentStructureTypes\";\n\nexport async function relinkContainerDocumentLocally<TRuntime>(params: {\n accessEpoch: number;\n commitSideEffect?: DocumentStructuralMutationRelinkInput[\"commitSideEffect\"];\n accessStateHash?: string | null | undefined;\n currentDocumentStore: DocumentStructuralMutationLocalStore<TRuntime>;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n remoteState?: RemoteDocumentPersistedState | undefined;\n requestSync: boolean;\n runtime: DocumentStructuralMutationRuntime;\n targetContainerId: string;\n}) {\n const {\n accessEpoch,\n accessStateHash,\n currentDocumentStore,\n host,\n note,\n remoteState,\n requestSync,\n runtime,\n targetContainerId,\n } = params;\n\n const relinkedNote = await currentDocumentStore.relink({\n accessEpoch,\n ...(accessStateHash === undefined ? {} : { accessStateHash }),\n containerId: targetContainerId,\n commitSideEffect: params.commitSideEffect,\n ...remoteState,\n documentId: note.documentId,\n localId: note.id,\n });\n if (!relinkedNote) {\n runtime.util.log(\n `Container contents: note ${note.id} could not be relinked after a structural mutation`,\n );\n return null;\n }\n\n host.mergeDocumentSummary(relinkedNote);\n currentDocumentStore.updateRuntime(\n host.documentWorkflowRuntime(targetContainerId),\n );\n if (requestSync) {\n currentDocumentStore.requestSync();\n }\n return relinkedNote;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveDeniedReplay.js","sourceRoot":"","sources":["documentMoveDeniedReplay.ts"],"names":[],"mappings":"AAaA,+EAA+E;AAC/E,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,yEAAyE;AACzE,8CAA8C;AAC9C,MAAM,6BAA6B,GAAG,IAAI,OAAO,EAG9C,CAAC;AAEJ,MAAM,UAAU,6BAA6B,CAC3C,KAA4B,EAC5B,OAAgB;IAEhB,MAAM,SAAS,GAAG,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3D,OAAO,CACL,SAAS,EAAE,OAAO,KAAK,OAAO;QAC9B,SAAS,CAAC,mBAAmB,KAAK,KAAK,CAAC,mBAAmB,CAC5D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAA4B,EAC5B,OAAgB;IAEhB,6BAA6B,CAAC,GAAG,CAAC,KAAK,EAAE;QACvC,OAAO;QACP,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;KAC/C,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\ntype ExecSql = ContainerContentsWorkflowRuntime[\"infra\"][\"execSql\"];\n\ninterface DeniedReplayLifecycle {\n readonly lifecycleGeneration?: number | undefined;\n}\n\ninterface DeniedReplayGeneration {\n execSql: ExecSql;\n lifecycleGeneration: number | undefined;\n}\n\n// One replay per store/database generation: parked denied intents flip back to\n// pending ahead of its first scan (row 7). A restart loses the in-memory\n// access-restored edge, and replacing the executor or lifecycle can expose a\n// different durable queue. Running inside the scan keeps ordering trivially\n// correct: replayed intents are attempted by this same pass, not stranded until\n// an unrelated trigger. Marked complete only after the reset lands, so a\n// transient failure retries on the next pass.\nconst deniedReplayGenerationByState = new WeakMap<\n DeniedReplayLifecycle,\n DeniedReplayGeneration\n>();\n\nexport function deniedReplayMatchesGeneration(\n state: DeniedReplayLifecycle,\n execSql: ExecSql,\n): boolean {\n const completed = deniedReplayGenerationByState.get(state);\n return (\n completed?.execSql === execSql &&\n completed.lifecycleGeneration === state.lifecycleGeneration\n );\n}\n\nexport function markDeniedReplayGeneration(\n state: DeniedReplayLifecycle,\n execSql: ExecSql,\n): void {\n deniedReplayGenerationByState.set(state, {\n execSql,\n lifecycleGeneration: state.lifecycleGeneration,\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveFailure.js","sourceRoot":"","sources":["documentMoveFailure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAsB3F,MAAM,UAAU,8BAA8B;IAC5C,OAAO;QACL,OAAO,EAAE,IAAI;QACb,mBAAmB,EAAE,KAAK;QAC1B,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAA+B,EAC/B,OAAuC;IAEvC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,KAAK,CAAC,mBAAmB;QACvB,KAAK,CAAC,mBAAmB,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,CAAC;IACtD,KAAK,CAAC,oBAAoB;QACxB,KAAK,CAAC,oBAAoB,IAAI,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACtE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC1C,KAA+B;IAE/B,MAAM,MAAM,GAAG,KAAK,CAAC,oBAAoB;QACvC,CAAC,CAAC,8DAA8D;QAChE,CAAC,CAAC,kDAAkD,CAAC;IACvD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GACV,OAAO,CAAC,MAAM,KAAK,IAAI;QACrB,CAAC,CAAC,OAAO,CAAC,OAAO;QACjB,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC;IAC/C,OAAO,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC;AAChC,CAAC","sourcesContent":["import { isVanishedContainerFailure } from \"../../data/containers/shared/mutationFailures\";\nimport type { DocumentLinkSetMutationFailure } from \"../documents\";\n\n/**\n * What a queued document move learned from its remote link/unlink attempts.\n * Every failure handed to the move's `onFailure` folds into this state; the\n * verdict (`pending`, `blocked`, `denied`) is read off it afterwards.\n */\nexport interface DocumentMoveFailureState {\n current: DocumentLinkSetMutationFailure | null;\n /** A 403 anywhere in the pass parks the intent as denied (row 7). */\n sawPermissionDenial: boolean;\n /**\n * The server proved a cited container no longer exists (coded projection\n * 404 or coded commit 409 `container_unavailable`). Retrying the SAME\n * request can never succeed — but the cited container may be a stale\n * ancestor in a cached path, so the verdict triggers a projection refresh\n * (documentMoveVanishedRefresh) before the intent parks terminally.\n */\n sawVanishedContainer: boolean;\n}\n\nexport function createDocumentMoveFailureState(): DocumentMoveFailureState {\n return {\n current: null,\n sawPermissionDenial: false,\n sawVanishedContainer: false,\n };\n}\n\nexport function recordDocumentMoveFailure(\n state: DocumentMoveFailureState,\n failure: DocumentLinkSetMutationFailure,\n): void {\n state.current = failure;\n state.sawPermissionDenial =\n state.sawPermissionDenial || failure.status === 403;\n state.sawVanishedContainer =\n state.sawVanishedContainer || isVanishedContainerFailure(failure);\n}\n\n/**\n * The queue-facing description of a failed remote move. The stable prefixes\n * are kept so existing consumers keep matching; the captured detail appends\n * the HTTP status when one was seen, so a revoked permission (403) reads\n * differently from an offline blip.\n */\nexport function describeRejectedDocumentMove(\n state: DocumentMoveFailureState,\n): string {\n const prefix = state.sawVanishedContainer\n ? \"Remote document move cites a container deleted on the server\"\n : \"Remote document move was rejected or unavailable\";\n const failure = state.current;\n if (!failure) {\n return prefix;\n }\n const detail =\n failure.status === null\n ? failure.message\n : `${failure.message} (${failure.status})`;\n return `${prefix}: ${detail}`;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveIntent.js","sourceRoot":"","sources":["documentMoveIntent.ts"],"names":[],"mappings":"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","sourcesContent":["import { DEFAULT_DOCUMENT_ACCESS_EPOCH } from \"../../data/documents/documentConstants\";\nimport type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { uniqueSortedStrings } from \"../../data/documents/shared/readers\";\nimport { sqlDocumentMoveIntentPersistence } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { defaultDocumentsPersistence } from \"../documents\";\nimport { listDocumentLinkedContainerIds } from \"./documentLinks\";\nimport { relinkContainerDocumentLocally } from \"./documentLocalRelink\";\nimport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationLocalStore,\n DocumentStructuralMutationRuntime,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\nasync function resolveOptimisticDocumentMoveLinks(input: {\n currentContainerId: string | null;\n documentId: string;\n replaceLinkedContainers?: boolean | undefined;\n runtime: DocumentStructuralMutationRuntime;\n targetContainerId: string;\n}): Promise<string[]> {\n if (input.replaceLinkedContainers) {\n return [input.targetContainerId];\n }\n\n const currentLinkedContainerIds = await listDocumentLinkedContainerIds(\n input.runtime.infra.execSql,\n input.documentId,\n );\n const linkedContainerIds =\n currentLinkedContainerIds.length > 0\n ? currentLinkedContainerIds\n : input.currentContainerId\n ? [input.currentContainerId]\n : [];\n\n return uniqueSortedStrings([\n ...linkedContainerIds.filter(\n (containerId) => containerId !== input.currentContainerId,\n ),\n input.targetContainerId,\n ]);\n}\n\nasync function resolveLocalMoveAccessEpoch(input: {\n localId: string;\n runtime: DocumentStructuralMutationRuntime;\n}): Promise<number> {\n const existingDocument = await defaultDocumentsPersistence.loadDocument(\n input.runtime.infra.execSql,\n input.localId,\n );\n // The local relink must keep the document's current key epoch. Falling back\n // is only for partially seeded local state; downgrading synced documents\n // would make offline edits use stale access material.\n return existingDocument?.accessEpoch ?? DEFAULT_DOCUMENT_ACCESS_EPOCH;\n}\n\nexport async function moveRemoteDocumentLinkLocally<TRuntime>(params: {\n currentDocumentStore: DocumentStructuralMutationLocalStore<TRuntime>;\n expandNode: (nodeId: string) => void;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary & { documentId: string };\n replaceLinkedContainers?: boolean | undefined;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<{ linksChanged: boolean; note: DocumentSummary | null }> {\n const {\n currentDocumentStore,\n expandNode,\n host,\n note,\n replaceLinkedContainers,\n runtime,\n scheduleSync,\n setLinkedContainerIdsForDocument,\n targetContainerId,\n } = params;\n const linkedContainerIds = await resolveOptimisticDocumentMoveLinks({\n currentContainerId: note.containerId,\n documentId: note.documentId,\n replaceLinkedContainers,\n runtime,\n targetContainerId,\n });\n\n // Apply the user's chosen placement locally now, then replay the signed\n // link-set mutation from this durable intent when auth/network/key context is\n // back. This mirrors container move intents: UI state should not wait on the\n // server, but the remote contract still converges through the normal writer\n // projection path.\n const intentId = crypto.randomUUID();\n\n const movedNote = await relinkContainerDocumentLocally({\n accessEpoch: await resolveLocalMoveAccessEpoch({\n localId: note.id,\n runtime,\n }),\n currentDocumentStore,\n host,\n note,\n commitSideEffect: async (execSql) => {\n await sqlDocumentMoveIntentPersistence.enqueueMoveIntent(execSql, {\n id: intentId,\n documentId: note.documentId,\n localId: note.id,\n replaceLinkedContainers,\n sourceContainerId: note.containerId,\n targetContainerId,\n });\n await sqlDocumentContainerProjectionPersistence.replaceDocumentLinks(\n execSql,\n note.documentId,\n linkedContainerIds,\n { moveIntentId: intentId },\n );\n },\n requestSync: false,\n runtime,\n targetContainerId,\n });\n if (!movedNote) {\n return { linksChanged: false, note: null };\n }\n\n setLinkedContainerIdsForDocument(note.documentId, linkedContainerIds);\n expandNode(targetContainerId);\n scheduleSync?.();\n runtime.util.log(\n `Container contents: queued note ${movedNote.id} move to ${targetContainerId}`,\n );\n return { linksChanged: true, note: movedNote };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveIntentErrors.js","sourceRoot":"","sources":["documentMoveIntentErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,yEAAyE,CAAC;AAG3H,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAU1D;IACC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,gCAAgC,CAAC,qBAAqB,CAC1D,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EACjC;QACE,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK,CAAC,SAAS;QAC7B,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CACF,CAAC;IACF,OAAO,KAAK,CAAC,SAAS,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["import { sqlDocumentMoveIntentPersistence } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\nexport async function recordPendingDocumentMoveIntentError(input: {\n blocked?: boolean | undefined;\n denied?: boolean | undefined;\n documentId: string;\n expectedIntentId?: string | undefined;\n expectedUpdatedAt?: string | undefined;\n isCurrent: () => boolean;\n message: string;\n state: { runtime: ContainerContentsWorkflowRuntime };\n unavailable?: boolean | undefined;\n}): Promise<boolean> {\n if (!input.isCurrent()) return false;\n await sqlDocumentMoveIntentPersistence.recordMoveIntentError(\n input.state.runtime.infra.execSql,\n {\n blocked: input.blocked,\n denied: input.denied,\n documentId: input.documentId,\n expectedIntentId: input.expectedIntentId,\n expectedUpdatedAt: input.expectedUpdatedAt,\n message: input.message,\n stillCurrent: input.isCurrent,\n unavailable: input.unavailable,\n },\n );\n return input.isCurrent();\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveIntentSettlement.js","sourceRoot":"","sources":["documentMoveIntentSettlement.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gCAAgC,GACjC,MAAM,yEAAyE,CAAC;AACjF,OAAO,EAAE,yCAAyC,EAAE,MAAM,0EAA0E,CAAC;AACrI,OAAO,EAAE,yBAAyB,EAAE,MAAM,qDAAqD,CAAC;AAChG,OAAO,EAAE,iCAAiC,EAAE,MAAM,4CAA4C,CAAC;AAG/F,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,KAM9C;IACC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAC5C,iCAAiC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,EACnD,KAAK,CAAC,MAAM,CAAC,UAAU,CACxB,CAAC;QACF,IAAI,MAAM,EAAE,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE;YAChC,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;QACJ,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,gCAAgC,CAAC,oBAAoB,CACzE,KAAK,CAAC,OAAO,EACb;QACE,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;QACnC,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE;QACjC,iBAAiB,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS;KAC1C,CACF,CAAC;IACF,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,MAAM,yCAAyC,CAAC,oBAAoB,CAClE,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM,CAAC,UAAU,EACvB,KAAK,CAAC,kBAAkB,CACzB,CAAC;AACJ,CAAC","sourcesContent":["import {\n type DocumentMoveIntentRecord,\n sqlDocumentMoveIntentPersistence,\n} from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { loadDocumentMovePlacement } from \"../../data/persistence/containers/documentPlacement\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\nexport async function settleDocumentMoveIntent(input: {\n execSql: ExecSql;\n intent: DocumentMoveIntentRecord;\n isCurrent: () => boolean;\n linkedContainerIds: readonly string[];\n partial: boolean;\n}): Promise<void> {\n if (!input.isCurrent()) {\n throw new Error(\"Document move generation changed before local settlement\");\n }\n if (input.partial) {\n const intent = await loadDocumentMovePlacement(\n getClientSQLitePersistenceRuntime(input.execSql).db,\n input.intent.documentId,\n );\n if (intent?.id !== input.intent.id)\n throw new Error(\n \"Document move intent was superseded before local settlement\",\n );\n return;\n }\n const settled = await sqlDocumentMoveIntentPersistence.markMoveIntentSynced(\n input.execSql,\n {\n documentId: input.intent.documentId,\n expectedIntentId: input.intent.id,\n expectedUpdatedAt: input.intent.updatedAt,\n },\n );\n if (!settled || !input.isCurrent()) {\n throw new Error(\n \"Document move intent was superseded before local settlement\",\n );\n }\n await sqlDocumentContainerProjectionPersistence.replaceDocumentLinks(\n input.execSql,\n input.intent.documentId,\n input.linkedContainerIds,\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveIntentSync.js","sourceRoot":"","sources":["documentMoveIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { reportAndRethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport {\n DOCUMENT_LINK_INTENT_TYPE,\n type DocumentMoveIntentRecord,\n sqlDocumentMoveIntentPersistence,\n} from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { errorMessage } from \"../../data/shared/errorMessage\";\nimport {\n type DocumentLinkSetFailureHandler,\n type DocumentRecord,\n defaultDocumentsPersistence,\n} from \"../documents\";\nimport { availableDocumentLinkIntent } from \"./availableDocumentLinkIntent\";\nimport { moveRemoteContainerDocument } from \"./documentLinks\";\nimport {\n deniedReplayMatchesGeneration,\n markDeniedReplayGeneration,\n} from \"./documentMoveDeniedReplay\";\nimport {\n type DocumentMoveFailureState,\n describeRejectedDocumentMove,\n} from \"./documentMoveFailure\";\nimport { recordPendingDocumentMoveIntentError } from \"./documentMoveIntentErrors\";\nimport { settleDocumentMoveIntent } from \"./documentMoveIntentSettlement\";\nimport { moveWithVanishedContainerRefresh } from \"./documentMoveVanishedRefresh\";\nimport type {\n DocumentStructuralMutationLocalStore,\n DocumentStructuralMutationRelinkInput,\n} from \"./documentStructureTypes\";\nimport type { ContainerContentsProjectionUserKeyResolver } from \"./projectionKeys\";\nimport type { ContainerState } from \"./remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"./remoteHydration/reconciliation\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\ntype DocumentMoveIntentReplayResult =\n | \"abandoned\"\n | \"moved\"\n | \"partial\"\n | \"blocked\"\n | \"failed\";\n\nexport interface DocumentMoveIntentSyncHost<TRuntime> {\n documentWorkflowRuntime: (containerId: string) => TRuntime;\n openDocumentStore: (input: {\n containerId: string;\n documentId: string | null;\n localId: string;\n }) => DocumentStructuralMutationLocalStore<TRuntime>;\n}\n\ninterface DocumentMoveIntentSyncState {\n containersById: ReadonlyMap<string, ContainerState>;\n lifecycleGeneration?: number | undefined;\n resolveProjectionUserKey: ContainerContentsProjectionUserKeyResolver;\n runtime: ContainerContentsWorkflowRuntime;\n}\n\nasync function relinkMovedDocumentStore<TRuntime>(input: {\n host: DocumentMoveIntentSyncHost<TRuntime>;\n isCurrent: () => boolean;\n intent: DocumentMoveIntentRecord;\n relinkInput: DocumentStructuralMutationRelinkInput;\n targetContainerId: string;\n}): Promise<boolean> {\n if (!input.isCurrent()) return false;\n const documentStore = input.host.openDocumentStore({\n containerId: input.targetContainerId,\n documentId: input.intent.documentId,\n localId: input.intent.localId,\n });\n if (!(await documentStore.ensureInitialized()) || !input.isCurrent()) {\n return false;\n }\n\n const relinked = await documentStore.relink({\n ...input.relinkInput,\n stillCurrent: input.isCurrent,\n });\n if (!relinked || !input.isCurrent()) {\n return false;\n }\n\n documentStore.updateRuntime(\n input.host.documentWorkflowRuntime(input.targetContainerId),\n );\n return input.isCurrent();\n}\n\nasync function persistMovedDocumentReplay<TRuntime>(input: {\n host: DocumentMoveIntentSyncHost<TRuntime>;\n intent: DocumentMoveIntentRecord;\n isCurrent: () => boolean;\n moved: NonNullable<Awaited<ReturnType<typeof moveRemoteContainerDocument>>>;\n state: DocumentMoveIntentSyncState;\n}): Promise<boolean> {\n const { host, intent, moved, state } = input;\n const existingDocument = await defaultDocumentsPersistence.loadDocument(\n state.runtime.infra.execSql,\n intent.localId,\n );\n if (!input.isCurrent() || !existingDocument) {\n return false;\n }\n\n const targetContainerId =\n intent.intentType === DOCUMENT_LINK_INTENT_TYPE &&\n existingDocument.containerId &&\n moved.linkedContainerIds.includes(existingDocument.containerId)\n ? existingDocument.containerId\n : moved.nextContainerId;\n\n const relinkInput: DocumentStructuralMutationRelinkInput = {\n accessEpoch: moved.accessEpoch ?? existingDocument.accessEpoch,\n ...(moved.accessStateHash === null\n ? {}\n : { accessStateHash: moved.accessStateHash }),\n containerId: targetContainerId,\n documentId: intent.documentId,\n localId: intent.localId,\n ...(moved.remoteState ?? {}),\n commitSideEffect: (transactionExecSql) =>\n settleDocumentMoveIntent({\n execSql: transactionExecSql,\n intent,\n isCurrent: input.isCurrent,\n linkedContainerIds: moved.linkedContainerIds,\n partial: moved.status === \"partial\",\n }),\n };\n\n return relinkMovedDocumentStore({\n host,\n isCurrent: input.isCurrent,\n intent,\n relinkInput,\n targetContainerId,\n });\n}\n\nasync function assertMoveIntentRotationPreflight<TRuntime>(input: {\n existingContainerId: string | null | undefined;\n host: DocumentMoveIntentSyncHost<TRuntime>;\n isCurrent: () => boolean;\n intent: DocumentMoveIntentRecord;\n}): Promise<Uint8Array | null> {\n if (!input.isCurrent()) return null;\n const preflightStore = input.host.openDocumentStore({\n // The optimistic move already changed local placement. Use that scope so\n // opening the destination view cannot invalidate this shared store's proof.\n // Remote link-set authorization still uses the intent's source below.\n containerId: input.existingContainerId ?? input.intent.targetContainerId,\n documentId: input.intent.documentId,\n localId: input.intent.localId,\n });\n if (!(await preflightStore.ensureInitialized())) {\n throw new Error(\"Document rotation preflight could not load the document\");\n }\n if (!input.isCurrent()) return null;\n const rotationSnapshot = await preflightStore.assertCanRotateContentKey();\n return input.isCurrent() ? rotationSnapshot : null;\n}\n\nasync function movePendingDocumentIntent<TRuntime>(input: {\n existingContainerId: string | null | undefined;\n host: DocumentMoveIntentSyncHost<TRuntime>;\n isCurrent: () => boolean;\n intent: DocumentMoveIntentRecord;\n onFailure: DocumentLinkSetFailureHandler;\n state: DocumentMoveIntentSyncState;\n}) {\n // Adding links keeps the content key and needs no full-history rotation proof.\n const linkOnly = input.intent.intentType === DOCUMENT_LINK_INTENT_TYPE;\n const rotationSnapshot =\n linkOnly && !input.intent.removedLinkContainerIds?.length\n ? new Uint8Array()\n : await assertMoveIntentRotationPreflight(input);\n if (!rotationSnapshot || !input.isCurrent()) return \"abandoned\" as const;\n return moveRemoteContainerDocument({\n linkOnly,\n additionalLinkContainerIds: input.intent.additionalLinkContainerIds,\n removedLinkContainerIds: input.intent.removedLinkContainerIds,\n currentContainerId:\n input.intent.sourceContainerId ??\n input.existingContainerId ??\n input.intent.targetContainerId,\n documentId: input.intent.documentId,\n isCurrent: input.isCurrent,\n noteId: input.intent.localId,\n onFailure: input.onFailure,\n replaceLinkedContainers: input.intent.replaceLinkedContainers,\n resolveProjectionUserKey: input.state.resolveProjectionUserKey,\n rotationSnapshot,\n runtime: input.state.runtime,\n targetContainerId: input.intent.targetContainerId,\n });\n}\n\nasync function resolveMoveIntentPreflight(input: {\n isCreatePending: (containerId: string) => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n isCurrent: () => boolean;\n intent: DocumentMoveIntentRecord;\n state: DocumentMoveIntentSyncState;\n}): Promise<\n | { existingDocument: DocumentRecord; result?: undefined }\n | { existingDocument?: undefined; result: DocumentMoveIntentReplayResult }\n> {\n const { intent, state } = input;\n const execSql = state.runtime.infra.execSql;\n const existingDocument = await defaultDocumentsPersistence.loadDocument(\n execSql,\n intent.localId,\n );\n if (!input.isCurrent()) return { result: \"abandoned\" };\n if (!existingDocument || existingDocument.documentId !== intent.documentId) {\n await recordPendingDocumentMoveIntentError({\n blocked: true,\n documentId: intent.documentId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Document move intent references a missing local document\",\n state,\n });\n return { result: \"blocked\" };\n }\n\n for (const targetId of new Set([\n intent.targetContainerId,\n ...(intent.additionalLinkContainerIds ?? []),\n ])) {\n const targetState = state.containersById.get(targetId);\n if (!targetState) {\n await recordPendingDocumentMoveIntentError({\n blocked: true,\n documentId: intent.documentId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message:\n \"Document move intent references a missing destination container\",\n state,\n });\n return { result: \"blocked\" };\n }\n if (input.isRemoteSyncBlocked(targetState.container.organizationId)) {\n return { result: \"blocked\" };\n }\n if (\n !hasRemoteContainerMetadataState(targetState) ||\n input.isCreatePending(targetId)\n ) {\n await recordPendingDocumentMoveIntentError({\n documentId: intent.documentId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Document move destination container is not synced yet\",\n state,\n });\n return { result: \"failed\" };\n }\n }\n return { existingDocument };\n}\n\nasync function recordRejectedDocumentMove(input: {\n failure: DocumentMoveFailureState;\n intent: DocumentMoveIntentRecord;\n isCurrent: () => boolean;\n state: DocumentMoveIntentSyncState;\n unavailable: boolean;\n}): Promise<void> {\n await recordPendingDocumentMoveIntentError({\n // A permission denial parks the intent for the access-restored signal\n // instead of replaying on every structural pass (row 7).\n denied: input.failure.sawPermissionDenial,\n documentId: input.intent.documentId,\n expectedIntentId: input.intent.id,\n expectedUpdatedAt: input.intent.updatedAt,\n isCurrent: input.isCurrent,\n message: describeRejectedDocumentMove(input.failure),\n state: input.state,\n // Terminal only after the vanished-container refresh proved the\n // destination itself gone: the intent can never commit as written and\n // nothing on this device can heal it, so it leaves the replay set instead\n // of re-issuing doomed requests every pass. The tombstone cascade\n // retargets it once hydration tears the deleted container down locally.\n // Every other vanished verdict stays pending for the next pass.\n unavailable: input.unavailable,\n });\n}\n\nfunction logSyncedDocumentMove(\n intent: DocumentMoveIntentRecord,\n state: DocumentMoveIntentSyncState,\n): void {\n state.runtime.util.log(\n `Container contents: synced queued document move ${intent.documentId}`,\n );\n}\n\nasync function settleMovedDocumentIntent<TRuntime>(input: {\n failure: DocumentMoveFailureState;\n host: DocumentMoveIntentSyncHost<TRuntime>;\n intent: DocumentMoveIntentRecord;\n isCurrent: () => boolean;\n moved: NonNullable<Awaited<ReturnType<typeof moveRemoteContainerDocument>>>;\n state: DocumentMoveIntentSyncState;\n unavailable: boolean;\n}): Promise<DocumentMoveIntentReplayResult> {\n const { intent, moved, state } = input;\n if (\n !(await persistMovedDocumentReplay({\n host: input.host,\n intent,\n isCurrent: input.isCurrent,\n moved,\n state,\n }))\n ) {\n if (!input.isCurrent()) return \"abandoned\";\n await recordPendingDocumentMoveIntentError({\n documentId: intent.documentId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Document move replay could not relink the local document\",\n state,\n });\n return \"failed\";\n }\n if (moved.status === \"partial\") {\n await recordPendingDocumentMoveIntentError({\n // An unlink refused for permissions parks like any other denied\n // move (row 7); other partials keep row 15's replay.\n denied: input.failure.sawPermissionDenial,\n documentId: intent.documentId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Remote document move partially applied; retry required\",\n state,\n // Terminal only when the refresh proved the destination itself gone\n // after the link had already landed; a vanished unlink alone stays\n // pending with its live link for the next pass to revoke.\n unavailable: input.unavailable,\n });\n return \"partial\";\n }\n\n logSyncedDocumentMove(intent, state);\n return \"moved\";\n}\n\nasync function trySyncPendingDocumentMoveIntent<TRuntime>(input: {\n host: DocumentMoveIntentSyncHost<TRuntime>;\n isCreatePending: (containerId: string) => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n isCurrent: () => boolean;\n intent: DocumentMoveIntentRecord;\n state: DocumentMoveIntentSyncState;\n}): Promise<DocumentMoveIntentReplayResult> {\n const { host, intent, state } = input;\n const available = availableDocumentLinkIntent(intent, (id) =>\n state.containersById.has(id),\n );\n const preflight = await resolveMoveIntentPreflight({\n ...input,\n intent: available.intent,\n });\n if (preflight.result !== undefined) {\n return preflight.result;\n }\n const { existingDocument } = preflight;\n\n try {\n const outcome = await moveWithVanishedContainerRefresh({\n apiClient: state.runtime.apiClient,\n attempt: (onFailure) =>\n movePendingDocumentIntent({\n existingContainerId: existingDocument.containerId,\n host,\n isCurrent: input.isCurrent,\n intent: available.intent,\n onFailure,\n state,\n }),\n execSql: state.runtime.infra.execSql,\n existingContainerId: existingDocument.containerId,\n intent: available.intent,\n isCurrent: input.isCurrent,\n });\n if (outcome === \"abandoned\" || !input.isCurrent()) return \"abandoned\";\n if (!outcome.moved) {\n await recordRejectedDocumentMove({\n failure: outcome.failure,\n intent,\n isCurrent: input.isCurrent,\n state,\n unavailable: outcome.unavailable,\n });\n return \"failed\";\n }\n return await settleMovedDocumentIntent({\n failure: outcome.failure,\n host,\n intent,\n isCurrent: input.isCurrent,\n moved: available.deferred\n ? { ...outcome.moved, status: \"partial\" }\n : outcome.moved,\n state,\n unavailable: outcome.unavailable,\n });\n } catch (error: unknown) {\n if (!input.isCurrent()) return \"abandoned\";\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.documentId,\n objectKind: \"document\",\n operation: \"document.move.replay\",\n },\n );\n if (!input.isCurrent()) return \"abandoned\";\n const message = errorMessage(error);\n await recordPendingDocumentMoveIntentError({\n documentId: intent.documentId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: `Failed to sync document move: ${message}`,\n state,\n });\n return \"failed\";\n }\n}\n\nexport async function syncPendingDocumentMoveIntents<TRuntime>(input: {\n host: DocumentMoveIntentSyncHost<TRuntime>;\n /** A destination whose create has not settled takes no document yet. */\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n state: DocumentMoveIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) return 0;\n const lifecycleState = input.state;\n const state = { ...lifecycleState };\n const execSql = state.runtime.infra.execSql;\n if (!deniedReplayMatchesGeneration(lifecycleState, execSql)) {\n await sqlDocumentMoveIntentPersistence.resetDeniedMoveIntents(execSql);\n if (!input.isCurrent()) return 0;\n markDeniedReplayGeneration(lifecycleState, execSql);\n }\n const pendingIntents =\n await sqlDocumentMoveIntentPersistence.listPendingMoveIntents(execSql);\n if (!input.isCurrent()) return 0;\n let movedCount = 0;\n\n for (const intent of pendingIntents) {\n if (!input.isCurrent()) return movedCount;\n const result = await trySyncPendingDocumentMoveIntent({\n host: input.host,\n isCreatePending: input.isCreatePending,\n isCurrent: input.isCurrent,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n state,\n });\n if (result === \"abandoned\") return movedCount;\n // A \"partial\" result (link applied, unlink still pending) must not count:\n // the caller re-arms this same structural lane whenever the count is\n // positive, so a deterministically failing unlink hot-looped the pump\n // (issue #1744). The intent row stays pending; event-driven, manual, and\n // startup lane requests retry it.\n if (result === \"moved\") {\n movedCount += 1;\n }\n }\n\n return movedCount;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentMoveVanishedRefresh.js","sourceRoot":"","sources":["documentMoveVanishedRefresh.ts"],"names":[],"mappings":"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","sourcesContent":["import { isContainerNotFoundFailure } from \"../../data/containers/shared/mutationFailures\";\nimport { readLinkedContainerIdsFromDocumentManifest } from \"../../data/documents/shared/projection\";\nimport type { DocumentMoveIntentRecord } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { DocumentLinkSetFailureHandler } from \"../documents\";\nimport { listDocumentLinkedContainerIds } from \"./documentLinks\";\nimport {\n createDocumentMoveFailureState,\n type DocumentMoveFailureState,\n recordDocumentMoveFailure,\n} from \"./documentMoveFailure\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\nexport interface VanishedContainerRefreshOutcome<TMoved> {\n readonly failure: DocumentMoveFailureState;\n readonly moved: TMoved;\n /**\n * Park the intent terminally. True only when the destination itself is\n * proven gone: a coded 404 on its projection probe after eviction. No\n * mutation verdict — first attempt or retry — is ever terminal.\n */\n readonly unavailable: boolean;\n}\n\n/**\n * Every container the unlink half of the move can cite. The unlink set is\n * read off the REMOTE document manifest's link set, so that set — refetched\n * after eviction so it is current — is the authority; the local link\n * projection, the intent's source, and the document's local placement are\n * unioned in so a source known only on one side still gets its cached path\n * refreshed. A superset is harmless: an eviction only forces a refetch, and\n * nothing here decides what gets unlinked.\n */\nasync function listMoveSourceContainerIds(input: {\n apiClient: ContainerContentsWorkflowRuntime[\"apiClient\"];\n execSql: ExecSql;\n existingContainerId: string | null | undefined;\n intent: DocumentMoveIntentRecord;\n}): Promise<string[]> {\n const { documentId, targetContainerId } = input.intent;\n const [remote, local] = await Promise.all([\n input.apiClient.getDocumentWriterProjectionResult(documentId, {\n reportErrors: false,\n }),\n listDocumentLinkedContainerIds(input.execSql, documentId),\n ]);\n const remoteLinkedContainerIds = remote.ok\n ? readLinkedContainerIdsFromDocumentManifest(remote.data)\n : [];\n return Array.from(\n new Set([\n ...remoteLinkedContainerIds,\n ...local,\n input.intent.sourceContainerId,\n input.existingContainerId,\n ]),\n )\n .filter(\n (containerId): containerId is string =>\n typeof containerId === \"string\" && containerId !== targetContainerId,\n )\n .sort();\n}\n\n/**\n * A vanished-container verdict (coded container 404 or `container_unavailable`\n * 409) does not by itself doom a queued move. The deleted container may be a\n * stale ANCESTOR in a cached path — the destination or a source was moved\n * under a live parent before its former parent was deleted — and the local\n * tombstone cascade cannot rescue that intent (it retargets only intents whose\n * source or destination IS the tombstoned container). So refresh before\n * declaring terminal: evict the cached destination, document, and source\n * projections, probe the destination, and retry once with the fresh paths.\n *\n * Only the destination's fate is terminal, and only as proven by its own\n * probe. Sources are evicted, never judged: the retry's unlink set comes from\n * the verified manifest alone, so a server-asserted \"source gone\" can neither\n * skip a revoke nor complete the move — a retry whose link landed but whose\n * unlink still vanished stays partial (pending) with a live link the queue\n * keeps trying to revoke. The retry's own vanished verdict, on either side, is\n * likewise never terminal: with the destination live it can only name another\n * ancestor deleted mid-pass, which the next pass's fresh paths outrun. The\n * pass is bounded to one retry; a transient probe failure leaves the intent\n * retriable (or denied on 403) for a later pass.\n */\nexport async function moveWithVanishedContainerRefresh<TMoved>(input: {\n apiClient: ContainerContentsWorkflowRuntime[\"apiClient\"];\n attempt: (\n onFailure: DocumentLinkSetFailureHandler,\n ) => Promise<TMoved | \"abandoned\">;\n execSql: ExecSql;\n existingContainerId: string | null | undefined;\n intent: DocumentMoveIntentRecord;\n isCurrent: () => boolean;\n}): Promise<VanishedContainerRefreshOutcome<TMoved> | \"abandoned\"> {\n const { apiClient, intent } = input;\n const firstFailure = createDocumentMoveFailureState();\n const first = await input.attempt((failure) =>\n recordDocumentMoveFailure(firstFailure, failure),\n );\n if (first === \"abandoned\" || !input.isCurrent()) return \"abandoned\";\n if (!firstFailure.sawVanishedContainer) {\n return { failure: firstFailure, moved: first, unavailable: false };\n }\n\n for (const targetContainerId of new Set([\n intent.targetContainerId,\n ...(intent.additionalLinkContainerIds ?? []),\n ])) {\n apiClient.evictContainerWriterProjection(targetContainerId);\n const destination = await apiClient.getContainerWriterProjectionResult(\n targetContainerId,\n { reportErrors: false },\n );\n apiClient.evictDocumentWriterProjection(intent.documentId);\n if (!input.isCurrent()) return \"abandoned\";\n if (!destination.ok) {\n destination.report();\n recordDocumentMoveFailure(firstFailure, destination);\n return {\n failure: firstFailure,\n moved: first,\n unavailable: isContainerNotFoundFailure(destination),\n };\n }\n }\n\n for (const sourceContainerId of await listMoveSourceContainerIds(input)) {\n apiClient.evictContainerWriterProjection(sourceContainerId);\n }\n if (!input.isCurrent()) return \"abandoned\";\n\n const retryFailure = createDocumentMoveFailureState();\n const retried = await input.attempt((failure) =>\n recordDocumentMoveFailure(retryFailure, failure),\n );\n if (retried === \"abandoned\" || !input.isCurrent()) return \"abandoned\";\n // The retry's own vanished verdict is never terminal. The destination was\n // just proven live, so a second `container_unavailable` can only name\n // another ancestor deleted during the refreshed attempt (or a source): the\n // intent stays pending with its failure recorded and the next pass starts\n // over with freshly evicted projections. One retry per pass keeps it\n // bounded; nothing in the queue backs a pending intent off between passes.\n return { failure: retryFailure, moved: retried, unavailable: false };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentPriming.js","sourceRoot":"","sources":["documentPriming.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n documentContainerProjectionTables,\n documentPlacementIntentTables,\n documentProjectionTables,\n documentTables,\n LOCAL_INTENT_LANES,\n} from \"../../data/sqlite/schema\";\nimport { ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport type {\n ContainerContentsContainerSubtreeState,\n ContainerContentsDocumentRuntimeTarget,\n ContainerDocumentPrimeHost,\n ContainerDocumentQueriesRuntime,\n} from \"./documentQueries/types\";\nimport { requestDocumentRuntimeTargetSync } from \"./documentRuntimeTargetSync\";\nimport { listDocumentRuntimeTargetsForContainerSubtreeFromRuntime } from \"./documentSubtreeQueries\";\nimport {\n getOrphanedDocumentQueryBind,\n getOrphanedDocumentWhereSql,\n} from \"./orphanedDocumentSql\";\n\ninterface PrimeRequiredDocumentCandidate {\n readonly localId: string;\n}\n\ninterface LoadedRootDocumentPrimeResult {\n readonly candidateCount: number;\n readonly orphanPrimedCount: number;\n readonly primedCount: number;\n readonly rootCount: number;\n readonly unroutableCount: number;\n}\n\n// Documents that still NEED a store opened at prime time: local-only creates,\n// queued outbound updates/attachments, an outgoing-delta marker behind the\n// stored content frontier (a deferred tail; encoding inequality\n// over-approximates, which only re-primes a store the old behavior always\n// primed), a never-hydrated document (a freshly discovered share whose\n// content pull the primed lane performs), or a document with a recorded sync\n// failure (a refused revalidation leaves no queued work, so the failure row\n// is the only ticket that re-drives the store — the retry that clears on the\n// next clean pass). Fully-synced hydrated documents are\n// deliberately absent: priming exists to re-drive durable work, and opening a\n// store per settled document is what made a 1000-document boot a storm.\nconst PENDING_PRIME_LOCAL_ID_SQL = `\n SELECT stored.local_id AS local_id\n FROM documents stored\n WHERE stored.app_kind = 'documents'\n AND (\n stored.document_id IS NULL\n OR stored.snapshot_end_version = ''\n OR stored.pull_continuation IS NOT NULL\n OR COALESCE(stored.pending_base_version, '') <> stored.snapshot_end_version\n OR EXISTS (\n SELECT 1\n FROM document_history_updates pending\n WHERE pending.app_kind = 'documents'\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n )\n OR stored.sync_failure_message IS NOT NULL\n OR EXISTS (\n SELECT 1\n FROM document_pending_attachments attachment\n WHERE attachment.local_id = stored.local_id\n )\n )\n`;\n\nconst PENDING_PRIME_DOCUMENT_CANDIDATE_SQL = `\n SELECT pending.local_id AS local_id\n FROM (${PENDING_PRIME_LOCAL_ID_SQL}) pending\n ORDER BY pending.local_id ASC\n`;\n\n// The structural startup probe and the priming worker share the same durable\n// predicate so they cannot disagree about what counts as document work.\nconst STARTUP_DOCUMENT_SYNC_WORK_SQL = `\n SELECT 1 AS present\n WHERE EXISTS (${PENDING_PRIME_LOCAL_ID_SQL})\n OR EXISTS (\n SELECT 1\n FROM local_intents intent\n -- Blocked and parked denied moves count: blocked intents replay on\n -- every scan (the blocking condition can heal after hydration), and\n -- the once-per-launch replay makes denied moves retriable — so a\n -- relaunch whose only durable work is either kind must still schedule\n -- the structural pass that re-attempts it (row 7). Unavailable moves\n -- are excluded: no pass ever replays them (#2278 #4).\n WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'\n AND intent.sync_status IN ('pending', 'blocked', 'denied')\n )\n LIMIT 1\n`;\n\nexport async function hasStartupDocumentSyncWork(\n runtimeOrExecSql:\n | ContainerDocumentQueriesRuntime\n | ContainerDocumentQueriesRuntime[\"infra\"][\"execSql\"],\n): Promise<boolean> {\n const execSql =\n typeof runtimeOrExecSql === \"function\"\n ? runtimeOrExecSql\n : runtimeOrExecSql.infra.execSql;\n await ensureSqlTables(execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentPlacementIntentTables,\n ]);\n const rows = await execSql(STARTUP_DOCUMENT_SYNC_WORK_SQL);\n return rows.length > 0;\n}\n\nasync function listPrimeRequiredDocumentCandidatesFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): Promise<PrimeRequiredDocumentCandidate[]> {\n await ensureSqlTables(runtime.infra.execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ]);\n const rows = await runtime.infra.execSql(\n PENDING_PRIME_DOCUMENT_CANDIDATE_SQL,\n );\n\n return rows.flatMap((row) => {\n const localId = Reflect.get(row, \"local_id\");\n if (typeof localId !== \"string\") {\n return [];\n }\n return [{ localId }];\n });\n}\n\n// A row with content but a NULL outgoing-delta marker is deliberately treated\n// as unsettled: the store persist path always sets the marker, so over-priming\n// is the safe direction.\nasync function listPrimeRequiredLocalIdsFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): Promise<ReadonlySet<string>> {\n const candidates =\n await listPrimeRequiredDocumentCandidatesFromRuntime(runtime);\n return new Set(candidates.map((candidate) => candidate.localId));\n}\n\n/**\n * Last-link orphans (docs/sync-edge-cases.md row 3): the container cascade\n * nulled their projection container and dropped their link rows, so no\n * subtree listing can route them. Placements held for unsigned tombstones\n * also qualify when every link is hidden; their link rows remain intact.\n * These documents are primed with a null container\n * scope instead — the documents runtime accepts one, and the document's own\n * sync pass then resolves its fate against the server: 403 parks it (row 8),\n * a coded 404 destroys it (row 1), and a local-only orphan's create attempt\n * records a terminal failure row. Hidden document kinds stay excluded, and\n * dangling non-null projections (a container row merely missing locally)\n * stay with stale-root recovery, exactly as before.\n *\n * Organization neutrality: the null scope changes only the runtime's\n * containerId — auth, crypto, and organization plumbing are identical to\n * every container-scoped runtime this store already primes with, the sync\n * pass derives billing and keying organizations from the document's own\n * plan and manifest, and a cross-organization author fails closed at the\n * sync layer's identity guard before anything is signed.\n */\nconst ORPHANED_PRIME_TARGET_SQL = `\n SELECT stored.local_id AS local_id, stored.document_id AS document_id\n FROM documents stored\n INNER JOIN document_projection projection\n ON projection.local_id = stored.local_id\n WHERE stored.app_kind = 'documents'\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"stored.document_id\",\n projectionAlias: \"projection\",\n })}\n ORDER BY stored.local_id ASC\n`;\n\n/**\n * Unattributed rows (empty/NULL organization) are always included: they are\n * device-first documents created before authentication, which belong to this\n * device's sole user and adopt the active organization when they create.\n */\nasync function listOrphanedDocumentPrimeTargets(\n runtime: ContainerDocumentQueriesRuntime,\n organizationId: string,\n): Promise<ContainerContentsDocumentRuntimeTarget[]> {\n await ensureSqlTables(runtime.infra.execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentContainerProjectionTables,\n ]);\n const rows = await runtime.infra.execSql(\n ORPHANED_PRIME_TARGET_SQL,\n getOrphanedDocumentQueryBind(organizationId),\n );\n return rows.flatMap((row) => {\n const localId = Reflect.get(row, \"local_id\");\n if (typeof localId !== \"string\") {\n return [];\n }\n const documentId = Reflect.get(row, \"document_id\");\n return [\n {\n documentId: typeof documentId === \"string\" ? documentId : null,\n localId,\n runtimeContainerId: null,\n },\n ];\n });\n}\n\nexport async function primeDocumentsForContainerSubtree<TRuntime>(input: {\n containersById: ReadonlyMap<string, ContainerContentsContainerSubtreeState>;\n host: ContainerDocumentPrimeHost<TRuntime>;\n isCurrent?: (() => boolean) | undefined;\n primeRequiredLocalIds?: ReadonlySet<string>;\n rootContainerId: string;\n runtime: ContainerDocumentQueriesRuntime;\n}): Promise<number> {\n const isCurrent = input.isCurrent ?? (() => true);\n if (!isCurrent()) return 0;\n const [targets, primeRequiredLocalIds] = await Promise.all([\n listDocumentRuntimeTargetsForContainerSubtreeFromRuntime({\n containersById: input.containersById,\n rootContainerId: input.rootContainerId,\n runtime: input.runtime,\n }),\n input.primeRequiredLocalIds ??\n listPrimeRequiredLocalIdsFromRuntime(input.runtime),\n ]);\n if (!isCurrent()) return 0;\n const primed = await requestDocumentRuntimeTargetSync({\n host: input.host,\n isCurrent,\n targets: targets.filter((target) =>\n primeRequiredLocalIds.has(target.localId),\n ),\n });\n return primed.size;\n}\n\nexport async function primeDocumentsForLoadedRoots<TRuntime>(input: {\n containersById: ReadonlyMap<string, ContainerContentsContainerSubtreeState>;\n host: ContainerDocumentPrimeHost<TRuntime>;\n isCurrent?: (() => boolean) | undefined;\n /**\n * The store scope's organization. Orphan priming is bounded to it: each\n * organization-scoped store resolves only its own orphans, matching the\n * per-organization invariant subtree routing provides implicitly (a pass\n * signed under another organization would fail the sync identity guard\n * instead of resolving). Absent — unauthenticated or scope-less callers —\n * orphan priming is skipped entirely.\n */\n organizationId?: string | null;\n runtime: ContainerDocumentQueriesRuntime;\n}): Promise<LoadedRootDocumentPrimeResult> {\n const isCurrent = input.isCurrent ?? (() => true);\n if (!isCurrent()) {\n return {\n candidateCount: 0,\n orphanPrimedCount: 0,\n primedCount: 0,\n rootCount: 0,\n unroutableCount: 0,\n };\n }\n const candidates = await listPrimeRequiredDocumentCandidatesFromRuntime(\n input.runtime,\n );\n if (!isCurrent()) {\n return {\n candidateCount: candidates.length,\n orphanPrimedCount: 0,\n primedCount: 0,\n rootCount: 0,\n unroutableCount: candidates.length,\n };\n }\n const rootContainerIds = Array.from(input.containersById.values()).flatMap(\n (containerState) =>\n containerState.container.parentId === null\n ? [containerState.container.id]\n : [],\n );\n const requiredLocalIds = new Set(\n candidates.map((candidate) => candidate.localId),\n );\n const primedLocalIds = new Set<string>();\n\n for (const rootContainerId of rootContainerIds) {\n if (!isCurrent()) break;\n const targets =\n await listDocumentRuntimeTargetsForContainerSubtreeFromRuntime({\n containersById: input.containersById,\n rootContainerId,\n runtime: input.runtime,\n });\n if (!isCurrent()) break;\n const primed = await requestDocumentRuntimeTargetSync({\n host: input.host,\n isCurrent,\n targets: targets.filter(\n (target) =>\n requiredLocalIds.has(target.localId) &&\n !primedLocalIds.has(target.localId),\n ),\n });\n for (const localId of primed) {\n primedLocalIds.add(localId);\n }\n }\n\n const orphanTargets = (\n isCurrent() && input.organizationId\n ? await listOrphanedDocumentPrimeTargets(\n input.runtime,\n input.organizationId,\n )\n : []\n ).filter(\n (target) =>\n requiredLocalIds.has(target.localId) &&\n !primedLocalIds.has(target.localId),\n );\n const orphanPrimed = await requestDocumentRuntimeTargetSync({\n host: input.host,\n isCurrent,\n targets: isCurrent() ? orphanTargets : [],\n });\n for (const localId of orphanPrimed) {\n primedLocalIds.add(localId);\n }\n\n return {\n candidateCount: candidates.length,\n orphanPrimedCount: orphanPrimed.size,\n primedCount: primedLocalIds.size,\n rootCount: rootContainerIds.length,\n unroutableCount: candidates.filter(\n (candidate) => !primedLocalIds.has(candidate.localId),\n ).length,\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentPurge.js","sourceRoot":"","sources":["documentPurge.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentPurgeResponse } from \"@tearleads/validators/response\";\nimport type { StoredDocumentKind } from \"../../data/documents/documentKinds\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport { rethrowProjectionVerificationCancelled } from \"../../data/keyingProjectionVerification/types\";\nimport { errorMessage } from \"../../data/shared/errorMessage\";\nimport {\n type DocumentsPersistence,\n defaultDocumentsPersistence,\n deletePersistedDocument,\n purgeRemoteDocument,\n reclaimDocumentOrphanBlobs,\n resolveDocumentCreateAuthor,\n} from \"../documents\";\nimport { ensureDocumentClientProjectionTables } from \"../documents/persistence\";\nimport type { SubtreePurgeRoot } from \"../documents/subtreePurgeScope\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../principals/runtimePolicyWarmer\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\ntype ContainerDocumentPurgeApi = Pick<\n ContainerContentsWorkflowRuntime[\"apiClient\"],\n | \"getPrincipalPolicyPages\"\n | \"getProjectionPolicyHistoryPages\"\n | \"getDocumentPurgeProof\"\n | \"getDocumentWriterProjectionResult\"\n | \"purgeDocument\"\n>;\ntype DocumentPurgeResult =\n | DocumentPurgeResponse\n | {\n readonly documentId: string;\n readonly purgedAt: string;\n readonly reclaimedBlobStorageKeys: readonly string[];\n }\n | null;\n\ninterface ContainerDocumentPurgeRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n apiClient: ContainerDocumentPurgeApi;\n}\n\ninterface PurgeRemoteContainerDocumentInput {\n beforeSubmit?: (() => Promise<boolean>) | undefined;\n documentId: string;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n stillCurrent?: (() => boolean) | undefined;\n documentKind: StoredDocumentKind;\n noteId: string;\n persistence?: DocumentsPersistence | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerDocumentPurgeRuntime;\n}\n\nasync function deleteAbsentDocumentState(input: {\n readonly commitPurgeProof: (\n transactionExecSql: ContainerDocumentPurgeRuntime[\"infra\"][\"execSql\"],\n ) => Promise<void>;\n readonly documentId: string;\n readonly documentKind: StoredDocumentKind;\n readonly noteId: string;\n readonly persistence: DocumentsPersistence;\n readonly runtime: ContainerDocumentPurgeRuntime;\n}): Promise<boolean> {\n return input.persistence.deleteDocumentSideRowsIfAbsent(\n input.runtime.infra.execSql,\n input.noteId,\n input.documentId,\n async (transactionExecSql) => {\n await input.runtime.infra.documentProjectors.deleteStoredDocumentClientProjection(\n {\n documentKind: input.documentKind,\n execSql: transactionExecSql,\n localId: input.noteId,\n },\n );\n await input.commitPurgeProof(transactionExecSql);\n },\n );\n}\n\nasync function commitVerifiedDocumentPurge(input: {\n readonly commitPurgeProof: (\n transactionExecSql: ContainerDocumentPurgeRuntime[\"infra\"][\"execSql\"],\n ) => Promise<void>;\n readonly documentId: string;\n readonly documentKind: StoredDocumentKind;\n readonly noteId: string;\n readonly persistence: DocumentsPersistence;\n readonly runtime: ContainerDocumentPurgeRuntime;\n}): Promise<boolean> {\n await input.persistence.ensureSchema(input.runtime.infra.execSql);\n await ensureDocumentClientProjectionTables({\n documentProjectors: input.runtime.infra.documentProjectors,\n execSql: input.runtime.infra.execSql,\n });\n const expectedRecord = await input.persistence.loadDocument(\n input.runtime.infra.execSql,\n input.noteId,\n );\n if (expectedRecord && expectedRecord.documentId !== input.documentId) {\n throw new Error(\n \"Local document identity changed while its remote purge was committing\",\n );\n }\n const deleted = expectedRecord\n ? await deletePersistedDocument({\n beforeDeleteInTransaction: input.commitPurgeProof,\n documentProjectors: input.runtime.infra.documentProjectors,\n execSql: input.runtime.infra.execSql,\n expectedRecord,\n localId: input.noteId,\n persistence: input.persistence,\n })\n : await deleteAbsentDocumentState(input);\n if (!deleted) {\n throw new Error(\n \"Local document state changed while its remote purge was committing\",\n );\n }\n return true;\n}\n\nexport async function purgeRemoteContainerDocument(\n input: PurgeRemoteContainerDocumentInput,\n): Promise<DocumentPurgeResult> {\n const { documentId, noteId, runtime } = input;\n const persistence = input.persistence ?? defaultDocumentsPersistence;\n try {\n const author = resolveDocumentCreateAuthor(runtime);\n if (!author) {\n runtime.util.log(\n `Container contents: failed to purge note ${noteId} because the local signing context is unavailable`,\n );\n return null;\n }\n let deleted = false;\n const response = await purgeRemoteDocument({\n apiClient: runtime.apiClient,\n beforeSubmit: input.beforeSubmit,\n author,\n documentId,\n expectedSubtreeRoot: input.expectedSubtreeRoot,\n stillCurrent: input.stillCurrent,\n execSql: runtime.infra.execSql,\n onVerifiedPurge: async ({ commitPurgeProof }) => {\n deleted = await commitVerifiedDocumentPurge({\n commitPurgeProof,\n documentId,\n documentKind: input.documentKind,\n noteId,\n persistence,\n runtime,\n });\n },\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!response) {\n runtime.util.log(\n `Container contents: failed to purge note ${noteId} (document ${documentId})`,\n );\n return null;\n }\n if (deleted) {\n void reclaimDocumentOrphanBlobs(runtime, persistence);\n }\n runtime.util.log(\n `Container contents: purged note ${noteId} (document ${documentId})`,\n );\n return response;\n } catch (error) {\n // A cancelled verification is neither a failure nor a completed purge; the\n // caller that owns the generation decides what to do with it.\n rethrowProjectionVerificationCancelled(error);\n await reportAndRethrowKeyingVerificationError(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: documentId,\n objectKind: \"document\",\n operation: \"document.purge\",\n },\n );\n runtime.util.log(\n `Container contents: failed to purge note ${noteId} (document ${documentId}): ${errorMessage(error)}`,\n );\n return null;\n }\n}\n\ninterface ContainerDocumentLocalPurgeRuntime\n extends Pick<ContainerContentsWorkflowRuntime, \"infra\" | \"util\"> {}\n\nexport async function purgeLocalContainerDocument(input: {\n beforeDeleteInTransaction?: Parameters<\n typeof deletePersistedDocument\n >[0][\"beforeDeleteInTransaction\"];\n noteId: string;\n expectedContainerId?: string | null | undefined;\n persistence?: DocumentsPersistence | undefined;\n runtime: ContainerDocumentLocalPurgeRuntime;\n}): Promise<DocumentPurgeResult> {\n const { noteId, runtime } = input;\n const persistence = input.persistence ?? defaultDocumentsPersistence;\n try {\n await persistence.ensureSchema(runtime.infra.execSql);\n const expectedRecord = await persistence.loadDocument(\n runtime.infra.execSql,\n noteId,\n );\n if (\n !expectedRecord ||\n expectedRecord.documentId !== null ||\n (input.expectedContainerId !== undefined &&\n expectedRecord.containerId !== input.expectedContainerId)\n ) {\n runtime.util.log(\n `Container contents: local-only purge refused for note ${noteId} because it is absent or remote-backed`,\n );\n return null;\n }\n const deleted = await deletePersistedDocument({\n beforeDeleteInTransaction: input.beforeDeleteInTransaction,\n documentProjectors: runtime.infra.documentProjectors,\n execSql: runtime.infra.execSql,\n expectedRecord,\n localId: noteId,\n persistence,\n });\n if (!deleted) {\n runtime.util.log(\n `Container contents: local-only purge refused for note ${noteId} because its identity changed`,\n );\n return null;\n }\n if (deleted) {\n void reclaimDocumentOrphanBlobs(runtime, persistence);\n }\n runtime.util.log(`Container contents: purged local-only note ${noteId}`);\n return {\n documentId: noteId,\n purgedAt: new Date().toISOString(),\n reclaimedBlobStorageKeys: [],\n };\n } catch (error) {\n runtime.util.log(\n `Container contents: failed to purge local-only note ${noteId}: ${errorMessage(error)}`,\n );\n return null;\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentQueries.js","sourceRoot":"","sources":["documentQueries.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { SyncWatermark } from \"@tearleads/validators/response\";\nimport type {\n DiscoveredDocumentInput,\n DocumentSummary,\n} from \"../../data/documents/documentSummary\";\nimport {\n hasRetainedContainerMetadata,\n listRecoveryFolderMoveIds,\n} from \"../../data/persistence/container-contents/containerRecoveryPersistence\";\nimport { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport {\n containerContentsSyncLane,\n sqlContainerSyncWatermarkPersistence,\n} from \"../../data/persistence/containers/containerSyncWatermarkPersistence\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport {\n applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones,\n sqlDocumentsPersistence,\n upsertDiscoveredDocuments,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport { localIntentTables } from \"../../data/sqlite/schema\";\nimport { type ExecSql, ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport { hydratedProjectionSql } from \"./documentQueries/hydrationSql\";\nimport {\n mapContainerContentsDocumentSummaryRow,\n mapContainerContentsDocumentSyncStateRow,\n mapContainerDocumentSidebarRow,\n mapContainerItemRow,\n readContainerContentsContainerItemCount,\n} from \"./documentQueries/rows\";\nimport {\n clampContainerItemWindowValue,\n getContainerContentsContainerDocumentSidebarOrderBy,\n getContainerContentsContainerItemOrderBy,\n getContainerContentsContainerItemsBaseSql,\n getContainerContentsDocumentPendingStateCtes,\n getContainerContentsDocumentRowsBaseSql,\n getContainerDocumentSidebarWindowLimit,\n getContainerItemWindowLimit,\n getOrphanedDocumentExistsSql,\n getOrphanedDocumentItemsBaseSql,\n getOrphanedDocumentRowsBaseSql,\n listContainerContentsSqlIdBatches,\n} from \"./documentQueries/sql\";\nimport type {\n ContainerDocumentLinkInput,\n ContainerDocumentQueriesRuntime,\n ContainerDocumentSidebarWindow,\n ContainerDocumentTombstone,\n ContainerItemSort,\n ContainerItemWindow,\n} from \"./documentQueries/types\";\nimport {\n createFolderRecoveryQueries,\n type RecoveryFolder,\n} from \"./folderRecovery\";\nimport {\n getOrphanedDocumentQueryBind,\n getOrphanedDocumentWhereSql,\n} from \"./orphanedDocumentSql\";\nimport {\n listPendingDownloads,\n type PendingDownloadQueueItem,\n} from \"./pendingDownloads\";\nimport {\n listPendingWrites,\n type PendingWriteQueueItem,\n resetPendingWriteRetryState,\n} from \"./pendingWrites\";\nimport type { ContainerDocumentObjectSyncState } from \"./syncState\";\n\nexport type {\n ContainerDocumentLinkInput,\n ContainerDocumentSidebarRow,\n ContainerDocumentTombstone,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n} from \"./documentQueries/types\";\n\ninterface ListContainerItemWindowInput {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n sort: ContainerItemSort;\n visibleForeignSystemContainerNames?: ReadonlyArray<string> | undefined;\n visibleSystemSlots?: ReadonlyArray<ContainerSystemSlot> | undefined;\n}\n\nexport interface ContainerDocumentQueries {\n listRecoveryFolderMoveIds(input: {\n currentOrganizationId: string | null;\n }): Promise<string[]>;\n listRecoveryFolders(input: {\n currentOrganizationId: string | null;\n }): Promise<RecoveryFolder[]>;\n discardRecoveryFolder(\n input: Pick<RecoveryFolder, \"containerId\" | \"organizationId\" | \"revision\">,\n ): Promise<boolean>;\n applyContainerDocumentTombstones(\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n hasOrphanedDocuments(input: {\n currentOrganizationId: string | null;\n }): Promise<boolean>;\n listContainerDocumentSidebarWindow(input: {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n }): Promise<ContainerDocumentSidebarWindow>;\n listContainerItemWindow(\n input: ListContainerItemWindowInput,\n ): Promise<ContainerItemWindow>;\n loadDocumentSyncState(\n localId: string,\n ): Promise<ContainerDocumentObjectSyncState | null>;\n loadDocumentSummary(\n localId: string,\n options?: { requireHydrated?: boolean },\n ): Promise<DocumentSummary | null>;\n loadOrphanedDocumentSummary(input: {\n requireHydrated?: boolean;\n currentOrganizationId: string | null;\n localId: string;\n }): Promise<DocumentSummary | null>;\n loadContainerDocumentWatermark(\n containerId: string,\n ): Promise<SyncWatermark | null>;\n listLinkedContainerIdsByDocumentIds(\n documentIds: ReadonlyArray<string>,\n ): Promise<ReadonlyMap<string, ReadonlyArray<string>>>;\n listPendingDownloads(): Promise<ReadonlyArray<PendingDownloadQueueItem>>;\n listPendingWrites(): Promise<ReadonlyArray<PendingWriteQueueItem>>;\n retryPendingWriteItem(input: {\n localId: string;\n namespace: string | null;\n objectKind: PendingWriteQueueItem[\"objectKind\"];\n }): Promise<void>;\n replaceDocumentLinksBatch(\n inputs: ReadonlyArray<ContainerDocumentLinkInput>,\n ): Promise<void>;\n saveContainerDocumentWatermark(\n containerId: string,\n watermark: SyncWatermark,\n ): Promise<void>;\n upsertDiscoveredDocuments(\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n}\n\nasync function listContainerItemWindow(\n execSql: ExecSql,\n input: ListContainerItemWindowInput,\n): Promise<ContainerItemWindow> {\n await ensureContainerTables(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, localIntentTables);\n\n const limit = getContainerItemWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const visibleSystemSlots = Array.from(\n new Set(input.visibleSystemSlots ?? []),\n );\n const currentOrganizationId = input.currentOrganizationId || null;\n const visibleForeignSystemContainerNames = currentOrganizationId\n ? Array.from(new Set(input.visibleForeignSystemContainerNames ?? []))\n : [];\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [\n input.containerId,\n ...visibleSystemSlots,\n ...(visibleForeignSystemContainerNames.length > 0\n ? [currentOrganizationId, ...visibleForeignSystemContainerNames]\n : []),\n input.containerId,\n input.containerId,\n ];\n const baseSql = orphaned\n ? getOrphanedDocumentItemsBaseSql()\n : getContainerContentsContainerItemsBaseSql(\n visibleSystemSlots.length,\n visibleForeignSystemContainerNames.length,\n );\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerItemOrderBy(input.sort)} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map((row) => mapContainerItemRow(input.containerId, row)),\n totalCount,\n };\n}\n\nasync function hasOrphanedDocuments(\n execSql: ExecSql,\n currentOrganizationId: string | null,\n): Promise<boolean> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n getOrphanedDocumentExistsSql(),\n getOrphanedDocumentQueryBind(currentOrganizationId),\n );\n return (\n rows.length > 0 ||\n (await hasRetainedContainerMetadata(execSql, currentOrganizationId)) ||\n (await listRecoveryFolderMoveIds(execSql, currentOrganizationId)).length > 0\n );\n}\n\nasync function listContainerDocumentSidebarWindow(\n execSql: ExecSql,\n input: {\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n },\n): Promise<ContainerDocumentSidebarWindow> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const limit = getContainerDocumentSidebarWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [input.containerId, input.containerId];\n const baseSql = orphaned\n ? getOrphanedDocumentRowsBaseSql()\n : getContainerContentsDocumentRowsBaseSql();\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerDocumentSidebarOrderBy()} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map(mapContainerDocumentSidebarRow),\n totalCount,\n };\n}\n\nasync function queryContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n scope: { bind: ReadonlyArray<string | null>; whereSql: string },\n): Promise<DocumentSummary | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n d.title AS title,\n d.updated_at AS updated_at,\n stored.access_state_hash AS access_state_hash,\n stored.effective_access_level AS effective_access_level\n FROM document_projection d\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = d.local_id\n WHERE d.local_id = ?\n ${scope.whereSql}\n LIMIT 1\n `,\n [localId, ...scope.bind],\n );\n\n return mapContainerContentsDocumentSummaryRow(rows[0] ?? {});\n}\n\nfunction loadContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: [],\n whereSql: requireHydrated\n ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}`\n : \"\",\n });\n}\n\nfunction loadContainerContentsOrphanedDocumentSummary(\n execSql: ExecSql,\n localId: string,\n currentOrganizationId: string | null,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: getOrphanedDocumentQueryBind(currentOrganizationId),\n whereSql: `${requireHydrated ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}` : \"\"} AND ${getOrphanedDocumentWhereSql(\n {\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n },\n )}`,\n });\n}\n\nasync function loadContainerContentsDocumentSyncState(\n execSql: ExecSql,\n localId: string,\n): Promise<ContainerDocumentObjectSyncState | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.document_id AS document_id,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE d.local_id = ?\n LIMIT 1\n `,\n [localId],\n );\n const [row] = rows;\n if (!row) {\n return null;\n }\n\n return mapContainerContentsDocumentSyncStateRow(row);\n}\n\nasync function listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql: ExecSql,\n documentIds: ReadonlyArray<string>,\n): Promise<ReadonlyMap<string, ReadonlyArray<string>>> {\n const uniqueDocumentIds = Array.from(new Set(documentIds));\n if (uniqueDocumentIds.length === 0) {\n return new Map();\n }\n\n const linkedContainerIdsByDocumentId = new Map<string, string[]>();\n for (const documentId of uniqueDocumentIds) {\n linkedContainerIdsByDocumentId.set(documentId, []);\n }\n\n for (const documentIdBatch of listContainerContentsSqlIdBatches(\n uniqueDocumentIds,\n )) {\n const batchLinkedContainerIdsByDocumentId =\n await sqlDocumentContainerProjectionPersistence.listLinkedContainerIdsByDocumentIds(\n execSql,\n documentIdBatch,\n );\n for (const [\n documentId,\n linkedContainerIds,\n ] of batchLinkedContainerIdsByDocumentId.entries()) {\n linkedContainerIdsByDocumentId.set(\n documentId,\n Array.from(linkedContainerIds),\n );\n }\n }\n\n return linkedContainerIdsByDocumentId;\n}\n\nexport function createContainerDocumentQueriesFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): ContainerDocumentQueries {\n const execSql = runtime.infra.execSql;\n return {\n ...createFolderRecoveryQueries(execSql),\n applyContainerDocumentTombstones(tombstones) {\n return applyPersistedContainerDocumentTombstones(execSql, tombstones);\n },\n hasOrphanedDocuments({ currentOrganizationId }) {\n return hasOrphanedDocuments(execSql, currentOrganizationId);\n },\n listContainerDocumentSidebarWindow(input) {\n return listContainerDocumentSidebarWindow(execSql, input);\n },\n listContainerItemWindow(input) {\n return listContainerItemWindow(execSql, input);\n },\n loadDocumentSyncState(localId) {\n return loadContainerContentsDocumentSyncState(execSql, localId);\n },\n loadDocumentSummary(localId, options) {\n return loadContainerContentsDocumentSummary(\n execSql,\n localId,\n options?.requireHydrated ?? false,\n );\n },\n loadOrphanedDocumentSummary({\n currentOrganizationId,\n localId,\n requireHydrated = false,\n }) {\n return loadContainerContentsOrphanedDocumentSummary(\n execSql,\n localId,\n currentOrganizationId,\n requireHydrated,\n );\n },\n loadContainerDocumentWatermark(containerId) {\n return sqlContainerSyncWatermarkPersistence.loadWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n );\n },\n listLinkedContainerIdsByDocumentIds(documentIds) {\n return listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql,\n documentIds,\n );\n },\n listPendingDownloads() {\n return listPendingDownloads(execSql);\n },\n listPendingWrites() {\n return listPendingWrites(execSql);\n },\n retryPendingWriteItem(input) {\n return resetPendingWriteRetryState(execSql, input);\n },\n replaceDocumentLinksBatch(inputs) {\n return sqlDocumentContainerProjectionPersistence.replaceDocumentLinksBatch(\n execSql,\n inputs,\n );\n },\n async saveContainerDocumentWatermark(containerId, watermark) {\n await sqlContainerSyncWatermarkPersistence.saveWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n watermark,\n );\n },\n upsertDiscoveredDocuments(inputs) {\n return upsertDiscoveredDocuments(execSql, inputs);\n },\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentRuntimeTargetSync.js","sourceRoot":"","sources":["documentRuntimeTargetSync.ts"],"names":[],"mappings":"AAMA,+EAA+E;AAC/E,8EAA8E;AAC9E,6CAA6C;AAC7C,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEzC,KAAK,UAAU,wBAAwB,CAAmB,KAYzD;IACC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjE,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAElD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,iBAAiB,CAAC;QAC3C,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IACE,iBAAiB,CAAC,IAAI,GAAG,CAAC;YAC1B,iBAAiB,CAAC,IAAI,GAAG,8BAA8B,KAAK,CAAC,EAC7D,CAAC;YACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,SAAS,EAAE;gBAAE,OAAO,iBAAiB,CAAC;QAC7C,CAAC;QAED,IAAI,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACnE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACxE,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;YACzC,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO;SACR,CAAC,CAAC;QACH,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAW,KAI1D;IACC,OAAO,wBAAwB,CAAC;QAC9B,GAAG,KAAK;QACR,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;gBACxC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sCAAsC,CAAW,KAIhE;IACC,OAAO,wBAAwB,CAAC;QAC9B,GAAG,KAAK;QACR,yEAAyE;QACzE,uEAAuE;QACvE,qEAAqE;QACrE,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,EAAE;KACvD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n ContainerContentsDocumentRuntimeTarget,\n ContainerDocumentPrimeHost,\n ContainerDocumentProbeHost,\n} from \"./documentQueries/types\";\n\n// Stores opened per macrotask. Opening is fire-and-forget, so yielding between\n// chunks keeps the main thread and serialized SQLite queue responsive while a\n// restored replica schedules a real backlog.\nconst DOCUMENT_STORE_OPEN_CHUNK_SIZE = 8;\n\nasync function requestRuntimeTargetSync<TRuntime, TStore>(input: {\n readonly host: {\n documentWorkflowRuntime: (containerId: string | null) => TRuntime;\n openDocumentStore: (input: {\n documentId: string | null;\n localId: string;\n runtime: TRuntime;\n }) => TStore;\n };\n readonly isCurrent?: (() => boolean) | undefined;\n readonly requestStoreSync: (store: TStore) => void;\n readonly targets: ReadonlyArray<ContainerContentsDocumentRuntimeTarget>;\n}): Promise<ReadonlySet<string>> {\n const requestedLocalIds = new Set<string>();\n const runtimesByContainerId = new Map<string | null, TRuntime>();\n const isCurrent = input.isCurrent ?? (() => true);\n\n for (const target of input.targets) {\n if (!isCurrent()) return requestedLocalIds;\n if (requestedLocalIds.has(target.localId)) {\n continue;\n }\n if (\n requestedLocalIds.size > 0 &&\n requestedLocalIds.size % DOCUMENT_STORE_OPEN_CHUNK_SIZE === 0\n ) {\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n if (!isCurrent()) return requestedLocalIds;\n }\n\n let runtime = runtimesByContainerId.get(target.runtimeContainerId);\n if (runtime === undefined) {\n runtime = input.host.documentWorkflowRuntime(target.runtimeContainerId);\n runtimesByContainerId.set(target.runtimeContainerId, runtime);\n }\n\n const store = input.host.openDocumentStore({\n documentId: target.documentId,\n localId: target.localId,\n runtime,\n });\n requestedLocalIds.add(target.localId);\n input.requestStoreSync(store);\n }\n\n return requestedLocalIds;\n}\n\nexport function requestDocumentRuntimeTargetSync<TRuntime>(input: {\n readonly host: ContainerDocumentPrimeHost<TRuntime>;\n readonly isCurrent?: (() => boolean) | undefined;\n readonly targets: ReadonlyArray<ContainerContentsDocumentRuntimeTarget>;\n}): Promise<ReadonlySet<string>> {\n return requestRuntimeTargetSync({\n ...input,\n requestStoreSync: (store) => {\n if (store.getSnapshot?.().ready ?? true) {\n store.requestSync();\n }\n },\n });\n}\n\nexport function requestRemoteDocumentRuntimeTargetSync<TRuntime>(input: {\n readonly host: ContainerDocumentProbeHost<TRuntime>;\n readonly isCurrent?: (() => boolean) | undefined;\n readonly targets: ReadonlyArray<ContainerContentsDocumentRuntimeTarget>;\n}): Promise<ReadonlySet<string>> {\n return requestRuntimeTargetSync({\n ...input,\n // Unlike ordinary startup priming, a probe must survive a freshly opened\n // store's initialization. requestRemoteSync records that intent before\n // scheduling, so the first ready pass performs an HTTP revalidation.\n requestStoreSync: (store) => store.requestRemoteSync(),\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentStructure.js","sourceRoot":"","sources":["documentStructure.ts"],"names":[],"mappings":"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","sourcesContent":["import { DEFAULT_DOCUMENT_ACCESS_EPOCH } from \"../../data/documents/documentConstants\";\nimport type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport {\n addDocumentLinkLocally,\n removeDocumentLinkLocally,\n} from \"./documentLinkIntent\";\nimport { relinkContainerDocumentLocally } from \"./documentLocalRelink\";\nimport { moveRemoteDocumentLinkLocally } from \"./documentMoveIntent\";\nimport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationRuntime,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\nexport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationRelinkInput,\n DocumentStructuralMutationRuntime,\n MergeDocumentSummary,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\ninterface DocumentStructuralMutationInput<TRuntime> {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n requireDocumentId: boolean;\n runtime: DocumentStructuralMutationRuntime;\n}\n\nexport function canMutateDocumentLink(runtime: {\n readonly auth: Pick<\n DocumentStructuralMutationRuntime[\"auth\"],\n \"isAuthenticated\"\n >;\n readonly infra: Pick<DocumentStructuralMutationRuntime[\"infra\"], \"dbStatus\">;\n readonly state: Pick<DocumentStructuralMutationRuntime[\"state\"], \"online\">;\n}): boolean {\n return (\n runtime.infra.dbStatus === \"ready\" &&\n runtime.auth.isAuthenticated &&\n runtime.state.online\n );\n}\n\nexport function canMutateLocalDocumentLink(runtime: {\n readonly infra: Pick<DocumentStructuralMutationRuntime[\"infra\"], \"dbStatus\">;\n}): boolean {\n return runtime.infra.dbStatus === \"ready\";\n}\n\nasync function openDocumentStoreForStructuralMutation<TRuntime>({\n host,\n note,\n requireDocumentId,\n runtime,\n}: DocumentStructuralMutationInput<TRuntime>) {\n if (requireDocumentId && !note.documentId) {\n return null;\n }\n\n const documentStore = host.openDocumentStore({\n containerId: note.containerId,\n documentId: note.documentId,\n localId: note.id,\n });\n if (!(await documentStore.ensureInitialized())) {\n runtime.util.log(\n `Container contents: note ${note.id} is not ready to mutate locally`,\n );\n return null;\n }\n\n return documentStore;\n}\n\nexport async function moveLocalDocumentLink<TRuntime>(params: {\n expandNode: (nodeId: string) => void;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n runtime: DocumentStructuralMutationRuntime;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { expandNode, host, note, runtime, targetContainerId } = params;\n if (note.containerId === targetContainerId) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: false,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n const movedNote = await relinkContainerDocumentLocally({\n accessEpoch: DEFAULT_DOCUMENT_ACCESS_EPOCH,\n currentDocumentStore,\n host,\n note,\n requestSync: true,\n runtime,\n targetContainerId,\n });\n if (!movedNote) {\n return null;\n }\n\n expandNode(targetContainerId);\n runtime.util.log(\n `Container contents: moved local note ${movedNote.id} to ${targetContainerId}`,\n );\n return movedNote;\n}\n\nexport async function moveDocumentLink<TRuntime>(params: {\n expandNode: (nodeId: string) => void;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n replaceLinkedContainers?: boolean | undefined;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<{ linksChanged: boolean; note: DocumentSummary | null }> {\n const {\n expandNode,\n host,\n note,\n replaceLinkedContainers,\n runtime,\n scheduleSync,\n setLinkedContainerIdsForDocument,\n targetContainerId,\n } = params;\n if (note.containerId === targetContainerId) {\n return { linksChanged: false, note: null };\n }\n if (!note.documentId) {\n const movedNote = await moveLocalDocumentLink({\n expandNode,\n host,\n note,\n runtime,\n targetContainerId,\n });\n return {\n linksChanged: movedNote !== null,\n note: movedNote,\n };\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return { linksChanged: false, note: null };\n }\n\n const queuedMove = await moveRemoteDocumentLinkLocally({\n currentDocumentStore,\n expandNode,\n host,\n note: {\n ...note,\n documentId: note.documentId,\n },\n replaceLinkedContainers,\n runtime,\n scheduleSync,\n setLinkedContainerIdsForDocument,\n targetContainerId,\n });\n return queuedMove;\n}\n\nexport async function addDocumentLink<TRuntime>(params: {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { host, note, runtime } = params;\n if (!note.documentId || !note.containerId) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n return addDocumentLinkLocally({\n ...params,\n currentDocumentStore,\n note: {\n ...note,\n documentId: note.documentId,\n containerId: note.containerId,\n },\n });\n}\n\nexport async function removeDocumentLink<TRuntime>(params: {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n removedContainerId: string;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n}): Promise<DocumentSummary | null> {\n const { host, note, runtime } = params;\n if (!note.documentId || !note.containerId) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n // Keep the rotation preflight before accepting an unlink. Replay proves it\n // again before publishing the signed key rotation from the durable intent.\n await currentDocumentStore.assertCanRotateContentKey();\n return removeDocumentLinkLocally({\n ...params,\n currentDocumentStore,\n note: {\n ...note,\n documentId: note.documentId,\n containerId: note.containerId,\n },\n });\n}\n\nexport async function activateDocumentLink<TRuntime>(params: {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n runtime: DocumentStructuralMutationRuntime;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { host, note, runtime, targetContainerId } = params;\n if (\n !note.documentId ||\n !note.containerId ||\n note.containerId === targetContainerId\n ) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n const relinkedNote = await relinkContainerDocumentLocally({\n accessEpoch: DEFAULT_DOCUMENT_ACCESS_EPOCH,\n currentDocumentStore,\n host,\n note,\n requestSync: false,\n runtime,\n targetContainerId,\n });\n if (!relinkedNote) {\n return null;\n }\n\n runtime.util.log(\n `Container contents: switched active note ${relinkedNote.id} to ${targetContainerId}`,\n );\n return relinkedNote;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentStructureTypes.js","sourceRoot":"","sources":["documentStructureTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport type { ExecSql, RelinkPersistedDocumentInput } from \"../documents\";\nimport type { ContainerContentsProjectionUserKeyResolver } from \"./projectionKeys\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\nexport type MergeDocumentSummary = (nextDocument: DocumentSummary) => void;\nexport type SetLinkedContainerIdsForDocument = (\n documentId: string,\n linkedContainerIds: ReadonlyArray<string>,\n) => void;\n\nexport type DocumentStructuralMutationRuntime =\n ContainerContentsWorkflowRuntime & {\n resolveProjectionUserKey: ContainerContentsProjectionUserKeyResolver;\n };\n\nexport interface DocumentStructuralMutationRelinkInput\n extends RelinkPersistedDocumentInput {\n commitSideEffect?:\n | ((transactionExecSql: ExecSql) => Promise<void>)\n | undefined;\n contentKeyBundle?: string | null | undefined;\n documentKekTargets?: string | null | undefined;\n documentManifestBundle?: string | null | undefined;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface DocumentStructuralMutationLocalStore<TRuntime> {\n assertCanRotateContentKey: () => Promise<Uint8Array>;\n ensureInitialized: () => Promise<boolean>;\n relink: (\n input: DocumentStructuralMutationRelinkInput,\n ) => Promise<DocumentSummary | null>;\n requestSync: () => void;\n updateRuntime: (runtime: TRuntime) => void;\n}\n\nexport interface DocumentStructuralMutationHost<TRuntime> {\n documentWorkflowRuntime: (containerId: string | null) => TRuntime;\n mergeDocumentSummary: MergeDocumentSummary;\n openDocumentStore: (input: {\n containerId: string | null;\n documentId: string | null;\n localId: string;\n }) => DocumentStructuralMutationLocalStore<TRuntime>;\n}\n"]}
|