@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":"documentSubtreeQueries.js","sourceRoot":"","sources":["documentSubtreeQueries.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport {\n containerDocumentPlacementKey,\n listContainerDocumentTombstoneHoldsForDocuments,\n} from \"../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { compareContainerContentsDocumentSummaries } from \"./documentQueries/rows\";\nimport { listContainerContentsSqlIdBatches } from \"./documentQueries/sql\";\nimport type {\n ContainerContentsContainerSubtreeState,\n ContainerContentsDocumentRuntimeTarget,\n ContainerContentsSharedDocumentSummaries,\n ContainerDocumentQueriesRuntime,\n} from \"./documentQueries/types\";\n\nfunction addContainerContentsDocumentSummaries(\n documentSummariesById: Map<string, DocumentSummary>,\n documentSummaries: ReadonlyArray<DocumentSummary>,\n): void {\n for (const documentSummary of documentSummaries) {\n documentSummariesById.set(documentSummary.id, documentSummary);\n }\n}\n\nasync function listContainerContentsDocumentIdsByContainerIds(\n execSql: ExecSql,\n containerIds: ReadonlyArray<string>,\n): Promise<string[]> {\n const documentIds = new Set<string>();\n\n for (const containerIdBatch of listContainerContentsSqlIdBatches(\n containerIds,\n )) {\n const batchDocumentIds =\n await sqlDocumentContainerProjectionPersistence.listDocumentIdsByContainerIds(\n execSql,\n containerIdBatch,\n );\n for (const documentId of batchDocumentIds) {\n documentIds.add(documentId);\n }\n }\n\n return Array.from(documentIds).sort();\n}\n\nasync function listContainerContentsDocumentSummariesByContainerIdsOrDocumentIds(\n execSql: ExecSql,\n input: {\n containerIds: ReadonlyArray<string>;\n documentIds: ReadonlyArray<string>;\n sortDocumentSummaries: boolean;\n },\n): Promise<DocumentSummary[]> {\n const documentSummariesById = new Map<string, DocumentSummary>();\n\n for (const containerIdBatch of listContainerContentsSqlIdBatches(\n input.containerIds,\n )) {\n addContainerContentsDocumentSummaries(\n documentSummariesById,\n await sqlDocumentsPersistence.listDocumentsByContainerIdsOrDocumentIds(\n execSql,\n {\n containerIds: containerIdBatch,\n documentIds: [],\n },\n ),\n );\n }\n\n for (const documentIdBatch of listContainerContentsSqlIdBatches(\n input.documentIds,\n )) {\n addContainerContentsDocumentSummaries(\n documentSummariesById,\n await sqlDocumentsPersistence.listDocumentsByContainerIdsOrDocumentIds(\n execSql,\n {\n containerIds: [],\n documentIds: documentIdBatch,\n },\n ),\n );\n }\n\n const documentSummaries = Array.from(documentSummariesById.values());\n return input.sortDocumentSummaries\n ? documentSummaries.sort(compareContainerContentsDocumentSummaries)\n : documentSummaries;\n}\n\nfunction heldPlacementKey(\n documentId: string | null,\n containerId: string,\n): string {\n return containerDocumentPlacementKey({\n containerId,\n documentId: documentId ?? \"\",\n });\n}\n\nfunction withoutHeldPlacements(\n linkedContainerIdsByDocumentId: ReadonlyMap<string, ReadonlyArray<string>>,\n holds: ReadonlyArray<{ containerId: string; documentId: string }>,\n): {\n held: ReadonlySet<string>;\n links: ReadonlyMap<string, ReadonlyArray<string>>;\n} {\n const held = new Set(\n holds.map((hold) => heldPlacementKey(hold.documentId, hold.containerId)),\n );\n if (held.size === 0) {\n return { held, links: linkedContainerIdsByDocumentId };\n }\n return {\n held,\n links: new Map(\n Array.from(linkedContainerIdsByDocumentId, ([documentId, ids]) => [\n documentId,\n ids.filter((id) => !held.has(heldPlacementKey(documentId, id))),\n ]),\n ),\n };\n}\n\n/**\n * Shared batched read pipeline for a flat set of container ids: linked\n * document ids → document summaries → linked container ids per document.\n * Sorting is optional so device-first projection reads can skip it.\n */\nexport async function listContainerContentsDocumentsForContainers(\n execSql: ExecSql,\n containerIds: ReadonlyArray<string>,\n options: { sortDocumentSummaries: boolean },\n): Promise<ContainerContentsSharedDocumentSummaries> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const linkedDocumentIds =\n await listContainerContentsDocumentIdsByContainerIds(execSql, containerIds);\n const documentSummaries =\n await listContainerContentsDocumentSummariesByContainerIdsOrDocumentIds(\n execSql,\n {\n containerIds,\n documentIds: linkedDocumentIds,\n sortDocumentSummaries: options.sortDocumentSummaries,\n },\n );\n const documentIds = Array.from(\n new Set(\n documentSummaries.flatMap((documentSummary) =>\n documentSummary.documentId ? [documentSummary.documentId] : [],\n ),\n ),\n );\n const linkedContainerIdsByDocumentId = withoutHeldPlacements(\n await sqlDocumentContainerProjectionPersistence.listLinkedContainerIdsByDocumentIds(\n execSql,\n documentIds,\n ),\n await listContainerDocumentTombstoneHoldsForDocuments(execSql, documentIds),\n );\n\n // An earlier link-id read can race a move. Recheck membership against the\n // summaries and final link read so a fresh trash summary cannot ride stale\n // root ids into the root view. Notification fences reject older summaries.\n // A held placement (a listing tombstone awaiting signed evidence) is not a\n // membership here either, matching the container item and sidebar views.\n const requestedIds = new Set(containerIds);\n return {\n documentSummaries: documentSummaries.filter(\n (summary) =>\n (summary.containerId !== null &&\n requestedIds.has(summary.containerId) &&\n !linkedContainerIdsByDocumentId.held.has(\n heldPlacementKey(summary.documentId, summary.containerId),\n )) ||\n (summary.documentId !== null &&\n linkedContainerIdsByDocumentId.links\n .get(summary.documentId)\n ?.some((id) => requestedIds.has(id))),\n ),\n linkedContainerIdsByDocumentId: linkedContainerIdsByDocumentId.links,\n };\n}\n\nfunction listContainerContentsContainerSubtreeIds(\n containersById: ReadonlyMap<string, ContainerContentsContainerSubtreeState>,\n rootContainerId: string,\n): string[] {\n const childrenByParentId = new Map<string, string[]>();\n for (const containerState of containersById.values()) {\n const parentId = containerState.container.parentId;\n if (parentId === null) {\n continue;\n }\n\n const children = childrenByParentId.get(parentId);\n if (children) {\n children.push(containerState.container.id);\n } else {\n childrenByParentId.set(parentId, [containerState.container.id]);\n }\n }\n\n const subtreeIds: string[] = [];\n const stack = [rootContainerId];\n const visited = new Set<string>();\n while (stack.length > 0) {\n const containerId = stack.pop();\n if (containerId === undefined || visited.has(containerId)) {\n continue;\n }\n visited.add(containerId);\n\n if (containersById.has(containerId)) {\n subtreeIds.push(containerId);\n }\n\n const children = childrenByParentId.get(containerId);\n if (children) {\n stack.push(...children);\n }\n }\n\n return subtreeIds;\n}\n\nfunction resolveContainerContentsDocumentRuntimeContainerId(params: {\n documentSummary: Pick<DocumentSummary, \"containerId\" | \"documentId\">;\n linkedContainerIdsByDocumentId: ReadonlyMap<string, ReadonlyArray<string>>;\n sharedContainerIds: ReadonlySet<string>;\n}): string | null {\n const {\n documentSummary,\n linkedContainerIdsByDocumentId,\n sharedContainerIds,\n } = params;\n if (\n documentSummary.containerId &&\n sharedContainerIds.has(documentSummary.containerId)\n ) {\n return documentSummary.containerId;\n }\n\n if (!documentSummary.documentId) {\n return null;\n }\n\n return (\n linkedContainerIdsByDocumentId\n .get(documentSummary.documentId)\n ?.find((containerId) => sharedContainerIds.has(containerId)) ?? null\n );\n}\n\nasync function listDocumentRuntimeTargetsForContainerSubtree(input: {\n containersById: ReadonlyMap<string, ContainerContentsContainerSubtreeState>;\n execSql: ExecSql;\n rootContainerId: string;\n}): Promise<ContainerContentsDocumentRuntimeTarget[]> {\n const { containersById, execSql, rootContainerId } = input;\n const sharedContainerIds = new Set(\n listContainerContentsContainerSubtreeIds(containersById, rootContainerId),\n );\n if (sharedContainerIds.size === 0) {\n return [];\n }\n\n const { documentSummaries, linkedContainerIdsByDocumentId } =\n await listContainerContentsDocumentsForContainers(\n execSql,\n Array.from(sharedContainerIds),\n { sortDocumentSummaries: true },\n );\n\n return documentSummaries.flatMap((documentSummary) => {\n const runtimeContainerId =\n resolveContainerContentsDocumentRuntimeContainerId({\n documentSummary,\n linkedContainerIdsByDocumentId,\n sharedContainerIds,\n });\n if (!runtimeContainerId) {\n return [];\n }\n\n return [\n {\n documentId: documentSummary.documentId,\n localId: documentSummary.id,\n runtimeContainerId,\n },\n ];\n });\n}\n\nexport function listDocumentRuntimeTargetsForContainerSubtreeFromRuntime({\n runtime,\n ...input\n}: Omit<\n Parameters<typeof listDocumentRuntimeTargetsForContainerSubtree>[0],\n \"execSql\"\n> & {\n runtime: ContainerDocumentQueriesRuntime;\n}): ReturnType<typeof listDocumentRuntimeTargetsForContainerSubtree> {\n return listDocumentRuntimeTargetsForContainerSubtree({\n ...input,\n execSql: runtime.infra.execSql,\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentTombstoneEvidence.js","sourceRoot":"","sources":["documentTombstoneEvidence.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DOCUMENT_NOT_FOUND_ERROR_CODE,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../data/documents/shared/projection\";\nimport { uniqueSortedStrings } from \"../../data/documents/shared/readers\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { reportKeyingVerificationErrorInCauseChain } from \"../../data/keyingProjectionVerification/error\";\nimport { createProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification/userKeyResolver\";\nimport { loadDocumentPurgeCheckpoint } from \"../../data/persistence/documentPurgeCheckpointPersistence\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../principals/runtimePolicyWarmer\";\nimport type {\n ContainerDocumentTombstone,\n ContainerDocumentTombstoneVerdict,\n ContainerDocumentTombstoneVerifier,\n} from \"./documentDiscoveryTypes\";\nimport { documentHeadMatchesOrganization } from \"./documentHeadScope\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\nexport interface VerifiedDocumentHeadLinkSet {\n readonly organizationId: string | null;\n readonly accessEpoch: number;\n /** Present for a signed head; a terminal purge has no live access state. */\n readonly accessStateHash?: string;\n readonly linkedContainerIds: ReadonlyArray<string>;\n}\n\n/**\n * The document's verified head link set, or `null` when no verified head is\n * available: the projection could not be fetched (the requester may no\n * longer read the document, or it was purged) or failed verification.\n */\nexport type DocumentHeadLinkSetLoader = (\n documentId: string,\n expectedManifestHash?: string,\n) => Promise<VerifiedDocumentHeadLinkSet | \"not-found\" | null>;\n\n/** The highest access epoch local state records for the document. */\nexport type LocalDocumentAccessEpochLoader = (\n documentId: string,\n) => Promise<number>;\n\nexport interface DocumentHeadLinkSetLoaderDeps {\n readonly assertDocumentWriterProjectionConsistent: typeof assertDocumentWriterProjectionConsistent;\n readonly loadDocumentPurgeCheckpoint: typeof loadDocumentPurgeCheckpoint;\n}\n\nexport const HEAD_LINK_SET_LOAD_CONCURRENCY = 4;\n/**\n * Head loads per settle. Tombstones beyond it stay unverified and are held\n * for a later, backed-off retry, so a bulk move out of a folder does not cost\n * every device an unbounded burst of fetches before the watermark advances.\n */\nexport const HEAD_LINK_SET_LOADS_PER_RUN = 32;\n\nasync function verifiedHeadLinkSet(\n runtime: ContainerContentsWorkflowRuntime,\n deps: DocumentHeadLinkSetLoaderDeps,\n documentId: string,\n projection: DocumentWriterProjectionResponse,\n): Promise<VerifiedDocumentHeadLinkSet> {\n const verified: { value?: VerifiedDocumentHeadLinkSet } = {};\n await deps.assertDocumentWriterProjectionConsistent(projection, {\n // Only the link set is read; a bundle wrapped to superseded KEK targets\n // still carries the signed head.\n allowStaleContentKeyBundle: true,\n execSql: runtime.infra.execSql,\n onVerifiedAuthorization: (authorization) => {\n const head = authorization.documentManifestByHash.get(\n projection.documentManifest.manifestHash,\n );\n if (head && head.state.documentId === documentId) {\n verified.value = {\n organizationId: head.state.organizationId,\n accessEpoch: head.state.epoch,\n accessStateHash: head.manifestHash,\n linkedContainerIds: uniqueSortedStrings(\n head.state.linkedContainerIds,\n ),\n };\n }\n },\n resolveProjectionUserKey: createProjectionUserKeyResolver(runtime),\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!verified.value) {\n throw new Error(\"Tombstone evidence lacks a verified document head\");\n }\n return verified.value;\n}\n\nasync function reportUnavailableHead(\n runtime: ContainerContentsWorkflowRuntime,\n documentId: string,\n error: unknown,\n): Promise<void> {\n const integrityFailure = await reportKeyingVerificationErrorInCauseChain(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: documentId,\n objectKind: \"document\",\n operation: \"document.tombstone-evidence\",\n },\n );\n try {\n if (\n !integrityFailure &&\n error instanceof ProjectionDependencyUnavailableError\n ) {\n // A policy can advance without changing this document's hash. Drop its\n // cached evidence so the held head can recover on the next run.\n runtime.apiClient.evictDocumentWriterProjection(documentId);\n runtime.util.log(\n `Container contents: tombstone evidence for document ${documentId} is awaiting current policy history`,\n );\n return;\n }\n runtime.util.logError?.(\n \"Container contents: tombstone evidence is unavailable\",\n error,\n );\n } catch {\n // A host logger that throws must not fail the discovery pass.\n }\n}\n\nexport function createDocumentHeadLinkSetLoader(\n runtime: ContainerContentsWorkflowRuntime,\n deps: DocumentHeadLinkSetLoaderDeps = {\n assertDocumentWriterProjectionConsistent,\n loadDocumentPurgeCheckpoint,\n },\n): DocumentHeadLinkSetLoader {\n return async (documentId, expectedManifestHash) => {\n try {\n // A verified purge proof is terminal signed evidence that the document\n // links nothing any more.\n if (\n await deps.loadDocumentPurgeCheckpoint(\n runtime.infra.execSql,\n documentId,\n )\n ) {\n return {\n organizationId: null,\n accessEpoch: Number.MAX_SAFE_INTEGER,\n linkedContainerIds: [],\n };\n }\n // Tombstones require a fresh head. Listings can reuse a matching cached\n // projection, whose signature and local checkpoint are still verified.\n if (!expectedManifestHash)\n runtime.apiClient.evictDocumentWriterProjection(documentId);\n let result = await runtime.apiClient.getDocumentWriterProjectionResult(\n documentId,\n { reportErrors: false },\n );\n if (\n expectedManifestHash &&\n result.ok &&\n result.data.documentManifest.manifestHash !== expectedManifestHash\n ) {\n runtime.apiClient.evictDocumentWriterProjection(documentId);\n result = await runtime.apiClient.getDocumentWriterProjectionResult(\n documentId,\n { reportErrors: false },\n );\n }\n if (!result.ok) {\n if (\n result.status === 404 &&\n result.code === DOCUMENT_NOT_FOUND_ERROR_CODE\n )\n return \"not-found\";\n runtime.util.log(\n `Container contents: tombstone evidence for document ${documentId} is unavailable (${result.status ?? \"offline\"})`,\n );\n return null;\n }\n return await verifiedHeadLinkSet(runtime, deps, documentId, result.data);\n } catch (error) {\n // Any failure leaves the tombstone unverified (held and retried); a\n // thrown error here must not fail the whole discovery pass.\n await reportUnavailableHead(runtime, documentId, error);\n return null;\n }\n };\n}\n\nfunction judgeTombstones(\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n head: VerifiedDocumentHeadLinkSet | null,\n): ContainerDocumentTombstoneVerdict[] {\n return tombstones.map((tombstone): ContainerDocumentTombstoneVerdict => {\n if (head === null) {\n return { kind: \"unverified\", tombstone };\n }\n if (head.linkedContainerIds.includes(tombstone.containerId)) {\n return {\n kind: \"refuted\",\n linkedContainerIds: head.linkedContainerIds,\n tombstone,\n };\n }\n return {\n kind: \"verified\",\n tombstone: {\n ...tombstone,\n accessEpoch: head.accessEpoch,\n linkedContainerIds: head.linkedContainerIds,\n },\n };\n });\n}\n\n/**\n * Judge listing tombstones against each document's verified head link set,\n * fetched once per document with bounded concurrency and a per-run cap. A\n * head whose epoch is below local document state is no evidence: it may be a\n * lagging replica or a replay, and applying it could delete rows a newer\n * listing or settled move wrote.\n */\nexport function createContainerDocumentTombstoneVerifier(\n organizationId: string | undefined,\n loadDocumentHeadLinkSet: DocumentHeadLinkSetLoader,\n loadLocalDocumentAccessEpoch: LocalDocumentAccessEpochLoader,\n): ContainerDocumentTombstoneVerifier {\n return async (tombstones) => {\n const byDocumentId = new Map<string, ContainerDocumentTombstone[]>();\n for (const tombstone of tombstones) {\n const group = byDocumentId.get(tombstone.documentId) ?? [];\n group.push(tombstone);\n byDocumentId.set(tombstone.documentId, group);\n }\n const groups = [...byDocumentId.entries()];\n const verdicts: ContainerDocumentTombstoneVerdict[][] = groups.map(\n ([, group], index): ContainerDocumentTombstoneVerdict[] =>\n index < HEAD_LINK_SET_LOADS_PER_RUN\n ? judgeTombstones(group, null)\n : group.map((tombstone) => ({ kind: \"deferred\", tombstone })),\n );\n let next = 0;\n const worker = async () => {\n while (next < Math.min(groups.length, HEAD_LINK_SET_LOADS_PER_RUN)) {\n const index = next++;\n const entry = groups[index];\n if (!entry) break;\n const [documentId, group] = entry;\n const head = await loadDocumentHeadLinkSet(documentId);\n if (head === null || head === \"not-found\") continue;\n if (!documentHeadMatchesOrganization(head, organizationId)) continue;\n // A local-state read that fails is treated like an unavailable head:\n // the tombstones stay held rather than failing the discovery pass.\n const localEpoch = await loadLocalDocumentAccessEpoch(documentId).catch(\n () => Number.MAX_SAFE_INTEGER,\n );\n if (head.accessEpoch < localEpoch) continue;\n verdicts[index] = judgeTombstones(group, head);\n }\n };\n await Promise.all(\n Array.from(\n { length: Math.min(HEAD_LINK_SET_LOAD_CONCURRENCY, groups.length) },\n worker,\n ),\n );\n return verdicts.flat();\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"documentTombstoneGate.js","sourceRoot":"","sources":["documentTombstoneGate.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { containerDocumentPlacementKey as placementKey } from \"../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence\";\nimport type {\n ContainerDocumentPlacement,\n ContainerDocumentTombstone,\n ContainerDocumentTombstoneVerdict,\n DiscoverContainerDocumentsOptions,\n} from \"./documentDiscoveryTypes\";\n\ntype TombstoneGateStore = Pick<\n DiscoverContainerDocumentsOptions,\n | \"applyContainerDocumentTombstones\"\n | \"holdContainerDocumentTombstones\"\n | \"listHeldContainerDocumentTombstones\"\n | \"listKnownContainerDocumentPlacements\"\n | \"refuteContainerDocumentTombstoneHolds\"\n | \"verifyContainerDocumentTombstones\"\n>;\n\nfunction dedupePlacements<T extends ContainerDocumentPlacement>(\n placements: ReadonlyArray<T>,\n): T[] {\n const seen = new Set<string>();\n return placements.filter((placement) => {\n const key = placementKey(placement);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/**\n * One candidate per placement the device actually holds; the newest server\n * timestamp wins. A tombstone for a placement this device never had has\n * nothing to remove or hide, so its head is not fetched.\n */\nasync function mergeTombstoneCandidates(\n store: TombstoneGateStore,\n listed: ReadonlyArray<ContainerDocumentTombstone>,\n held: ReadonlyArray<ContainerDocumentTombstone>,\n): Promise<ContainerDocumentTombstone[]> {\n const known = new Set(\n (await store.listKnownContainerDocumentPlacements(listed)).map(\n placementKey,\n ),\n );\n const byPlacement = new Map<string, ContainerDocumentTombstone>();\n for (const tombstone of [\n ...held,\n ...listed.filter((tombstone) => known.has(placementKey(tombstone))),\n ]) {\n const key = placementKey(tombstone);\n const current = byPlacement.get(key);\n if (\n !current ||\n Date.parse(current.updatedAt) < Date.parse(tombstone.updatedAt)\n ) {\n byPlacement.set(key, tombstone);\n }\n }\n return [...byPlacement.values()];\n}\n\nfunction assertVerdictsCoverCandidates(\n candidates: ReadonlyArray<ContainerDocumentTombstone>,\n verdicts: ReadonlyArray<ContainerDocumentTombstoneVerdict>,\n): void {\n const verdictKeys = new Set(\n verdicts.map((verdict) => placementKey(verdict.tombstone)),\n );\n if (\n verdictKeys.size !== verdicts.length ||\n verdictKeys.size !== candidates.length ||\n candidates.some((candidate) => !verdictKeys.has(placementKey(candidate)))\n ) {\n throw new Error(\n \"Container document tombstone verification must return one verdict per tombstone\",\n );\n }\n}\n\n/**\n * Apply a tombstone only when the signed head omits its container. Unavailable\n * heads leave hidden placements. A head that still links a container keeps its\n * placement visible, but retains a backed-off retry: even an uncached signed\n * head can lag the listing, so its refutation must not discard an honest move.\n * Listing items pass their own signed-head gate before reaching persistence.\n */\nexport async function settleContainerDocumentTombstones(input: {\n containerIds: ReadonlyArray<string>;\n store: TombstoneGateStore;\n tombstones: ReadonlyArray<ContainerDocumentTombstone>;\n}): Promise<ReadonlyArray<DocumentSummary>> {\n const { store } = input;\n const held = await store.listHeldContainerDocumentTombstones(\n input.containerIds,\n );\n const candidates = await mergeTombstoneCandidates(\n store,\n input.tombstones,\n held,\n );\n if (candidates.length === 0) {\n return [];\n }\n\n const verdicts = await store.verifyContainerDocumentTombstones(candidates);\n assertVerdictsCoverCandidates(candidates, verdicts);\n const verified = verdicts.flatMap((verdict) =>\n verdict.kind === \"verified\" ? [verdict.tombstone] : [],\n );\n const refuted = verdicts.flatMap((verdict) =>\n verdict.kind === \"refuted\" ? [verdict.tombstone] : [],\n );\n const unverified = verdicts.flatMap((verdict) =>\n verdict.kind === \"unverified\" ? [verdict.tombstone] : [],\n );\n const deferred = verdicts.flatMap((verdict) =>\n verdict.kind === \"deferred\"\n ? [{ ...verdict.tombstone, deferred: true }]\n : [],\n );\n // A loaded head is evidence for every placement it links, including holds\n // on this document that were not due this run: make them visible while\n // retaining each retry, since the head may lag any of those tombstones.\n const headLinkedPlacements = verdicts.flatMap((verdict) => {\n if (verdict.kind !== \"verified\" && verdict.kind !== \"refuted\") return [];\n const linked =\n verdict.kind === \"verified\"\n ? verdict.tombstone.linkedContainerIds\n : verdict.linkedContainerIds;\n return linked.map((containerId) => ({\n containerId,\n documentId: verdict.tombstone.documentId,\n }));\n });\n\n const summaries =\n verified.length > 0\n ? await store.applyContainerDocumentTombstones(verified)\n : [];\n const retryKeys = new Set(refuted.map(placementKey));\n const visibleRetries = dedupePlacements(headLinkedPlacements).filter(\n (placement) => !retryKeys.has(placementKey(placement)),\n );\n if (visibleRetries.length > 0) {\n await store.refuteContainerDocumentTombstoneHolds(visibleRetries);\n }\n const retries = [\n ...unverified,\n ...deferred,\n ...refuted.map((tombstone) => ({ ...tombstone, refuted: true })),\n ];\n if (retries.length > 0) await store.holdContainerDocumentTombstones(retries);\n return summaries;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"folderRecovery.js","sourceRoot":"","sources":["folderRecovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,+BAA+B,EAC/B,0BAA0B,GAC3B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACL,gCAAgC,EAChC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,wEAAwE,CAAC;AAahF,MAAM,UAAU,2BAA2B,CAAC,OAAgB;IAC1D,OAAO;QACL,yBAAyB,CAAC,KAEzB;YACC,OAAO,yBAAyB,CAAC,OAAO,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,CAAC,mBAAmB,CAAC,KAEzB;YACC,MAAM,OAAO,GAAG,MAAM,6BAA6B,CACjD,OAAO,EACP,KAAK,CAAC,qBAAqB,CAC5B,CAAC;YACF,OAAO,OAAO,CAAC,GAAG,CAChB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE;gBACnD,MAAM,GAAG,GAAG,MAAM,+BAA+B,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBACtE,IAAI,CAAC;oBACH,IAAI,eAAe;wBACjB,aAAa,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;oBACvD,OAAO;wBACL,GAAG,MAAM;wBACT,GAAG,0BAA0B,CAAC,GAAG,EAAE,iBAAiB,CAAC;qBACtD,CAAC;gBACJ,CAAC;wBAAS,CAAC;oBACT,GAAG,CAAC,IAAI,EAAE,CAAC;gBACb,CAAC;YACH,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;QACD,qBAAqB,CACnB,KAGC;YAED,OAAO,gCAAgC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport { importUpdates } from \"@tearleads/loro\";\nimport {\n createContainerMetadataDocument,\n readContainerMetadataValue,\n} from \"../../data/containers/containerMetadataDocument\";\nimport {\n discardRetainedContainerMetadata,\n listRecoveryFolderMoveIds,\n listRetainedContainerMetadata,\n} from \"../../data/persistence/container-contents/containerRecoveryPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\nexport interface RecoveryFolder {\n containerId: string;\n organizationId: string;\n name: string;\n icon: string | null;\n pendingUpdateCount: number;\n hasStructuralIntent: boolean;\n revision: string;\n}\n\nexport function createFolderRecoveryQueries(execSql: ExecSql) {\n return {\n listRecoveryFolderMoveIds(input: {\n currentOrganizationId: string | null;\n }): Promise<string[]> {\n return listRecoveryFolderMoveIds(execSql, input.currentOrganizationId);\n },\n async listRecoveryFolders(input: {\n currentOrganizationId: string | null;\n }): Promise<RecoveryFolder[]> {\n const records = await listRetainedContainerMetadata(\n execSql,\n input.currentOrganizationId,\n );\n return Promise.all(\n records.map(async ({ metadataUpdates, ...record }) => {\n const doc = await createContainerMetadataDocument(record.containerId);\n try {\n if (metadataUpdates)\n importUpdates(doc, [base64ToBytes(metadataUpdates)]);\n return {\n ...record,\n ...readContainerMetadataValue(doc, \"Untitled folder\"),\n };\n } finally {\n doc.free();\n }\n }),\n );\n },\n discardRecoveryFolder(\n input: Pick<\n RecoveryFolder,\n \"containerId\" | \"organizationId\" | \"revision\"\n >,\n ): Promise<boolean> {\n return discardRetainedContainerMetadata(execSql, input);\n },\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n encodeVersionVector,\n exportFullHistorySnapshot,\n} from \"@tearleads/loro\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { readPullContinuation } from \"../../data/documents/shared/syncPagination\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport type { ContainerContentsPersistence } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport type { PendingUpdateRecord } from \"../../data/sqlite/documentPersistence\";\nimport { settleOutgoingPassAndDecideReArm } from \"../../data/sync/outgoingUpdateSettlement\";\nimport { shouldClearDocumentSyncFailureAfterPass } from \"../documents\";\nimport { applyIncomingContainerMetadataUpdates } from \"./metadataIncomingUpdateIsolation\";\nimport {\n currentMetadataPullContinuation,\n hasCurrentContainerMetadataReadState,\n installContainerMetadataRecord,\n persistContainerMetadataStateFromRuntime,\n} from \"./metadataPersistence\";\nimport {\n type ContainerMetadataSyncAttempt,\n type ContainerMetadataSyncRuntime,\n syncRemoteContainerMetadata,\n} from \"./metadataRemoteSync\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"./metadataStateIsolation\";\nimport { shouldRequestContainerMetadataFollowup } from \"./metadataSyncFollowup\";\n\nexport {\n hasContainerMetadataDocumentUpdateEvent,\n listContainerMetadataDocumentUpdateIds,\n} from \"./metadataEvents\";\nexport {\n installContainerMetadataRecord,\n persistContainerMetadataStateFromRuntime,\n renameContainerMetadataStateFromRuntime,\n setContainerIconMetadataStateFromRuntime,\n} from \"./metadataPersistence\";\n\nimport { invalidateContainerMetadataPullContinuation } from \"./metadataPullContinuationInvalidation\";\nimport {\n cleanupContainerMetadataRegistrationsOnFailure,\n discardUnacceptedContainerMetadataUpdateIds,\n preRegisterMaterializedContainerMetadataUpdateIds,\n} from \"./metadataSyncRegistrations\";\nimport type {\n ContainerMetadataState,\n MissingContainerMetadataState,\n SyncedContainerMetadataState,\n} from \"./metadataTypes\";\n\nexport {\n cleanupContainerMetadataRegistrationsOnFailure,\n preRegisterMaterializedContainerMetadataUpdateIds,\n} from \"./metadataSyncRegistrations\";\nexport type { ContainerMetadataPatch } from \"./metadataTypes\";\n\nexport function settleContainerMetadataOutgoingPass(\n metadataState: ContainerMetadataState,\n attempt: ContainerMetadataSyncAttempt,\n): boolean {\n const shouldReArmOutgoing = settleOutgoingPassAndDecideReArm(metadataState, {\n exhaustedPendingUpdateCount: attempt.synced.exhaustedPendingUpdateCount,\n outgoingUpdateCount: attempt.outgoingUpdateCount,\n rekeyedUpdateCount: attempt.synced.rekeyedPendingUpdateIds.length,\n settledUpdateCount: attempt.synced.settledPendingUpdateIds.length,\n acceptedRecoveryBaseline: attempt.synced.acceptedRecoveryBaseline,\n });\n return (\n attempt.synced.hasDeferredPendingUpdates ||\n shouldReArmOutgoing ||\n attempt.synced.hasIncompletePull\n );\n}\n\nfunction documentWriterProjectionMatchesMetadataSyncResponse(\n writerProjection: DocumentWriterProjectionResponse,\n synced: ContainerMetadataSyncAttempt[\"synced\"],\n): boolean {\n return (\n writerProjection.contentKeyBundle.contentKeyEpoch ===\n synced.response.contentKeyBundle.contentKeyEpoch &&\n writerProjection.contentKeyBundle.linkSetManifestHash ===\n synced.response.contentKeyBundle.linkSetManifestHash &&\n writerProjection.contentKeyBundle.targetHash ===\n synced.response.contentKeyBundle.targetHash &&\n writerProjection.documentKekTargets.linkSetManifestHash ===\n synced.response.documentKekTargets.linkSetManifestHash &&\n writerProjection.documentKekTargets.documentKeyTargetHash ===\n synced.response.documentKekTargets.documentKeyTargetHash\n );\n}\n\nfunction resolveSyncedContainerMetadataWriterProjection(\n metadataState: ContainerMetadataState,\n synced: ContainerMetadataSyncAttempt[\"synced\"],\n): DocumentWriterProjectionResponse | null {\n const writerProjection =\n synced.writerProjection ??\n (metadataState.metadataWriterProjection?.documentId ===\n synced.plan.documentId\n ? metadataState.metadataWriterProjection\n : null);\n return writerProjection &&\n documentWriterProjectionMatchesMetadataSyncResponse(\n writerProjection,\n synced,\n )\n ? writerProjection\n : null;\n}\n\n/**\n * Heals a stale metadata content-key bundle by rotating to a fresh content\n * key anchored by this full-history snapshot.\n */\nfunction metadataRotationSnapshotProvider(\n metadataState: ContainerMetadataState,\n): () => Promise<Uint8Array | null> {\n return async () => exportFullHistorySnapshot(metadataState.doc);\n}\n\ninterface SyncContainerMetadataStateInput {\n forceReadSync?: boolean | undefined;\n isCurrent: () => boolean;\n /**\n * Register sent ids before the network await so early self echoes cannot arm\n * a redundant read-sync. Shared with {@link listContainerMetadataDocumentUpdateIds}.\n */\n locallyAcceptedUpdateIds?: Set<string> | undefined;\n metadataState: ContainerMetadataState;\n onDurableStateNeedsReload?: (() => void) | undefined;\n persistence: ContainerContentsPersistence;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerMetadataSyncRuntime;\n targetSecretKey: Uint8Array;\n}\n\nasync function requestContainerMetadataSync(input: {\n documentId: string;\n metadataState: ContainerMetadataState;\n pendingUpdates: readonly PendingUpdateRecord[];\n sentUpdateIds: string[];\n syncInput: SyncContainerMetadataStateInput;\n}): Promise<ContainerMetadataSyncAttempt | null> {\n const { metadataState, sentUpdateIds, syncInput } = input;\n const { isCurrent, persistence, runtime } = syncInput;\n return cleanupContainerMetadataRegistrationsOnFailure(\n syncInput.locallyAcceptedUpdateIds,\n sentUpdateIds,\n () =>\n syncRemoteContainerMetadata({\n buildRotationSnapshot: metadataRotationSnapshotProvider(metadataState),\n containerId: metadataState.container.id,\n currentDocument: metadataState.doc,\n documentId: input.documentId,\n isCurrent,\n lastCommitLsn: metadataState.record.lastCommitLsn,\n localVersionVector: encodeVersionVector(metadataState.doc),\n onOutgoingUpdatesMaterialized: (updateIds) => {\n if (isCurrent()) {\n preRegisterMaterializedContainerMetadataUpdateIds(\n syncInput.locallyAcceptedUpdateIds,\n sentUpdateIds,\n updateIds,\n );\n }\n },\n onPullContinuationInvalidated: (continuation) =>\n invalidateContainerMetadataPullContinuation({\n continuation,\n isCurrent,\n metadataState,\n persistence,\n runtime,\n }),\n pendingUpdates: input.pendingUpdates,\n persistedState: metadataState.record,\n pullContinuation:\n currentMetadataPullContinuation(metadataState) ?? undefined,\n rekeyPendingUpdate: persistence.rekeyPendingUpdate,\n resolveProjectionUserKey: syncInput.resolveProjectionUserKey,\n runtime,\n targetSecretKey: syncInput.targetSecretKey,\n writerProjection:\n metadataState.metadataWriterProjection?.documentId ===\n input.documentId\n ? metadataState.metadataWriterProjection\n : undefined,\n }),\n );\n}\n\nexport async function syncContainerMetadataState(\n input: SyncContainerMetadataStateInput,\n): Promise<\n SyncedContainerMetadataState | MissingContainerMetadataState | null\n> {\n const { persistence, runtime } = input;\n const liveMetadataState = input.metadataState;\n const { isCurrent } = input;\n if (!isCurrent()) {\n return null;\n }\n const { documentId } = liveMetadataState.record;\n if (!documentId) {\n return null;\n }\n const execSql = runtime.infra.execSql;\n\n const pendingUpdates = await persistence.listPendingUpdates(\n execSql,\n liveMetadataState.container.id,\n );\n if (!isCurrent()) {\n return null;\n }\n if (\n pendingUpdates.length === 0 &&\n currentMetadataPullContinuation(liveMetadataState) === null &&\n !liveMetadataState.record.pullContinuationRecoveryRequired &&\n !input.forceReadSync &&\n hasCurrentContainerMetadataReadState(liveMetadataState.record)\n ) {\n return null;\n }\n const metadataState =\n await createDetachedContainerMetadataState(liveMetadataState);\n if (!isCurrent()) {\n return null;\n }\n\n const sentUpdateIds: string[] = [];\n\n const syncAttempt = await requestContainerMetadataSync({\n documentId,\n metadataState,\n pendingUpdates,\n sentUpdateIds,\n syncInput: input,\n });\n if (!syncAttempt) {\n return null;\n }\n if (!isCurrent()) {\n discardUnacceptedContainerMetadataUpdateIds(\n input.locallyAcceptedUpdateIds,\n sentUpdateIds,\n [],\n );\n return null;\n }\n const finalized = await finalizeContainerMetadataSync({\n documentId,\n isCurrent,\n locallyAcceptedUpdateIds: input.locallyAcceptedUpdateIds,\n metadataState,\n onDurableStateNeedsReload: input.onDurableStateNeedsReload,\n persistence,\n runtime,\n sentUpdateIds,\n syncAttempt,\n });\n if (!isCurrent() || !finalized) {\n return null;\n }\n if (!(\"missing\" in finalized)) {\n installDetachedContainerMetadataState(liveMetadataState, metadataState, {\n preserveConcurrentMetadataEdit: true,\n });\n }\n return finalized;\n}\n\nasync function finalizeContainerMetadataSync(input: {\n documentId: string;\n isCurrent: () => boolean;\n locallyAcceptedUpdateIds: Set<string> | undefined;\n metadataState: ContainerMetadataState;\n onDurableStateNeedsReload?: (() => void) | undefined;\n persistence: ContainerContentsPersistence;\n runtime: ContainerMetadataSyncRuntime;\n sentUpdateIds: readonly string[];\n syncAttempt: ContainerMetadataSyncAttempt;\n}): Promise<\n SyncedContainerMetadataState | MissingContainerMetadataState | null\n> {\n const { metadataState, syncAttempt } = input;\n const { outgoingUpdateCount, synced } = syncAttempt;\n if (!input.isCurrent()) {\n discardUnacceptedContainerMetadataUpdateIds(\n input.locallyAcceptedUpdateIds,\n input.sentUpdateIds,\n [],\n );\n return null;\n }\n // An id sent but not accepted will never be echoed. Accepted ids stay\n // registered until their realtime echo consumes them.\n discardUnacceptedContainerMetadataUpdateIds(\n input.locallyAcceptedUpdateIds,\n input.sentUpdateIds,\n synced.response.acceptedOutgoingUpdateIds,\n );\n metadataState.metadataWriterProjection =\n resolveSyncedContainerMetadataWriterProjection(metadataState, synced);\n if (synced.decryptedUpdates.length > 0) {\n applyIncomingContainerMetadataUpdates(metadataState.doc, synced);\n }\n const persisted = await persistContainerMetadataStateFromRuntime({\n acceptedPendingUpdateIds: synced.settledPendingUpdateIds,\n clearSyncFailure: shouldClearDocumentSyncFailureAfterPass(\n synced,\n outgoingUpdateCount,\n ),\n expectedSyncState: {\n pullContinuation: syncAttempt.consumedPullContinuation ?? null,\n record: syncAttempt.requestRecord,\n },\n metadataState,\n onDurableStateNeedsReload: input.onDurableStateNeedsReload,\n patch: {\n ...synced.persistedState,\n documentId: input.documentId,\n lastCommitLsn:\n synced.response.commitLsn ?? metadataState.record.lastCommitLsn ?? null,\n metadataDocumentId: input.documentId,\n pullContinuation: readPullContinuation(synced.response),\n },\n persistence: input.persistence,\n runtime: input.runtime,\n stillCurrent: input.isCurrent,\n });\n if (!input.isCurrent()) {\n discardUnacceptedContainerMetadataUpdateIds(\n input.locallyAcceptedUpdateIds,\n input.sentUpdateIds,\n [],\n );\n return null;\n }\n if (!persisted) {\n discardUnacceptedContainerMetadataUpdateIds(\n input.locallyAcceptedUpdateIds,\n input.sentUpdateIds,\n [],\n );\n metadataState.metadataWriterProjection = null;\n return { missing: true };\n }\n metadataState.container = persisted.container;\n installContainerMetadataRecord(metadataState, persisted.record);\n if (persisted.pullContinuationSuperseded) {\n // The response's accepted IDs were not durably settled. Treat every\n // pre-registration as unapplied so an early echo cannot hide work that the\n // forced follow-up still needs to reconcile.\n discardUnacceptedContainerMetadataUpdateIds(\n input.locallyAcceptedUpdateIds,\n input.sentUpdateIds,\n [],\n );\n metadataState.metadataWriterProjection = null;\n }\n\n return {\n ...persisted,\n shouldRequestFollowupSync: shouldRequestContainerMetadataFollowup({\n persisted,\n settleOutgoingPass: () =>\n settleContainerMetadataOutgoingPass(metadataState, syncAttempt),\n }),\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataEvents.js","sourceRoot":"","sources":["metadataEvents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAGjF,MAAM,UAAU,uCAAuC,CACrD,MAA8B,EAC9B,cAAwE,EACxE,wBAAsC;IAEtC,0EAA0E;IAC1E,mCAAmC;IACnC,OAAO,CACL,sCAAsC,CACpC,MAAM,EACN,cAAc,EACd,wBAAwB,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,SAAS,CACzE,CAAC,MAAM,GAAG,CAAC,CACb,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,SAAS,4BAA4B,CACnC,KAAoD,EACpD,wBAAiD;IAEjD,IACE,CAAC,wBAAwB;QACzB,CAAC,KAAK,CAAC,SAAS;QAChB,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,wBAAwB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,iBAAiB,GAAG,IAAI,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,sCAAsC,CACpD,MAA8B,EAC9B,cAAwE,EACxE,wBAAsC;IAEtC,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9C,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;QAC3C,IAAI,OAAO,aAAa,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACxD,mBAAmB,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,IAAI,mBAAmB,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE9C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IACE,CAAC,4BAA4B,CAAC,KAAK,CAAC;YACpC,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAC1C,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAE,CAAC;YACnE,SAAS;QACX,CAAC;QACD,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACtC,CAAC","sourcesContent":["import { isDocumentUpdateCreatedEvent } from \"../../data/documents/documentSync\";\nimport type { DocumentRecord } from \"../../data/sqlite/documentPersistence\";\n\nexport function hasContainerMetadataDocumentUpdateEvent(\n events: ReadonlyArray<unknown>,\n metadataStates: Iterable<{ record: Pick<DocumentRecord, \"documentId\"> }>,\n locallyAcceptedUpdateIds?: Set<string>,\n): boolean {\n // A boolean predicate must not consume self-echo ids before the real list\n // pass classifies the same events.\n return (\n listContainerMetadataDocumentUpdateIds(\n events,\n metadataStates,\n locallyAcceptedUpdateIds ? new Set(locallyAcceptedUpdateIds) : undefined,\n ).length > 0\n );\n}\n\n/** Consume local ids and report whether an event still contains a peer id. */\nfunction metadataEventHasRemoteUpdate(\n event: { updateIds?: readonly string[] | undefined },\n locallyAcceptedUpdateIds: Set<string> | undefined,\n): boolean {\n if (\n !locallyAcceptedUpdateIds ||\n !event.updateIds ||\n event.updateIds.length === 0\n ) {\n return true;\n }\n\n let remoteUpdateFound = false;\n for (const updateId of event.updateIds) {\n if (locallyAcceptedUpdateIds.has(updateId)) {\n locallyAcceptedUpdateIds.delete(updateId);\n } else {\n remoteUpdateFound = true;\n }\n }\n return remoteUpdateFound;\n}\n\nexport function listContainerMetadataDocumentUpdateIds(\n events: ReadonlyArray<unknown>,\n metadataStates: Iterable<{ record: Pick<DocumentRecord, \"documentId\"> }>,\n locallyAcceptedUpdateIds?: Set<string>,\n): string[] {\n const metadataDocumentIds = new Set<string>();\n for (const metadataState of metadataStates) {\n if (typeof metadataState.record.documentId === \"string\") {\n metadataDocumentIds.add(metadataState.record.documentId);\n }\n }\n if (metadataDocumentIds.size === 0) return [];\n\n const eventDocumentIds = new Set<string>();\n for (const event of events) {\n if (\n !isDocumentUpdateCreatedEvent(event) ||\n !metadataDocumentIds.has(event.documentId)\n ) {\n continue;\n }\n if (!metadataEventHasRemoteUpdate(event, locallyAcceptedUpdateIds)) {\n continue;\n }\n eventDocumentIds.add(event.documentId);\n }\n\n return Array.from(eventDocumentIds);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataIncomingUpdateIsolation.js","sourceRoot":"","sources":["metadataIncomingUpdateIsolation.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,yDAAyD,CAAC;AAEjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,iCAAiC,EAAE,MAAM,4CAA4C,CAAC;AAC/F,OAAO,EAEL,wBAAwB,GACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,2CAA2C,CAAC;AAIzF,MAAM,CAAC,KAAK,UAAU,gCAAgC,CAAC,KAStD;IACC,MAAM,wBAAwB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;QACpE,MAAM,iCAAiC,CAAC,aAAa,CAAC,CAAC,kBAAkB,CACvE,KAAK,IAAI,EAAE;YACT,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,KAAK,KAAK;gBAAE,OAAO;YAC1C,MAAM,yBAAyB,CAC7B,aAAa,EACb,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,OAAO,CACd,CAAC;QACJ,CAAC,EACD,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,KAAK,KAAK,CACpC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qCAAqC,CACnD,eAA8C,EAC9C,MAA0D;IAE1D,kCAAkC,CAAC,eAAe,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAM/C;IACC,OAAO;QACL,gCAAgC,EAAE,KAAK,EACrC,OAAyC,EACzC,EAAE;YACF,MAAM,gCAAgC,CAAC;gBACrC,GAAG,KAAK;gBACR,OAAO,EAAE;oBACP,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACrC,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,MAAM,EAAE,IAAI;iBACb;aACF,CAAC,CAAC;YACH,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,KAAK,KAAK;gBAAE,OAAO;YAC1C,4BAA4B,CAC1B,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,QAAQ,EACd,OAAO,CACR,CAAC;QACJ,CAAC;QACD,uBAAuB,EAAE,CACvB,MAAuE,EACvE,EAAE,CACF,iCAAiC,CAAC;YAChC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,eAAe,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;SACzC,CAAC;KACL,CAAC;AACJ,CAAC","sourcesContent":["import {\n type DocumentSyncUpdateIsolationError,\n importDecryptedDocumentSyncUpdates,\n validateDocumentSyncUpdateImports,\n} from \"../../data/documents/shared/documentSyncUpdateIsolation\";\nimport type { SyncRemoteDocumentResult } from \"../../data/documents/shared/types\";\nimport { recordDocumentSyncFailure } from \"../../data/sqlite/documentPersistence\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n runSerializedSqlMutation,\n} from \"../../data/sqlite/sqlSchema\";\nimport { reportDocumentSyncQuarantine } from \"../documents/reportDocumentSyncQuarantine\";\nimport type { WorkflowRuntimeUtilInput } from \"../runtimeInput\";\nimport type { ContainerMetadataState } from \"./metadataTypes\";\n\nexport async function recordCurrentMetadataSyncFailure(input: {\n execSql: ExecSql;\n failure: {\n readonly attemptedAt: string;\n readonly message: string;\n readonly status: number | null;\n };\n isCurrent?: (() => boolean) | undefined;\n metadataScope: { appKind: string; localId: string };\n}): Promise<void> {\n await runSerializedSqlMutation(input.execSql, async (lockedExecSql) => {\n await getClientSQLitePersistenceRuntime(lockedExecSql).guardedTransaction(\n async () => {\n if (input.isCurrent?.() === false) return;\n await recordDocumentSyncFailure(\n lockedExecSql,\n input.metadataScope,\n input.failure,\n );\n },\n () => input.isCurrent?.() !== false,\n );\n });\n}\n\nexport function applyIncomingContainerMetadataUpdates(\n currentDocument: ContainerMetadataState[\"doc\"],\n result: Pick<SyncRemoteDocumentResult, \"decryptedUpdates\">,\n): void {\n importDecryptedDocumentSyncUpdates(currentDocument, result.decryptedUpdates);\n}\n\nexport function metadataIncomingUpdateIsolation(input: {\n currentDocument: ContainerMetadataState[\"doc\"];\n execSql: ExecSql;\n isCurrent?: (() => boolean) | undefined;\n logError?: WorkflowRuntimeUtilInput[\"logError\"] | undefined;\n metadataScope: { appKind: string; localId: string };\n}) {\n return {\n onIncomingUpdateIsolationFailure: async (\n failure: DocumentSyncUpdateIsolationError,\n ) => {\n await recordCurrentMetadataSyncFailure({\n ...input,\n failure: {\n attemptedAt: new Date().toISOString(),\n message: failure.message,\n status: null,\n },\n });\n if (input.isCurrent?.() === false) return;\n reportDocumentSyncQuarantine(\n input.currentDocument,\n input.logError,\n failure,\n );\n },\n validateIncomingUpdates: (\n result: Pick<SyncRemoteDocumentResult, \"decryptedUpdates\" | \"response\">,\n ) =>\n validateDocumentSyncUpdateImports({\n currentDocument: input.currentDocument,\n decryptedUpdates: result.decryptedUpdates,\n responseUpdates: result.response.updates,\n }),\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataMutationPreparation.js","sourceRoot":"","sources":["metadataMutationPreparation.ts"],"names":[],"mappings":"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","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport {\n encodeVersionVector,\n exportUpdatesSince,\n importUpdates,\n} from \"@tearleads/loro\";\nimport {\n getDefaultContainerName,\n readContainerMetadataValue,\n writeContainerMetadataValue,\n} from \"../../data/containers/containerMetadataDocument\";\nimport { documentSyncPullContinuationsEqual } from \"../../data/documents/shared/syncPagination\";\nimport { canWriteEffectiveAccessLevel } from \"../../data/keying/accessLevel\";\nimport type { ContainerContentsPersistence } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { ContainerDocumentRecord as DocumentRecord } from \"./containerPersistence\";\nimport {\n type ExpectedContainerMetadataSyncState,\n metadataSyncSecurityContextMatches,\n replaceSupersededMetadataIdentity,\n sameNullableMetadataValue,\n} from \"./metadataSyncSettlement\";\nimport type {\n ContainerMetadataPatch,\n ContainerMetadataState,\n} from \"./metadataTypes\";\n\nexport interface PersistContainerMetadataStateInput {\n acceptedPendingUpdateIds?: readonly string[] | undefined;\n clearSyncFailure?: boolean | undefined;\n execSql: ExecSql;\n expectedSyncState?: ExpectedContainerMetadataSyncState | undefined;\n localMetadataPatch?:\n | Partial<Pick<ContainerMetadataPatch, \"icon\" | \"name\">>\n | undefined;\n localUpdate?: Uint8Array | undefined;\n metadataState: ContainerMetadataState;\n createIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"createIntentSettlement\"];\n moveIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"moveIntentSettlement\"];\n patch?: Partial<ContainerMetadataPatch> | undefined;\n persistence: ContainerContentsPersistence;\n preserveDurableStructureWhenPending?: boolean | undefined;\n saveOptions?:\n | Parameters<ContainerContentsPersistence[\"saveContainer\"]>[3]\n | undefined;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nexport function currentMetadataPullContinuation(\n metadataState: ContainerMetadataState,\n) {\n return Object.hasOwn(metadataState, \"pullContinuation\")\n ? (metadataState.pullContinuation ?? null)\n : (metadataState.record.pullContinuation ?? null);\n}\n\nexport function resolveMetadataSecurityContext(\n metadataState: ContainerMetadataState,\n patch: Partial<ContainerMetadataPatch>,\n) {\n const currentDocumentId = metadataState.record.documentId ?? null;\n const documentId =\n patch.documentId !== undefined ? patch.documentId : currentDocumentId;\n const accessEpoch = patch.accessEpoch ?? metadataState.record.accessEpoch;\n const documentIdChanged = documentId !== currentDocumentId;\n\n return {\n accessEpoch,\n changed:\n documentIdChanged || accessEpoch !== metadataState.record.accessEpoch,\n documentId,\n documentIdChanged,\n };\n}\n\nfunction mergeDurableMetadataCheckpoint(input: {\n durableRecord: DocumentRecord | null;\n metadataState: ContainerMetadataState;\n securityContext: ReturnType<typeof resolveMetadataSecurityContext>;\n}): void {\n const { durableRecord, metadataState, securityContext } = input;\n if (\n !durableRecord?.metadataUpdates ||\n durableRecord.documentId !== metadataState.record.documentId ||\n durableRecord.documentId !== securityContext.documentId ||\n durableRecord.accessEpoch !== metadataState.record.accessEpoch ||\n durableRecord.accessEpoch !== securityContext.accessEpoch\n ) {\n return;\n }\n\n importUpdates(metadataState.doc, [\n base64ToBytes(durableRecord.metadataUpdates),\n ]);\n}\n\nexport async function loadAuthoritativeContainerMetadataState(input: {\n containerId: string;\n execSql: ExecSql;\n persistence: ContainerContentsPersistence;\n}) {\n const stored = await input.persistence.loadContainerMetadataState(\n input.execSql,\n input.containerId,\n );\n return stored?.record\n ? { container: stored.container, record: stored.record }\n : null;\n}\n\nfunction localMetadataWriteAccessWasRevoked(input: {\n authoritativeState: NonNullable<\n Awaited<ReturnType<typeof loadAuthoritativeContainerMetadataState>>\n >;\n mutationInput: PersistContainerMetadataStateInput;\n}): boolean {\n return (\n input.mutationInput.expectedSyncState === undefined &&\n input.mutationInput.localUpdate !== undefined &&\n canWriteEffectiveAccessLevel(\n input.mutationInput.metadataState.container.effectiveAccessLevel,\n ) &&\n !canWriteEffectiveAccessLevel(\n input.authoritativeState.container.effectiveAccessLevel,\n )\n );\n}\n\nasync function prepareRebasedLocalMetadataMutation(input: {\n authoritativeState: NonNullable<\n Awaited<ReturnType<typeof loadAuthoritativeContainerMetadataState>>\n >;\n metadataState: ContainerMetadataState;\n localMetadataPatch:\n | Partial<Pick<ContainerMetadataPatch, \"icon\" | \"name\">>\n | undefined;\n patch: Partial<ContainerMetadataPatch>;\n}) {\n const { authoritativeState, metadataState, patch } = input;\n const replacementVersion = encodeVersionVector(metadataState.doc);\n const replacementMetadata = readContainerMetadataValue(\n metadataState.doc,\n getDefaultContainerName(authoritativeState.container.parentId),\n );\n writeContainerMetadataValue(metadataState.doc, {\n ...replacementMetadata,\n ...input.localMetadataPatch,\n });\n const rebasedMetadataState = {\n ...metadataState,\n container: authoritativeState.container,\n pullContinuation: authoritativeState.record.pullContinuation ?? null,\n record: authoritativeState.record,\n };\n return {\n durableRecord: authoritativeState.record,\n mutationContainer: authoritativeState.container,\n mutationMetadataState: rebasedMetadataState,\n mutationPatch: patch,\n pendingLocalUpdate: exportUpdatesSince(\n metadataState.doc,\n replacementVersion,\n ),\n pullContinuationSuperseded: false,\n securityContext: resolveMetadataSecurityContext(\n rebasedMetadataState,\n patch,\n ),\n securityContextMatches: true,\n };\n}\n\nfunction resolveMetadataSettlementMatch(\n expectedSyncState: ExpectedContainerMetadataSyncState | undefined,\n durableRecord: DocumentRecord | null,\n) {\n if (!expectedSyncState) {\n return {\n contentStateSuperseded: false,\n pullContinuationSuperseded: false,\n securityContextMatches: true,\n };\n }\n const securityContextMatches = metadataSyncSecurityContextMatches(\n durableRecord,\n expectedSyncState.record,\n );\n const progressStateMatches =\n securityContextMatches &&\n sameNullableMetadataValue(\n durableRecord?.lastCommitLsn,\n expectedSyncState.record.lastCommitLsn,\n ) &&\n Boolean(durableRecord?.pullContinuationRecoveryRequired) ===\n Boolean(expectedSyncState.record.pullContinuationRecoveryRequired) &&\n documentSyncPullContinuationsEqual(\n durableRecord?.pullContinuation,\n expectedSyncState.pullContinuation,\n );\n const contentStateMatches =\n progressStateMatches &&\n sameNullableMetadataValue(\n durableRecord?.metadataUpdates,\n expectedSyncState.record.metadataUpdates,\n ) &&\n sameNullableMetadataValue(\n durableRecord?.snapshotEndVersion,\n expectedSyncState.record.snapshotEndVersion,\n );\n return {\n contentStateSuperseded: progressStateMatches && !contentStateMatches,\n pullContinuationSuperseded: !progressStateMatches,\n securityContextMatches,\n };\n}\n\nexport async function prepareContainerMetadataMutation(\n input: PersistContainerMetadataStateInput,\n execSql: ExecSql,\n patch: Partial<ContainerMetadataPatch>,\n) {\n const { metadataState, persistence } = input;\n const authoritativeState = await loadAuthoritativeContainerMetadataState({\n containerId: metadataState.container.id,\n execSql,\n persistence,\n });\n if (!authoritativeState) {\n return {\n authoritativeState: null,\n pullContinuationSuperseded: true,\n securityContextMatches: false,\n };\n }\n if (\n localMetadataWriteAccessWasRevoked({\n authoritativeState,\n mutationInput: input,\n })\n ) {\n await replaceSupersededMetadataIdentity({\n durableRecord: authoritativeState.record,\n metadataState,\n });\n return {\n authoritativeState,\n pullContinuationSuperseded: true,\n securityContextMatches: false,\n };\n }\n const durableRecord = authoritativeState.record;\n const mutationMetadataState = durableRecord\n ? {\n ...metadataState,\n pullContinuation: durableRecord.pullContinuation ?? null,\n record: durableRecord,\n }\n : metadataState;\n const capturedSecurityContextMatches =\n durableRecord !== null &&\n metadataSyncSecurityContextMatches(durableRecord, metadataState.record);\n const {\n contentStateSuperseded,\n pullContinuationSuperseded,\n securityContextMatches,\n } = resolveMetadataSettlementMatch(input.expectedSyncState, durableRecord);\n\n if (\n input.expectedSyncState === undefined &&\n !capturedSecurityContextMatches\n ) {\n await replaceSupersededMetadataIdentity({\n durableRecord: authoritativeState.record,\n metadataState,\n });\n if (input.localUpdate === undefined) {\n return {\n authoritativeState,\n pullContinuationSuperseded: true,\n securityContextMatches: false,\n };\n }\n return prepareRebasedLocalMetadataMutation({\n authoritativeState,\n localMetadataPatch: input.localMetadataPatch,\n metadataState,\n patch,\n });\n }\n const mutationPatch = pullContinuationSuperseded ? {} : patch;\n const securityContext = resolveMetadataSecurityContext(\n mutationMetadataState,\n mutationPatch,\n );\n if (\n securityContextMatches &&\n (input.expectedSyncState === undefined || contentStateSuperseded)\n ) {\n mergeDurableMetadataCheckpoint({\n durableRecord,\n metadataState,\n securityContext,\n });\n }\n return {\n durableRecord,\n mutationContainer: authoritativeState.container,\n mutationMetadataState,\n mutationPatch,\n pendingLocalUpdate: input.localUpdate,\n pullContinuationSuperseded,\n securityContext,\n securityContextMatches,\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataPersistence.js","sourceRoot":"","sources":["metadataPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeVersionVector, exportUpdatesSince } from \"@tearleads/loro\";\nimport {\n getDefaultContainerName,\n readContainerMetadataValue,\n writeContainerMetadataValue,\n} from \"../../data/containers/containerMetadataDocument\";\nimport { createPendingUpdateFields } from \"../../data/documents/documentSync\";\nimport type { ContainerContentsPersistence } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport type { ContainerRecord } from \"../../data/persistence/containers/containerPersistence\";\nimport {\n type ExecSql,\n runSerializedSqlMutation,\n} from \"../../data/sqlite/sqlSchema\";\nimport type { ContainerDocumentRecord as DocumentRecord } from \"./containerPersistence\";\nimport {\n currentMetadataPullContinuation,\n loadAuthoritativeContainerMetadataState,\n type PersistContainerMetadataStateInput,\n prepareContainerMetadataMutation,\n} from \"./metadataMutationPreparation\";\nimport {\n buildContainerMetadataRecord,\n resolveContainerSystemSlot,\n resolveMetadataDocumentId,\n} from \"./metadataRecord\";\nimport { installContainerMetadataRecord } from \"./metadataStateInstallation\";\nimport {\n type ExpectedContainerMetadataSyncState,\n metadataSyncSecurityContextMatches,\n replaceSupersededMetadataIdentity,\n} from \"./metadataSyncSettlement\";\nimport type {\n ContainerMetadataPatch,\n ContainerMetadataState,\n PersistedContainerMetadataState,\n} from \"./metadataTypes\";\nimport type { ContainerContentsWorkflowSqlRuntime } from \"./runtime\";\n\ntype ContainerMetadataPersistenceRuntime = ContainerContentsWorkflowSqlRuntime;\nconst MAX_METADATA_MUTATION_COMMIT_ATTEMPTS = 8;\ntype SaveContainerOptions = Parameters<\n ContainerContentsPersistence[\"saveContainer\"]\n>[3];\n\nexport { hasCurrentContainerMetadataReadState } from \"./metadataReadState\";\nexport { installContainerMetadataRecord } from \"./metadataStateInstallation\";\nexport { currentMetadataPullContinuation };\n\nfunction invalidateMetadataWriterProjection(\n metadataState: ContainerMetadataState,\n securityContextChanged: boolean,\n): void {\n if (securityContextChanged) {\n metadataState.metadataWriterProjection = null;\n }\n}\ntype PreparedContainerMetadataMutation = Awaited<\n ReturnType<typeof prepareContainerMetadataMutation>\n>;\ntype ApplicableContainerMetadataMutation = Exclude<\n PreparedContainerMetadataMutation,\n { authoritativeState: unknown }\n>;\nasync function settleSupersededMetadataMutation(input: {\n acceptedPendingUpdateIds?: readonly string[] | undefined;\n execSql: ExecSql;\n expectedRecord?: DocumentRecord | undefined;\n metadataState: ContainerMetadataState;\n persistence: ContainerContentsPersistence;\n prepared: PreparedContainerMetadataMutation;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<PersistedContainerMetadataState | null> {\n const { metadataState, persistence, prepared } = input;\n const settledState = input.expectedRecord\n ? await persistence.settleAcceptedMetadataPendingUpdates(input.execSql, {\n containerId: metadataState.container.id,\n expectedRecord: input.expectedRecord,\n pendingUpdateIds: input.acceptedPendingUpdateIds ?? [],\n stillCurrent: input.stillCurrent,\n })\n : undefined;\n if (\"authoritativeState\" in prepared) {\n const authoritativeState = settledState ?? prepared.authoritativeState;\n if (!authoritativeState?.record) return null;\n metadataState.container = authoritativeState.container;\n installContainerMetadataRecord(metadataState, authoritativeState.record);\n return {\n container: authoritativeState.container,\n pullContinuationSuperseded: true,\n record: authoritativeState.record,\n syncIdentitySuperseded: true,\n };\n }\n const authoritativeState =\n settledState ??\n (await loadAuthoritativeContainerMetadataState({\n containerId: metadataState.container.id,\n execSql: input.execSql,\n persistence,\n }));\n if (!authoritativeState?.record) return null;\n // The rejected response may already have mutated the live Loro document.\n // Rebuild from the authoritative durable snapshot instead of merging into\n // that losing document, which would retain non-overlapping rejected fields.\n await replaceSupersededMetadataIdentity({\n durableRecord: authoritativeState.record,\n metadataState,\n });\n metadataState.container = authoritativeState.container;\n installContainerMetadataRecord(metadataState, authoritativeState.record);\n return {\n container: authoritativeState.container,\n pullContinuationSuperseded: true,\n record: authoritativeState.record,\n ...(!prepared.securityContextMatches\n ? { syncIdentitySuperseded: true as const }\n : {}),\n };\n}\nasync function persistPreparedMetadataMutation(input: {\n clearSyncFailure?: boolean | undefined;\n createIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"createIntentSettlement\"];\n execSql: ExecSql;\n metadataState: ContainerMetadataState;\n moveIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"moveIntentSettlement\"];\n persistence: ContainerContentsPersistence;\n prepared: ApplicableContainerMetadataMutation;\n acceptedPendingUpdateIds?: readonly string[] | undefined;\n preserveDurableStructureWhenPending?: boolean | undefined;\n saveOptions?: SaveContainerOptions;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n | PersistedContainerMetadataState\n | {\n conflict: true;\n currentState: Awaited<\n ReturnType<ContainerContentsPersistence[\"loadContainerMetadataState\"]>\n >;\n staleServerState?: true;\n }\n> {\n const { metadataState, persistence, prepared } = input;\n const metadata = readContainerMetadataValue(\n metadataState.doc,\n getDefaultContainerName(prepared.mutationContainer.parentId),\n );\n const nextContainer: ContainerRecord = {\n ...prepared.mutationContainer,\n ...(prepared.mutationPatch.effectiveAccessLevel !== undefined\n ? {\n effectiveAccessLevel: prepared.mutationPatch.effectiveAccessLevel,\n }\n : {}),\n organizationId:\n prepared.mutationPatch.organizationId ??\n prepared.mutationContainer.organizationId,\n parentId:\n prepared.mutationPatch.parentId ?? prepared.mutationContainer.parentId,\n metadataDocumentId: resolveMetadataDocumentId(\n prepared.mutationPatch,\n prepared.mutationContainer,\n ),\n systemSlot: resolveContainerSystemSlot(\n prepared.mutationPatch,\n prepared.mutationContainer,\n ),\n name: prepared.mutationPatch.name ?? metadata.name,\n icon:\n prepared.mutationPatch.icon !== undefined\n ? prepared.mutationPatch.icon\n : metadata.icon,\n };\n const nextRecord = buildContainerMetadataRecord({\n metadataState: prepared.mutationMetadataState,\n patch: prepared.mutationPatch,\n securityContext: prepared.securityContext,\n });\n const pendingUpdate = prepared.pendingLocalUpdate\n ? (createPendingUpdateFields(prepared.pendingLocalUpdate) ?? undefined)\n : undefined;\n const committed = await persistence.commitMetadataMutation(input.execSql, {\n acceptedPendingUpdateIds: input.acceptedPendingUpdateIds ?? [],\n clearSyncFailure: input.clearSyncFailure,\n container: nextContainer,\n createIntentSettlement: input.createIntentSettlement,\n expectedContainer: prepared.mutationContainer,\n expectedRecord: prepared.durableRecord,\n moveIntentSettlement: input.moveIntentSettlement,\n pendingUpdate,\n preserveDurableStructureWhenPending:\n input.preserveDurableStructureWhenPending,\n record: nextRecord,\n saveOptions: input.saveOptions,\n settleAcceptedPendingOnConflict:\n input.acceptedPendingUpdateIds !== undefined,\n stillCurrent: input.stillCurrent,\n });\n if (!committed.committed) {\n return {\n conflict: true,\n currentState: committed.currentState,\n ...(committed.staleServerState\n ? { staleServerState: true as const }\n : {}),\n };\n }\n invalidateMetadataWriterProjection(\n metadataState,\n prepared.securityContext.changed,\n );\n return {\n container: committed.container,\n record: nextRecord,\n ...(committed.createIntentSettled\n ? { createIntentSettled: true as const }\n : {}),\n ...(committed.moveIntentSettled\n ? { moveIntentSettled: true as const }\n : {}),\n };\n}\nasync function adoptMetadataCommitConflict(input: {\n currentState: Awaited<\n ReturnType<ContainerContentsPersistence[\"loadContainerMetadataState\"]>\n >;\n expectedRecord: DocumentRecord;\n expectedSyncState?: ExpectedContainerMetadataSyncState | undefined;\n metadataState: ContainerMetadataState;\n staleServerState?: true | undefined;\n}): Promise<PersistedContainerMetadataState | null | \"retry\"> {\n if (!input.staleServerState && input.expectedSyncState === undefined) {\n return \"retry\";\n }\n if (!input.currentState?.record) return null;\n await replaceSupersededMetadataIdentity({\n durableRecord: input.currentState.record,\n metadataState: input.metadataState,\n });\n input.metadataState.container = input.currentState.container;\n installContainerMetadataRecord(\n input.metadataState,\n input.currentState.record,\n );\n return {\n container: input.currentState.container,\n pullContinuationSuperseded: true,\n record: input.currentState.record,\n ...(input.staleServerState ? { mutationSuperseded: true as const } : {}),\n ...(!metadataSyncSecurityContextMatches(\n input.currentState.record,\n input.expectedSyncState?.record ?? input.expectedRecord,\n )\n ? { syncIdentitySuperseded: true as const }\n : {}),\n };\n}\nasync function persistContainerMetadataState(\n input: PersistContainerMetadataStateInput,\n): Promise<PersistedContainerMetadataState | null> {\n const patch = input.patch ?? {};\n const prepareMutation = prepareContainerMetadataMutation;\n return runSerializedSqlMutation(input.execSql, async (lockedExecSql) => {\n for (\n let attempt = 0;\n attempt < MAX_METADATA_MUTATION_COMMIT_ATTEMPTS;\n attempt += 1\n ) {\n const prepared = await prepareMutation(input, lockedExecSql, patch);\n if (input.stillCurrent?.() === false) return null;\n if (\n \"authoritativeState\" in prepared ||\n prepared.pullContinuationSuperseded\n ) {\n return settleSupersededMetadataMutation({\n acceptedPendingUpdateIds: input.acceptedPendingUpdateIds,\n execSql: lockedExecSql,\n expectedRecord: input.expectedSyncState?.record,\n metadataState: input.metadataState,\n persistence: input.persistence,\n prepared,\n stillCurrent: input.stillCurrent,\n });\n }\n const persisted = await persistPreparedMetadataMutation({\n acceptedPendingUpdateIds: input.acceptedPendingUpdateIds,\n clearSyncFailure: input.clearSyncFailure,\n createIntentSettlement: input.createIntentSettlement,\n execSql: lockedExecSql,\n metadataState: input.metadataState,\n moveIntentSettlement: input.moveIntentSettlement,\n persistence: input.persistence,\n prepared,\n preserveDurableStructureWhenPending:\n input.preserveDurableStructureWhenPending,\n saveOptions: input.saveOptions,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n if (!(\"conflict\" in persisted)) return persisted;\n const conflict = await adoptMetadataCommitConflict({\n currentState: persisted.currentState,\n expectedRecord: prepared.durableRecord,\n expectedSyncState: input.expectedSyncState,\n metadataState: input.metadataState,\n staleServerState: persisted.staleServerState,\n });\n if (conflict !== \"retry\") return conflict;\n }\n throw new Error(\n `Container metadata mutation commit gave up after ${MAX_METADATA_MUTATION_COMMIT_ATTEMPTS} concurrent conflicts`,\n );\n });\n}\ntype PersistContainerMetadataStateRuntimeInput = Omit<\n PersistContainerMetadataStateInput,\n \"execSql\"\n> & {\n onDurableStateNeedsReload?: (() => void) | undefined;\n persistence: ContainerContentsPersistence;\n runtime: ContainerMetadataPersistenceRuntime;\n};\n\nexport function persistContainerMetadataStateFromRuntime(\n input: PersistContainerMetadataStateRuntimeInput & {\n expectedSyncState: ExpectedContainerMetadataSyncState;\n },\n): Promise<PersistedContainerMetadataState | null>;\nexport function persistContainerMetadataStateFromRuntime(\n input: PersistContainerMetadataStateRuntimeInput & {\n expectedSyncState?: undefined;\n },\n): Promise<PersistedContainerMetadataState | null>;\nexport async function persistContainerMetadataStateFromRuntime(\n input: PersistContainerMetadataStateRuntimeInput,\n): Promise<PersistedContainerMetadataState | null> {\n const { onDurableStateNeedsReload, runtime, ...persistenceInput } = input;\n const execSql = runtime.infra.execSql;\n const persisted = await persistContainerMetadataState({\n ...persistenceInput,\n execSql,\n });\n if (input.stillCurrent?.() === false) {\n onDurableStateNeedsReload?.();\n return null;\n }\n return persisted;\n}\n\nasync function writeContainerMetadataPatch(input: {\n execSql: ExecSql;\n metadataState: ContainerMetadataState;\n patch: Partial<Pick<ContainerMetadataPatch, \"icon\" | \"name\">>;\n persistence: ContainerContentsPersistence;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<PersistedContainerMetadataState | null> {\n const { execSql, metadataState, patch, persistence } = input;\n const metadata = readContainerMetadataValue(\n metadataState.doc,\n getDefaultContainerName(metadataState.container.parentId),\n );\n const previousVersion = encodeVersionVector(metadataState.doc);\n writeContainerMetadataValue(metadataState.doc, { ...metadata, ...patch });\n const update = exportUpdatesSince(metadataState.doc, previousVersion);\n\n return persistContainerMetadataState({\n execSql,\n localMetadataPatch: patch,\n localUpdate: update,\n metadataState,\n patch,\n persistence,\n stillCurrent: input.stillCurrent,\n });\n}\n\nexport async function renameContainerMetadataStateFromRuntime(input: {\n metadataState: ContainerMetadataState;\n name: string;\n persistence: ContainerContentsPersistence;\n runtime: ContainerMetadataPersistenceRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<PersistedContainerMetadataState | null> {\n const trimmedName = input.name.trim();\n if (!trimmedName) {\n return null;\n }\n\n return writeContainerMetadataPatch({\n execSql: input.runtime.infra.execSql,\n metadataState: input.metadataState,\n patch: { name: trimmedName },\n persistence: input.persistence,\n stillCurrent: input.stillCurrent,\n });\n}\n\nexport async function setContainerIconMetadataStateFromRuntime(input: {\n icon: string | null;\n metadataState: ContainerMetadataState;\n persistence: ContainerContentsPersistence;\n runtime: ContainerMetadataPersistenceRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<PersistedContainerMetadataState | null> {\n return writeContainerMetadataPatch({\n execSql: input.runtime.infra.execSql,\n metadataState: input.metadataState,\n patch: { icon: input.icon?.trim() || null },\n persistence: input.persistence,\n stillCurrent: input.stillCurrent,\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataPullContinuationInvalidation.js","sourceRoot":"","sources":["metadataPullContinuationInvalidation.ts"],"names":[],"mappings":"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","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport { importUpdates } from \"@tearleads/loro\";\nimport {\n type DocumentSyncPullContinuation,\n documentSyncPullContinuationsEqual,\n} from \"../../data/documents/shared/syncPagination\";\nimport type { ContainerContentsPersistence } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport { runSerializedSqlMutation } from \"../../data/sqlite/sqlSchema\";\nimport { currentMetadataPullContinuation } from \"./metadataPersistence\";\nimport type { ContainerMetadataState } from \"./metadataTypes\";\nimport type { ContainerContentsWorkflowSqlRuntime } from \"./runtime\";\n\nfunction metadataInvalidationStateMatches(input: {\n accessEpoch: number;\n continuation: DocumentSyncPullContinuation;\n documentId: string;\n durableRecord: NonNullable<\n Awaited<\n ReturnType<ContainerContentsPersistence[\"loadContainerMetadataRecord\"]>\n >\n >;\n metadataState: ContainerMetadataState;\n}): boolean {\n const {\n accessEpoch,\n continuation,\n documentId,\n durableRecord,\n metadataState,\n } = input;\n return (\n metadataState.record.documentId === documentId &&\n metadataState.record.accessEpoch === accessEpoch &&\n durableRecord.documentId === documentId &&\n durableRecord.accessEpoch === accessEpoch &&\n (durableRecord.accessStateHash ?? null) ===\n (metadataState.record.accessStateHash ?? null) &&\n (durableRecord.contentKeyBundle ?? null) ===\n (metadataState.record.contentKeyBundle ?? null) &&\n (durableRecord.documentKekTargets ?? null) ===\n (metadataState.record.documentKekTargets ?? null) &&\n (durableRecord.documentManifestBundle ?? null) ===\n (metadataState.record.documentManifestBundle ?? null) &&\n documentSyncPullContinuationsEqual(\n currentMetadataPullContinuation(metadataState),\n continuation,\n )\n );\n}\n\nexport async function invalidateContainerMetadataPullContinuation(input: {\n continuation: DocumentSyncPullContinuation;\n isCurrent?: (() => boolean) | undefined;\n metadataState: ContainerMetadataState;\n persistence: ContainerContentsPersistence;\n runtime: ContainerContentsWorkflowSqlRuntime;\n}): Promise<void> {\n const { continuation, metadataState, runtime } = input;\n if (input.isCurrent?.() === false) return;\n const { accessEpoch, documentId } = metadataState.record;\n if (!documentId) return;\n\n await runSerializedSqlMutation(\n runtime.infra.execSql,\n async (lockedExecSql) => {\n if (input.isCurrent?.() === false) return;\n const durableRecord =\n await input.persistence.invalidateMetadataPullContinuation(\n lockedExecSql,\n {\n accessEpoch,\n accessStateHash: metadataState.record.accessStateHash ?? null,\n continuation,\n containerId: metadataState.container.id,\n contentKeyBundle: metadataState.record.contentKeyBundle ?? null,\n documentId,\n documentKekTargets: metadataState.record.documentKekTargets ?? null,\n documentManifestBundle:\n metadataState.record.documentManifestBundle ?? null,\n lastCommitLsn: metadataState.record.lastCommitLsn ?? null,\n stillCurrent: input.isCurrent,\n },\n );\n if (\n input.isCurrent?.() === false ||\n !durableRecord ||\n !metadataInvalidationStateMatches({\n accessEpoch,\n continuation,\n documentId,\n durableRecord,\n metadataState,\n })\n ) {\n return;\n }\n if (durableRecord.metadataUpdates) {\n importUpdates(metadataState.doc, [\n base64ToBytes(durableRecord.metadataUpdates),\n ]);\n }\n const {\n pullContinuation: _stalePullContinuation,\n pullContinuationRecoveryRequired: _staleRecoveryMarker,\n ...liveRecord\n } = metadataState.record;\n metadataState.record = { ...liveRecord, ...durableRecord };\n metadataState.pullContinuation = durableRecord.pullContinuation ?? null;\n },\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataReadState.js","sourceRoot":"","sources":["metadataReadState.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oCAAoC,CAClD,MAMC;IAED,OAAO,CACL,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ;QACxC,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QAC/B,OAAO,MAAM,CAAC,gBAAgB,KAAK,QAAQ;QAC3C,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAClC,OAAO,MAAM,CAAC,kBAAkB,KAAK,QAAQ;QAC7C,MAAM,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;QACpC,OAAO,MAAM,CAAC,sBAAsB,KAAK,QAAQ;QACjD,MAAM,CAAC,sBAAsB,CAAC,MAAM,GAAG,CAAC,CACzC,CAAC;AACJ,CAAC","sourcesContent":["import type { ContainerDocumentRecord as DocumentRecord } from \"./containerPersistence\";\n\nexport function hasCurrentContainerMetadataReadState(\n record: Pick<\n DocumentRecord,\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\"\n | \"lastCommitLsn\"\n >,\n): boolean {\n return (\n typeof record.lastCommitLsn === \"string\" &&\n record.lastCommitLsn.length > 0 &&\n typeof record.contentKeyBundle === \"string\" &&\n record.contentKeyBundle.length > 0 &&\n typeof record.documentKekTargets === \"string\" &&\n record.documentKekTargets.length > 0 &&\n typeof record.documentManifestBundle === \"string\" &&\n record.documentManifestBundle.length > 0\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataRecord.js","sourceRoot":"","sources":["metadataRecord.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { exportAllUpdates } from \"@tearleads/loro\";\nimport type { ContainerRecord } from \"../../data/persistence/containers/containerPersistence\";\nimport type { ContainerDocumentRecord as DocumentRecord } from \"./containerPersistence\";\nimport {\n currentMetadataPullContinuation,\n type resolveMetadataSecurityContext,\n} from \"./metadataMutationPreparation\";\nimport type {\n ContainerMetadataPatch,\n ContainerMetadataState,\n} from \"./metadataTypes\";\n\ntype NullableContainerMetadataDocumentField =\n | \"accessStateHash\"\n | \"lastCommitLsn\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\";\n\nexport function resolveContainerSystemSlot(\n patch: Partial<ContainerMetadataPatch>,\n container: ContainerRecord,\n): NonNullable<ContainerRecord[\"systemSlot\"]> | null {\n return patch.systemSlot ?? container.systemSlot ?? null;\n}\n\nexport function resolveMetadataDocumentId(\n patch: Partial<ContainerMetadataPatch>,\n container: ContainerRecord,\n): ContainerRecord[\"metadataDocumentId\"] {\n return (\n patch.metadataDocumentId ?? patch.documentId ?? container.metadataDocumentId\n );\n}\n\nfunction resolveNullableContainerMetadataDocumentField(\n patch: Partial<ContainerMetadataPatch>,\n key: NullableContainerMetadataDocumentField,\n currentValue: string | null | undefined,\n resetWhenUnpatched = false,\n): string | null {\n if (Object.hasOwn(patch, key)) return patch[key] ?? null;\n return resetWhenUnpatched ? null : (currentValue ?? null);\n}\n\nfunction resolveMetadataPullState(\n metadataState: ContainerMetadataState,\n patch: Partial<ContainerMetadataPatch>,\n securityContextChanged: boolean,\n): Pick<\n DocumentRecord,\n \"pullContinuation\" | \"pullContinuationRecoveryRequired\"\n> {\n if (Object.hasOwn(patch, \"pullContinuation\")) {\n return { pullContinuation: patch.pullContinuation ?? null };\n }\n if (securityContextChanged) return { pullContinuation: null };\n if (metadataState.record.pullContinuationRecoveryRequired) {\n return { pullContinuationRecoveryRequired: true };\n }\n return { pullContinuation: currentMetadataPullContinuation(metadataState) };\n}\n\nexport function buildContainerMetadataRecord(input: {\n metadataState: ContainerMetadataState;\n patch: Partial<ContainerMetadataPatch>;\n securityContext: ReturnType<typeof resolveMetadataSecurityContext>;\n}): DocumentRecord {\n const { metadataState, patch, securityContext } = input;\n return {\n id: metadataState.container.id,\n documentId: securityContext.documentId,\n metadataUpdates:\n patch.metadataUpdates ??\n bytesToBase64(exportAllUpdates(metadataState.doc)),\n snapshotEndVersion: \"\",\n accessEpoch: securityContext.accessEpoch,\n accessStateHash: resolveNullableContainerMetadataDocumentField(\n patch,\n \"accessStateHash\",\n metadataState.record.accessStateHash,\n securityContext.changed,\n ),\n lastCommitLsn: resolveNullableContainerMetadataDocumentField(\n patch,\n \"lastCommitLsn\",\n metadataState.record.lastCommitLsn,\n securityContext.documentIdChanged,\n ),\n contentKeyBundle: resolveNullableContainerMetadataDocumentField(\n patch,\n \"contentKeyBundle\",\n metadataState.record.contentKeyBundle,\n securityContext.changed,\n ),\n documentKekTargets: resolveNullableContainerMetadataDocumentField(\n patch,\n \"documentKekTargets\",\n metadataState.record.documentKekTargets,\n securityContext.changed,\n ),\n documentManifestBundle: resolveNullableContainerMetadataDocumentField(\n patch,\n \"documentManifestBundle\",\n metadataState.record.documentManifestBundle,\n securityContext.changed,\n ),\n ...resolveMetadataPullState(metadataState, patch, securityContext.changed),\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataRemoteSync.js","sourceRoot":"","sources":["metadataRemoteSync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,wEAAwE,CAAC;AAErH,OAAO,EACL,qCAAqC,EACrC,iCAAiC,EAEjC,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kCAAkC,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,sBAAsB,CAAC;AA4DzE,SAAS,kCAAkC,CAAC,KAK3C;IACC,OAAO;QACL,wBAAwB,EACtB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS;YAChD,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,KAAK,CAAC,yBAAyB,IAAI,IAAI,CAAC;QAC/C,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAuC;IAEvC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACjD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,MAAM,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,GAAG,CACd,sFAAsF,CACvF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IACtC,MAAM,aAAa,GAAG;QACpB,OAAO,EAAE,2BAA2B;QACpC,OAAO,EAAE,KAAK,CAAC,WAAW;KAC3B,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM;QACN,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;QAClD,UAAU;QACV,OAAO;QACP,mBAAmB,EAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB;QACrD,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,MAAM,EAAE,KAAK,CAAC,aAAa,IAAI,SAAS;QACxC,GAAG,+BAA+B,CAAC;YACjC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,OAAO;YACP,SAAS;YACT,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ;YAC/B,aAAa;SACd,CAAC;QACF,6BAA6B,EAAE,KAAK,CAAC,6BAA6B;QAClE,6BAA6B,EAAE,KAAK,CAAC,6BAA6B;QAClE,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC;QACtE,uBAAuB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACzC,MAAM,gCAAgC,CAAC;gBACrC,OAAO;gBACP,OAAO,EAAE;oBACP,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACrC,OAAO,EAAE,iCAAiC,CAAC,OAAO,CAAC;oBACnD,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB;gBACD,SAAS;gBACT,aAAa;aACd,CAAC,CAAC;QACL,CAAC;QACD,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,SAAS;QACrD,kBAAkB,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,EAAE,CAC7C,SAAS,EAAE;YACT,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,YAAY,EAAE,QAAQ,CAAC;YAClD,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QAC3B,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;QACxD,sBAAsB,EAAE,qCAAqC,CAAC;YAC5D,SAAS,EAAE,oBAAoB;YAC/B,OAAO;YACP,cAAc,EAAE,qBAAqB;SACtC,CAAC;QACF,YAAY,EAAE,SAAS;QACvB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,+BAA+B,EAC7B,kCAAkC,CAAC,OAAO,CAAC;QAC7C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;KACzC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAC1B,iCAAiC,CAAC;QAChC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,KAAK;QACL,OAAO;KACR,CAAC,CACH,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,kCAAkC,CAAC;QACxC,mBAAmB,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM;QAChD,yBAAyB,EAAE,KAAK,CAAC,gBAAgB;QACjD,aAAa,EAAE,KAAK,CAAC,cAAc;QACnC,MAAM;KACP,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { CONTAINER_METADATA_APP_KIND } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport type { PendingUpdateRecord } from \"../../data/sqlite/documentPersistence\";\nimport {\n createDocumentWriterPublicKeyResolver,\n describeDocumentSyncSubmitFailure,\n type RekeyPendingUpdate,\n resolveDocumentCreateAuthor,\n syncRemoteDocument,\n} from \"../documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../principals/runtimePolicyWarmer\";\nimport {\n metadataIncomingUpdateIsolation,\n recordCurrentMetadataSyncFailure,\n} from \"./metadataIncomingUpdateIsolation\";\nimport { deferRecoverableMetadataSyncError } from \"./metadataSyncErrors\";\nimport type { ContainerMetadataState } from \"./metadataTypes\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\ntype ContainerMetadataSyncApi = Parameters<\n typeof syncRemoteDocument\n>[0][\"apiClient\"] &\n Pick<\n ContainerContentsWorkflowRuntime[\"apiClient\"],\n \"getPrincipalPolicyPages\" | \"getProjectionPolicyHistoryPages\"\n >;\n\nexport interface ContainerMetadataSyncRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n apiClient: ContainerMetadataSyncApi;\n}\n\ntype ContainerMetadataSyncResult = NonNullable<\n Awaited<ReturnType<typeof syncRemoteDocument>>\n>;\n\nexport interface ContainerMetadataSyncAttempt {\n consumedPullContinuation: ContainerMetadataState[\"pullContinuation\"];\n outgoingUpdateCount: number;\n requestRecord: ContainerMetadataState[\"record\"];\n synced: ContainerMetadataSyncResult;\n}\n\ninterface SyncRemoteContainerMetadataInput {\n buildRotationSnapshot?: (() => Promise<Uint8Array | null>) | undefined;\n containerId: string;\n currentDocument: ContainerMetadataState[\"doc\"];\n documentId: string | null;\n isCurrent: () => boolean;\n lastCommitLsn?: string | null | undefined;\n localVersionVector: string | null;\n onOutgoingUpdatesMaterialized?:\n | ((updateIds: readonly string[]) => void)\n | undefined;\n onPullContinuationInvalidated?: Parameters<\n typeof syncRemoteDocument\n >[0][\"onPullContinuationInvalidated\"];\n pendingUpdates: readonly PendingUpdateRecord[];\n persistedState: ContainerMetadataState[\"record\"];\n pullContinuation?: ContainerMetadataState[\"pullContinuation\"];\n rekeyPendingUpdate: RekeyPendingUpdate;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerMetadataSyncRuntime;\n targetSecretKey: Uint8Array;\n writerProjection?: DocumentWriterProjectionResponse | undefined;\n}\n\nfunction createContainerMetadataSyncAttempt(input: {\n outgoingUpdateCount: number;\n requestedPullContinuation: ContainerMetadataState[\"pullContinuation\"];\n requestRecord: ContainerMetadataState[\"record\"];\n synced: ContainerMetadataSyncResult;\n}): ContainerMetadataSyncAttempt {\n return {\n consumedPullContinuation:\n input.synced.plan.request.pullCursor === undefined\n ? null\n : (input.requestedPullContinuation ?? null),\n outgoingUpdateCount: input.outgoingUpdateCount,\n requestRecord: input.requestRecord,\n synced: input.synced,\n };\n}\n\nexport async function syncRemoteContainerMetadata(\n input: SyncRemoteContainerMetadataInput,\n): Promise<ContainerMetadataSyncAttempt | null> {\n const { documentId, isCurrent, runtime } = input;\n if (!documentId) return null;\n const author = resolveDocumentCreateAuthor(runtime);\n if (!author) {\n runtime.util.log(\n \"Container contents: skipped metadata sync because the writer context is unavailable.\",\n );\n return null;\n }\n const execSql = runtime.infra.execSql;\n const metadataScope = {\n appKind: CONTAINER_METADATA_APP_KIND,\n localId: input.containerId,\n };\n const synced = await syncRemoteDocument({\n apiClient: runtime.apiClient,\n author,\n buildRotationSnapshot: input.buildRotationSnapshot,\n documentId,\n execSql,\n isRemoteSyncBlocked: runtime.util.isRemoteSyncBlocked,\n localVersionVector: input.localVersionVector,\n minLsn: input.lastCommitLsn ?? undefined,\n ...metadataIncomingUpdateIsolation({\n currentDocument: input.currentDocument,\n execSql,\n isCurrent,\n logError: runtime.util.logError,\n metadataScope,\n }),\n onOutgoingUpdatesMaterialized: input.onOutgoingUpdatesMaterialized,\n onPullContinuationInvalidated: input.onPullContinuationInvalidated,\n onSyncTrace: (line) => runtime.util.log(`Container contents: ${line}`),\n onTerminalSubmitFailure: async (failure) => {\n await recordCurrentMetadataSyncFailure({\n execSql,\n failure: {\n attemptedAt: new Date().toISOString(),\n message: describeDocumentSyncSubmitFailure(failure),\n status: failure.status,\n },\n isCurrent,\n metadataScope,\n });\n },\n pendingUpdates: input.pendingUpdates,\n persistedState: input.persistedState,\n pullContinuation: input.pullContinuation ?? undefined,\n rekeyPendingUpdate: (rekeyExecSql, updateId) =>\n isCurrent()\n ? input.rekeyPendingUpdate(rekeyExecSql, updateId)\n : Promise.resolve(null),\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveWriterPublicKey: createDocumentWriterPublicKeyResolver({\n logPrefix: \"Container contents\",\n runtime,\n writerKeyLabel: \"metadata writer key\",\n }),\n stillCurrent: isCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n writerProjection: input.writerProjection,\n }).catch((error: unknown) =>\n deferRecoverableMetadataSyncError({\n containerId: input.containerId,\n error,\n runtime,\n }),\n );\n if (!synced) return null;\n return createContainerMetadataSyncAttempt({\n outgoingUpdateCount: input.pendingUpdates.length,\n requestedPullContinuation: input.pullContinuation,\n requestRecord: input.persistedState,\n synced,\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataStateInstallation.js","sourceRoot":"","sources":["metadataStateInstallation.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,8BAA8B,CAC5C,aAAqC,EACrC,MAA+B;IAE/B,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;IAC9B,aAAa,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC;AACnE,CAAC","sourcesContent":["import type { ContainerDocumentRecord } from \"./containerPersistence\";\nimport type { ContainerMetadataState } from \"./metadataTypes\";\n\nexport function installContainerMetadataRecord(\n metadataState: ContainerMetadataState,\n record: ContainerDocumentRecord,\n): void {\n metadataState.record = record;\n metadataState.pullContinuation = record.pullContinuation ?? null;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataStateIsolation.js","sourceRoot":"","sources":["metadataStateIsolation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,aAAa,EACb,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,+BAA+B,EAC/B,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,kCAAkC,EAAE,MAAM,0BAA0B,CAAC;AAE9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAe9D,SAAS,6BAA6B,CACpC,UAA4C,EAC5C,eAAiD;IAEjD,IAAI,kCAAkC,CAAC,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC;QACpE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,yEAAyE;IACzE,uEAAuE;IACvE,gEAAgE;IAChE,OAAO;QACL,GAAG,eAAe;QAClB,eAAe,EAAE,UAAU,CAAC,eAAe;QAC3C,kBAAkB,EAAE,UAAU,CAAC,kBAAkB;QACjD,GAAG,CAAC,UAAU,CAAC,kBAAkB,KAAK,SAAS;YAC7C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,kBAAkB,EAAE,UAAU,CAAC,kBAAkB,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,aAAqC,EACrC,UAMI,EAAE;IAEN,MAAM,GAAG,GAAG,MAAM,+BAA+B,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC9E,cAAc,CAAC,GAAG,EAAE,yBAAyB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,OAAO;QACL,GAAG,aAAa;QAChB,SAAS,EAAE,EAAE,GAAG,aAAa,CAAC,SAAS,EAAE;QACzC,cAAc,EAAE;YACd,eAAe,EAAE,mBAAmB,CAAC,aAAa,CAAC,GAAG,CAAC;YACvD,0BAA0B,EACxB,OAAO,CAAC,0BAA0B;gBAClC,oBAAoB,CAAC,aAAa,CAAC;SACtC;QACD,GAAG;QACH,MAAM,EAAE,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qCAAqC,CACnD,MAA8B,EAC9B,SAAyC,EACzC,UAAmD,EAAE;IAErD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,SAAS,CAAC,MAAM,CAAC;IACpE,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,wBAAwB,GAAG,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,MAAM,oBAAoB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACrD,MAAM,8BAA8B,GAClC,OAAO,CAAC,8BAA8B,KAAK,IAAI;QAC/C,mBAAmB,KAAK,SAAS,CAAC,cAAc,CAAC,eAAe;QAChE,CAAC,sBAAsB,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,CAAC;IACzE,MAAM,eAAe,GAAG,8BAA8B;QACpD,CAAC,CAAC,6BAA6B,CAAC,UAAU,EAAE,eAAe,CAAC;QAC5D,CAAC,CAAC,eAAe,CAAC;IAEpB,IAAI,8BAA8B,EAAE,CAAC;QACnC,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,0BAA0B,CACzC,MAAM,CAAC,GAAG,EACV,uBAAuB,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CACtD,CAAC;QACF,MAAM,CAAC,SAAS,GAAG;YACjB,GAAG,SAAS,CAAC,SAAS;YACtB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;SACpB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;QACvC,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;IAC7B,CAAC;IACD,wEAAwE;IACxE,4EAA4E;IAC5E,kEAAkE;IAClE,IACE,oBAAoB,CAAC,MAAM,CAAC;QAC5B,SAAS,CAAC,cAAc,CAAC,0BAA0B;QAEnD,MAAM,CAAC,wBAAwB,GAAG,SAAS,CAAC,wBAAwB,CAAC;IACvE,MAAM,CAAC,gBAAgB,GAAG,8BAA8B;QACtD,CAAC,CAAC,kCAAkC,CAAC,UAAU,EAAE,eAAe,CAAC;YAC/D,CAAC,CAAC,oBAAoB;YACtB,CAAC,CAAC,CAAC,eAAe,CAAC,gBAAgB,IAAI,IAAI,CAAC;QAC9C,CAAC,CAAC,CAAC,eAAe,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC;IAChC,MAAM,CAAC,kBAAkB,GAAG,SAAS,CAAC,kBAAkB,CAAC;AAC3D,CAAC","sourcesContent":["import {\n encodeVersionVector,\n exportAllUpdates,\n exportFullHistorySnapshot,\n importSnapshot,\n importUpdates,\n satisfiesVersionVector,\n} from \"@tearleads/loro\";\nimport {\n createContainerMetadataDocument,\n getDefaultContainerName,\n readContainerMetadataValue,\n} from \"../../data/containers/containerMetadataDocument\";\nimport { metadataSyncSecurityContextMatches } from \"./metadataSyncSettlement\";\nimport type { ContainerMetadataState } from \"./metadataTypes\";\nimport { projectionGeneration } from \"./projectionGeneration\";\n\nexport interface DetachedContainerMetadataState extends ContainerMetadataState {\n readonly detachedSource: {\n readonly metadataVersion: string;\n /** The live state's `writerProjectionGeneration` when it was detached. */\n readonly writerProjectionGeneration: number;\n };\n}\n\ninterface DetachedContainerMetadataInstallOptions {\n readonly candidateRecord?: ContainerMetadataState[\"record\"];\n readonly preserveConcurrentMetadataEdit?: boolean;\n}\n\nfunction mergeConcurrentMetadataRecord(\n liveRecord: ContainerMetadataState[\"record\"],\n candidateRecord: ContainerMetadataState[\"record\"],\n): ContainerMetadataState[\"record\"] {\n if (metadataSyncSecurityContextMatches(liveRecord, candidateRecord)) {\n return liveRecord;\n }\n\n // The live document owns the concurrent CRDT frontier, but the candidate\n // owns the newly committed remote identity. Carry only the fields that\n // describe the live CRDT history across that identity boundary.\n return {\n ...candidateRecord,\n metadataUpdates: liveRecord.metadataUpdates,\n snapshotEndVersion: liveRecord.snapshotEndVersion,\n ...(liveRecord.pendingBaseVersion === undefined\n ? {}\n : { pendingBaseVersion: liveRecord.pendingBaseVersion }),\n };\n}\n\n/**\n * Gives an asynchronous sync pass its own mutable metadata projection. Durable\n * settlement can then repair or replace the candidate without changing the\n * live store until the caller has rechecked its lifecycle generation.\n */\nexport async function createDetachedContainerMetadataState(\n metadataState: ContainerMetadataState,\n options: {\n /**\n * The live generation captured when the surrounding operation began, for\n * callers that awaited (a request, a policy warm-up) before detaching.\n */\n readonly writerProjectionGeneration?: number | undefined;\n } = {},\n): Promise<DetachedContainerMetadataState> {\n const doc = await createContainerMetadataDocument(metadataState.container.id);\n importSnapshot(doc, exportFullHistorySnapshot(metadataState.doc));\n return {\n ...metadataState,\n container: { ...metadataState.container },\n detachedSource: {\n metadataVersion: encodeVersionVector(metadataState.doc),\n writerProjectionGeneration:\n options.writerProjectionGeneration ??\n projectionGeneration(metadataState),\n },\n doc,\n record: { ...metadataState.record },\n };\n}\n\nexport function installDetachedContainerMetadataState(\n target: ContainerMetadataState,\n candidate: DetachedContainerMetadataState,\n options: DetachedContainerMetadataInstallOptions = {},\n): void {\n const candidateRecord = options.candidateRecord ?? candidate.record;\n const liveMetadataVersion = encodeVersionVector(target.doc);\n const candidateMetadataVersion = encodeVersionVector(candidate.doc);\n const liveRecord = target.record;\n const livePullContinuation = target.pullContinuation;\n const preserveConcurrentLiveMetadata =\n options.preserveConcurrentMetadataEdit === true &&\n liveMetadataVersion !== candidate.detachedSource.metadataVersion &&\n !satisfiesVersionVector(candidateMetadataVersion, liveMetadataVersion);\n const installedRecord = preserveConcurrentLiveMetadata\n ? mergeConcurrentMetadataRecord(liveRecord, candidateRecord)\n : candidateRecord;\n\n if (preserveConcurrentLiveMetadata) {\n importUpdates(target.doc, [exportAllUpdates(candidate.doc)]);\n const metadata = readContainerMetadataValue(\n target.doc,\n getDefaultContainerName(candidate.container.parentId),\n );\n target.container = {\n ...candidate.container,\n icon: metadata.icon,\n name: metadata.name,\n };\n } else {\n target.container = candidate.container;\n target.doc = candidate.doc;\n }\n // A hint invalidated the live projections while this candidate was out;\n // its copy may cite a pre-hint manifest, so the live slot stays as the hint\n // left it and the next metadata write fetches a fresh projection.\n if (\n projectionGeneration(target) ===\n candidate.detachedSource.writerProjectionGeneration\n )\n target.metadataWriterProjection = candidate.metadataWriterProjection;\n target.pullContinuation = preserveConcurrentLiveMetadata\n ? metadataSyncSecurityContextMatches(liveRecord, candidateRecord)\n ? livePullContinuation\n : (candidateRecord.pullContinuation ?? null)\n : (candidateRecord.pullContinuation ?? null);\n target.record = installedRecord;\n target.rekeyOnlyPassCount = candidate.rekeyOnlyPassCount;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataSyncErrors.js","sourceRoot":"","sources":["metadataSyncErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,yDAAyD,CAAC;AAC7G,OAAO,EACL,yBAAyB,EACzB,yCAAyC,GAC1C,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,+BAA+B,EAAE,MAAM,qEAAqE,CAAC;AAGtH,SAAS,0CAA0C,CAAC,KAAc;IAChE,4EAA4E;IAC5E,2EAA2E;IAC3E,IAAI,yBAAyB,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5D,OAAO,CACL,OAAO,CAAC,UAAU,CAChB,gEAAgE,CACjE;QACD,OAAO,CAAC,UAAU,CAAC,6CAA6C,CAAC;QACjE,OAAO,CAAC,UAAU,CAAC,sCAAsC,CAAC;QAC1D,OAAO,CAAC,UAAU,CAAC,iDAAiD,CAAC;QACrE,OAAO,CAAC,UAAU,CAAC,gCAAgC,CAAC;QACpD,OAAO,KAAK,oCAAoC;QAChD,OAAO,KAAK,4CAA4C,CACzD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CAAC,KAUvD;IACC,IAAI,kCAAkC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,yCAAyC,CAC7C,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EACzC;YACE,QAAQ,EAAE,KAAK,CAAC,WAAW;YAC3B,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,yBAAyB;YACpC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc;SAClD,CACF,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CACpB,iEAAiE,KAAK,CAAC,WAAW,kEAAkE,CACrJ,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,0CAA0C,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CACpB,kDAAkD,KAAK,CAAC,WAAW,6CAA6C,CACjH,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,IAAI,+BAA+B,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CACpB,kDAAkD,KAAK,CAAC,WAAW,2DAA2D,CAC/H,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,CAAC,KAAK,CAAC;AACpB,CAAC","sourcesContent":["import { isDocumentSyncUpdateIsolationError } from \"../../data/documents/shared/documentSyncUpdateIsolation\";\nimport {\n isKeyingVerificationError,\n reportKeyingVerificationErrorInCauseChain,\n} from \"../../data/keyingProjectionVerification/error\";\nimport { isPrincipalPolicyNotCachedError } from \"../../data/keyingProjectionVerification/principalPolicyVerification\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\n\nfunction isStaleContainerMetadataSecurityStateError(error: unknown): boolean {\n // Signed-state verification failures are terminal integrity incidents, even\n // when their diagnostic message resembles an ordinary stale-key condition.\n if (isKeyingVerificationError(error)) return false;\n const message = error instanceof Error ? error.message : \"\";\n\n return (\n message.startsWith(\n \"Document authorizing container KEK path could not be unwrapped\",\n ) ||\n message.startsWith(\"Document content key could not be unwrapped\") ||\n message.startsWith(\"Document content-key bundle is stale\") ||\n message.startsWith(\"Document content-key re-wrap KEK is unavailable\") ||\n message.startsWith(\"Document stale-bundle recovery\") ||\n message === \"Document sync target hash mismatch\" ||\n message === \"Document sync content-key targets mismatch\"\n );\n}\n\nexport async function deferRecoverableMetadataSyncError(input: {\n containerId: string;\n error: unknown;\n runtime: {\n auth: { organizationId: string | null };\n util: {\n log: (message: string) => void;\n reportSecurityIncident: SecurityIncidentReporter;\n };\n };\n}): Promise<null> {\n if (isDocumentSyncUpdateIsolationError(input.error)) {\n await reportKeyingVerificationErrorInCauseChain(\n input.error,\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.containerId,\n objectKind: \"container\",\n operation: \"container.metadata.sync\",\n organizationId: input.runtime.auth.organizationId,\n },\n );\n input.runtime.util.log(\n `Container contents: quarantined incoming metadata updates for ${input.containerId}; deferred this container without blocking later metadata syncs.`,\n );\n return null;\n }\n\n if (isStaleContainerMetadataSecurityStateError(input.error)) {\n input.runtime.util.log(\n `Container contents: deferred metadata sync for ${input.containerId} because its content-key targets are stale.`,\n );\n return null;\n }\n\n // A cold principal-policy cache is transient: warming already ran and failed\n // within this attempt. Keep the needing-sync state set for the next trigger.\n if (isPrincipalPolicyNotCachedError(input.error)) {\n input.runtime.util.log(\n `Container contents: deferred metadata sync for ${input.containerId} because a referenced principal policy is not cached yet.`,\n );\n return null;\n }\n\n throw input.error;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataSyncSettlement.js","sourceRoot":"","sources":["metadataSyncSettlement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,+BAA+B,EAAE,MAAM,iDAAiD,CAAC;AAUlG,MAAM,UAAU,yBAAyB,CACvC,IAA+B,EAC/B,KAAgC;IAEhC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,OAA8B,EAC9B,QAAwB;IAExB,OAAO,CACL,OAAO,KAAK,IAAI;QAChB,OAAO,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE;QAC1B,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;QAC1C,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW;QAC5C,yBAAyB,CACvB,OAAO,CAAC,eAAe,EACvB,QAAQ,CAAC,eAAe,CACzB;QACD,yBAAyB,CACvB,OAAO,CAAC,gBAAgB,EACxB,QAAQ,CAAC,gBAAgB,CAC1B;QACD,yBAAyB,CACvB,OAAO,CAAC,kBAAkB,EAC1B,QAAQ,CAAC,kBAAkB,CAC5B;QACD,yBAAyB,CACvB,OAAO,CAAC,sBAAsB,EAC9B,QAAQ,CAAC,sBAAsB,CAChC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CAAC,KAGvD;IACC,MAAM,cAAc,GAAG,MAAM,+BAA+B,CAC1D,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CACjC,CAAC;IACF,IAAI,KAAK,CAAC,aAAa,EAAE,eAAe,EAAE,CAAC;QACzC,aAAa,CAAC,cAAc,EAAE;YAC5B,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,GAAG,GAAG,cAAc,CAAC;IACzC,KAAK,CAAC,aAAa,CAAC,wBAAwB,GAAG,IAAI,CAAC;AACtD,CAAC","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport { importUpdates } from \"@tearleads/loro\";\nimport { createContainerMetadataDocument } from \"../../data/containers/containerMetadataDocument\";\nimport type { DocumentSyncPullContinuation } from \"../../data/documents/shared/syncPagination\";\nimport type { ContainerDocumentRecord as DocumentRecord } from \"./containerPersistence\";\nimport type { ContainerMetadataState } from \"./metadataTypes\";\n\nexport interface ExpectedContainerMetadataSyncState {\n pullContinuation: DocumentSyncPullContinuation | null;\n record: DocumentRecord;\n}\n\nexport function sameNullableMetadataValue(\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean {\n return (left ?? null) === (right ?? null);\n}\n\nexport function metadataSyncSecurityContextMatches(\n current: DocumentRecord | null,\n expected: DocumentRecord,\n): boolean {\n return (\n current !== null &&\n current.id === expected.id &&\n current.documentId === expected.documentId &&\n current.accessEpoch === expected.accessEpoch &&\n sameNullableMetadataValue(\n current.accessStateHash,\n expected.accessStateHash,\n ) &&\n sameNullableMetadataValue(\n current.contentKeyBundle,\n expected.contentKeyBundle,\n ) &&\n sameNullableMetadataValue(\n current.documentKekTargets,\n expected.documentKekTargets,\n ) &&\n sameNullableMetadataValue(\n current.documentManifestBundle,\n expected.documentManifestBundle,\n )\n );\n}\n\nexport async function replaceSupersededMetadataIdentity(input: {\n durableRecord: DocumentRecord | null;\n metadataState: ContainerMetadataState;\n}): Promise<void> {\n const replacementDoc = await createContainerMetadataDocument(\n input.metadataState.container.id,\n );\n if (input.durableRecord?.metadataUpdates) {\n importUpdates(replacementDoc, [\n base64ToBytes(input.durableRecord.metadataUpdates),\n ]);\n }\n input.metadataState.doc = replacementDoc;\n input.metadataState.metadataWriterProjection = null;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataTypes.js","sourceRoot":"","sources":["metadataTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { ContainerMetadataDocument } from \"../../data/containers/containerMetadataDocument\";\nimport type { DocumentSyncPullContinuation } from \"../../data/documents/shared/syncPagination\";\nimport type { ContainerMetadataRecord } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport type { ContainerRecord } from \"../../data/persistence/containers/containerPersistence\";\n\nexport interface ContainerMetadataState {\n container: ContainerRecord;\n doc: ContainerMetadataDocument;\n metadataWriterProjection?:\n | DocumentWriterProjectionResponse\n | null\n | undefined;\n /** See `ContainerState.writerProjectionGeneration`; shared by both caches. */\n writerProjectionGeneration?: number | undefined;\n /** Durable continuation mirrored from the metadata document record. */\n pullContinuation?: DocumentSyncPullContinuation | null | undefined;\n record: ContainerMetadataRecord;\n /**\n * Consecutive completed sync passes that re-keyed conflicted pending updates\n * without settling anything; bounds the rekey-driven follow-up sync. See\n * shouldReArmAfterOutgoingSettlement.\n */\n rekeyOnlyPassCount?: number | undefined;\n}\n\nexport interface ContainerMetadataPatch {\n accessEpoch: number;\n accessStateHash: string | null;\n effectiveAccessLevel: ContainerRecord[\"effectiveAccessLevel\"];\n documentId: string | null;\n icon: string | null;\n lastCommitLsn: string | null;\n metadataDocumentId: string | null;\n systemSlot: ContainerRecord[\"systemSlot\"];\n metadataUpdates: string;\n name: string;\n organizationId: string;\n parentId: string | null;\n pullContinuation: DocumentSyncPullContinuation | null;\n contentKeyBundle: string | null;\n documentKekTargets: string | null;\n documentManifestBundle: string | null;\n}\n\nexport interface PersistedContainerMetadataState {\n container: ContainerRecord;\n createIntentSettled?: true;\n moveIntentSettled?: true;\n mutationSuperseded?: true;\n pullContinuationSuperseded?: true;\n record: ContainerMetadataRecord;\n syncIdentitySuperseded?: true;\n}\n\nexport interface SyncedContainerMetadataState\n extends PersistedContainerMetadataState {\n shouldRequestFollowupSync: boolean;\n}\n\nexport interface MissingContainerMetadataState {\n missing: true;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"orphanedDocumentSql.js","sourceRoot":"","sources":["orphanedDocumentSql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAErF,MAAM,UAAU,2BAA2B,CAAC,KAG3C;IACC,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IACjD,OAAO;;QAED,eAAe;;;2CAGoB,aAAa;4CACZ,eAAe;;;;;QAKnD,eAAe;WACZ,eAAe;WACf,eAAe;;UAEhB,eAAe,0BAA0B,6BAA6B,CAAC,GAAG,CAC9E,GAAG,EAAE,CAAC,GAAG,CACV,CAAC,IAAI,CAAC,IAAI,CAAC;;QAER,aAAa;;;;mCAIc,aAAa;;;;;;;;;GAS7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,qBAAgD;IAEhD,OAAO,CAAC,qBAAqB,IAAI,EAAE,EAAE,GAAG,6BAA6B,CAAC,CAAC;AACzE,CAAC","sourcesContent":["import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from \"../../data/documents/documentSummary\";\n\nexport function getOrphanedDocumentWhereSql(input: {\n documentIdSql: string;\n projectionAlias: string;\n}): string {\n const { documentIdSql, projectionAlias } = input;\n return `\n (\n ${projectionAlias}.container_id IS NULL\n OR EXISTS (\n SELECT 1 FROM container_document_tombstone_holds primary_hold\n WHERE primary_hold.document_id = ${documentIdSql}\n AND primary_hold.container_id = ${projectionAlias}.container_id\n AND primary_hold.hidden = 1\n )\n )\n AND (\n ${projectionAlias}.organization_id = ?\n OR ${projectionAlias}.organization_id IS NULL\n OR ${projectionAlias}.organization_id = ''\n )\n AND ${projectionAlias}.document_kind NOT IN (${HIDDEN_DOCUMENT_SUMMARY_KINDS.map(\n () => \"?\",\n ).join(\", \")})\n AND (\n ${documentIdSql} IS NULL\n OR NOT EXISTS (\n SELECT 1\n FROM document_container_projection link\n WHERE link.document_id = ${documentIdSql}\n AND NOT EXISTS (\n SELECT 1 FROM container_document_tombstone_holds link_hold\n WHERE link_hold.document_id = link.document_id\n AND link_hold.container_id = link.container_id\n AND link_hold.hidden = 1\n )\n )\n )\n `;\n}\n\nexport function getOrphanedDocumentQueryBind(\n currentOrganizationId: string | null | undefined,\n): ReadonlyArray<string> {\n return [currentOrganizationId ?? \"\", ...HIDDEN_DOCUMENT_SUMMARY_KINDS];\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pendingDownloads.js","sourceRoot":"","sources":["pendingDownloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wDAAwD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAEhG,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAYzE,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB;IAEhB,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,uBAAuB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;;kBAEX,uBAAuB,CAAC,QAAQ,CAAC;;;kBAGjC,uBAAuB,CAAC,QAAQ,CAAC;;;;;;;;;aAStC,uBAAuB,CAAC,QAAQ,CAAC;;;;GAI3C,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,MAAM,EACJ,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,UAAU,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,EACL,MAAM,EACN,UAAU,EAAE,SAAS,GACtB,GAAG,GAAG,CAAC;QACR,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,UAAU,KAAK,QAAQ;YAC/D,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAA6B;YACrC,OAAO;YACP,UAAU;YACV,UAAU,EAAE,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW;YAC9D,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;YAC/C,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc;YACzD,SAAS,EAAE,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;SAC5D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { emptyContentFrontierSql } from \"./documentQueries/hydrationSql\";\n\nexport interface PendingDownloadQueueItem {\n localId: string;\n documentId: string;\n objectKind: \"document\" | \"container\";\n /** Null until content supplies a reliable title and type. */\n title: string | null;\n reason: \"initial\" | \"continuation\";\n lastError: string | null;\n}\n\n/** Durable, already-discovered content pulls, including folder metadata. */\nexport async function listPendingDownloads(\n execSql: ExecSql,\n): Promise<ReadonlyArray<PendingDownloadQueueItem>> {\n await ensureContainerTables(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const rows = await execSql(`\n SELECT stored.local_id, stored.document_id, stored.app_kind,\n CASE WHEN ${emptyContentFrontierSql(\"stored\")} THEN NULL\n WHEN stored.app_kind = 'documents' THEN d.title\n ELSE folder.display_name END AS title,\n CASE WHEN ${emptyContentFrontierSql(\"stored\")} THEN 'initial'\n ELSE 'continuation' END AS reason,\n stored.sync_failure_message AS last_error\n FROM documents stored\n LEFT JOIN document_projection d ON stored.app_kind = 'documents'\n AND d.local_id = stored.local_id\n LEFT JOIN containers folder ON stored.app_kind = 'container-metadata'\n AND folder.id = stored.local_id\n WHERE stored.document_id IS NOT NULL\n AND (${emptyContentFrontierSql(\"stored\")} OR stored.pull_continuation IS NOT NULL)\n AND ((stored.app_kind = 'documents' AND d.local_id IS NOT NULL)\n OR (stored.app_kind = 'container-metadata' AND folder.id IS NOT NULL))\n ORDER BY stored.updated_at, stored.app_kind, stored.local_id\n `);\n return rows.flatMap((row) => {\n const {\n local_id: localId,\n document_id: documentId,\n app_kind: appKind,\n title,\n reason,\n last_error: lastError,\n } = row;\n if (typeof localId !== \"string\" || typeof documentId !== \"string\")\n return [];\n const item: PendingDownloadQueueItem = {\n localId,\n documentId,\n objectKind: appKind === \"documents\" ? \"document\" : \"container\",\n title: typeof title === \"string\" ? title : null,\n reason: reason === \"initial\" ? \"initial\" : \"continuation\",\n lastError: typeof lastError === \"string\" ? lastError : null,\n };\n return [item];\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pendingWrites.js","sourceRoot":"","sources":["pendingWrites.ts"],"names":[],"mappings":"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","sourcesContent":["import { CONTAINER_METADATA_APP_KIND } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport { sqlDocumentMoveIntentPersistence } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport { DOCUMENTS_APP_KIND } from \"../../data/persistence/documents/internal/constants\";\nimport {\n clearDocumentSyncFailure,\n resetDocumentPendingUpdateRekeyBudget,\n} from \"../../data/sqlite/documentPersistence\";\nimport {\n documentPlacementIntentTables,\n documentTables,\n LOCAL_INTENT_LANES,\n} from \"../../data/sqlite/schema\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport { defaultContainerContentsPersistence } from \"./containerPersistence\";\nimport { groupPendingWriteCandidates } from \"./pendingWrites/aggregation\";\nimport {\n hasDeferredTailScopeWork,\n listDeferredPendingWriteCandidates,\n} from \"./pendingWrites/deferredTails\";\nimport { listPersistedPendingWriteCandidates } from \"./pendingWrites/sources\";\nimport type { PendingWriteQueueItem } from \"./pendingWritesTypes\";\n\nexport type {\n PendingWriteQueueItem,\n PendingWriteQueueItemStatus,\n PendingWriteQueueObjectKind,\n PendingWriteQueueOperation,\n PendingWriteQueueOperationKind,\n PendingWriteQueueOperationStatus,\n} from \"./pendingWritesTypes\";\n\n/**\n * List identity-wide local state that still requires a remote write. The\n * returned diagnostic contains only navigation/display metadata and aggregate\n * counts; serialized updates, local storage keys, and upload crypto stay below\n * the workflow boundary.\n */\nexport async function listPendingWrites(\n execSql: ExecSql,\n): Promise<ReadonlyArray<PendingWriteQueueItem>> {\n await defaultContainerContentsPersistence.ensureSchema(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n await sqlDocumentMoveIntentPersistence.ensureSchema(execSql);\n\n const [persisted, deferred] = await Promise.all([\n listPersistedPendingWriteCandidates(execSql),\n listDeferredPendingWriteCandidates(execSql),\n ]);\n return groupPendingWriteCandidates([...persisted, ...deferred]);\n}\n\n/**\n * Explicit manual retry for one write-queue item: reset the durable re-key\n * budget for the item's ACTUAL pending-update scope (container metadata and\n * unknown document namespaces re-key through the same recovery path as\n * ordinary documents) and clear the recorded terminal failure — the next\n * pass re-records both if they still hold. The cap protects against a\n * server driving a network-speed re-key loop; a deliberate user retry is\n * the rate-limited signal that conditions have changed (e.g. an outage that\n * burned the budget has healed). The caller re-arms the sync lanes.\n */\nexport async function resetPendingWriteRetryState(\n execSql: ExecSql,\n input: {\n localId: string;\n /** The item's `namespace` — the unrecognized documents.app_kind, if any. */\n namespace: string | null;\n objectKind: PendingWriteQueueItem[\"objectKind\"];\n },\n): Promise<void> {\n const appKind =\n input.objectKind === \"container\"\n ? CONTAINER_METADATA_APP_KIND\n : (input.namespace ??\n (input.objectKind === \"document\" ? DOCUMENTS_APP_KIND : null));\n if (appKind === null) {\n // An unknown object kind with no namespace: there is no scope to reset,\n // and guessing one could clear an unrelated scope sharing the localId.\n return;\n }\n const scope = { appKind, localId: input.localId };\n await resetDocumentPendingUpdateRekeyBudget(execSql, scope);\n if (appKind === DOCUMENTS_APP_KIND) {\n // A deliberate retry is the rate-limited signal that conditions changed:\n // a parked permission-denied move (row 7) replays once, like row 11's\n // re-key budget reset.\n await sqlDocumentMoveIntentPersistence.resetDeniedMoveIntents(execSql, {\n localId: input.localId,\n });\n }\n // Clearing the failure row is part of the re-key budget reset (edge-case\n // row 11) and only makes sense alongside queued work. A failure-only item\n // (a refused revalidation, row 13) has no queued work: its row is the\n // priming ticket that re-drives the store, so it must survive the retry\n // and clear on the next clean pass instead of vanishing with no request.\n if (await hasQueuedScopeWork(execSql, scope)) {\n await clearDocumentSyncFailure(execSql, scope);\n }\n}\n\n/**\n * Whether ANY durable outbound work exists for the scope — CRDT updates,\n * staged attachment uploads, move intents, a never-created local document, or\n * a deferred write whose only durable content is the history tail ahead of\n * its covered frontier. Mirrors the queue's own document candidate sources,\n * so \"failure-only\" here agrees with the item the panel rendered.\n */\nasync function hasQueuedScopeWork(\n execSql: ExecSql,\n scope: { appKind: string; localId: string },\n): Promise<boolean> {\n await ensureSqlTables(execSql, [\n ...documentTables,\n ...documentPlacementIntentTables,\n ]);\n const rows = await execSql(\n `SELECT 1 AS present\n WHERE EXISTS (\n SELECT 1 FROM document_history_updates pending\n WHERE pending.app_kind = ? AND pending.local_id = ?\n AND pending.update_id IS NOT NULL\n )\n OR EXISTS (\n SELECT 1 FROM document_pending_attachments attachment\n WHERE attachment.local_id = ?\n )\n OR EXISTS (\n SELECT 1 FROM local_intents intent\n WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'\n AND intent.local_id = ?\n AND intent.intent_type IN ('document.move', 'document.link')\n )\n OR EXISTS (\n SELECT 1 FROM documents stored\n WHERE stored.app_kind = ? AND stored.local_id = ?\n AND stored.document_id IS NULL\n )\n LIMIT 1`,\n [\n scope.appKind,\n scope.localId,\n scope.localId,\n scope.localId,\n scope.appKind,\n scope.localId,\n ],\n );\n if (rows.length > 0) {\n return true;\n }\n // The queue's deferred-update source has no queued rows to probe: the\n // write lives in the durable history tail, detectable only by the\n // version-vector coverage check.\n return hasDeferredTailScopeWork(execSql, scope);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"remoteContainerPageHydration.js","sourceRoot":"","sources":["remoteContainerPageHydration.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRuntimePrincipalPolicyWarmer } from \"../principals/runtimePolicyWarmer\";\nimport {\n listRemoteContainerIdsWithPendingMetadataUpdates,\n listRemoteContainerIdsWithPendingStructuralIntents,\n upsertIsolatedRemoteContainerState,\n} from \"./remoteContainerState\";\nimport { containerStateMatchesFingerprint } from \"./remoteHydration/containerStateFingerprint\";\nimport { prefetchDestinationProjections } from \"./remoteHydration/destinationPrefetch\";\nimport { cachedDestinationRole } from \"./remoteHydration/destinationRoleCache\";\nimport { markContainerParentLaneFetched } from \"./remoteHydration/laneFetchMarkers\";\nimport { fetchContainerParentLaneBatch } from \"./remoteHydration/parentLaneFetch\";\nimport { cacheRemoteContainerPrincipalPolicies } from \"./remoteHydration/principalPolicyCache\";\nimport {\n applyContainerTombstones,\n getApplicableRemoteContainerItems,\n} from \"./remoteHydration/tombstoneApplication\";\nimport type {\n ContainerChildIndex,\n ContainerParentHydrationLane,\n ExpectedContainerState,\n FetchedContainerParentLanePage,\n ListedRemoteContainerPageItem,\n QueueContainerParentLane,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"./remoteHydration/types\";\n\nconst CONTAINER_PARENT_HYDRATION_CONCURRENCY = 4;\n\ninterface HydrationProgress {\n changedCount: number;\n complete: boolean;\n shouldStop: boolean;\n}\nasync function applyRemoteContainerPage(input: {\n childIdsByParentId: ContainerChildIndex;\n expectedContainerStates: ReadonlyMap<string, ExpectedContainerState>;\n expectedHydrationTombstones: FetchedContainerParentLanePage[\"expectedHydrationTombstones\"];\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n items: ReadonlyArray<ListedRemoteContainerPageItem>;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<{ changedCount: number; completed: boolean }> {\n const {\n childIdsByParentId,\n expectedContainerStates,\n expectedHydrationTombstones,\n host,\n items,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let hydratedCount = 0;\n let pageCompleted = true;\n await cacheRemoteContainerPrincipalPolicies({\n cacheReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n state.runtime,\n ),\n remoteContainers: items,\n stillCurrent: input.isCurrent,\n });\n if (input.isCurrent?.() === false) {\n return { changedCount: 0, completed: false };\n }\n const [\n containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents,\n ] = await Promise.all([\n listRemoteContainerIdsWithPendingMetadataUpdates({\n remoteContainers: items,\n state,\n }),\n listRemoteContainerIdsWithPendingStructuralIntents({\n remoteContainers: items,\n state,\n }),\n ]);\n if (input.isCurrent?.() === false) {\n return { changedCount: 0, completed: false };\n }\n const prefetchedProjections = await prefetchDestinationProjections({\n containerIds: items.flatMap((item) =>\n seenContainerIds.has(item.id) ||\n state.containersById.has(item.id) ||\n expectedHydrationTombstones.get(item.id) ||\n cachedDestinationRole(state.runtime.infra.execSql, item)\n ? []\n : [item.id],\n ),\n isCurrent: input.isCurrent,\n runtime: state.runtime,\n });\n for (const container of items) {\n if (input.isCurrent?.() === false) {\n return { changedCount: hydratedCount, completed: false };\n }\n if (!seenContainerIds.has(container.id)) {\n if (\n !containerStateMatchesFingerprint({\n currentState: state.containersById.get(container.id),\n expectedFingerprint: expectedContainerStates.get(container.id)\n ?.fingerprint,\n })\n ) {\n pageCompleted = false;\n continue;\n }\n const upserted = await upsertIsolatedRemoteContainerState({\n childIdsByParentId,\n containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents,\n host,\n isCurrent: input.isCurrent,\n expectedHydrationTombstone:\n expectedHydrationTombstones.get(container.id) ?? null,\n prefetchedProjection: prefetchedProjections.get(container.id),\n remoteContainer: container,\n state,\n });\n if (!upserted) {\n pageCompleted = false;\n continue;\n }\n seenContainerIds.add(container.id);\n hydratedCount += 1;\n if (input.isCurrent?.() === false) {\n return { changedCount: hydratedCount, completed: false };\n }\n }\n queueParentLane(container.id);\n }\n\n return { changedCount: hydratedCount, completed: pageCompleted };\n}\n\nexport function canHydrateRemoteContainers(\n state: RemoteContainerHydrationState,\n): boolean {\n return (\n state.runtime.auth.isAuthenticated &&\n state.runtime.state.online &&\n state.runtime.infra.dbStatus === \"ready\"\n );\n}\n\nasync function applyContainerParentLanePage(input: {\n childIdsByParentId: ContainerChildIndex;\n fetchedPage: FetchedContainerParentLanePage;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n queueContinuationLane: (lane: ContainerParentHydrationLane) => void;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n fetchedPage,\n host,\n queueContinuationLane,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n const {\n expectedContainerStates,\n expectedHydrationTombstones,\n lane,\n response,\n syncLane,\n } = fetchedPage;\n let changedCount = 0;\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const remoteContainerItems = getApplicableRemoteContainerItems(response);\n const tombstoneResult = await applyContainerTombstones({\n childIdsByParentId,\n expectedContainerStates,\n isCurrent: input.isCurrent,\n remoteContainerItems,\n response,\n state,\n });\n if (!tombstoneResult.current) {\n return { changedCount, complete: false, shouldStop: true };\n }\n changedCount += tombstoneResult.changedCount;\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (tombstoneResult.changedCount > 0) {\n // A live tombstone cascade may have orphaned documents (row 3); re-arm\n // document priming so their null-scoped passes run now rather than on\n // the next startup.\n host.requestDocumentPriming?.();\n }\n\n const appliedPage = await applyRemoteContainerPage({\n childIdsByParentId,\n expectedContainerStates,\n expectedHydrationTombstones,\n host,\n isCurrent: input.isCurrent,\n items: remoteContainerItems,\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += appliedPage.changedCount;\n if (!tombstoneResult.completed || !appliedPage.completed) {\n // Keep this page retryable without discarding independent lanes, including\n // children of roots first discovered here. Otherwise the root becomes known\n // but its children are never fetched by subsequent root-only refreshes.\n return { changedCount, complete: false, shouldStop: false };\n }\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const didMarkFetched = await markContainerParentLaneFetched({\n isCurrent: input.isCurrent,\n response,\n state,\n syncLane,\n });\n if (!didMarkFetched) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n if (!response.hasMore) {\n return { changedCount, complete: true, shouldStop: false };\n }\n if (!response.nextWatermark) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n queueContinuationLane({\n parentId: lane.parentId,\n watermark: response.nextWatermark,\n });\n return { changedCount, complete: true, shouldStop: false };\n}\n\nfunction takeContainerParentLaneBatch(input: {\n lanes: ContainerParentHydrationLane[];\n state: RemoteContainerHydrationState;\n}): ContainerParentHydrationLane[] {\n const { lanes, state } = input;\n const batch: ContainerParentHydrationLane[] = [];\n\n while (\n lanes.length > 0 &&\n batch.length < CONTAINER_PARENT_HYDRATION_CONCURRENCY\n ) {\n const lane = lanes.shift();\n if (\n lane &&\n (lane.parentId === null || state.containersById.has(lane.parentId))\n ) {\n batch.push(lane);\n }\n }\n\n return batch;\n}\n\nasync function applyContainerParentLaneBatch(input: {\n childIdsByParentId: ContainerChildIndex;\n fetchedPages: ReadonlyArray<FetchedContainerParentLanePage>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n lanes: ContainerParentHydrationLane[];\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n fetchedPages,\n host,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let changedCount = 0;\n let complete = true;\n\n for (const fetchedPage of fetchedPages) {\n if (!canHydrateRemoteContainers(state) || input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (\n fetchedPage.lane.parentId !== null &&\n !state.containersById.has(fetchedPage.lane.parentId)\n ) {\n continue;\n }\n\n const result = await applyContainerParentLanePage({\n childIdsByParentId,\n fetchedPage,\n host,\n isCurrent: input.isCurrent,\n queueContinuationLane: (lane) => lanes.push(lane),\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += result.changedCount;\n complete &&= result.complete;\n\n if (result.shouldStop) {\n return { changedCount, complete: false, shouldStop: true };\n }\n }\n\n return { changedCount, complete, shouldStop: false };\n}\n\nexport async function hydrateContainerParentLanes(input: {\n childIdsByParentId: ContainerChildIndex;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n lanes: ContainerParentHydrationLane[];\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n host,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let changedCount = 0;\n let complete = true;\n\n while (lanes.length > 0) {\n if (!canHydrateRemoteContainers(state) || input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const batch = takeContainerParentLaneBatch({ lanes, state });\n if (batch.length === 0) {\n continue;\n }\n\n const fetchedPages = await fetchContainerParentLaneBatch({\n batch,\n isCurrent: input.isCurrent,\n state,\n });\n if (!fetchedPages) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const result = await applyContainerParentLaneBatch({\n childIdsByParentId,\n fetchedPages,\n host,\n isCurrent: input.isCurrent,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += result.changedCount;\n complete &&= result.complete;\n\n if (result.shouldStop) {\n return { changedCount, complete: false, shouldStop: true };\n }\n }\n\n return { changedCount, complete, shouldStop: false };\n}\n"]}
|