@tearleads/client-sdk 0.1.61 → 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/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/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/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/{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/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/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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentMoveVanishedRefresh.js","sourceRoot":"","sources":["documentMoveVanishedRefresh.ts"],"names":[],"mappings":"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","sourcesContent":["import { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport { readLinkedContainerIdsFromDocumentManifest } from \"../../../data/documents/shared/projection\";\nimport type { DocumentMoveIntentRecord } from \"../../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { DocumentLinkSetFailureHandler } from \"../../documents\";\nimport { listDocumentLinkedContainerIds } from \"../documentLinks\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\nimport {\n createDocumentMoveFailureState,\n type DocumentMoveFailureState,\n recordDocumentMoveFailure,\n} from \"./documentMoveFailure\";\n\nexport interface VanishedContainerRefreshOutcome<TMoved> {\n readonly failure: DocumentMoveFailureState;\n readonly moved: TMoved;\n /**\n * Park the intent terminally. True only when the destination itself is\n * proven gone: a coded 404 on its projection probe after eviction. No\n * mutation verdict — first attempt or retry — is ever terminal.\n */\n readonly unavailable: boolean;\n}\n\n/**\n * Every container the unlink half of the move can cite. The unlink set is\n * read off the REMOTE document manifest's link set, so that set — refetched\n * after eviction so it is current — is the authority; the local link\n * projection, the intent's source, and the document's local placement are\n * unioned in so a source known only on one side still gets its cached path\n * refreshed. A superset is harmless: an eviction only forces a refetch, and\n * nothing here decides what gets unlinked.\n */\nasync function listMoveSourceContainerIds(input: {\n apiClient: ContainerContentsWorkflowRuntime[\"apiClient\"];\n execSql: ExecSql;\n existingContainerId: string | null | undefined;\n intent: DocumentMoveIntentRecord;\n}): Promise<string[]> {\n const { documentId, targetContainerId } = input.intent;\n const [remote, local] = await Promise.all([\n input.apiClient.getDocumentWriterProjectionResult(documentId, {\n reportErrors: false,\n }),\n listDocumentLinkedContainerIds(input.execSql, documentId),\n ]);\n const remoteLinkedContainerIds = remote.ok\n ? readLinkedContainerIdsFromDocumentManifest(remote.data)\n : [];\n return Array.from(\n new Set([\n ...remoteLinkedContainerIds,\n ...local,\n input.intent.sourceContainerId,\n input.existingContainerId,\n ]),\n )\n .filter(\n (containerId): containerId is string =>\n typeof containerId === \"string\" && containerId !== targetContainerId,\n )\n .sort();\n}\n\n/**\n * A vanished-container verdict (coded container 404 or `container_unavailable`\n * 409) does not by itself doom a queued move. The deleted container may be a\n * stale ANCESTOR in a cached path — the destination or a source was moved\n * under a live parent before its former parent was deleted — and the local\n * tombstone cascade cannot rescue that intent (it retargets only intents whose\n * source or destination IS the tombstoned container). So refresh before\n * declaring terminal: evict the cached destination, document, and source\n * projections, probe the destination, and retry once with the fresh paths.\n *\n * Only the destination's fate is terminal, and only as proven by its own\n * probe. Sources are evicted, never judged: the retry's unlink set comes from\n * the verified manifest alone, so a server-asserted \"source gone\" can neither\n * skip a revoke nor complete the move — a retry whose link landed but whose\n * unlink still vanished stays partial (pending) with a live link the queue\n * keeps trying to revoke. The retry's own vanished verdict, on either side, is\n * likewise never terminal: with the destination live it can only name another\n * ancestor deleted mid-pass, which the next pass's fresh paths outrun. The\n * pass is bounded to one retry; a transient probe failure leaves the intent\n * retriable (or denied on 403) for a later pass.\n */\nexport async function moveWithVanishedContainerRefresh<TMoved>(input: {\n apiClient: ContainerContentsWorkflowRuntime[\"apiClient\"];\n attempt: (\n onFailure: DocumentLinkSetFailureHandler,\n ) => Promise<TMoved | \"abandoned\">;\n execSql: ExecSql;\n existingContainerId: string | null | undefined;\n intent: DocumentMoveIntentRecord;\n isCurrent: () => boolean;\n}): Promise<VanishedContainerRefreshOutcome<TMoved> | \"abandoned\"> {\n const { apiClient, intent } = input;\n const firstFailure = createDocumentMoveFailureState();\n const first = await input.attempt((failure) =>\n recordDocumentMoveFailure(firstFailure, failure),\n );\n if (first === \"abandoned\" || !input.isCurrent()) return \"abandoned\";\n if (!firstFailure.sawVanishedContainer) {\n return { failure: firstFailure, moved: first, unavailable: false };\n }\n\n for (const targetContainerId of new Set([\n intent.targetContainerId,\n ...(intent.additionalLinkContainerIds ?? []),\n ])) {\n apiClient.evictContainerWriterProjection(targetContainerId);\n const destination = await apiClient.getContainerWriterProjectionResult(\n targetContainerId,\n { reportErrors: false },\n );\n apiClient.evictDocumentWriterProjection(intent.documentId);\n if (!input.isCurrent()) return \"abandoned\";\n if (!destination.ok) {\n destination.report();\n recordDocumentMoveFailure(firstFailure, destination);\n return {\n failure: firstFailure,\n moved: first,\n unavailable: isContainerNotFoundFailure(destination),\n };\n }\n }\n\n for (const sourceContainerId of await listMoveSourceContainerIds(input)) {\n apiClient.evictContainerWriterProjection(sourceContainerId);\n }\n if (!input.isCurrent()) return \"abandoned\";\n\n const retryFailure = createDocumentMoveFailureState();\n const retried = await input.attempt((failure) =>\n recordDocumentMoveFailure(retryFailure, failure),\n );\n if (retried === \"abandoned\" || !input.isCurrent()) return \"abandoned\";\n // The retry's own vanished verdict is never terminal. The destination was\n // just proven live, so a second `container_unavailable` can only name\n // another ancestor deleted during the refreshed attempt (or a source): the\n // intent stays pending with its failure recorded and the next pass starts\n // over with freshly evicted projections. One retry per pass keeps it\n // bounded; nothing in the queue backs a pending intent off between passes.\n return { failure: retryFailure, moved: retried, unavailable: false };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from "
|
|
2
|
-
import { documentContainerProjectionTables, documentProjectionTables, documentTables, } from "
|
|
3
|
-
import { ensureSqlTables } from "
|
|
4
|
-
import { listContainerContentsSqlIdBatches } from "
|
|
1
|
+
import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from "../../../data/documents/documentSummary.js";
|
|
2
|
+
import { documentContainerProjectionTables, documentProjectionTables, documentTables, } from "../../../data/sqlite/schema.js";
|
|
3
|
+
import { ensureSqlTables } from "../../../data/sqlite/sqlSchema.js";
|
|
4
|
+
import { listContainerContentsSqlIdBatches } from "../documentQueries/sql.js";
|
|
5
5
|
import { requestRemoteDocumentRuntimeTargetSync } from "./documentRuntimeTargetSync.js";
|
|
6
6
|
const DOCUMENT_HYDRATION_PROBE_REQUEST_BATCH_SIZE = 8;
|
|
7
7
|
const DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE = 64;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentHydrationProbe.js","sourceRoot":"","sources":["documentHydrationProbe.ts"],"names":[],"mappings":"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","sourcesContent":["import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from \"../../../data/documents/documentSummary\";\nimport {\n documentContainerProjectionTables,\n documentProjectionTables,\n documentTables,\n} from \"../../../data/sqlite/schema\";\nimport { ensureSqlTables } from \"../../../data/sqlite/sqlSchema\";\nimport { listContainerContentsSqlIdBatches } from \"../documentQueries/sql\";\nimport type {\n ContainerContentsDocumentRuntimeTarget,\n ContainerDocumentProbeHost,\n ContainerDocumentQueriesRuntime,\n} from \"../documentQueries/types\";\nimport { requestRemoteDocumentRuntimeTargetSync } from \"./documentRuntimeTargetSync\";\n\nconst DOCUMENT_HYDRATION_PROBE_REQUEST_BATCH_SIZE = 8;\nconst DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE = 64;\n\ninterface DocumentHydrationProbeBatchResult {\n readonly done: boolean;\n readonly nextCursor: string | null;\n readonly requestedCount: number;\n}\n\ntype RemoteDocumentProbeTarget = Omit<\n ContainerContentsDocumentRuntimeTarget,\n \"documentId\" | \"runtimeContainerId\"\n> & {\n readonly documentId: string;\n readonly preferredRuntimeContainer: boolean;\n readonly runtimeContainerId: string;\n};\n\nfunction valuePlaceholders(values: ReadonlyArray<unknown>): string {\n return values.map(() => \"?\").join(\", \");\n}\n\nfunction valueRows(values: ReadonlyArray<unknown>): string {\n return values.map(() => \"(?)\").join(\", \");\n}\n\nfunction readProbeTarget(row: unknown): RemoteDocumentProbeTarget {\n // These aliases are wholly internal SQL contracts; fail loudly if a query\n // edit violates them instead of silently skipping a persisted document.\n if (row === null || (typeof row !== \"object\" && typeof row !== \"function\")) {\n throw new Error(\"Document hydration probe returned an invalid target\");\n }\n const documentId = Reflect.get(row, \"document_id\");\n const localId = Reflect.get(row, \"local_id\");\n const projectedContainerId = Reflect.get(row, \"projected_container_id\");\n const runtimeContainerId = Reflect.get(row, \"container_id\");\n if (\n typeof documentId !== \"string\" ||\n typeof localId !== \"string\" ||\n typeof runtimeContainerId !== \"string\"\n ) {\n throw new Error(\"Document hydration probe returned an invalid target\");\n }\n return {\n documentId,\n localId,\n preferredRuntimeContainer: projectedContainerId === runtimeContainerId,\n runtimeContainerId,\n };\n}\n\nasync function listRemoteDocumentProbeBatchForContainerIds(input: {\n readonly afterLocalId: string | null;\n readonly containerIds: ReadonlyArray<string>;\n readonly runtime: ContainerDocumentQueriesRuntime;\n}): Promise<RemoteDocumentProbeTarget[]> {\n const rows = await input.runtime.infra.execSql(\n `\n WITH eligible_container_ids(container_id) AS (\n VALUES ${valueRows(input.containerIds)}\n )\n SELECT\n stored.local_id AS local_id,\n stored.document_id AS document_id,\n projection.container_id AS projected_container_id,\n COALESCE(\n projected_container.container_id,\n MIN(linked_container.container_id)\n ) AS container_id\n FROM documents stored\n INNER JOIN document_projection projection\n ON projection.local_id = stored.local_id\n LEFT JOIN eligible_container_ids projected_container\n ON projected_container.container_id = projection.container_id\n LEFT JOIN document_container_projection link\n ON link.document_id = stored.document_id\n LEFT JOIN eligible_container_ids linked_container\n ON linked_container.container_id = link.container_id\n WHERE stored.app_kind = 'documents'\n AND stored.document_id IS NOT NULL\n AND (? IS NULL OR stored.local_id > ?)\n AND (\n projected_container.container_id IS NOT NULL\n OR linked_container.container_id IS NOT NULL\n )\n AND projection.document_kind NOT IN (${valuePlaceholders(\n HIDDEN_DOCUMENT_SUMMARY_KINDS,\n )})\n GROUP BY\n stored.local_id,\n stored.document_id,\n projection.container_id,\n projected_container.container_id\n ORDER BY stored.local_id ASC\n LIMIT ?\n `,\n [\n ...input.containerIds,\n input.afterLocalId,\n input.afterLocalId,\n ...HIDDEN_DOCUMENT_SUMMARY_KINDS,\n DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE,\n ],\n );\n return rows.map(readProbeTarget);\n}\n\nfunction mergeRemoteDocumentProbeTargets(\n batches: ReadonlyArray<ReadonlyArray<RemoteDocumentProbeTarget>>,\n): RemoteDocumentProbeTarget[] {\n const targetsByLocalId = new Map<string, RemoteDocumentProbeTarget>();\n for (const batch of batches) {\n for (const target of batch) {\n const existing = targetsByLocalId.get(target.localId);\n if (\n existing === undefined ||\n (target.preferredRuntimeContainer &&\n !existing.preferredRuntimeContainer) ||\n (target.preferredRuntimeContainer ===\n existing.preferredRuntimeContainer &&\n target.runtimeContainerId < existing.runtimeContainerId)\n ) {\n targetsByLocalId.set(target.localId, target);\n }\n }\n }\n return [...targetsByLocalId.values()]\n .sort((left, right) =>\n left.localId < right.localId ? -1 : Number(left.localId > right.localId),\n )\n .slice(0, DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE);\n}\n\nasync function listRemoteDocumentProbeBatch(input: {\n readonly afterLocalId: string | null;\n readonly listedContainerIds: ReadonlySet<string>;\n readonly runtime: ContainerDocumentQueriesRuntime;\n}): Promise<RemoteDocumentProbeTarget[]> {\n const containerIds = [...input.listedContainerIds];\n if (containerIds.length === 0) {\n return [];\n }\n\n await ensureSqlTables(input.runtime.infra.execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentContainerProjectionTables,\n ]);\n const batches: RemoteDocumentProbeTarget[][] = [];\n for (const containerIdBatch of listContainerContentsSqlIdBatches(\n containerIds,\n )) {\n batches.push(\n await listRemoteDocumentProbeBatchForContainerIds({\n afterLocalId: input.afterLocalId,\n containerIds: containerIdBatch,\n runtime: input.runtime,\n }),\n );\n }\n return mergeRemoteDocumentProbeTargets(batches);\n}\n\n/**\n * Opens at most one bounded batch of visible, remote-backed local documents\n * linked to an authoritatively listed container but absent from every full\n * listing. Each store's ordinary sync pass owns its coded-404/403 verdict.\n */\nexport async function probeUndiscoveredRemoteDocumentBatch<TRuntime>(input: {\n readonly afterLocalId: string | null;\n readonly host: ContainerDocumentProbeHost<TRuntime>;\n readonly listedContainerIds: ReadonlySet<string>;\n readonly listedDocumentIds: ReadonlySet<string>;\n readonly runtime: ContainerDocumentQueriesRuntime;\n}): Promise<DocumentHydrationProbeBatchResult> {\n const scanned = await listRemoteDocumentProbeBatch(input);\n const candidates = scanned.filter(\n (target) => !input.listedDocumentIds.has(target.documentId),\n );\n const targets = candidates.slice(\n 0,\n DOCUMENT_HYDRATION_PROBE_REQUEST_BATCH_SIZE,\n );\n const requested = await requestRemoteDocumentRuntimeTargetSync({\n host: input.host,\n targets,\n });\n const hasUnrequestedCandidate = candidates.length > targets.length;\n const scanPageMayContinue =\n scanned.length === DOCUMENT_HYDRATION_PROBE_SCAN_BATCH_SIZE;\n const done = !hasUnrequestedCandidate && !scanPageMayContinue;\n const nextCursorTarget = hasUnrequestedCandidate\n ? targets.at(-1)\n : scanned.at(-1);\n return {\n done,\n nextCursor: done ? null : (nextCursorTarget?.localId ?? null),\n requestedCount: requested.size,\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentRuntimeTargetSync.js","sourceRoot":"","sources":["documentRuntimeTargetSync.ts"],"names":[],"mappings":"AAMA,+EAA+E;AAC/E,8EAA8E;AAC9E,6CAA6C;AAC7C,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEzC,KAAK,UAAU,wBAAwB,CAAmB,KAYzD;IACC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjE,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAElD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,iBAAiB,CAAC;QAC3C,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IACE,iBAAiB,CAAC,IAAI,GAAG,CAAC;YAC1B,iBAAiB,CAAC,IAAI,GAAG,8BAA8B,KAAK,CAAC,EAC7D,CAAC;YACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,SAAS,EAAE;gBAAE,OAAO,iBAAiB,CAAC;QAC7C,CAAC;QAED,IAAI,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACnE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACxE,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;YACzC,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO;SACR,CAAC,CAAC;QACH,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAW,KAI1D;IACC,OAAO,wBAAwB,CAAC;QAC9B,GAAG,KAAK;QACR,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;gBACxC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sCAAsC,CAAW,KAIhE;IACC,OAAO,wBAAwB,CAAC;QAC9B,GAAG,KAAK;QACR,yEAAyE;QACzE,uEAAuE;QACvE,qEAAqE;QACrE,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,EAAE;KACvD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n ContainerContentsDocumentRuntimeTarget,\n ContainerDocumentPrimeHost,\n ContainerDocumentProbeHost,\n} from \"../documentQueries/types\";\n\n// Stores opened per macrotask. Opening is fire-and-forget, so yielding between\n// chunks keeps the main thread and serialized SQLite queue responsive while a\n// restored replica schedules a real backlog.\nconst DOCUMENT_STORE_OPEN_CHUNK_SIZE = 8;\n\nasync function requestRuntimeTargetSync<TRuntime, TStore>(input: {\n readonly host: {\n documentWorkflowRuntime: (containerId: string | null) => TRuntime;\n openDocumentStore: (input: {\n documentId: string | null;\n localId: string;\n runtime: TRuntime;\n }) => TStore;\n };\n readonly isCurrent?: (() => boolean) | undefined;\n readonly requestStoreSync: (store: TStore) => void;\n readonly targets: ReadonlyArray<ContainerContentsDocumentRuntimeTarget>;\n}): Promise<ReadonlySet<string>> {\n const requestedLocalIds = new Set<string>();\n const runtimesByContainerId = new Map<string | null, TRuntime>();\n const isCurrent = input.isCurrent ?? (() => true);\n\n for (const target of input.targets) {\n if (!isCurrent()) return requestedLocalIds;\n if (requestedLocalIds.has(target.localId)) {\n continue;\n }\n if (\n requestedLocalIds.size > 0 &&\n requestedLocalIds.size % DOCUMENT_STORE_OPEN_CHUNK_SIZE === 0\n ) {\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n if (!isCurrent()) return requestedLocalIds;\n }\n\n let runtime = runtimesByContainerId.get(target.runtimeContainerId);\n if (runtime === undefined) {\n runtime = input.host.documentWorkflowRuntime(target.runtimeContainerId);\n runtimesByContainerId.set(target.runtimeContainerId, runtime);\n }\n\n const store = input.host.openDocumentStore({\n documentId: target.documentId,\n localId: target.localId,\n runtime,\n });\n requestedLocalIds.add(target.localId);\n input.requestStoreSync(store);\n }\n\n return requestedLocalIds;\n}\n\nexport function requestDocumentRuntimeTargetSync<TRuntime>(input: {\n readonly host: ContainerDocumentPrimeHost<TRuntime>;\n readonly isCurrent?: (() => boolean) | undefined;\n readonly targets: ReadonlyArray<ContainerContentsDocumentRuntimeTarget>;\n}): Promise<ReadonlySet<string>> {\n return requestRuntimeTargetSync({\n ...input,\n requestStoreSync: (store) => {\n if (store.getSnapshot?.().ready ?? true) {\n store.requestSync();\n }\n },\n });\n}\n\nexport function requestRemoteDocumentRuntimeTargetSync<TRuntime>(input: {\n readonly host: ContainerDocumentProbeHost<TRuntime>;\n readonly isCurrent?: (() => boolean) | undefined;\n readonly targets: ReadonlyArray<ContainerContentsDocumentRuntimeTarget>;\n}): Promise<ReadonlySet<string>> {\n return requestRuntimeTargetSync({\n ...input,\n // Unlike ordinary startup priming, a probe must survive a freshly opened\n // store's initialization. requestRemoteSync records that intent before\n // scheduling, so the first ready pass performs an HTTP revalidation.\n requestStoreSync: (store) => store.requestRemoteSync(),\n });\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { documentContainerProjectionTables, documentPlacementIntentTables, documentProjectionTables, documentTables, LOCAL_INTENT_LANES, } from "
|
|
2
|
-
import { ensureSqlTables } from "
|
|
1
|
+
import { documentContainerProjectionTables, documentPlacementIntentTables, documentProjectionTables, documentTables, LOCAL_INTENT_LANES, } from "../../../data/sqlite/schema.js";
|
|
2
|
+
import { ensureSqlTables } from "../../../data/sqlite/sqlSchema.js";
|
|
3
|
+
import { listDocumentRuntimeTargetsForContainerSubtreeFromRuntime } from "../documentQueries/documentSubtreeQueries.js";
|
|
4
|
+
import { getOrphanedDocumentQueryBind, getOrphanedDocumentWhereSql, } from "../documentQueries/orphanedDocumentSql.js";
|
|
3
5
|
import { requestDocumentRuntimeTargetSync } from "./documentRuntimeTargetSync.js";
|
|
4
|
-
import { listDocumentRuntimeTargetsForContainerSubtreeFromRuntime } from "./documentSubtreeQueries.js";
|
|
5
|
-
import { getOrphanedDocumentQueryBind, getOrphanedDocumentWhereSql, } from "./orphanedDocumentSql.js";
|
|
6
6
|
// Documents that still NEED a store opened at prime time: local-only creates,
|
|
7
7
|
// queued outbound updates/attachments, an outgoing-delta marker behind the
|
|
8
8
|
// stored content frontier (a deferred tail; encoding inequality
|
|
@@ -242,4 +242,4 @@ export async function primeDocumentsForLoadedRoots(input) {
|
|
|
242
242
|
unroutableCount: candidates.filter((candidate) => !primedLocalIds.has(candidate.localId)).length,
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
|
-
//# sourceMappingURL=
|
|
245
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n documentContainerProjectionTables,\n documentPlacementIntentTables,\n documentProjectionTables,\n documentTables,\n LOCAL_INTENT_LANES,\n} from \"../../../data/sqlite/schema\";\nimport { ensureSqlTables } from \"../../../data/sqlite/sqlSchema\";\nimport { listDocumentRuntimeTargetsForContainerSubtreeFromRuntime } from \"../documentQueries/documentSubtreeQueries\";\nimport {\n getOrphanedDocumentQueryBind,\n getOrphanedDocumentWhereSql,\n} from \"../documentQueries/orphanedDocumentSql\";\nimport type {\n ContainerContentsContainerSubtreeState,\n ContainerContentsDocumentRuntimeTarget,\n ContainerDocumentPrimeHost,\n ContainerDocumentQueriesRuntime,\n} from \"../documentQueries/types\";\nimport { requestDocumentRuntimeTargetSync } from \"./documentRuntimeTargetSync\";\n\ninterface PrimeRequiredDocumentCandidate {\n readonly localId: string;\n}\n\ninterface LoadedRootDocumentPrimeResult {\n readonly candidateCount: number;\n readonly orphanPrimedCount: number;\n readonly primedCount: number;\n readonly rootCount: number;\n readonly unroutableCount: number;\n}\n\n// Documents that still NEED a store opened at prime time: local-only creates,\n// queued outbound updates/attachments, an outgoing-delta marker behind the\n// stored content frontier (a deferred tail; encoding inequality\n// over-approximates, which only re-primes a store the old behavior always\n// primed), a never-hydrated document (a freshly discovered share whose\n// content pull the primed lane performs), or a document with a recorded sync\n// failure (a refused revalidation leaves no queued work, so the failure row\n// is the only ticket that re-drives the store — the retry that clears on the\n// next clean pass). Fully-synced hydrated documents are\n// deliberately absent: priming exists to re-drive durable work, and opening a\n// store per settled document is what made a 1000-document boot a storm.\nconst PENDING_PRIME_LOCAL_ID_SQL = `\n SELECT stored.local_id AS local_id\n FROM documents stored\n WHERE stored.app_kind = 'documents'\n AND (\n stored.document_id IS NULL\n OR stored.snapshot_end_version = ''\n OR stored.pull_continuation IS NOT NULL\n OR COALESCE(stored.pending_base_version, '') <> stored.snapshot_end_version\n OR EXISTS (\n SELECT 1\n FROM document_history_updates pending\n WHERE pending.app_kind = 'documents'\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n )\n OR stored.sync_failure_message IS NOT NULL\n OR EXISTS (\n SELECT 1\n FROM document_pending_attachments attachment\n WHERE attachment.local_id = stored.local_id\n )\n )\n`;\n\nconst PENDING_PRIME_DOCUMENT_CANDIDATE_SQL = `\n SELECT pending.local_id AS local_id\n FROM (${PENDING_PRIME_LOCAL_ID_SQL}) pending\n ORDER BY pending.local_id ASC\n`;\n\n// The structural startup probe and the priming worker share the same durable\n// predicate so they cannot disagree about what counts as document work.\nconst STARTUP_DOCUMENT_SYNC_WORK_SQL = `\n SELECT 1 AS present\n WHERE EXISTS (${PENDING_PRIME_LOCAL_ID_SQL})\n OR EXISTS (\n SELECT 1\n FROM local_intents intent\n -- Blocked and parked denied moves count: blocked intents replay on\n -- every scan (the blocking condition can heal after hydration), and\n -- the once-per-launch replay makes denied moves retriable — so a\n -- relaunch whose only durable work is either kind must still schedule\n -- the structural pass that re-attempts it (row 7). Unavailable moves\n -- are excluded: no pass ever replays them (#2278 #4).\n WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'\n AND intent.sync_status IN ('pending', 'blocked', 'denied')\n )\n LIMIT 1\n`;\n\nexport async function hasStartupDocumentSyncWork(\n runtimeOrExecSql:\n | ContainerDocumentQueriesRuntime\n | ContainerDocumentQueriesRuntime[\"infra\"][\"execSql\"],\n): Promise<boolean> {\n const execSql =\n typeof runtimeOrExecSql === \"function\"\n ? runtimeOrExecSql\n : runtimeOrExecSql.infra.execSql;\n await ensureSqlTables(execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentPlacementIntentTables,\n ]);\n const rows = await execSql(STARTUP_DOCUMENT_SYNC_WORK_SQL);\n return rows.length > 0;\n}\n\nasync function listPrimeRequiredDocumentCandidatesFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): Promise<PrimeRequiredDocumentCandidate[]> {\n await ensureSqlTables(runtime.infra.execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ]);\n const rows = await runtime.infra.execSql(\n PENDING_PRIME_DOCUMENT_CANDIDATE_SQL,\n );\n\n return rows.flatMap((row) => {\n const localId = Reflect.get(row, \"local_id\");\n if (typeof localId !== \"string\") {\n return [];\n }\n return [{ localId }];\n });\n}\n\n// A row with content but a NULL outgoing-delta marker is deliberately treated\n// as unsettled: the store persist path always sets the marker, so over-priming\n// is the safe direction.\nasync function listPrimeRequiredLocalIdsFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): Promise<ReadonlySet<string>> {\n const candidates =\n await listPrimeRequiredDocumentCandidatesFromRuntime(runtime);\n return new Set(candidates.map((candidate) => candidate.localId));\n}\n\n/**\n * Last-link orphans (docs/sync-edge-cases.md row 3): the container cascade\n * nulled their projection container and dropped their link rows, so no\n * subtree listing can route them. Placements held for unsigned tombstones\n * also qualify when every link is hidden; their link rows remain intact.\n * These documents are primed with a null container\n * scope instead — the documents runtime accepts one, and the document's own\n * sync pass then resolves its fate against the server: 403 parks it (row 8),\n * a coded 404 destroys it (row 1), and a local-only orphan's create attempt\n * records a terminal failure row. Hidden document kinds stay excluded, and\n * dangling non-null projections (a container row merely missing locally)\n * stay with stale-root recovery, exactly as before.\n *\n * Organization neutrality: the null scope changes only the runtime's\n * containerId — auth, crypto, and organization plumbing are identical to\n * every container-scoped runtime this store already primes with, the sync\n * pass derives billing and keying organizations from the document's own\n * plan and manifest, and a cross-organization author fails closed at the\n * sync layer's identity guard before anything is signed.\n */\nconst ORPHANED_PRIME_TARGET_SQL = `\n SELECT stored.local_id AS local_id, stored.document_id AS document_id\n FROM documents stored\n INNER JOIN document_projection projection\n ON projection.local_id = stored.local_id\n WHERE stored.app_kind = 'documents'\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"stored.document_id\",\n projectionAlias: \"projection\",\n })}\n ORDER BY stored.local_id ASC\n`;\n\n/**\n * Unattributed rows (empty/NULL organization) are always included: they are\n * device-first documents created before authentication, which belong to this\n * device's sole user and adopt the active organization when they create.\n */\nasync function listOrphanedDocumentPrimeTargets(\n runtime: ContainerDocumentQueriesRuntime,\n organizationId: string,\n): Promise<ContainerContentsDocumentRuntimeTarget[]> {\n await ensureSqlTables(runtime.infra.execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentContainerProjectionTables,\n ]);\n const rows = await runtime.infra.execSql(\n ORPHANED_PRIME_TARGET_SQL,\n getOrphanedDocumentQueryBind(organizationId),\n );\n return rows.flatMap((row) => {\n const localId = Reflect.get(row, \"local_id\");\n if (typeof localId !== \"string\") {\n return [];\n }\n const documentId = Reflect.get(row, \"document_id\");\n return [\n {\n documentId: typeof documentId === \"string\" ? documentId : null,\n localId,\n runtimeContainerId: null,\n },\n ];\n });\n}\n\nexport async function primeDocumentsForContainerSubtree<TRuntime>(input: {\n containersById: ReadonlyMap<string, ContainerContentsContainerSubtreeState>;\n host: ContainerDocumentPrimeHost<TRuntime>;\n isCurrent?: (() => boolean) | undefined;\n primeRequiredLocalIds?: ReadonlySet<string>;\n rootContainerId: string;\n runtime: ContainerDocumentQueriesRuntime;\n}): Promise<number> {\n const isCurrent = input.isCurrent ?? (() => true);\n if (!isCurrent()) return 0;\n const [targets, primeRequiredLocalIds] = await Promise.all([\n listDocumentRuntimeTargetsForContainerSubtreeFromRuntime({\n containersById: input.containersById,\n rootContainerId: input.rootContainerId,\n runtime: input.runtime,\n }),\n input.primeRequiredLocalIds ??\n listPrimeRequiredLocalIdsFromRuntime(input.runtime),\n ]);\n if (!isCurrent()) return 0;\n const primed = await requestDocumentRuntimeTargetSync({\n host: input.host,\n isCurrent,\n targets: targets.filter((target) =>\n primeRequiredLocalIds.has(target.localId),\n ),\n });\n return primed.size;\n}\n\nexport async function primeDocumentsForLoadedRoots<TRuntime>(input: {\n containersById: ReadonlyMap<string, ContainerContentsContainerSubtreeState>;\n host: ContainerDocumentPrimeHost<TRuntime>;\n isCurrent?: (() => boolean) | undefined;\n /**\n * The store scope's organization. Orphan priming is bounded to it: each\n * organization-scoped store resolves only its own orphans, matching the\n * per-organization invariant subtree routing provides implicitly (a pass\n * signed under another organization would fail the sync identity guard\n * instead of resolving). Absent — unauthenticated or scope-less callers —\n * orphan priming is skipped entirely.\n */\n organizationId?: string | null;\n runtime: ContainerDocumentQueriesRuntime;\n}): Promise<LoadedRootDocumentPrimeResult> {\n const isCurrent = input.isCurrent ?? (() => true);\n if (!isCurrent()) {\n return {\n candidateCount: 0,\n orphanPrimedCount: 0,\n primedCount: 0,\n rootCount: 0,\n unroutableCount: 0,\n };\n }\n const candidates = await listPrimeRequiredDocumentCandidatesFromRuntime(\n input.runtime,\n );\n if (!isCurrent()) {\n return {\n candidateCount: candidates.length,\n orphanPrimedCount: 0,\n primedCount: 0,\n rootCount: 0,\n unroutableCount: candidates.length,\n };\n }\n const rootContainerIds = Array.from(input.containersById.values()).flatMap(\n (containerState) =>\n containerState.container.parentId === null\n ? [containerState.container.id]\n : [],\n );\n const requiredLocalIds = new Set(\n candidates.map((candidate) => candidate.localId),\n );\n const primedLocalIds = new Set<string>();\n\n for (const rootContainerId of rootContainerIds) {\n if (!isCurrent()) break;\n const targets =\n await listDocumentRuntimeTargetsForContainerSubtreeFromRuntime({\n containersById: input.containersById,\n rootContainerId,\n runtime: input.runtime,\n });\n if (!isCurrent()) break;\n const primed = await requestDocumentRuntimeTargetSync({\n host: input.host,\n isCurrent,\n targets: targets.filter(\n (target) =>\n requiredLocalIds.has(target.localId) &&\n !primedLocalIds.has(target.localId),\n ),\n });\n for (const localId of primed) {\n primedLocalIds.add(localId);\n }\n }\n\n const orphanTargets = (\n isCurrent() && input.organizationId\n ? await listOrphanedDocumentPrimeTargets(\n input.runtime,\n input.organizationId,\n )\n : []\n ).filter(\n (target) =>\n requiredLocalIds.has(target.localId) &&\n !primedLocalIds.has(target.localId),\n );\n const orphanPrimed = await requestDocumentRuntimeTargetSync({\n host: input.host,\n isCurrent,\n targets: isCurrent() ? orphanTargets : [],\n });\n for (const localId of orphanPrimed) {\n primedLocalIds.add(localId);\n }\n\n return {\n candidateCount: candidates.length,\n orphanPrimedCount: orphanPrimed.size,\n primedCount: primedLocalIds.size,\n rootCount: rootContainerIds.length,\n unroutableCount: candidates.filter(\n (candidate) => !primedLocalIds.has(candidate.localId),\n ).length,\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DocumentSummary } from "
|
|
1
|
+
import type { DocumentSummary } from "../../../data/documents/documentSummary.js";
|
|
2
2
|
import type { DocumentStructuralMutationHost, DocumentStructuralMutationRuntime, SetLinkedContainerIdsForDocument } from "./documentStructureTypes.js";
|
|
3
3
|
export type { DocumentStructuralMutationHost, DocumentStructuralMutationRelinkInput, DocumentStructuralMutationRuntime, MergeDocumentSummary, SetLinkedContainerIdsForDocument, } from "./documentStructureTypes.js";
|
|
4
4
|
export declare function canMutateDocumentLink(runtime: {
|
package/workflows/container-contents/{documentStructure.js → documentQueries/documentStructure.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DEFAULT_DOCUMENT_ACCESS_EPOCH } from "
|
|
2
|
-
import { addDocumentLinkLocally, removeDocumentLinkLocally, } from "
|
|
3
|
-
import { relinkContainerDocumentLocally } from "
|
|
4
|
-
import { moveRemoteDocumentLinkLocally } from "
|
|
1
|
+
import { DEFAULT_DOCUMENT_ACCESS_EPOCH } from "../../../data/documents/documentConstants.js";
|
|
2
|
+
import { addDocumentLinkLocally, removeDocumentLinkLocally, } from "../documentLinks/documentLinkIntent.js";
|
|
3
|
+
import { relinkContainerDocumentLocally } from "../documentLinks/documentLocalRelink.js";
|
|
4
|
+
import { moveRemoteDocumentLinkLocally } from "../documentMove/documentMoveIntent.js";
|
|
5
5
|
export function canMutateDocumentLink(runtime) {
|
|
6
6
|
return (runtime.infra.dbStatus === "ready" &&
|
|
7
7
|
runtime.auth.isAuthenticated &&
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentStructure.js","sourceRoot":"","sources":["documentStructure.ts"],"names":[],"mappings":"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","sourcesContent":["import { DEFAULT_DOCUMENT_ACCESS_EPOCH } from \"../../../data/documents/documentConstants\";\nimport type { DocumentSummary } from \"../../../data/documents/documentSummary\";\nimport {\n addDocumentLinkLocally,\n removeDocumentLinkLocally,\n} from \"../documentLinks/documentLinkIntent\";\nimport { relinkContainerDocumentLocally } from \"../documentLinks/documentLocalRelink\";\nimport { moveRemoteDocumentLinkLocally } from \"../documentMove/documentMoveIntent\";\nimport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationRuntime,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\nexport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationRelinkInput,\n DocumentStructuralMutationRuntime,\n MergeDocumentSummary,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\ninterface DocumentStructuralMutationInput<TRuntime> {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n requireDocumentId: boolean;\n runtime: DocumentStructuralMutationRuntime;\n}\n\nexport function canMutateDocumentLink(runtime: {\n readonly auth: Pick<\n DocumentStructuralMutationRuntime[\"auth\"],\n \"isAuthenticated\"\n >;\n readonly infra: Pick<DocumentStructuralMutationRuntime[\"infra\"], \"dbStatus\">;\n readonly state: Pick<DocumentStructuralMutationRuntime[\"state\"], \"online\">;\n}): boolean {\n return (\n runtime.infra.dbStatus === \"ready\" &&\n runtime.auth.isAuthenticated &&\n runtime.state.online\n );\n}\n\nexport function canMutateLocalDocumentLink(runtime: {\n readonly infra: Pick<DocumentStructuralMutationRuntime[\"infra\"], \"dbStatus\">;\n}): boolean {\n return runtime.infra.dbStatus === \"ready\";\n}\n\nasync function openDocumentStoreForStructuralMutation<TRuntime>({\n host,\n note,\n requireDocumentId,\n runtime,\n}: DocumentStructuralMutationInput<TRuntime>) {\n if (requireDocumentId && !note.documentId) {\n return null;\n }\n\n const documentStore = host.openDocumentStore({\n containerId: note.containerId,\n documentId: note.documentId,\n localId: note.id,\n });\n if (!(await documentStore.ensureInitialized())) {\n runtime.util.log(\n `Container contents: note ${note.id} is not ready to mutate locally`,\n );\n return null;\n }\n\n return documentStore;\n}\n\nexport async function moveLocalDocumentLink<TRuntime>(params: {\n expandNode: (nodeId: string) => void;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n runtime: DocumentStructuralMutationRuntime;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { expandNode, host, note, runtime, targetContainerId } = params;\n if (note.containerId === targetContainerId) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: false,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n const movedNote = await relinkContainerDocumentLocally({\n accessEpoch: DEFAULT_DOCUMENT_ACCESS_EPOCH,\n currentDocumentStore,\n host,\n note,\n requestSync: true,\n runtime,\n targetContainerId,\n });\n if (!movedNote) {\n return null;\n }\n\n expandNode(targetContainerId);\n runtime.util.log(\n `Container contents: moved local note ${movedNote.id} to ${targetContainerId}`,\n );\n return movedNote;\n}\n\nexport async function moveDocumentLink<TRuntime>(params: {\n expandNode: (nodeId: string) => void;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n replaceLinkedContainers?: boolean | undefined;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<{ linksChanged: boolean; note: DocumentSummary | null }> {\n const {\n expandNode,\n host,\n note,\n replaceLinkedContainers,\n runtime,\n scheduleSync,\n setLinkedContainerIdsForDocument,\n targetContainerId,\n } = params;\n if (note.containerId === targetContainerId) {\n return { linksChanged: false, note: null };\n }\n if (!note.documentId) {\n const movedNote = await moveLocalDocumentLink({\n expandNode,\n host,\n note,\n runtime,\n targetContainerId,\n });\n return {\n linksChanged: movedNote !== null,\n note: movedNote,\n };\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return { linksChanged: false, note: null };\n }\n\n const queuedMove = await moveRemoteDocumentLinkLocally({\n currentDocumentStore,\n expandNode,\n host,\n note: {\n ...note,\n documentId: note.documentId,\n },\n replaceLinkedContainers,\n runtime,\n scheduleSync,\n setLinkedContainerIdsForDocument,\n targetContainerId,\n });\n return queuedMove;\n}\n\nexport async function addDocumentLink<TRuntime>(params: {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { host, note, runtime } = params;\n if (!note.documentId || !note.containerId) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n return addDocumentLinkLocally({\n ...params,\n currentDocumentStore,\n note: {\n ...note,\n documentId: note.documentId,\n containerId: note.containerId,\n },\n });\n}\n\nexport async function removeDocumentLink<TRuntime>(params: {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n removedContainerId: string;\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n}): Promise<DocumentSummary | null> {\n const { host, note, runtime } = params;\n if (!note.documentId || !note.containerId) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n // Keep the rotation preflight before accepting an unlink. Replay proves it\n // again before publishing the signed key rotation from the durable intent.\n await currentDocumentStore.assertCanRotateContentKey();\n return removeDocumentLinkLocally({\n ...params,\n currentDocumentStore,\n note: {\n ...note,\n documentId: note.documentId,\n containerId: note.containerId,\n },\n });\n}\n\nexport async function activateDocumentLink<TRuntime>(params: {\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary;\n runtime: DocumentStructuralMutationRuntime;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { host, note, runtime, targetContainerId } = params;\n if (\n !note.documentId ||\n !note.containerId ||\n note.containerId === targetContainerId\n ) {\n return null;\n }\n\n const currentDocumentStore = await openDocumentStoreForStructuralMutation({\n host,\n note,\n requireDocumentId: true,\n runtime,\n });\n if (!currentDocumentStore) {\n return null;\n }\n\n const relinkedNote = await relinkContainerDocumentLocally({\n accessEpoch: DEFAULT_DOCUMENT_ACCESS_EPOCH,\n currentDocumentStore,\n host,\n note,\n requestSync: false,\n runtime,\n targetContainerId,\n });\n if (!relinkedNote) {\n return null;\n }\n\n runtime.util.log(\n `Container contents: switched active note ${relinkedNote.id} to ${targetContainerId}`,\n );\n return relinkedNote;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { DocumentSummary } from "
|
|
2
|
-
import type { ExecSql, RelinkPersistedDocumentInput } from "
|
|
3
|
-
import type { ContainerContentsProjectionUserKeyResolver } from "
|
|
4
|
-
import type { ContainerContentsWorkflowRuntime } from "
|
|
1
|
+
import type { DocumentSummary } from "../../../data/documents/documentSummary.js";
|
|
2
|
+
import type { ExecSql, RelinkPersistedDocumentInput } from "../../documents/index.js";
|
|
3
|
+
import type { ContainerContentsProjectionUserKeyResolver } from "../projectionKeys.js";
|
|
4
|
+
import type { ContainerContentsWorkflowRuntime } from "../runtime.js";
|
|
5
5
|
export type MergeDocumentSummary = (nextDocument: DocumentSummary) => void;
|
|
6
6
|
export type SetLinkedContainerIdsForDocument = (documentId: string, linkedContainerIds: ReadonlyArray<string>) => void;
|
|
7
7
|
export type DocumentStructuralMutationRuntime = ContainerContentsWorkflowRuntime & {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentStructureTypes.js","sourceRoot":"","sources":["documentStructureTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentSummary } from \"../../../data/documents/documentSummary\";\nimport type { ExecSql, RelinkPersistedDocumentInput } from \"../../documents\";\nimport type { ContainerContentsProjectionUserKeyResolver } from \"../projectionKeys\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport type MergeDocumentSummary = (nextDocument: DocumentSummary) => void;\nexport type SetLinkedContainerIdsForDocument = (\n documentId: string,\n linkedContainerIds: ReadonlyArray<string>,\n) => void;\n\nexport type DocumentStructuralMutationRuntime =\n ContainerContentsWorkflowRuntime & {\n resolveProjectionUserKey: ContainerContentsProjectionUserKeyResolver;\n };\n\nexport interface DocumentStructuralMutationRelinkInput\n extends RelinkPersistedDocumentInput {\n commitSideEffect?:\n | ((transactionExecSql: ExecSql) => Promise<void>)\n | undefined;\n contentKeyBundle?: string | null | undefined;\n documentKekTargets?: string | null | undefined;\n documentManifestBundle?: string | null | undefined;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface DocumentStructuralMutationLocalStore<TRuntime> {\n assertCanRotateContentKey: () => Promise<Uint8Array>;\n ensureInitialized: () => Promise<boolean>;\n relink: (\n input: DocumentStructuralMutationRelinkInput,\n ) => Promise<DocumentSummary | null>;\n requestSync: () => void;\n updateRuntime: (runtime: TRuntime) => void;\n}\n\nexport interface DocumentStructuralMutationHost<TRuntime> {\n documentWorkflowRuntime: (containerId: string | null) => TRuntime;\n mergeDocumentSummary: MergeDocumentSummary;\n openDocumentStore: (input: {\n containerId: string | null;\n documentId: string | null;\n localId: string;\n }) => DocumentStructuralMutationLocalStore<TRuntime>;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { sqlDocumentContainerProjectionPersistence } from "
|
|
2
|
-
import { containerDocumentPlacementKey, listContainerDocumentTombstoneHoldsForDocuments, } from "
|
|
3
|
-
import { sqlDocumentsPersistence } from "
|
|
4
|
-
import { compareContainerContentsDocumentSummaries } from "./
|
|
5
|
-
import { listContainerContentsSqlIdBatches } from "./
|
|
1
|
+
import { sqlDocumentContainerProjectionPersistence } from "../../../data/persistence/containers/documentContainerProjectionPersistence.js";
|
|
2
|
+
import { containerDocumentPlacementKey, listContainerDocumentTombstoneHoldsForDocuments, } from "../../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js";
|
|
3
|
+
import { sqlDocumentsPersistence } from "../../../data/persistence/documents/documentsPersistence.js";
|
|
4
|
+
import { compareContainerContentsDocumentSummaries } from "./rows.js";
|
|
5
|
+
import { listContainerContentsSqlIdBatches } from "./sql.js";
|
|
6
6
|
function addContainerContentsDocumentSummaries(documentSummariesById, documentSummaries) {
|
|
7
7
|
for (const documentSummary of documentSummaries) {
|
|
8
8
|
documentSummariesById.set(documentSummary.id, documentSummary);
|
|
@@ -0,0 +1 @@
|
|
|
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 \"./rows\";\nimport { listContainerContentsSqlIdBatches } from \"./sql\";\nimport type {\n ContainerContentsContainerSubtreeState,\n ContainerContentsDocumentRuntimeTarget,\n ContainerContentsSharedDocumentSummaries,\n ContainerDocumentQueriesRuntime,\n} from \"./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,12 +1,12 @@
|
|
|
1
|
-
import type { ContainerSystemSlot } from "
|
|
2
|
-
import type { SyncWatermark } from "
|
|
3
|
-
import type { DiscoveredDocumentInput, DocumentSummary } from "
|
|
4
|
-
import
|
|
5
|
-
import { type RecoveryFolder } from "
|
|
1
|
+
import type { ContainerSystemSlot } from "../../../internal/validators/containerSystemSlot.js";
|
|
2
|
+
import type { SyncWatermark } from "../../../internal/validators/response/index.js";
|
|
3
|
+
import type { DiscoveredDocumentInput, DocumentSummary } from "../../../data/documents/documentSummary.js";
|
|
4
|
+
import { type PendingWriteQueueItem } from "../pendingWrites/index.js";
|
|
5
|
+
import { type RecoveryFolder } from "../recovery/folderRecovery.js";
|
|
6
|
+
import type { ContainerDocumentObjectSyncState } from "../syncState.js";
|
|
6
7
|
import { type PendingDownloadQueueItem } from "./pendingDownloads.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
export type { ContainerDocumentLinkInput, ContainerDocumentSidebarRow, ContainerDocumentTombstone, ContainerItemRow, ContainerItemSort, ContainerItemSortDirection, ContainerItemSortKey, } from "./documentQueries/types.js";
|
|
8
|
+
import type { ContainerDocumentLinkInput, ContainerDocumentQueriesRuntime, ContainerDocumentSidebarWindow, ContainerDocumentTombstone, ContainerItemSort, ContainerItemWindow } from "./types.js";
|
|
9
|
+
export type { ContainerDocumentLinkInput, ContainerDocumentSidebarRow, ContainerDocumentTombstone, ContainerItemRow, ContainerItemSort, ContainerItemSortDirection, ContainerItemSortKey, } from "./types.js";
|
|
10
10
|
interface ListContainerItemWindowInput {
|
|
11
11
|
/** Null selects the virtual orphaned-documents recovery collection. */
|
|
12
12
|
containerId: string | null;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { hasRetainedContainerMetadata, listRecoveryFolderMoveIds, } from "
|
|
2
|
-
import { ensureContainerTables } from "
|
|
3
|
-
import { containerContentsSyncLane, sqlContainerSyncWatermarkPersistence, } from "
|
|
4
|
-
import { sqlDocumentContainerProjectionPersistence } from "
|
|
5
|
-
import { applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones, sqlDocumentsPersistence, upsertDiscoveredDocuments, } from "
|
|
6
|
-
import { localIntentTables } from "
|
|
7
|
-
import { ensureSqlTables } from "
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { createFolderRecoveryQueries, } from "./folderRecovery.js";
|
|
1
|
+
import { hasRetainedContainerMetadata, listRecoveryFolderMoveIds, } from "../../../data/persistence/container-contents/containerRecoveryPersistence.js";
|
|
2
|
+
import { ensureContainerTables } from "../../../data/persistence/containers/containerPersistence.js";
|
|
3
|
+
import { containerContentsSyncLane, sqlContainerSyncWatermarkPersistence, } from "../../../data/persistence/containers/containerSyncWatermarkPersistence.js";
|
|
4
|
+
import { sqlDocumentContainerProjectionPersistence } from "../../../data/persistence/containers/documentContainerProjectionPersistence.js";
|
|
5
|
+
import { applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones, sqlDocumentsPersistence, upsertDiscoveredDocuments, } from "../../../data/persistence/documents/documentsPersistence.js";
|
|
6
|
+
import { localIntentTables } from "../../../data/sqlite/schema.js";
|
|
7
|
+
import { ensureSqlTables } from "../../../data/sqlite/sqlSchema.js";
|
|
8
|
+
import { listPendingWrites, resetPendingWriteRetryState, } from "../pendingWrites/index.js";
|
|
9
|
+
import { createFolderRecoveryQueries, } from "../recovery/folderRecovery.js";
|
|
10
|
+
import { hydratedProjectionSql } from "./hydrationSql.js";
|
|
12
11
|
import { getOrphanedDocumentQueryBind, getOrphanedDocumentWhereSql, } from "./orphanedDocumentSql.js";
|
|
13
12
|
import { listPendingDownloads, } from "./pendingDownloads.js";
|
|
14
|
-
import {
|
|
13
|
+
import { mapContainerContentsDocumentSummaryRow, mapContainerContentsDocumentSyncStateRow, mapContainerDocumentSidebarRow, mapContainerItemRow, readContainerContentsContainerItemCount, } from "./rows.js";
|
|
14
|
+
import { clampContainerItemWindowValue, getContainerContentsContainerDocumentSidebarOrderBy, getContainerContentsContainerItemOrderBy, getContainerContentsContainerItemsBaseSql, getContainerContentsDocumentPendingStateCtes, getContainerContentsDocumentRowsBaseSql, getContainerDocumentSidebarWindowLimit, getContainerItemWindowLimit, getOrphanedDocumentExistsSql, getOrphanedDocumentItemsBaseSql, getOrphanedDocumentRowsBaseSql, listContainerContentsSqlIdBatches, } from "./sql.js";
|
|
15
15
|
async function listContainerItemWindow(execSql, input) {
|
|
16
16
|
await ensureContainerTables(execSql);
|
|
17
17
|
await sqlDocumentsPersistence.ensureSchema(execSql);
|
|
@@ -209,4 +209,4 @@ export function createContainerDocumentQueriesFromRuntime(runtime) {
|
|
|
209
209
|
},
|
|
210
210
|
};
|
|
211
211
|
}
|
|
212
|
-
//# sourceMappingURL=
|
|
212
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { SyncWatermark } from \"@tearleads/validators/response\";\nimport type {\n DiscoveredDocumentInput,\n DocumentSummary,\n} from \"../../../data/documents/documentSummary\";\nimport {\n hasRetainedContainerMetadata,\n listRecoveryFolderMoveIds,\n} from \"../../../data/persistence/container-contents/containerRecoveryPersistence\";\nimport { ensureContainerTables } from \"../../../data/persistence/containers/containerPersistence\";\nimport {\n containerContentsSyncLane,\n sqlContainerSyncWatermarkPersistence,\n} from \"../../../data/persistence/containers/containerSyncWatermarkPersistence\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport {\n applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones,\n sqlDocumentsPersistence,\n upsertDiscoveredDocuments,\n} from \"../../../data/persistence/documents/documentsPersistence\";\nimport { localIntentTables } from \"../../../data/sqlite/schema\";\nimport { type ExecSql, ensureSqlTables } from \"../../../data/sqlite/sqlSchema\";\nimport {\n listPendingWrites,\n type PendingWriteQueueItem,\n resetPendingWriteRetryState,\n} from \"../pendingWrites\";\nimport {\n createFolderRecoveryQueries,\n type RecoveryFolder,\n} from \"../recovery/folderRecovery\";\nimport type { ContainerDocumentObjectSyncState } from \"../syncState\";\nimport { hydratedProjectionSql } from \"./hydrationSql\";\nimport {\n getOrphanedDocumentQueryBind,\n getOrphanedDocumentWhereSql,\n} from \"./orphanedDocumentSql\";\nimport {\n listPendingDownloads,\n type PendingDownloadQueueItem,\n} from \"./pendingDownloads\";\nimport {\n mapContainerContentsDocumentSummaryRow,\n mapContainerContentsDocumentSyncStateRow,\n mapContainerDocumentSidebarRow,\n mapContainerItemRow,\n readContainerContentsContainerItemCount,\n} from \"./rows\";\nimport {\n clampContainerItemWindowValue,\n getContainerContentsContainerDocumentSidebarOrderBy,\n getContainerContentsContainerItemOrderBy,\n getContainerContentsContainerItemsBaseSql,\n getContainerContentsDocumentPendingStateCtes,\n getContainerContentsDocumentRowsBaseSql,\n getContainerDocumentSidebarWindowLimit,\n getContainerItemWindowLimit,\n getOrphanedDocumentExistsSql,\n getOrphanedDocumentItemsBaseSql,\n getOrphanedDocumentRowsBaseSql,\n listContainerContentsSqlIdBatches,\n} from \"./sql\";\nimport type {\n ContainerDocumentLinkInput,\n ContainerDocumentQueriesRuntime,\n ContainerDocumentSidebarWindow,\n ContainerDocumentTombstone,\n ContainerItemSort,\n ContainerItemWindow,\n} from \"./types\";\n\nexport type {\n ContainerDocumentLinkInput,\n ContainerDocumentSidebarRow,\n ContainerDocumentTombstone,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n} from \"./types\";\n\ninterface ListContainerItemWindowInput {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n sort: ContainerItemSort;\n visibleForeignSystemContainerNames?: ReadonlyArray<string> | undefined;\n visibleSystemSlots?: ReadonlyArray<ContainerSystemSlot> | undefined;\n}\n\nexport interface ContainerDocumentQueries {\n listRecoveryFolderMoveIds(input: {\n currentOrganizationId: string | null;\n }): Promise<string[]>;\n listRecoveryFolders(input: {\n currentOrganizationId: string | null;\n }): Promise<RecoveryFolder[]>;\n discardRecoveryFolder(\n input: Pick<RecoveryFolder, \"containerId\" | \"organizationId\" | \"revision\">,\n ): Promise<boolean>;\n applyContainerDocumentTombstones(\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n hasOrphanedDocuments(input: {\n currentOrganizationId: string | null;\n }): Promise<boolean>;\n listContainerDocumentSidebarWindow(input: {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n }): Promise<ContainerDocumentSidebarWindow>;\n listContainerItemWindow(\n input: ListContainerItemWindowInput,\n ): Promise<ContainerItemWindow>;\n loadDocumentSyncState(\n localId: string,\n ): Promise<ContainerDocumentObjectSyncState | null>;\n loadDocumentSummary(\n localId: string,\n options?: { requireHydrated?: boolean },\n ): Promise<DocumentSummary | null>;\n loadOrphanedDocumentSummary(input: {\n requireHydrated?: boolean;\n currentOrganizationId: string | null;\n localId: string;\n }): Promise<DocumentSummary | null>;\n loadContainerDocumentWatermark(\n containerId: string,\n ): Promise<SyncWatermark | null>;\n listLinkedContainerIdsByDocumentIds(\n documentIds: ReadonlyArray<string>,\n ): Promise<ReadonlyMap<string, ReadonlyArray<string>>>;\n listPendingDownloads(): Promise<ReadonlyArray<PendingDownloadQueueItem>>;\n listPendingWrites(): Promise<ReadonlyArray<PendingWriteQueueItem>>;\n retryPendingWriteItem(input: {\n localId: string;\n namespace: string | null;\n objectKind: PendingWriteQueueItem[\"objectKind\"];\n }): Promise<void>;\n replaceDocumentLinksBatch(\n inputs: ReadonlyArray<ContainerDocumentLinkInput>,\n ): Promise<void>;\n saveContainerDocumentWatermark(\n containerId: string,\n watermark: SyncWatermark,\n ): Promise<void>;\n upsertDiscoveredDocuments(\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n}\n\nasync function listContainerItemWindow(\n execSql: ExecSql,\n input: ListContainerItemWindowInput,\n): Promise<ContainerItemWindow> {\n await ensureContainerTables(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, localIntentTables);\n\n const limit = getContainerItemWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const visibleSystemSlots = Array.from(\n new Set(input.visibleSystemSlots ?? []),\n );\n const currentOrganizationId = input.currentOrganizationId || null;\n const visibleForeignSystemContainerNames = currentOrganizationId\n ? Array.from(new Set(input.visibleForeignSystemContainerNames ?? []))\n : [];\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [\n input.containerId,\n ...visibleSystemSlots,\n ...(visibleForeignSystemContainerNames.length > 0\n ? [currentOrganizationId, ...visibleForeignSystemContainerNames]\n : []),\n input.containerId,\n input.containerId,\n ];\n const baseSql = orphaned\n ? getOrphanedDocumentItemsBaseSql()\n : getContainerContentsContainerItemsBaseSql(\n visibleSystemSlots.length,\n visibleForeignSystemContainerNames.length,\n );\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerItemOrderBy(input.sort)} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map((row) => mapContainerItemRow(input.containerId, row)),\n totalCount,\n };\n}\n\nasync function hasOrphanedDocuments(\n execSql: ExecSql,\n currentOrganizationId: string | null,\n): Promise<boolean> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n getOrphanedDocumentExistsSql(),\n getOrphanedDocumentQueryBind(currentOrganizationId),\n );\n return (\n rows.length > 0 ||\n (await hasRetainedContainerMetadata(execSql, currentOrganizationId)) ||\n (await listRecoveryFolderMoveIds(execSql, currentOrganizationId)).length > 0\n );\n}\n\nasync function listContainerDocumentSidebarWindow(\n execSql: ExecSql,\n input: {\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n },\n): Promise<ContainerDocumentSidebarWindow> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const limit = getContainerDocumentSidebarWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [input.containerId, input.containerId];\n const baseSql = orphaned\n ? getOrphanedDocumentRowsBaseSql()\n : getContainerContentsDocumentRowsBaseSql();\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerDocumentSidebarOrderBy()} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map(mapContainerDocumentSidebarRow),\n totalCount,\n };\n}\n\nasync function queryContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n scope: { bind: ReadonlyArray<string | null>; whereSql: string },\n): Promise<DocumentSummary | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n d.title AS title,\n d.updated_at AS updated_at,\n stored.access_state_hash AS access_state_hash,\n stored.effective_access_level AS effective_access_level\n FROM document_projection d\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = d.local_id\n WHERE d.local_id = ?\n ${scope.whereSql}\n LIMIT 1\n `,\n [localId, ...scope.bind],\n );\n\n return mapContainerContentsDocumentSummaryRow(rows[0] ?? {});\n}\n\nfunction loadContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: [],\n whereSql: requireHydrated\n ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}`\n : \"\",\n });\n}\n\nfunction loadContainerContentsOrphanedDocumentSummary(\n execSql: ExecSql,\n localId: string,\n currentOrganizationId: string | null,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: getOrphanedDocumentQueryBind(currentOrganizationId),\n whereSql: `${requireHydrated ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}` : \"\"} AND ${getOrphanedDocumentWhereSql(\n {\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n },\n )}`,\n });\n}\n\nasync function loadContainerContentsDocumentSyncState(\n execSql: ExecSql,\n localId: string,\n): Promise<ContainerDocumentObjectSyncState | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.document_id AS document_id,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE d.local_id = ?\n LIMIT 1\n `,\n [localId],\n );\n const [row] = rows;\n if (!row) {\n return null;\n }\n\n return mapContainerContentsDocumentSyncStateRow(row);\n}\n\nasync function listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql: ExecSql,\n documentIds: ReadonlyArray<string>,\n): Promise<ReadonlyMap<string, ReadonlyArray<string>>> {\n const uniqueDocumentIds = Array.from(new Set(documentIds));\n if (uniqueDocumentIds.length === 0) {\n return new Map();\n }\n\n const linkedContainerIdsByDocumentId = new Map<string, string[]>();\n for (const documentId of uniqueDocumentIds) {\n linkedContainerIdsByDocumentId.set(documentId, []);\n }\n\n for (const documentIdBatch of listContainerContentsSqlIdBatches(\n uniqueDocumentIds,\n )) {\n const batchLinkedContainerIdsByDocumentId =\n await sqlDocumentContainerProjectionPersistence.listLinkedContainerIdsByDocumentIds(\n execSql,\n documentIdBatch,\n );\n for (const [\n documentId,\n linkedContainerIds,\n ] of batchLinkedContainerIdsByDocumentId.entries()) {\n linkedContainerIdsByDocumentId.set(\n documentId,\n Array.from(linkedContainerIds),\n );\n }\n }\n\n return linkedContainerIdsByDocumentId;\n}\n\nexport function createContainerDocumentQueriesFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): ContainerDocumentQueries {\n const execSql = runtime.infra.execSql;\n return {\n ...createFolderRecoveryQueries(execSql),\n applyContainerDocumentTombstones(tombstones) {\n return applyPersistedContainerDocumentTombstones(execSql, tombstones);\n },\n hasOrphanedDocuments({ currentOrganizationId }) {\n return hasOrphanedDocuments(execSql, currentOrganizationId);\n },\n listContainerDocumentSidebarWindow(input) {\n return listContainerDocumentSidebarWindow(execSql, input);\n },\n listContainerItemWindow(input) {\n return listContainerItemWindow(execSql, input);\n },\n loadDocumentSyncState(localId) {\n return loadContainerContentsDocumentSyncState(execSql, localId);\n },\n loadDocumentSummary(localId, options) {\n return loadContainerContentsDocumentSummary(\n execSql,\n localId,\n options?.requireHydrated ?? false,\n );\n },\n loadOrphanedDocumentSummary({\n currentOrganizationId,\n localId,\n requireHydrated = false,\n }) {\n return loadContainerContentsOrphanedDocumentSummary(\n execSql,\n localId,\n currentOrganizationId,\n requireHydrated,\n );\n },\n loadContainerDocumentWatermark(containerId) {\n return sqlContainerSyncWatermarkPersistence.loadWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n );\n },\n listLinkedContainerIdsByDocumentIds(documentIds) {\n return listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql,\n documentIds,\n );\n },\n listPendingDownloads() {\n return listPendingDownloads(execSql);\n },\n listPendingWrites() {\n return listPendingWrites(execSql);\n },\n retryPendingWriteItem(input) {\n return resetPendingWriteRetryState(execSql, input);\n },\n replaceDocumentLinksBatch(inputs) {\n return sqlDocumentContainerProjectionPersistence.replaceDocumentLinksBatch(\n execSql,\n inputs,\n );\n },\n async saveContainerDocumentWatermark(containerId, watermark) {\n await sqlContainerSyncWatermarkPersistence.saveWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n watermark,\n );\n },\n upsertDiscoveredDocuments(inputs) {\n return upsertDiscoveredDocuments(execSql, inputs);\n },\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from "
|
|
1
|
+
import { HIDDEN_DOCUMENT_SUMMARY_KINDS } from "../../../data/documents/documentSummary.js";
|
|
2
2
|
export function getOrphanedDocumentWhereSql(input) {
|
|
3
3
|
const { documentIdSql, projectionAlias } = input;
|
|
4
4
|
return `
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orphanedDocumentSql.js","sourceRoot":"","sources":["orphanedDocumentSql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AAExF,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"]}
|
package/workflows/container-contents/{pendingDownloads.js → documentQueries/pendingDownloads.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ensureContainerTables } from "
|
|
2
|
-
import { sqlDocumentsPersistence } from "
|
|
3
|
-
import { emptyContentFrontierSql } from "./
|
|
1
|
+
import { ensureContainerTables } from "../../../data/persistence/containers/containerPersistence.js";
|
|
2
|
+
import { sqlDocumentsPersistence } from "../../../data/persistence/documents/documentsPersistence.js";
|
|
3
|
+
import { emptyContentFrontierSql } from "./hydrationSql.js";
|
|
4
4
|
/** Durable, already-discovered content pulls, including folder metadata. */
|
|
5
5
|
export async function listPendingDownloads(execSql) {
|
|
6
6
|
await ensureContainerTables(execSql);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pendingDownloads.js","sourceRoot":"","sources":["pendingDownloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2DAA2D,CAAC;AAClG,OAAO,EAAE,uBAAuB,EAAE,MAAM,0DAA0D,CAAC;AAEnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAYzD,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 \"./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,6 +1,6 @@
|
|
|
1
1
|
import { LOCAL_INTENT_LANES } from "../../../data/sqlite/schema.js";
|
|
2
|
-
import { getOrphanedDocumentWhereSql } from "../orphanedDocumentSql.js";
|
|
3
2
|
import { hydratedProjectionSql } from "./hydrationSql.js";
|
|
3
|
+
import { getOrphanedDocumentWhereSql } from "./orphanedDocumentSql.js";
|
|
4
4
|
// Keep each IN clause below SQLite's historical 999 bind-parameter limit.
|
|
5
5
|
const CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE = 500;
|
|
6
6
|
const MAX_CONTAINER_ITEM_WINDOW_LIMIT = 200;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.js","sourceRoot":"","sources":["sql.ts"],"names":[],"mappings":"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","sourcesContent":["import { LOCAL_INTENT_LANES } from \"../../../data/sqlite/schema\";\nimport { getOrphanedDocumentWhereSql } from \"../orphanedDocumentSql\";\nimport { hydratedProjectionSql } from \"./hydrationSql\";\nimport type { ContainerItemSort } from \"./types\";\n\n// Keep each IN clause below SQLite's historical 999 bind-parameter limit.\nconst CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE = 500;\nconst MAX_CONTAINER_ITEM_WINDOW_LIMIT = 200;\nconst MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT = 200;\n\nexport function listContainerContentsSqlIdBatches(\n values: ReadonlyArray<string>,\n): ReadonlyArray<ReadonlyArray<string>> {\n const batches: string[][] = [];\n\n for (\n let index = 0;\n index < values.length;\n index += CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE\n ) {\n batches.push(\n values.slice(index, index + CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE),\n );\n }\n\n return batches;\n}\n\nexport function clampContainerItemWindowValue(value: number): number {\n return Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n}\n\nexport function getContainerItemWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_ITEM_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerDocumentSidebarWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerContentsContainerItemOrderBy(\n sort: ContainerItemSort,\n): string {\n const direction = sort.direction === \"desc\" ? \"DESC\" : \"ASC\";\n\n if (sort.key === \"type\") {\n return `type_sort COLLATE NOCASE ${direction}, name COLLATE NOCASE ASC, item_kind_sort ASC, item_id ASC`;\n }\n\n if (sort.key === \"created\") {\n return `created_at IS NULL ASC, created_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"modified\") {\n return `updated_at IS NULL ASC, updated_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"name\") {\n return `item_kind_sort ASC, name COLLATE NOCASE ${direction}, type_sort COLLATE NOCASE ASC, item_id ASC`;\n }\n\n return \"item_kind_sort ASC, name COLLATE NOCASE ASC, type_sort COLLATE NOCASE ASC, item_id ASC\";\n}\n\nexport function getContainerContentsDocumentPendingStateCtes(): string {\n return `\n document_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'documents' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n document_pending_attachment_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_attachment_count,\n COALESCE(SUM(byte_length), 0) AS pending_attachment_bytes\n FROM document_pending_attachments\n GROUP BY local_id\n )\n `;\n}\n\ninterface ContainerSystemFilterCounts {\n visibleForeignSystemContainerNameCount: number;\n visibleSystemSlotCount: number;\n}\n\nexport function getContainerDisplayNameSql(containerAlias: string): string {\n return `COALESCE(${containerAlias}.display_name, CASE WHEN ${containerAlias}.parent_id IS NULL THEN '/' ELSE 'Untitled' END)`;\n}\n\n/**\n * Display attribution for an object reached through a container: the\n * container's organization when attached, else the projection row's own.\n */\nexport function getContainerOrganizationAttributionSql(aliases: {\n containerAlias: string;\n projectionAlias: string;\n}): string {\n return `COALESCE(NULLIF(${aliases.containerAlias}.organization_id, ''), NULLIF(${aliases.projectionAlias}.organization_id, ''))`;\n}\n\nfunction getContainerContentsContainerSystemSlotFilter(\n counts: ContainerSystemFilterCounts,\n): string {\n const clauses = [\"c.system_slot IS NULL\"];\n\n if (counts.visibleSystemSlotCount > 0) {\n const visibleSystemSlotBindMarkers = Array.from(\n { length: counts.visibleSystemSlotCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(`c.system_slot IN (${visibleSystemSlotBindMarkers})`);\n }\n\n if (counts.visibleForeignSystemContainerNameCount > 0) {\n const visibleSystemNameBindMarkers = Array.from(\n { length: counts.visibleForeignSystemContainerNameCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(\n `(c.organization_id != '' AND c.organization_id != ? AND ${getContainerDisplayNameSql(\"c\")} IN (${visibleSystemNameBindMarkers}))`,\n );\n }\n\n return `(${clauses.join(\" OR \")})`;\n}\n\n/**\n * A `(document, container)` placement under a tombstone hold is hidden from\n * container views: the server said the document left the container, but the\n * signed head that would prove it is not yet available, so the row is kept\n * and hidden rather than deleted (`container_document_tombstone_holds`).\n */\nfunction getHeldPlacementExclusionSql(\n documentIdSql: string,\n containerIdSql: string,\n): string {\n return `\n AND NOT EXISTS (\n SELECT 1\n FROM container_document_tombstone_holds hold\n WHERE hold.document_id = ${documentIdSql}\n AND hold.container_id = ${containerIdSql}\n AND hold.hidden = 1\n )`;\n}\n\nexport function getContainerContentsContainerItemsBaseSql(\n visibleSystemSlotCount = 0,\n visibleForeignSystemContainerNameCount = 0,\n): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_metadata_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'container-metadata' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n pending_container_create_intents AS (\n SELECT\n subject_id AS container_id,\n MAX(last_error) AS last_error\n FROM local_intents\n WHERE lane = '${LOCAL_INTENT_LANES.containerCreate}'\n AND intent_type = 'container.create'\n AND sync_status = 'pending'\n GROUP BY subject_id\n ),\n container_items AS (\n SELECT\n 'container' AS item_kind,\n 0 AS item_kind_sort,\n c.id AS item_id,\n NULL AS document_id,\n NULL AS document_kind,\n c.metadata_document_id AS metadata_document_id,\n c.local_updated_at AS local_updated_at,\n c.server_created_at AS server_created_at,\n c.server_updated_at AS server_updated_at,\n c.icon AS icon,\n COALESCE(container_updates.pending_update_count, 0) AS pending_update_count,\n 0 AS pending_attachment_count,\n 0 AS pending_attachment_bytes,\n create_intent.last_error AS sync_last_error,\n ${getContainerDisplayNameSql(\"c\")} AS name,\n 'folder' AS type_sort,\n COALESCE(c.server_created_at, c.local_created_at) AS created_at,\n COALESCE(c.server_updated_at, c.local_updated_at) AS updated_at\n FROM containers c\n LEFT JOIN container_metadata_pending_update_counts container_updates\n ON container_updates.local_id = c.id\n LEFT JOIN pending_container_create_intents create_intent\n ON create_intent.container_id = c.id\n WHERE c.parent_id = ?\n AND ${hydratedProjectionSql(\"c.id\", \"container-metadata\")}\n AND ${getContainerContentsContainerSystemSlotFilter({\n visibleForeignSystemContainerNameCount,\n visibleSystemSlotCount,\n })}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_items\n `;\n}\n\nexport function getContainerContentsDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_documents AS (\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n linked.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_documents\n `;\n}\n\nexport function getOrphanedDocumentItemsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n orphaned_document_items AS (\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n )\n SELECT *\n FROM orphaned_document_items\n `;\n}\n\nexport function getOrphanedDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n `;\n}\n\nexport function getOrphanedDocumentExistsSql(): string {\n return `\n SELECT 1\n FROM document_projection d\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n LIMIT 1\n `;\n}\n\nexport function getContainerContentsContainerDocumentSidebarOrderBy(): string {\n return \"updated_at IS NULL ASC, updated_at DESC, title COLLATE NOCASE ASC, local_id ASC\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["sql.ts"],"names":[],"mappings":"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","sourcesContent":["import { LOCAL_INTENT_LANES } from \"../../../data/sqlite/schema\";\nimport { hydratedProjectionSql } from \"./hydrationSql\";\nimport { getOrphanedDocumentWhereSql } from \"./orphanedDocumentSql\";\nimport type { ContainerItemSort } from \"./types\";\n\n// Keep each IN clause below SQLite's historical 999 bind-parameter limit.\nconst CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE = 500;\nconst MAX_CONTAINER_ITEM_WINDOW_LIMIT = 200;\nconst MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT = 200;\n\nexport function listContainerContentsSqlIdBatches(\n values: ReadonlyArray<string>,\n): ReadonlyArray<ReadonlyArray<string>> {\n const batches: string[][] = [];\n\n for (\n let index = 0;\n index < values.length;\n index += CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE\n ) {\n batches.push(\n values.slice(index, index + CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE),\n );\n }\n\n return batches;\n}\n\nexport function clampContainerItemWindowValue(value: number): number {\n return Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n}\n\nexport function getContainerItemWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_ITEM_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerDocumentSidebarWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerContentsContainerItemOrderBy(\n sort: ContainerItemSort,\n): string {\n const direction = sort.direction === \"desc\" ? \"DESC\" : \"ASC\";\n\n if (sort.key === \"type\") {\n return `type_sort COLLATE NOCASE ${direction}, name COLLATE NOCASE ASC, item_kind_sort ASC, item_id ASC`;\n }\n\n if (sort.key === \"created\") {\n return `created_at IS NULL ASC, created_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"modified\") {\n return `updated_at IS NULL ASC, updated_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"name\") {\n return `item_kind_sort ASC, name COLLATE NOCASE ${direction}, type_sort COLLATE NOCASE ASC, item_id ASC`;\n }\n\n return \"item_kind_sort ASC, name COLLATE NOCASE ASC, type_sort COLLATE NOCASE ASC, item_id ASC\";\n}\n\nexport function getContainerContentsDocumentPendingStateCtes(): string {\n return `\n document_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'documents' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n document_pending_attachment_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_attachment_count,\n COALESCE(SUM(byte_length), 0) AS pending_attachment_bytes\n FROM document_pending_attachments\n GROUP BY local_id\n )\n `;\n}\n\ninterface ContainerSystemFilterCounts {\n visibleForeignSystemContainerNameCount: number;\n visibleSystemSlotCount: number;\n}\n\nexport function getContainerDisplayNameSql(containerAlias: string): string {\n return `COALESCE(${containerAlias}.display_name, CASE WHEN ${containerAlias}.parent_id IS NULL THEN '/' ELSE 'Untitled' END)`;\n}\n\n/**\n * Display attribution for an object reached through a container: the\n * container's organization when attached, else the projection row's own.\n */\nexport function getContainerOrganizationAttributionSql(aliases: {\n containerAlias: string;\n projectionAlias: string;\n}): string {\n return `COALESCE(NULLIF(${aliases.containerAlias}.organization_id, ''), NULLIF(${aliases.projectionAlias}.organization_id, ''))`;\n}\n\nfunction getContainerContentsContainerSystemSlotFilter(\n counts: ContainerSystemFilterCounts,\n): string {\n const clauses = [\"c.system_slot IS NULL\"];\n\n if (counts.visibleSystemSlotCount > 0) {\n const visibleSystemSlotBindMarkers = Array.from(\n { length: counts.visibleSystemSlotCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(`c.system_slot IN (${visibleSystemSlotBindMarkers})`);\n }\n\n if (counts.visibleForeignSystemContainerNameCount > 0) {\n const visibleSystemNameBindMarkers = Array.from(\n { length: counts.visibleForeignSystemContainerNameCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(\n `(c.organization_id != '' AND c.organization_id != ? AND ${getContainerDisplayNameSql(\"c\")} IN (${visibleSystemNameBindMarkers}))`,\n );\n }\n\n return `(${clauses.join(\" OR \")})`;\n}\n\n/**\n * A `(document, container)` placement under a tombstone hold is hidden from\n * container views: the server said the document left the container, but the\n * signed head that would prove it is not yet available, so the row is kept\n * and hidden rather than deleted (`container_document_tombstone_holds`).\n */\nfunction getHeldPlacementExclusionSql(\n documentIdSql: string,\n containerIdSql: string,\n): string {\n return `\n AND NOT EXISTS (\n SELECT 1\n FROM container_document_tombstone_holds hold\n WHERE hold.document_id = ${documentIdSql}\n AND hold.container_id = ${containerIdSql}\n AND hold.hidden = 1\n )`;\n}\n\nexport function getContainerContentsContainerItemsBaseSql(\n visibleSystemSlotCount = 0,\n visibleForeignSystemContainerNameCount = 0,\n): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_metadata_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'container-metadata' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n pending_container_create_intents AS (\n SELECT\n subject_id AS container_id,\n MAX(last_error) AS last_error\n FROM local_intents\n WHERE lane = '${LOCAL_INTENT_LANES.containerCreate}'\n AND intent_type = 'container.create'\n AND sync_status = 'pending'\n GROUP BY subject_id\n ),\n container_items AS (\n SELECT\n 'container' AS item_kind,\n 0 AS item_kind_sort,\n c.id AS item_id,\n NULL AS document_id,\n NULL AS document_kind,\n c.metadata_document_id AS metadata_document_id,\n c.local_updated_at AS local_updated_at,\n c.server_created_at AS server_created_at,\n c.server_updated_at AS server_updated_at,\n c.icon AS icon,\n COALESCE(container_updates.pending_update_count, 0) AS pending_update_count,\n 0 AS pending_attachment_count,\n 0 AS pending_attachment_bytes,\n create_intent.last_error AS sync_last_error,\n ${getContainerDisplayNameSql(\"c\")} AS name,\n 'folder' AS type_sort,\n COALESCE(c.server_created_at, c.local_created_at) AS created_at,\n COALESCE(c.server_updated_at, c.local_updated_at) AS updated_at\n FROM containers c\n LEFT JOIN container_metadata_pending_update_counts container_updates\n ON container_updates.local_id = c.id\n LEFT JOIN pending_container_create_intents create_intent\n ON create_intent.container_id = c.id\n WHERE c.parent_id = ?\n AND ${hydratedProjectionSql(\"c.id\", \"container-metadata\")}\n AND ${getContainerContentsContainerSystemSlotFilter({\n visibleForeignSystemContainerNameCount,\n visibleSystemSlotCount,\n })}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_items\n `;\n}\n\nexport function getContainerContentsDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_documents AS (\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n linked.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_documents\n `;\n}\n\nexport function getOrphanedDocumentItemsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n orphaned_document_items AS (\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n )\n SELECT *\n FROM orphaned_document_items\n `;\n}\n\nexport function getOrphanedDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n `;\n}\n\nexport function getOrphanedDocumentExistsSql(): string {\n return `\n SELECT 1\n FROM document_projection d\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n LIMIT 1\n `;\n}\n\nexport function getContainerContentsContainerDocumentSidebarOrderBy(): string {\n return \"updated_at IS NULL ASC, updated_at DESC, title COLLATE NOCASE ASC, local_id ASC\";\n}\n"]}
|