@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.
Files changed (273) hide show
  1. package/client/containerContents/documentDiscovery.js +5 -5
  2. package/client/containerContents/documentDiscovery.js.map +1 -1
  3. package/client/containerContents/index.d.ts +7 -7
  4. package/client/containerContents/index.js +7 -7
  5. package/client/containerContents/index.js.map +1 -1
  6. package/client/containerContents/types.d.ts +6 -6
  7. package/client/containerContents/types.js.map +1 -1
  8. package/client/deviceFirst/index.js +2 -2
  9. package/client/deviceFirst/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/stores/container-contents/containerStatePersistence.js +1 -1
  12. package/stores/container-contents/documentRecovery.js +2 -2
  13. package/stores/container-contents/documentRecovery.js.map +1 -1
  14. package/stores/container-contents/documentWork.js.map +1 -1
  15. package/stores/container-contents/localRefresh.js +2 -2
  16. package/stores/container-contents/localRefresh.js.map +1 -1
  17. package/stores/container-contents/operations.js +2 -2
  18. package/stores/container-contents/operations.js.map +1 -1
  19. package/stores/container-contents/remoteContainerIngestion.js +1 -1
  20. package/stores/container-contents/remoteEventSync.js +1 -1
  21. package/stores/container-contents/remoteHydrationRequest.js +1 -1
  22. package/stores/container-contents/setContainerIconOperation.js +2 -2
  23. package/stores/container-contents/setContainerIconOperation.js.map +1 -1
  24. package/stores/container-contents/shareOperations.js +1 -1
  25. package/stores/container-contents/startupHydration.js +1 -1
  26. package/stores/container-contents/syncAgent.d.ts +2 -2
  27. package/stores/container-contents/syncAgentTypes.d.ts +1 -1
  28. package/stores/container-contents/syncLaneIteration.js +2 -2
  29. package/stores/container-contents/syncLaneIteration.js.map +1 -1
  30. package/stores/container-contents/systemContainerIcon.js +1 -1
  31. package/stores/container-contents/systemContainerIcon.js.map +1 -1
  32. package/workflows/container-contents/{documentAttributionRanges.d.ts → attribution/documentAttributionRanges.d.ts} +1 -1
  33. package/workflows/container-contents/{documentCharacterBlame.js → attribution/documentCharacterBlame.js} +3 -3
  34. package/workflows/container-contents/attribution/documentCharacterBlame.js.map +1 -0
  35. package/workflows/container-contents/{documentFieldBlame.js → attribution/documentFieldBlame.js} +4 -4
  36. package/workflows/container-contents/attribution/documentFieldBlame.js.map +1 -0
  37. package/workflows/container-contents/container-state/createIntentSync.js +1 -1
  38. package/workflows/container-contents/container-state/createIntentSync.js.map +1 -1
  39. package/workflows/container-contents/container-state/moveIntentSync.js +1 -1
  40. package/workflows/container-contents/container-state/moveIntentSync.js.map +1 -1
  41. package/workflows/container-contents/container-state/purgeTree.js +2 -2
  42. package/workflows/container-contents/container-state/purgeTree.js.map +1 -1
  43. package/workflows/container-contents/container-state/sharePersistence.js +2 -2
  44. package/workflows/container-contents/container-state/sharePersistence.js.map +1 -1
  45. package/workflows/container-contents/{containerDocumentListing.js → documentDiscovery/containerDocumentListing.js} +1 -1
  46. package/workflows/container-contents/{documentDiscoveryApply.js → documentDiscovery/documentDiscoveryApply.js} +3 -3
  47. package/workflows/container-contents/documentDiscovery/documentDiscoveryApply.js.map +1 -0
  48. package/workflows/container-contents/{documentDiscoveryCandidates.js.map → documentDiscovery/documentDiscoveryCandidates.js.map} +1 -1
  49. package/workflows/container-contents/{documentDiscoveryEvidence.js → documentDiscovery/documentDiscoveryEvidence.js} +1 -1
  50. package/workflows/container-contents/documentDiscovery/documentDiscoveryEvidence.js.map +1 -0
  51. package/workflows/container-contents/{documentDiscoveryInputs.js → documentDiscovery/documentDiscoveryInputs.js} +2 -2
  52. package/workflows/container-contents/documentDiscovery/documentDiscoveryInputs.js.map +1 -0
  53. package/workflows/container-contents/documentDiscovery/documentDiscoveryLanes.js.map +1 -0
  54. package/workflows/container-contents/{documentDiscoveryTypes.d.ts → documentDiscovery/documentDiscoveryTypes.d.ts} +4 -4
  55. package/workflows/container-contents/documentDiscovery/documentDiscoveryTypes.js.map +1 -0
  56. package/workflows/container-contents/{documentDiscovery.d.ts → documentDiscovery/index.d.ts} +1 -1
  57. package/workflows/container-contents/{documentDiscovery.js → documentDiscovery/index.js} +5 -5
  58. package/workflows/container-contents/documentDiscovery/index.js.map +1 -0
  59. package/workflows/container-contents/{availableDocumentLinkIntent.js → documentLinks/availableDocumentLinkIntent.js} +1 -1
  60. package/workflows/container-contents/documentLinks/availableDocumentLinkIntent.js.map +1 -0
  61. package/workflows/container-contents/{deferredDocumentLinks.js → documentLinks/deferredDocumentLinks.js} +1 -1
  62. package/workflows/container-contents/documentLinks/deferredDocumentLinks.js.map +1 -0
  63. package/workflows/container-contents/{documentLinkIntent.js → documentLinks/documentLinkIntent.js} +4 -4
  64. package/workflows/container-contents/documentLinks/documentLinkIntent.js.map +1 -0
  65. package/workflows/container-contents/documentLinks/documentLocalRelink.js.map +1 -0
  66. package/workflows/container-contents/{documentLinks.d.ts → documentLinks/index.d.ts} +5 -5
  67. package/workflows/container-contents/{documentLinks.js → documentLinks/index.js} +10 -10
  68. package/workflows/container-contents/documentLinks/index.js.map +1 -0
  69. package/workflows/container-contents/documentMove/documentMoveDeniedReplay.js.map +1 -0
  70. package/workflows/container-contents/{documentMoveFailure.js → documentMove/documentMoveFailure.js} +1 -1
  71. package/workflows/container-contents/documentMove/documentMoveFailure.js.map +1 -0
  72. package/workflows/container-contents/{documentMoveIntent.js → documentMove/documentMoveIntent.js} +7 -7
  73. package/workflows/container-contents/documentMove/documentMoveIntent.js.map +1 -0
  74. package/workflows/container-contents/{documentMoveIntentErrors.js → documentMove/documentMoveIntentErrors.js} +1 -1
  75. package/workflows/container-contents/documentMove/documentMoveIntentErrors.js.map +1 -0
  76. package/workflows/container-contents/{documentMoveIntentSettlement.js → documentMove/documentMoveIntentSettlement.js} +4 -4
  77. package/workflows/container-contents/documentMove/documentMoveIntentSettlement.js.map +1 -0
  78. package/workflows/container-contents/{documentMoveIntentSync.js → documentMove/documentMoveIntentSync.js} +7 -7
  79. package/workflows/container-contents/documentMove/documentMoveIntentSync.js.map +1 -0
  80. package/workflows/container-contents/{documentMoveVanishedRefresh.js → documentMove/documentMoveVanishedRefresh.js} +3 -3
  81. package/workflows/container-contents/documentMove/documentMoveVanishedRefresh.js.map +1 -0
  82. package/workflows/container-contents/{documentHydrationProbe.js → documentPriming/documentHydrationProbe.js} +4 -4
  83. package/workflows/container-contents/documentPriming/documentHydrationProbe.js.map +1 -0
  84. package/workflows/container-contents/documentPriming/documentRuntimeTargetSync.js.map +1 -0
  85. package/workflows/container-contents/{documentPriming.js → documentPriming/index.js} +5 -5
  86. package/workflows/container-contents/documentPriming/index.js.map +1 -0
  87. package/workflows/container-contents/{documentStructure.d.ts → documentQueries/documentStructure.d.ts} +1 -1
  88. package/workflows/container-contents/{documentStructure.js → documentQueries/documentStructure.js} +4 -4
  89. package/workflows/container-contents/documentQueries/documentStructure.js.map +1 -0
  90. package/workflows/container-contents/{documentStructureTypes.d.ts → documentQueries/documentStructureTypes.d.ts} +4 -4
  91. package/workflows/container-contents/documentQueries/documentStructureTypes.js.map +1 -0
  92. package/workflows/container-contents/{documentSubtreeQueries.js → documentQueries/documentSubtreeQueries.js} +5 -5
  93. package/workflows/container-contents/documentQueries/documentSubtreeQueries.js.map +1 -0
  94. package/workflows/container-contents/{documentQueries.d.ts → documentQueries/index.d.ts} +8 -8
  95. package/workflows/container-contents/{documentQueries.js → documentQueries/index.js} +13 -13
  96. package/workflows/container-contents/documentQueries/index.js.map +1 -0
  97. package/workflows/container-contents/{orphanedDocumentSql.js → documentQueries/orphanedDocumentSql.js} +1 -1
  98. package/workflows/container-contents/documentQueries/orphanedDocumentSql.js.map +1 -0
  99. package/workflows/container-contents/{pendingDownloads.d.ts → documentQueries/pendingDownloads.d.ts} +1 -1
  100. package/workflows/container-contents/{pendingDownloads.js → documentQueries/pendingDownloads.js} +3 -3
  101. package/workflows/container-contents/documentQueries/pendingDownloads.js.map +1 -0
  102. package/workflows/container-contents/documentQueries/sql.js +1 -1
  103. package/workflows/container-contents/documentQueries/sql.js.map +1 -1
  104. package/workflows/container-contents/index.d.ts +13 -13
  105. package/workflows/container-contents/index.js +11 -11
  106. package/workflows/container-contents/index.js.map +1 -1
  107. package/workflows/container-contents/{blobInfo.d.ts → info/blobInfo.d.ts} +1 -1
  108. package/workflows/container-contents/{blobInfo.js → info/blobInfo.js} +4 -4
  109. package/workflows/container-contents/info/blobInfo.js.map +1 -0
  110. package/workflows/container-contents/{blobInfoTypes.d.ts → info/blobInfoTypes.d.ts} +1 -1
  111. package/workflows/container-contents/info/blobInfoTypes.js.map +1 -0
  112. package/workflows/container-contents/{containerInfo.d.ts → info/containerInfo.d.ts} +4 -4
  113. package/workflows/container-contents/{containerInfo.js → info/containerInfo.js} +5 -5
  114. package/workflows/container-contents/info/containerInfo.js.map +1 -0
  115. package/workflows/container-contents/{documentInfo.d.ts → info/documentInfo.d.ts} +3 -3
  116. package/workflows/container-contents/{documentInfo.js → info/documentInfo.js} +11 -11
  117. package/workflows/container-contents/info/documentInfo.js.map +1 -0
  118. package/workflows/container-contents/{documentInfoTypes.d.ts → info/documentInfoTypes.d.ts} +3 -3
  119. package/workflows/container-contents/info/documentInfoTypes.js.map +1 -0
  120. package/workflows/container-contents/{metadata.d.ts → metadata/index.d.ts} +2 -2
  121. package/workflows/container-contents/{metadata.js → metadata/index.js} +5 -5
  122. package/workflows/container-contents/metadata/index.js.map +1 -0
  123. package/workflows/container-contents/{metadataEvents.d.ts → metadata/metadataEvents.d.ts} +1 -1
  124. package/workflows/container-contents/{metadataEvents.js → metadata/metadataEvents.js} +1 -1
  125. package/workflows/container-contents/metadata/metadataEvents.js.map +1 -0
  126. package/workflows/container-contents/{metadataIncomingUpdateIsolation.js → metadata/metadataIncomingUpdateIsolation.js} +5 -5
  127. package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js.map +1 -0
  128. package/workflows/container-contents/{metadataMutationPreparation.d.ts → metadata/metadataMutationPreparation.d.ts} +7 -7
  129. package/workflows/container-contents/{metadataMutationPreparation.js → metadata/metadataMutationPreparation.js} +5 -5
  130. package/workflows/container-contents/metadata/metadataMutationPreparation.js.map +1 -0
  131. package/workflows/container-contents/{metadataPersistence.d.ts → metadata/metadataPersistence.d.ts} +2 -2
  132. package/workflows/container-contents/{metadataPersistence.js → metadata/metadataPersistence.js} +4 -4
  133. package/workflows/container-contents/metadata/metadataPersistence.js.map +1 -0
  134. package/workflows/container-contents/{metadataPullContinuationInvalidation.js → metadata/metadataPullContinuationInvalidation.js} +4 -4
  135. package/workflows/container-contents/metadata/metadataPullContinuationInvalidation.js.map +1 -0
  136. package/workflows/container-contents/{metadataReadState.d.ts → metadata/metadataReadState.d.ts} +1 -1
  137. package/workflows/container-contents/metadata/metadataReadState.js.map +1 -0
  138. package/workflows/container-contents/{metadataRecord.js → metadata/metadataRecord.js} +2 -2
  139. package/workflows/container-contents/metadata/metadataRecord.js.map +1 -0
  140. package/workflows/container-contents/{metadataRemoteSync.d.ts → metadata/metadataRemoteSync.d.ts} +5 -5
  141. package/workflows/container-contents/{metadataRemoteSync.js → metadata/metadataRemoteSync.js} +3 -3
  142. package/workflows/container-contents/metadata/metadataRemoteSync.js.map +1 -0
  143. package/workflows/container-contents/{metadataStateInstallation.d.ts → metadata/metadataStateInstallation.d.ts} +1 -1
  144. package/workflows/container-contents/metadata/metadataStateInstallation.js.map +1 -0
  145. package/workflows/container-contents/{metadataStateIsolation.js → metadata/metadataStateIsolation.js} +3 -3
  146. package/workflows/container-contents/metadata/metadataStateIsolation.js.map +1 -0
  147. package/workflows/container-contents/{metadataSyncErrors.js → metadata/metadataSyncErrors.js} +3 -3
  148. package/workflows/container-contents/metadata/metadataSyncErrors.js.map +1 -0
  149. package/workflows/container-contents/{metadataSyncSettlement.d.ts → metadata/metadataSyncSettlement.d.ts} +2 -2
  150. package/workflows/container-contents/{metadataSyncSettlement.js → metadata/metadataSyncSettlement.js} +3 -3
  151. package/workflows/container-contents/metadata/metadataSyncSettlement.js.map +1 -0
  152. package/workflows/container-contents/{metadataTypes.d.ts → metadata/metadataTypes.d.ts} +5 -5
  153. package/workflows/container-contents/metadata/metadataTypes.js.map +1 -0
  154. package/workflows/container-contents/pendingWrites/aggregation.js.map +1 -1
  155. package/workflows/container-contents/pendingWrites/deferredTails.js.map +1 -1
  156. package/workflows/container-contents/{pendingWrites.d.ts → pendingWrites/index.d.ts} +1 -1
  157. package/workflows/container-contents/{pendingWrites.js → pendingWrites/index.js} +12 -12
  158. package/workflows/container-contents/pendingWrites/index.js.map +1 -0
  159. package/workflows/container-contents/projectionGeneration.js.map +1 -1
  160. package/workflows/container-contents/projectionView.js +1 -1
  161. package/workflows/container-contents/projectionView.js.map +1 -1
  162. package/workflows/container-contents/{folderRecovery.d.ts → recovery/folderRecovery.d.ts} +1 -1
  163. package/workflows/container-contents/{folderRecovery.js → recovery/folderRecovery.js} +4 -4
  164. package/workflows/container-contents/recovery/folderRecovery.js.map +1 -0
  165. package/workflows/container-contents/{staleRootRecovery.js → recovery/staleRootRecovery.js} +1 -1
  166. package/workflows/container-contents/recovery/staleRootRecovery.js.map +1 -0
  167. package/workflows/container-contents/remoteHydration/completeHydration.js +1 -1
  168. package/workflows/container-contents/remoteHydration/completeHydration.js.map +1 -1
  169. package/workflows/container-contents/remoteHydration/heldContainerRebind.js +1 -1
  170. package/workflows/container-contents/remoteHydration/heldContainerRebind.js.map +1 -1
  171. package/workflows/container-contents/{remoteHydration.d.ts → remoteHydration/index.d.ts} +2 -2
  172. package/workflows/container-contents/{remoteHydration.js → remoteHydration/index.js} +6 -6
  173. package/workflows/container-contents/remoteHydration/index.js.map +1 -0
  174. package/workflows/container-contents/{remoteContainerPageHydration.js → remoteHydration/remoteContainerPageHydration.js} +8 -8
  175. package/workflows/container-contents/remoteHydration/remoteContainerPageHydration.js.map +1 -0
  176. package/workflows/container-contents/{remoteContainerState.js → remoteHydration/remoteContainerState.js} +11 -11
  177. package/workflows/container-contents/remoteHydration/remoteContainerState.js.map +1 -0
  178. package/workflows/container-contents/remoteHydration/types.d.ts +1 -1
  179. package/workflows/container-contents/{documentPurge.d.ts → tombstones/documentPurge.d.ts} +6 -6
  180. package/workflows/container-contents/{documentPurge.js → tombstones/documentPurge.js} +6 -6
  181. package/workflows/container-contents/tombstones/documentPurge.js.map +1 -0
  182. package/workflows/container-contents/{documentTombstoneEvidence.js → tombstones/documentTombstoneEvidence.js} +9 -9
  183. package/workflows/container-contents/tombstones/documentTombstoneEvidence.js.map +1 -0
  184. package/workflows/container-contents/{documentTombstoneGate.js → tombstones/documentTombstoneGate.js} +1 -1
  185. package/workflows/container-contents/tombstones/documentTombstoneGate.js.map +1 -0
  186. package/workflows/container-contents/availableDocumentLinkIntent.js.map +0 -1
  187. package/workflows/container-contents/blobInfo.js.map +0 -1
  188. package/workflows/container-contents/blobInfoTypes.js.map +0 -1
  189. package/workflows/container-contents/containerInfo.js.map +0 -1
  190. package/workflows/container-contents/deferredDocumentLinks.js.map +0 -1
  191. package/workflows/container-contents/documentCharacterBlame.js.map +0 -1
  192. package/workflows/container-contents/documentDiscovery.js.map +0 -1
  193. package/workflows/container-contents/documentDiscoveryApply.js.map +0 -1
  194. package/workflows/container-contents/documentDiscoveryEvidence.js.map +0 -1
  195. package/workflows/container-contents/documentDiscoveryInputs.js.map +0 -1
  196. package/workflows/container-contents/documentDiscoveryLanes.js.map +0 -1
  197. package/workflows/container-contents/documentDiscoveryTypes.js.map +0 -1
  198. package/workflows/container-contents/documentFieldBlame.js.map +0 -1
  199. package/workflows/container-contents/documentHydrationProbe.js.map +0 -1
  200. package/workflows/container-contents/documentInfo.js.map +0 -1
  201. package/workflows/container-contents/documentInfoTypes.js.map +0 -1
  202. package/workflows/container-contents/documentLinkIntent.js.map +0 -1
  203. package/workflows/container-contents/documentLinks.js.map +0 -1
  204. package/workflows/container-contents/documentLocalRelink.js.map +0 -1
  205. package/workflows/container-contents/documentMoveDeniedReplay.js.map +0 -1
  206. package/workflows/container-contents/documentMoveFailure.js.map +0 -1
  207. package/workflows/container-contents/documentMoveIntent.js.map +0 -1
  208. package/workflows/container-contents/documentMoveIntentErrors.js.map +0 -1
  209. package/workflows/container-contents/documentMoveIntentSettlement.js.map +0 -1
  210. package/workflows/container-contents/documentMoveIntentSync.js.map +0 -1
  211. package/workflows/container-contents/documentMoveVanishedRefresh.js.map +0 -1
  212. package/workflows/container-contents/documentPriming.js.map +0 -1
  213. package/workflows/container-contents/documentPurge.js.map +0 -1
  214. package/workflows/container-contents/documentQueries.js.map +0 -1
  215. package/workflows/container-contents/documentRuntimeTargetSync.js.map +0 -1
  216. package/workflows/container-contents/documentStructure.js.map +0 -1
  217. package/workflows/container-contents/documentStructureTypes.js.map +0 -1
  218. package/workflows/container-contents/documentSubtreeQueries.js.map +0 -1
  219. package/workflows/container-contents/documentTombstoneEvidence.js.map +0 -1
  220. package/workflows/container-contents/documentTombstoneGate.js.map +0 -1
  221. package/workflows/container-contents/folderRecovery.js.map +0 -1
  222. package/workflows/container-contents/metadata.js.map +0 -1
  223. package/workflows/container-contents/metadataEvents.js.map +0 -1
  224. package/workflows/container-contents/metadataIncomingUpdateIsolation.js.map +0 -1
  225. package/workflows/container-contents/metadataMutationPreparation.js.map +0 -1
  226. package/workflows/container-contents/metadataPersistence.js.map +0 -1
  227. package/workflows/container-contents/metadataPullContinuationInvalidation.js.map +0 -1
  228. package/workflows/container-contents/metadataReadState.js.map +0 -1
  229. package/workflows/container-contents/metadataRecord.js.map +0 -1
  230. package/workflows/container-contents/metadataRemoteSync.js.map +0 -1
  231. package/workflows/container-contents/metadataStateInstallation.js.map +0 -1
  232. package/workflows/container-contents/metadataStateIsolation.js.map +0 -1
  233. package/workflows/container-contents/metadataSyncErrors.js.map +0 -1
  234. package/workflows/container-contents/metadataSyncSettlement.js.map +0 -1
  235. package/workflows/container-contents/metadataTypes.js.map +0 -1
  236. package/workflows/container-contents/orphanedDocumentSql.js.map +0 -1
  237. package/workflows/container-contents/pendingDownloads.js.map +0 -1
  238. package/workflows/container-contents/pendingWrites.js.map +0 -1
  239. package/workflows/container-contents/remoteContainerPageHydration.js.map +0 -1
  240. package/workflows/container-contents/remoteContainerState.js.map +0 -1
  241. package/workflows/container-contents/remoteHydration.js.map +0 -1
  242. package/workflows/container-contents/staleRootRecovery.js.map +0 -1
  243. /package/workflows/container-contents/{documentAttributionRanges.js → attribution/documentAttributionRanges.js} +0 -0
  244. /package/workflows/container-contents/{documentAttributionRanges.js.map → attribution/documentAttributionRanges.js.map} +0 -0
  245. /package/workflows/container-contents/{containerDocumentListing.js.map → documentDiscovery/containerDocumentListing.js.map} +0 -0
  246. /package/workflows/container-contents/{documentDiscoveryCandidates.js → documentDiscovery/documentDiscoveryCandidates.js} +0 -0
  247. /package/workflows/container-contents/{documentDiscoveryLanes.js → documentDiscovery/documentDiscoveryLanes.js} +0 -0
  248. /package/workflows/container-contents/{documentDiscoveryTypes.js → documentDiscovery/documentDiscoveryTypes.js} +0 -0
  249. /package/workflows/container-contents/{documentHeadScope.js → documentDiscovery/documentHeadScope.js} +0 -0
  250. /package/workflows/container-contents/{documentHeadScope.js.map → documentDiscovery/documentHeadScope.js.map} +0 -0
  251. /package/workflows/container-contents/{documentLocalRelink.js → documentLinks/documentLocalRelink.js} +0 -0
  252. /package/workflows/container-contents/{documentMoveDeniedReplay.js → documentMove/documentMoveDeniedReplay.js} +0 -0
  253. /package/workflows/container-contents/{documentMoveUnlinkIds.js → documentMove/documentMoveUnlinkIds.js} +0 -0
  254. /package/workflows/container-contents/{documentMoveUnlinkIds.js.map → documentMove/documentMoveUnlinkIds.js.map} +0 -0
  255. /package/workflows/container-contents/{documentRuntimeTargetSync.js → documentPriming/documentRuntimeTargetSync.js} +0 -0
  256. /package/workflows/container-contents/{documentStructureTypes.js → documentQueries/documentStructureTypes.js} +0 -0
  257. /package/workflows/container-contents/{blobInfoRows.js → info/blobInfoRows.js} +0 -0
  258. /package/workflows/container-contents/{blobInfoRows.js.map → info/blobInfoRows.js.map} +0 -0
  259. /package/workflows/container-contents/{blobInfoTypes.js → info/blobInfoTypes.js} +0 -0
  260. /package/workflows/container-contents/{documentInfoTypes.js → info/documentInfoTypes.js} +0 -0
  261. /package/workflows/container-contents/{metadataReadState.js → metadata/metadataReadState.js} +0 -0
  262. /package/workflows/container-contents/{metadataStateInstallation.js → metadata/metadataStateInstallation.js} +0 -0
  263. /package/workflows/container-contents/{metadataSyncFollowup.js → metadata/metadataSyncFollowup.js} +0 -0
  264. /package/workflows/container-contents/{metadataSyncFollowup.js.map → metadata/metadataSyncFollowup.js.map} +0 -0
  265. /package/workflows/container-contents/{metadataSyncRegistrations.d.ts → metadata/metadataSyncRegistrations.d.ts} +0 -0
  266. /package/workflows/container-contents/{metadataSyncRegistrations.js → metadata/metadataSyncRegistrations.js} +0 -0
  267. /package/workflows/container-contents/{metadataSyncRegistrations.js.map → metadata/metadataSyncRegistrations.js.map} +0 -0
  268. /package/workflows/container-contents/{metadataTypes.js → metadata/metadataTypes.js} +0 -0
  269. /package/workflows/container-contents/{pendingWritesTypes.d.ts → pendingWrites/pendingWritesTypes.d.ts} +0 -0
  270. /package/workflows/container-contents/{pendingWritesTypes.js → pendingWrites/pendingWritesTypes.js} +0 -0
  271. /package/workflows/container-contents/{pendingWritesTypes.js.map → pendingWrites/pendingWritesTypes.js.map} +0 -0
  272. /package/workflows/container-contents/{remoteHydrationLog.js → remoteHydration/remoteHydrationLog.js} +0 -0
  273. /package/workflows/container-contents/{remoteHydrationLog.js.map → remoteHydration/remoteHydrationLog.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentTombstoneEvidence.js","sourceRoot":"","sources":["documentTombstoneEvidence.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DOCUMENT_NOT_FOUND_ERROR_CODE,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../data/documents/shared/projection\";\nimport { uniqueSortedStrings } from \"../../../data/documents/shared/readers\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { reportKeyingVerificationErrorInCauseChain } from \"../../../data/keyingProjectionVerification/error\";\nimport { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport { loadDocumentPurgeCheckpoint } from \"../../../data/persistence/documentPurgeCheckpointPersistence\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type {\n ContainerDocumentTombstone,\n ContainerDocumentTombstoneVerdict,\n ContainerDocumentTombstoneVerifier,\n} from \"../documentDiscovery/documentDiscoveryTypes\";\nimport { documentHeadMatchesOrganization } from \"../documentDiscovery/documentHeadScope\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport interface VerifiedDocumentHeadLinkSet {\n readonly organizationId: string | null;\n readonly accessEpoch: number;\n /** Present for a signed head; a terminal purge has no live access state. */\n readonly accessStateHash?: string;\n readonly linkedContainerIds: ReadonlyArray<string>;\n}\n\n/**\n * The document's verified head link set, or `null` when no verified head is\n * available: the projection could not be fetched (the requester may no\n * longer read the document, or it was purged) or failed verification.\n */\nexport type DocumentHeadLinkSetLoader = (\n documentId: string,\n expectedManifestHash?: string,\n) => Promise<VerifiedDocumentHeadLinkSet | \"not-found\" | null>;\n\n/** The highest access epoch local state records for the document. */\nexport type LocalDocumentAccessEpochLoader = (\n documentId: string,\n) => Promise<number>;\n\nexport interface DocumentHeadLinkSetLoaderDeps {\n readonly assertDocumentWriterProjectionConsistent: typeof assertDocumentWriterProjectionConsistent;\n readonly loadDocumentPurgeCheckpoint: typeof loadDocumentPurgeCheckpoint;\n}\n\nexport const HEAD_LINK_SET_LOAD_CONCURRENCY = 4;\n/**\n * Head loads per settle. Tombstones beyond it stay unverified and are held\n * for a later, backed-off retry, so a bulk move out of a folder does not cost\n * every device an unbounded burst of fetches before the watermark advances.\n */\nexport const HEAD_LINK_SET_LOADS_PER_RUN = 32;\n\nasync function verifiedHeadLinkSet(\n runtime: ContainerContentsWorkflowRuntime,\n deps: DocumentHeadLinkSetLoaderDeps,\n documentId: string,\n projection: DocumentWriterProjectionResponse,\n): Promise<VerifiedDocumentHeadLinkSet> {\n const verified: { value?: VerifiedDocumentHeadLinkSet } = {};\n await deps.assertDocumentWriterProjectionConsistent(projection, {\n // Only the link set is read; a bundle wrapped to superseded KEK targets\n // still carries the signed head.\n allowStaleContentKeyBundle: true,\n execSql: runtime.infra.execSql,\n onVerifiedAuthorization: (authorization) => {\n const head = authorization.documentManifestByHash.get(\n projection.documentManifest.manifestHash,\n );\n if (head && head.state.documentId === documentId) {\n verified.value = {\n organizationId: head.state.organizationId,\n accessEpoch: head.state.epoch,\n accessStateHash: head.manifestHash,\n linkedContainerIds: uniqueSortedStrings(\n head.state.linkedContainerIds,\n ),\n };\n }\n },\n resolveProjectionUserKey: createProjectionUserKeyResolver(runtime),\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!verified.value) {\n throw new Error(\"Tombstone evidence lacks a verified document head\");\n }\n return verified.value;\n}\n\nasync function reportUnavailableHead(\n runtime: ContainerContentsWorkflowRuntime,\n documentId: string,\n error: unknown,\n): Promise<void> {\n const integrityFailure = await reportKeyingVerificationErrorInCauseChain(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: documentId,\n objectKind: \"document\",\n operation: \"document.tombstone-evidence\",\n },\n );\n try {\n if (\n !integrityFailure &&\n error instanceof ProjectionDependencyUnavailableError\n ) {\n // A policy can advance without changing this document's hash. Drop its\n // cached evidence so the held head can recover on the next run.\n runtime.apiClient.evictDocumentWriterProjection(documentId);\n runtime.util.log(\n `Container contents: tombstone evidence for document ${documentId} is awaiting current policy history`,\n );\n return;\n }\n runtime.util.logError?.(\n \"Container contents: tombstone evidence is unavailable\",\n error,\n );\n } catch {\n // A host logger that throws must not fail the discovery pass.\n }\n}\n\nexport function createDocumentHeadLinkSetLoader(\n runtime: ContainerContentsWorkflowRuntime,\n deps: DocumentHeadLinkSetLoaderDeps = {\n assertDocumentWriterProjectionConsistent,\n loadDocumentPurgeCheckpoint,\n },\n): DocumentHeadLinkSetLoader {\n return async (documentId, expectedManifestHash) => {\n try {\n // A verified purge proof is terminal signed evidence that the document\n // links nothing any more.\n if (\n await deps.loadDocumentPurgeCheckpoint(\n runtime.infra.execSql,\n documentId,\n )\n ) {\n return {\n organizationId: null,\n accessEpoch: Number.MAX_SAFE_INTEGER,\n linkedContainerIds: [],\n };\n }\n // Tombstones require a fresh head. Listings can reuse a matching cached\n // projection, whose signature and local checkpoint are still verified.\n if (!expectedManifestHash)\n runtime.apiClient.evictDocumentWriterProjection(documentId);\n let result = await runtime.apiClient.getDocumentWriterProjectionResult(\n documentId,\n { reportErrors: false },\n );\n if (\n expectedManifestHash &&\n result.ok &&\n result.data.documentManifest.manifestHash !== expectedManifestHash\n ) {\n runtime.apiClient.evictDocumentWriterProjection(documentId);\n result = await runtime.apiClient.getDocumentWriterProjectionResult(\n documentId,\n { reportErrors: false },\n );\n }\n if (!result.ok) {\n if (\n result.status === 404 &&\n result.code === DOCUMENT_NOT_FOUND_ERROR_CODE\n )\n return \"not-found\";\n runtime.util.log(\n `Container contents: tombstone evidence for document ${documentId} is unavailable (${result.status ?? \"offline\"})`,\n );\n return null;\n }\n return await verifiedHeadLinkSet(runtime, deps, documentId, result.data);\n } catch (error) {\n // Any failure leaves the tombstone unverified (held and retried); a\n // thrown error here must not fail the whole discovery pass.\n await reportUnavailableHead(runtime, documentId, error);\n return null;\n }\n };\n}\n\nfunction judgeTombstones(\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n head: VerifiedDocumentHeadLinkSet | null,\n): ContainerDocumentTombstoneVerdict[] {\n return tombstones.map((tombstone): ContainerDocumentTombstoneVerdict => {\n if (head === null) {\n return { kind: \"unverified\", tombstone };\n }\n if (head.linkedContainerIds.includes(tombstone.containerId)) {\n return {\n kind: \"refuted\",\n linkedContainerIds: head.linkedContainerIds,\n tombstone,\n };\n }\n return {\n kind: \"verified\",\n tombstone: {\n ...tombstone,\n accessEpoch: head.accessEpoch,\n linkedContainerIds: head.linkedContainerIds,\n },\n };\n });\n}\n\n/**\n * Judge listing tombstones against each document's verified head link set,\n * fetched once per document with bounded concurrency and a per-run cap. A\n * head whose epoch is below local document state is no evidence: it may be a\n * lagging replica or a replay, and applying it could delete rows a newer\n * listing or settled move wrote.\n */\nexport function createContainerDocumentTombstoneVerifier(\n organizationId: string | undefined,\n loadDocumentHeadLinkSet: DocumentHeadLinkSetLoader,\n loadLocalDocumentAccessEpoch: LocalDocumentAccessEpochLoader,\n): ContainerDocumentTombstoneVerifier {\n return async (tombstones) => {\n const byDocumentId = new Map<string, ContainerDocumentTombstone[]>();\n for (const tombstone of tombstones) {\n const group = byDocumentId.get(tombstone.documentId) ?? [];\n group.push(tombstone);\n byDocumentId.set(tombstone.documentId, group);\n }\n const groups = [...byDocumentId.entries()];\n const verdicts: ContainerDocumentTombstoneVerdict[][] = groups.map(\n ([, group], index): ContainerDocumentTombstoneVerdict[] =>\n index < HEAD_LINK_SET_LOADS_PER_RUN\n ? judgeTombstones(group, null)\n : group.map((tombstone) => ({ kind: \"deferred\", tombstone })),\n );\n let next = 0;\n const worker = async () => {\n while (next < Math.min(groups.length, HEAD_LINK_SET_LOADS_PER_RUN)) {\n const index = next++;\n const entry = groups[index];\n if (!entry) break;\n const [documentId, group] = entry;\n const head = await loadDocumentHeadLinkSet(documentId);\n if (head === null || head === \"not-found\") continue;\n if (!documentHeadMatchesOrganization(head, organizationId)) continue;\n // A local-state read that fails is treated like an unavailable head:\n // the tombstones stay held rather than failing the discovery pass.\n const localEpoch = await loadLocalDocumentAccessEpoch(documentId).catch(\n () => Number.MAX_SAFE_INTEGER,\n );\n if (head.accessEpoch < localEpoch) continue;\n verdicts[index] = judgeTombstones(group, head);\n }\n };\n await Promise.all(\n Array.from(\n { length: Math.min(HEAD_LINK_SET_LOAD_CONCURRENCY, groups.length) },\n worker,\n ),\n );\n return verdicts.flat();\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { containerDocumentPlacementKey as placementKey } from "../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js";
1
+ import { containerDocumentPlacementKey as placementKey } from "../../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js";
2
2
  function dedupePlacements(placements) {
3
3
  const seen = new Set();
4
4
  return placements.filter((placement) => {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentTombstoneGate.js","sourceRoot":"","sources":["documentTombstoneGate.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../../data/documents/documentSummary\";\nimport { containerDocumentPlacementKey as placementKey } from \"../../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence\";\nimport type {\n ContainerDocumentPlacement,\n ContainerDocumentTombstone,\n ContainerDocumentTombstoneVerdict,\n DiscoverContainerDocumentsOptions,\n} from \"../documentDiscovery/documentDiscoveryTypes\";\n\ntype TombstoneGateStore = Pick<\n DiscoverContainerDocumentsOptions,\n | \"applyContainerDocumentTombstones\"\n | \"holdContainerDocumentTombstones\"\n | \"listHeldContainerDocumentTombstones\"\n | \"listKnownContainerDocumentPlacements\"\n | \"refuteContainerDocumentTombstoneHolds\"\n | \"verifyContainerDocumentTombstones\"\n>;\n\nfunction dedupePlacements<T extends ContainerDocumentPlacement>(\n placements: ReadonlyArray<T>,\n): T[] {\n const seen = new Set<string>();\n return placements.filter((placement) => {\n const key = placementKey(placement);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/**\n * One candidate per placement the device actually holds; the newest server\n * timestamp wins. A tombstone for a placement this device never had has\n * nothing to remove or hide, so its head is not fetched.\n */\nasync function mergeTombstoneCandidates(\n store: TombstoneGateStore,\n listed: ReadonlyArray<ContainerDocumentTombstone>,\n held: ReadonlyArray<ContainerDocumentTombstone>,\n): Promise<ContainerDocumentTombstone[]> {\n const known = new Set(\n (await store.listKnownContainerDocumentPlacements(listed)).map(\n placementKey,\n ),\n );\n const byPlacement = new Map<string, ContainerDocumentTombstone>();\n for (const tombstone of [\n ...held,\n ...listed.filter((tombstone) => known.has(placementKey(tombstone))),\n ]) {\n const key = placementKey(tombstone);\n const current = byPlacement.get(key);\n if (\n !current ||\n Date.parse(current.updatedAt) < Date.parse(tombstone.updatedAt)\n ) {\n byPlacement.set(key, tombstone);\n }\n }\n return [...byPlacement.values()];\n}\n\nfunction assertVerdictsCoverCandidates(\n candidates: ReadonlyArray<ContainerDocumentTombstone>,\n verdicts: ReadonlyArray<ContainerDocumentTombstoneVerdict>,\n): void {\n const verdictKeys = new Set(\n verdicts.map((verdict) => placementKey(verdict.tombstone)),\n );\n if (\n verdictKeys.size !== verdicts.length ||\n verdictKeys.size !== candidates.length ||\n candidates.some((candidate) => !verdictKeys.has(placementKey(candidate)))\n ) {\n throw new Error(\n \"Container document tombstone verification must return one verdict per tombstone\",\n );\n }\n}\n\n/**\n * Apply a tombstone only when the signed head omits its container. Unavailable\n * heads leave hidden placements. A head that still links a container keeps its\n * placement visible, but retains a backed-off retry: even an uncached signed\n * head can lag the listing, so its refutation must not discard an honest move.\n * Listing items pass their own signed-head gate before reaching persistence.\n */\nexport async function settleContainerDocumentTombstones(input: {\n containerIds: ReadonlyArray<string>;\n store: TombstoneGateStore;\n tombstones: ReadonlyArray<ContainerDocumentTombstone>;\n}): Promise<ReadonlyArray<DocumentSummary>> {\n const { store } = input;\n const held = await store.listHeldContainerDocumentTombstones(\n input.containerIds,\n );\n const candidates = await mergeTombstoneCandidates(\n store,\n input.tombstones,\n held,\n );\n if (candidates.length === 0) {\n return [];\n }\n\n const verdicts = await store.verifyContainerDocumentTombstones(candidates);\n assertVerdictsCoverCandidates(candidates, verdicts);\n const verified = verdicts.flatMap((verdict) =>\n verdict.kind === \"verified\" ? [verdict.tombstone] : [],\n );\n const refuted = verdicts.flatMap((verdict) =>\n verdict.kind === \"refuted\" ? [verdict.tombstone] : [],\n );\n const unverified = verdicts.flatMap((verdict) =>\n verdict.kind === \"unverified\" ? [verdict.tombstone] : [],\n );\n const deferred = verdicts.flatMap((verdict) =>\n verdict.kind === \"deferred\"\n ? [{ ...verdict.tombstone, deferred: true }]\n : [],\n );\n // A loaded head is evidence for every placement it links, including holds\n // on this document that were not due this run: make them visible while\n // retaining each retry, since the head may lag any of those tombstones.\n const headLinkedPlacements = verdicts.flatMap((verdict) => {\n if (verdict.kind !== \"verified\" && verdict.kind !== \"refuted\") return [];\n const linked =\n verdict.kind === \"verified\"\n ? verdict.tombstone.linkedContainerIds\n : verdict.linkedContainerIds;\n return linked.map((containerId) => ({\n containerId,\n documentId: verdict.tombstone.documentId,\n }));\n });\n\n const summaries =\n verified.length > 0\n ? await store.applyContainerDocumentTombstones(verified)\n : [];\n const retryKeys = new Set(refuted.map(placementKey));\n const visibleRetries = dedupePlacements(headLinkedPlacements).filter(\n (placement) => !retryKeys.has(placementKey(placement)),\n );\n if (visibleRetries.length > 0) {\n await store.refuteContainerDocumentTombstoneHolds(visibleRetries);\n }\n const retries = [\n ...unverified,\n ...deferred,\n ...refuted.map((tombstone) => ({ ...tombstone, refuted: true })),\n ];\n if (retries.length > 0) await store.holdContainerDocumentTombstones(retries);\n return summaries;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"availableDocumentLinkIntent.js","sourceRoot":"","sources":["availableDocumentLinkIntent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAE1B,MAAM,yEAAyE,CAAC;AAEjF,kFAAkF;AAClF,MAAM,UAAU,2BAA2B,CACzC,MAAgC,EAChC,YAAqC;IAErC,IAAI,MAAM,CAAC,UAAU,KAAK,yBAAyB;QACjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACrC,+EAA+E;IAC/E,4DAA4D;IAC5D,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC;IACvD,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAC9D,CAAC,CAAC,MAAM,CAAC,iBAAiB;QAC1B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACb,CAAC,MAAM,CAAC,iBAAiB,IAAI,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC;gBACjE,CAAC,CAAC,MAAM,CAAC,iBAAiB;gBAC1B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACpB,IACE,CAAC,iBAAiB;QAClB,CAAC,CAAC,QAAQ,IAAI,iBAAiB,KAAK,MAAM,CAAC,iBAAiB,CAAC;QAE7D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,OAAO;QACL,QAAQ;QACR,MAAM,EAAE;YACN,GAAG,MAAM;YACT,iBAAiB;YACjB,0BAA0B,EAAE,SAAS;YACrC,GAAG,CAAC,QAAQ;gBACV,CAAC,CAAC,EAAE,uBAAuB,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE;gBACjE,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CAAC;AACJ,CAAC","sourcesContent":["import {\n DOCUMENT_LINK_INTENT_TYPE,\n type DocumentMoveIntentRecord,\n} from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\n\n/** Plan available additions without forgetting any part of the durable intent. */\nexport function availableDocumentLinkIntent(\n intent: DocumentMoveIntentRecord,\n hasContainer: (id: string) => boolean,\n): { intent: DocumentMoveIntentRecord; deferred: boolean } {\n if (intent.intentType !== DOCUMENT_LINK_INTENT_TYPE)\n return { intent, deferred: false };\n // For link intents the primary target is a routing hint, often the old source.\n // Only explicit additions can defer the requested removals.\n const requested = [...new Set(intent.additionalLinkContainerIds ?? [])];\n const available = requested.filter(hasContainer);\n const deferred = available.length !== requested.length;\n const targetContainerId = hasContainer(intent.targetContainerId)\n ? intent.targetContainerId\n : (available[0] ??\n (intent.sourceContainerId && hasContainer(intent.sourceContainerId)\n ? intent.sourceContainerId\n : undefined));\n if (\n !targetContainerId ||\n (!deferred && targetContainerId === intent.targetContainerId)\n )\n return { intent, deferred };\n return {\n deferred,\n intent: {\n ...intent,\n targetContainerId,\n additionalLinkContainerIds: available,\n ...(deferred\n ? { removedLinkContainerIds: [], replaceLinkedContainers: false }\n : {}),\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"blobInfo.js","sourceRoot":"","sources":["blobInfo.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n asc,\n count,\n countDistinct,\n desc,\n eq,\n gt,\n inArray,\n isNull,\n sql,\n} from \"drizzle-orm\";\nimport { unionAll } from \"drizzle-orm/sqlite-core\";\nimport { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport {\n containers,\n documentAttachmentBlobProjection,\n documentPendingAttachments,\n documentProjection,\n} from \"../../data/sqlite/schema\";\nimport {\n type ClientSQLiteDatabase,\n getClientSQLitePersistenceRuntime,\n} from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport {\n attachBlobInfoReferences,\n mapBlobInfoReferenceRow,\n mapBlobInfoRow,\n readRequiredNumber,\n} from \"./blobInfoRows\";\nimport type {\n BlobInfo,\n BlobInfoAttachmentKind,\n BlobInfoDocumentReference,\n BlobInfoInput,\n BlobInfoList,\n BlobInfoSort,\n} from \"./blobInfoTypes\";\n\nexport type {\n BlobInfo,\n BlobInfoAttachmentKind,\n BlobInfoDocumentReference,\n BlobInfoInput,\n BlobInfoList,\n BlobInfoSort,\n BlobInfoSortDirection,\n BlobInfoSortKey,\n} from \"./blobInfoTypes\";\n\nconst DEFAULT_BLOB_INFO_LIMIT = 200;\nconst MAX_BLOB_INFO_LIMIT = 999;\nconst DEFAULT_BLOB_INFO_SORT: BlobInfoSort = {\n direction: \"desc\",\n key: \"updated\",\n};\n\nfunction normalizeBlobInfoWindowValue(value: number | undefined): number {\n if (value === undefined || !Number.isFinite(value)) {\n return 0;\n }\n\n return Math.max(0, Math.trunc(value));\n}\n\nfunction normalizeBlobInfoLimit(value: number | undefined): number {\n if (value === undefined) {\n return DEFAULT_BLOB_INFO_LIMIT;\n }\n\n return Math.min(MAX_BLOB_INFO_LIMIT, normalizeBlobInfoWindowValue(value));\n}\n\nfunction normalizeBlobInfoQuery(value: string | undefined): string {\n return value?.trim().toLocaleLowerCase() ?? \"\";\n}\n\nfunction normalizeBlobInfoSort(value: BlobInfoSort | undefined): BlobInfoSort {\n if (!value) {\n return DEFAULT_BLOB_INFO_SORT;\n }\n\n if (\n (value.direction !== \"asc\" && value.direction !== \"desc\") ||\n (value.key !== \"byteLength\" &&\n value.key !== \"mimeType\" &&\n value.key !== \"updated\")\n ) {\n return DEFAULT_BLOB_INFO_SORT;\n }\n\n return value;\n}\n\nfunction createPendingBlobInfoReferencesSelect(db: ClientSQLiteDatabase) {\n return db\n .select({\n attachmentKind: sql<BlobInfoAttachmentKind>`'pending'`.as(\n \"attachment_kind\",\n ),\n blobId: sql<string | null>`NULL`.as(\"blob_id\"),\n blobKey:\n sql<string>`'storage:' || ${documentPendingAttachments.storageKey}`.as(\n \"blob_key\",\n ),\n byteLength: documentPendingAttachments.byteLength,\n changedAtSort: sql<string>`${documentPendingAttachments.createdAt}`.as(\n \"changed_at_sort\",\n ),\n containerId: documentProjection.containerId,\n createdAt: sql<string | null>`${documentPendingAttachments.createdAt}`.as(\n \"created_at\",\n ),\n documentId: documentProjection.documentId,\n documentKind: documentProjection.documentKind,\n documentTitle: documentProjection.title,\n localId: documentPendingAttachments.localId,\n mimeType: documentPendingAttachments.mimeType,\n name: sql<string | null>`${documentPendingAttachments.name}`.as(\"name\"),\n organizationId: sql<string | null>`COALESCE(\n NULLIF(${containers.organizationId}, ''),\n NULLIF(${documentProjection.organizationId}, '')\n )`.as(\"organization_id\"),\n searchText: sql<string>`LOWER(\n COALESCE(${documentPendingAttachments.storageKey}, '')\n || CHAR(0) || COALESCE(${documentPendingAttachments.mimeType}, '')\n || CHAR(0) || COALESCE(${documentPendingAttachments.name}, '')\n || CHAR(0) || COALESCE(${documentPendingAttachments.localId}, '')\n || CHAR(0) || COALESCE(${documentProjection.documentId}, '')\n || CHAR(0) || COALESCE(${documentProjection.title}, '')\n || CHAR(0) || COALESCE(${documentProjection.containerId}, '')\n || CHAR(0) || COALESCE(\n NULLIF(${containers.organizationId}, ''),\n NULLIF(${documentProjection.organizationId}, ''),\n ''\n )\n || CHAR(0) || COALESCE(${documentPendingAttachments.slotId}, '')\n )`.as(\"search_text\"),\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n updatedAt: sql<string | null>`NULL`.as(\"updated_at\"),\n })\n .from(documentPendingAttachments)\n .leftJoin(\n documentProjection,\n eq(documentProjection.localId, documentPendingAttachments.localId),\n )\n .leftJoin(containers, eq(containers.id, documentProjection.containerId));\n}\n\n// Detached rows are excluded here rather than at each call site: a slot unlinked\n// from a synced document keeps its row until the detach reaches the server, and\n// it stops being a reference the moment it is unlinked.\nfunction createLocalBlobInfoReferencesSelect(db: ClientSQLiteDatabase) {\n return db\n .select({\n attachmentKind: sql<BlobInfoAttachmentKind>`'local'`.as(\n \"attachment_kind\",\n ),\n blobId: documentAttachmentBlobProjection.blobId,\n blobKey: sql<string>`CASE\n WHEN ${documentAttachmentBlobProjection.blobId} IS NOT NULL\n AND ${documentAttachmentBlobProjection.blobId} <> ''\n THEN 'blob:' || ${documentAttachmentBlobProjection.blobId}\n ELSE 'storage:' || ${documentAttachmentBlobProjection.storageKey}\n END`.as(\"blob_key\"),\n byteLength: documentAttachmentBlobProjection.byteLength,\n changedAtSort:\n sql<string>`${documentAttachmentBlobProjection.updatedAt}`.as(\n \"changed_at_sort\",\n ),\n containerId: documentProjection.containerId,\n createdAt: sql<string | null>`NULL`.as(\"created_at\"),\n documentId: documentProjection.documentId,\n documentKind: documentProjection.documentKind,\n documentTitle: documentProjection.title,\n localId: documentAttachmentBlobProjection.localId,\n mimeType: documentAttachmentBlobProjection.mimeType,\n name: sql<string | null>`NULL`.as(\"name\"),\n organizationId: sql<string | null>`COALESCE(\n NULLIF(${containers.organizationId}, ''),\n NULLIF(${documentProjection.organizationId}, '')\n )`.as(\"organization_id\"),\n searchText: sql<string>`LOWER(\n COALESCE(${documentAttachmentBlobProjection.blobId}, '')\n || CHAR(0) || COALESCE(${documentAttachmentBlobProjection.storageKey}, '')\n || CHAR(0) || COALESCE(${documentAttachmentBlobProjection.mimeType}, '')\n || CHAR(0) || COALESCE(${documentAttachmentBlobProjection.localId}, '')\n || CHAR(0) || COALESCE(${documentProjection.documentId}, '')\n || CHAR(0) || COALESCE(${documentProjection.title}, '')\n || CHAR(0) || COALESCE(${documentProjection.containerId}, '')\n || CHAR(0) || COALESCE(\n NULLIF(${containers.organizationId}, ''),\n NULLIF(${documentProjection.organizationId}, ''),\n ''\n )\n || CHAR(0) || COALESCE(${documentAttachmentBlobProjection.slotId}, '')\n )`.as(\"search_text\"),\n slotId: documentAttachmentBlobProjection.slotId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n updatedAt: sql<\n string | null\n >`${documentAttachmentBlobProjection.updatedAt}`.as(\"updated_at\"),\n })\n .from(documentAttachmentBlobProjection)\n .leftJoin(\n documentProjection,\n eq(documentProjection.localId, documentAttachmentBlobProjection.localId),\n )\n .leftJoin(containers, eq(containers.id, documentProjection.containerId))\n .where(isNull(documentAttachmentBlobProjection.detachedAt));\n}\n\nfunction createBlobInfoReferencesCte(db: ClientSQLiteDatabase) {\n return db\n .$with(\"blob_info_references\")\n .as(\n unionAll(\n createPendingBlobInfoReferencesSelect(db),\n createLocalBlobInfoReferencesSelect(db),\n ),\n );\n}\n\nfunction createGroupedBlobInfoCtes(input: {\n readonly db: ClientSQLiteDatabase;\n readonly query: string;\n}) {\n const blobInfoReferences = createBlobInfoReferencesCte(input.db);\n const groupedBlobInfoSelection = {\n blobId: sql<\n string | null\n >`MIN(NULLIF(${blobInfoReferences.blobId}, ''))`.as(\"blob_id\"),\n blobKey: blobInfoReferences.blobKey,\n byteLength: sql<number>`MAX(${blobInfoReferences.byteLength})`.as(\n \"byte_length\",\n ),\n changedAtSort: sql<string | null>`COALESCE(\n MAX(NULLIF(${blobInfoReferences.updatedAt}, '')),\n MIN(NULLIF(${blobInfoReferences.createdAt}, ''))\n )`.as(\"changed_at_sort\"),\n createdAt: sql<\n string | null\n >`MIN(NULLIF(${blobInfoReferences.createdAt}, ''))`.as(\"created_at\"),\n documentCount: countDistinct(blobInfoReferences.localId).as(\n \"document_count\",\n ),\n mimeType: sql<\n string | null\n >`MIN(NULLIF(${blobInfoReferences.mimeType}, ''))`.as(\"mime_type\"),\n name: sql<string | null>`MIN(NULLIF(${blobInfoReferences.name}, ''))`.as(\n \"name\",\n ),\n organizationId: sql<string | null>`CASE\n WHEN COUNT(NULLIF(${blobInfoReferences.organizationId}, '')) = COUNT(*)\n AND COUNT(DISTINCT NULLIF(${blobInfoReferences.organizationId}, '')) = 1\n THEN MIN(NULLIF(${blobInfoReferences.organizationId}, ''))\n ELSE NULL\n END`.as(\"organization_id\"),\n referenceCount: count().as(\"reference_count\"),\n storageKey: sql<string>`MIN(${blobInfoReferences.storageKey})`.as(\n \"storage_key\",\n ),\n updatedAt: sql<\n string | null\n >`MAX(NULLIF(${blobInfoReferences.updatedAt}, ''))`.as(\"updated_at\"),\n };\n\n if (input.query === \"\") {\n const groupedBlobInfo = input.db.$with(\"grouped_blob_info\").as(\n input.db\n .select(groupedBlobInfoSelection)\n .from(blobInfoReferences)\n .groupBy(({ blobKey }) => blobKey),\n );\n\n return { blobInfoReferences, groupedBlobInfo, matchingBlobKeys: null };\n }\n\n const matchingBlobKeys = input.db.$with(\"matching_blob_keys\").as(\n input.db\n .selectDistinct({\n matchingBlobKey: sql<string>`${blobInfoReferences.blobKey}`.as(\n \"matching_blob_key\",\n ),\n })\n .from(blobInfoReferences)\n .where(\n gt(\n sql<number>`INSTR(${blobInfoReferences.searchText}, ${input.query})`,\n 0,\n ),\n ),\n );\n const groupedBlobInfo = input.db.$with(\"grouped_blob_info\").as(\n input.db\n .select(groupedBlobInfoSelection)\n .from(blobInfoReferences)\n .innerJoin(\n matchingBlobKeys,\n eq(matchingBlobKeys.matchingBlobKey, blobInfoReferences.blobKey),\n )\n .groupBy(({ blobKey }) => blobKey),\n );\n\n return { blobInfoReferences, groupedBlobInfo, matchingBlobKeys };\n}\n\nasync function countBlobInfoRows(input: {\n readonly db: ClientSQLiteDatabase;\n readonly query: string;\n}): Promise<number> {\n const { blobInfoReferences, groupedBlobInfo, matchingBlobKeys } =\n createGroupedBlobInfoCtes(input);\n const rows =\n matchingBlobKeys === null\n ? await input.db\n .with(blobInfoReferences, groupedBlobInfo)\n .select({ totalCount: count().as(\"total_count\") })\n .from(groupedBlobInfo)\n : await input.db\n .with(blobInfoReferences, matchingBlobKeys, groupedBlobInfo)\n .select({ totalCount: count().as(\"total_count\") })\n .from(groupedBlobInfo);\n\n return readRequiredNumber(rows[0]?.totalCount, \"total_count\");\n}\n\nasync function listBlobInfoRows(input: {\n readonly db: ClientSQLiteDatabase;\n readonly limit: number;\n readonly offset: number;\n readonly query: string;\n readonly sort: BlobInfoSort;\n}): Promise<Array<Omit<BlobInfo, \"references\">>> {\n const { blobInfoReferences, groupedBlobInfo, matchingBlobKeys } =\n createGroupedBlobInfoCtes(input);\n const changedAtSortDirection =\n input.sort.direction === \"desc\"\n ? desc(groupedBlobInfo.changedAtSort)\n : asc(groupedBlobInfo.changedAtSort);\n const byteLengthSortDirection =\n input.sort.direction === \"desc\"\n ? desc(groupedBlobInfo.byteLength)\n : asc(groupedBlobInfo.byteLength);\n let orderBy: ReturnType<typeof asc | typeof desc>[];\n if (input.sort.key === \"mimeType\") {\n orderBy = [\n asc(sql`${groupedBlobInfo.mimeType} IS NULL`),\n input.sort.direction === \"desc\"\n ? desc(sql`${groupedBlobInfo.mimeType} COLLATE NOCASE`)\n : asc(sql`${groupedBlobInfo.mimeType} COLLATE NOCASE`),\n desc(groupedBlobInfo.changedAtSort),\n asc(groupedBlobInfo.blobKey),\n ];\n } else if (input.sort.key === \"byteLength\") {\n orderBy = [\n byteLengthSortDirection,\n desc(groupedBlobInfo.changedAtSort),\n asc(groupedBlobInfo.blobKey),\n ];\n } else {\n orderBy = [\n asc(sql`${groupedBlobInfo.changedAtSort} IS NULL`),\n changedAtSortDirection,\n asc(groupedBlobInfo.blobKey),\n ];\n }\n const selection = {\n blobId: groupedBlobInfo.blobId,\n blobKey: groupedBlobInfo.blobKey,\n byteLength: groupedBlobInfo.byteLength,\n createdAt: groupedBlobInfo.createdAt,\n documentCount: groupedBlobInfo.documentCount,\n mimeType: groupedBlobInfo.mimeType,\n name: groupedBlobInfo.name,\n organizationId: groupedBlobInfo.organizationId,\n referenceCount: groupedBlobInfo.referenceCount,\n storageKey: groupedBlobInfo.storageKey,\n updatedAt: groupedBlobInfo.updatedAt,\n };\n const rows =\n matchingBlobKeys === null\n ? await input.db\n .with(blobInfoReferences, groupedBlobInfo)\n .select(selection)\n .from(groupedBlobInfo)\n .orderBy(...orderBy)\n .limit(input.limit)\n .offset(input.offset)\n : await input.db\n .with(blobInfoReferences, matchingBlobKeys, groupedBlobInfo)\n .select(selection)\n .from(groupedBlobInfo)\n .orderBy(...orderBy)\n .limit(input.limit)\n .offset(input.offset);\n\n return rows.map(mapBlobInfoRow);\n}\n\nasync function listBlobInfoReferencesForKeys(input: {\n readonly db: ClientSQLiteDatabase;\n readonly keys: ReadonlyArray<string>;\n}): Promise<BlobInfoDocumentReference[]> {\n if (input.keys.length === 0) {\n return [];\n }\n\n const blobInfoReferences = createBlobInfoReferencesCte(input.db);\n const rows = await input.db\n .with(blobInfoReferences)\n .select({\n attachmentKind: blobInfoReferences.attachmentKind,\n blobId: blobInfoReferences.blobId,\n byteLength: blobInfoReferences.byteLength,\n containerId: blobInfoReferences.containerId,\n createdAt: blobInfoReferences.createdAt,\n documentId: blobInfoReferences.documentId,\n documentKind: blobInfoReferences.documentKind,\n documentTitle: blobInfoReferences.documentTitle,\n localId: blobInfoReferences.localId,\n mimeType: blobInfoReferences.mimeType,\n name: blobInfoReferences.name,\n slotId: blobInfoReferences.slotId,\n storageKey: blobInfoReferences.storageKey,\n updatedAt: blobInfoReferences.updatedAt,\n })\n .from(blobInfoReferences)\n .where(inArray(blobInfoReferences.blobKey, [...input.keys]))\n .orderBy(\n asc(blobInfoReferences.blobKey),\n desc(blobInfoReferences.changedAtSort),\n asc(blobInfoReferences.localId),\n asc(blobInfoReferences.slotId),\n );\n\n return rows.map(mapBlobInfoReferenceRow);\n}\n\nexport async function listBlobInfo(\n input: BlobInfoInput & { readonly execSql?: ExecSql | null | undefined },\n): Promise<BlobInfoList> {\n if (!input.execSql) {\n return { rows: [], totalCount: 0 };\n }\n\n const query = normalizeBlobInfoQuery(input.query);\n const limit = normalizeBlobInfoLimit(input.limit);\n const offset = normalizeBlobInfoWindowValue(input.offset);\n const sort = normalizeBlobInfoSort(input.sort);\n await sqlDocumentsPersistence.ensureSchema(input.execSql);\n await ensureContainerTables(input.execSql);\n const { db } = getClientSQLitePersistenceRuntime(input.execSql);\n\n const totalCount = await countBlobInfoRows({\n db,\n query,\n });\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const groupedRows = await listBlobInfoRows({\n db,\n limit,\n offset,\n query,\n sort,\n });\n const references = await listBlobInfoReferencesForKeys({\n db,\n keys: groupedRows.map((row) => row.key),\n });\n\n return {\n rows: attachBlobInfoReferences({ references, rows: groupedRows }),\n totalCount,\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"blobInfoTypes.js","sourceRoot":"","sources":["blobInfoTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { StoredDocumentKind } from \"../../data/documents/documentKinds\";\n\nexport type BlobInfoAttachmentKind = \"local\" | \"pending\";\nexport type BlobInfoSortDirection = \"asc\" | \"desc\";\nexport type BlobInfoSortKey = \"byteLength\" | \"mimeType\" | \"updated\";\n\nexport interface BlobInfoSort {\n readonly direction: BlobInfoSortDirection;\n readonly key: BlobInfoSortKey;\n}\n\nexport interface BlobInfoDocumentReference {\n readonly attachmentKind: BlobInfoAttachmentKind;\n readonly blobId: string | null;\n readonly byteLength: number;\n readonly containerId: string | null;\n readonly createdAt: string | null;\n readonly documentId: string | null;\n readonly documentKind: StoredDocumentKind | null;\n readonly documentTitle: string | null;\n readonly localId: string;\n readonly mimeType: string | null;\n readonly name: string | null;\n readonly slotId: string;\n readonly storageKey: string;\n readonly updatedAt: string | null;\n}\n\nexport interface BlobInfo {\n readonly blobId: string | null;\n readonly byteLength: number;\n readonly createdAt: string | null;\n readonly documentCount: number;\n readonly key: string;\n readonly mimeType: string | null;\n readonly name: string | null;\n // Identity-wide display attribution from referenced document containers;\n // null when missing or inconsistent rather than guessing across a boundary.\n readonly organizationId: string | null;\n readonly referenceCount: number;\n readonly references: ReadonlyArray<BlobInfoDocumentReference>;\n readonly storageKey: string;\n readonly updatedAt: string | null;\n}\n\nexport interface BlobInfoList {\n readonly rows: ReadonlyArray<BlobInfo>;\n readonly totalCount: number;\n}\n\nexport interface BlobInfoInput {\n readonly limit?: number | undefined;\n readonly offset?: number | undefined;\n readonly query?: string | undefined;\n readonly sort?: BlobInfoSort | undefined;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"containerInfo.js","sourceRoot":"","sources":["containerInfo.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerAccessLevel,\n ContainerGrantSubjectType,\n} from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { eq } from \"drizzle-orm\";\nimport {\n getTargetContainerContext,\n readContainerState,\n} from \"../../data/containers/shared/projection\";\nimport { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport {\n type ContainerSyncWatermarkLane,\n containerContentsSyncLane,\n containerParentSyncLane,\n containerSyncWatermarkLaneKey,\n sqlContainerSyncWatermarkPersistence,\n} from \"../../data/persistence/containers/containerSyncWatermarkPersistence\";\nimport { containers } from \"../../data/sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { OrganizationGroupSummary } from \"../organizations/readModel\";\n\nexport type ContainerShareAccessLevel = ContainerAccessLevel;\n\nexport interface ContainerInfoGrant {\n accessLevel: ContainerAccessLevel;\n subjectId: string;\n subjectType: ContainerGrantSubjectType;\n}\n\nexport interface ContainerInfoGrantRow extends ContainerInfoGrant {\n inherited: boolean;\n sourceContainerId: string;\n}\n\nexport interface ContainerInfoSyncCursor {\n label: string;\n laneId: string;\n laneKind: string;\n savedAt: string | null;\n watermarkId: string | null;\n watermarkUpdatedAt: string | null;\n}\n\nexport interface ContainerInfoPathEntry {\n containerId: string;\n containerKeyEpoch: number;\n containerKeyEpochId: string;\n directGrantCount: number;\n eventHash: string;\n keyEpochHash: string;\n keyTargetHash: string;\n manifestHash: string;\n manifestHistoryCount: number;\n parentContainerId: string | null;\n parentManifestHash: string | null;\n recipientTargetCount: number;\n referencedPrincipalCount: number;\n wrapCount: number;\n}\n\nexport interface ContainerInfoSecurityDetails {\n currentContainerKeyEpoch: number;\n currentContainerKeyEpochId: string;\n currentManifestHash: string;\n currentManifestHistoryCount: number;\n currentParentContainerKeyEpochId: string | null;\n currentReferencedPrincipalCount: number;\n path: ContainerInfoPathEntry[];\n pathLength: number;\n}\n\nexport interface ContainerInfoRemoteDetails {\n grantRows: ContainerInfoGrantRow[];\n grants: ContainerInfoGrant[];\n groups: OrganizationGroupSummary[];\n security?: ContainerInfoSecurityDetails;\n syncCursors: ContainerInfoSyncCursor[];\n}\n\nexport interface ContainerInfoLocalDetails {\n createdAt: string | null;\n updatedAt: string | null;\n}\n\nexport interface ContainerInfo {\n local: ContainerInfoLocalDetails;\n remoteInfo: ContainerInfoRemoteDetails | null;\n}\n\ninterface ContainerInfoApi {\n getContainerWriterProjection: (\n containerId: string,\n ) => Promise<ContainerWriterProjectionResponse | null>;\n}\n\nexport type ContainerInfoRemoteMode = \"always\" | \"if-synced\" | \"never\";\n\ninterface LocalContainerInfoRecord {\n hasSyncedContainer: boolean;\n localCreatedAt: string | null;\n localUpdatedAt: string | null;\n organizationId: string | null;\n parentId: string | null;\n}\n\nfunction sortContainerInfoGrants<T extends ContainerInfoGrant>(\n grants: readonly T[],\n): T[] {\n return [...grants].sort((left, right) =>\n `${left.subjectType}:${left.subjectId}`.localeCompare(\n `${right.subjectType}:${right.subjectId}`,\n ),\n );\n}\n\nfunction toContainerInfoGrant(grant: ContainerInfoGrant): ContainerInfoGrant {\n return {\n accessLevel: grant.accessLevel,\n subjectId: grant.subjectId,\n subjectType: grant.subjectType,\n };\n}\n\nfunction getContainerInfoGrantRows(\n projection: ContainerWriterProjectionResponse,\n): ContainerInfoGrantRow[] {\n const rows = projection.path.flatMap((bundle) => {\n const state = readContainerState(bundle);\n\n return state.directGrants.map((grant) => ({\n ...toContainerInfoGrant(grant),\n inherited: state.containerId !== projection.containerId,\n sourceContainerId: state.containerId,\n }));\n });\n\n return sortContainerInfoGrants(rows);\n}\n\nfunction getContainerInfoPathEntries(\n projection: ContainerWriterProjectionResponse,\n): ContainerInfoPathEntry[] {\n return projection.path.map((bundle, index) => {\n const state = readContainerState(bundle);\n const kek = projection.containerKeks[index];\n if (!kek) {\n throw new Error(\"Container projection path and KEKs are inconsistent\");\n }\n\n return {\n containerId: state.containerId,\n containerKeyEpoch: kek.containerKeyEpoch,\n containerKeyEpochId: kek.containerKeyEpochId,\n directGrantCount: state.directGrants.length,\n eventHash: state.eventHash,\n keyEpochHash: kek.keyEpochHash,\n keyTargetHash: kek.keyTargetHash,\n manifestHash: bundle.manifestHash,\n manifestHistoryCount: kek.containerManifestHistory.length,\n parentContainerId: state.parentContainerId,\n parentManifestHash: state.parentManifestHash,\n recipientTargetCount: kek.recipientTargets.length,\n referencedPrincipalCount: state.referencedPrincipalHeads.length,\n wrapCount: kek.wraps.length,\n };\n });\n}\n\nfunction getContainerInfoSecurityDetails(\n projection: ContainerWriterProjectionResponse,\n): ContainerInfoSecurityDetails {\n const path = getContainerInfoPathEntries(projection);\n const targetPathEntry = path.at(-1);\n const targetKek = projection.containerKeks.at(-1);\n if (!targetPathEntry || !targetKek) {\n throw new Error(\"Container projection is empty\");\n }\n\n return {\n currentContainerKeyEpoch: targetPathEntry.containerKeyEpoch,\n currentContainerKeyEpochId: targetPathEntry.containerKeyEpochId,\n currentManifestHash: targetPathEntry.manifestHash,\n currentManifestHistoryCount: targetPathEntry.manifestHistoryCount,\n currentParentContainerKeyEpochId: targetKek.parentContainerKeyEpochId,\n currentReferencedPrincipalCount: targetPathEntry.referencedPrincipalCount,\n path,\n pathLength: path.length,\n };\n}\n\ninterface ContainerInfoSyncCursorDefinition {\n label: string;\n lane: ContainerSyncWatermarkLane;\n}\n\nfunction getContainerSyncCursorDefinitions(input: {\n containerId: string;\n parentId: string | null;\n}): ContainerInfoSyncCursorDefinition[] {\n return [\n {\n label: \"Parent Listing\",\n lane: containerParentSyncLane(input.parentId),\n },\n {\n label: \"Child Containers\",\n lane: containerParentSyncLane(input.containerId),\n },\n {\n label: \"Documents\",\n lane: containerContentsSyncLane(input.containerId),\n },\n ];\n}\n\nasync function loadContainerSyncCursors(input: {\n containerId: string;\n execSql: ExecSql | null;\n parentId: string | null;\n}): Promise<ContainerInfoSyncCursor[]> {\n const cursorDefinitions = getContainerSyncCursorDefinitions(input);\n let records: Awaited<\n ReturnType<typeof sqlContainerSyncWatermarkPersistence.loadWatermarkRecords>\n > = [];\n if (input.execSql) {\n await sqlContainerSyncWatermarkPersistence.ensureSchema(input.execSql);\n records = await sqlContainerSyncWatermarkPersistence.loadWatermarkRecords(\n input.execSql,\n cursorDefinitions.map(({ lane }) => lane),\n );\n }\n\n return cursorDefinitions.map((definition, index) => {\n const { laneId, laneKind } = containerSyncWatermarkLaneKey(definition.lane);\n const record = records[index] ?? null;\n\n return {\n label: definition.label,\n laneId,\n laneKind,\n savedAt: record?.updatedAt ?? null,\n watermarkId: record?.watermark.id ?? null,\n watermarkUpdatedAt: record?.watermark.updatedAt ?? null,\n };\n });\n}\n\nasync function loadLocalContainerInfoRecord(input: {\n containerId: string;\n execSql: ExecSql | null;\n parentId: string | null;\n}): Promise<LocalContainerInfoRecord> {\n const fallback: LocalContainerInfoRecord = {\n hasSyncedContainer: false,\n localCreatedAt: null,\n localUpdatedAt: null,\n organizationId: null,\n parentId: input.parentId,\n };\n\n if (!input.execSql) {\n return fallback;\n }\n\n await ensureContainerTables(input.execSql);\n\n const { db } = getClientSQLitePersistenceRuntime(input.execSql);\n const rows = await db\n .select({\n localCreatedAt: containers.localCreatedAt,\n localUpdatedAt: containers.localUpdatedAt,\n metadataDocumentId: containers.metadataDocumentId,\n organizationId: containers.organizationId,\n parentId: containers.parentId,\n })\n .from(containers)\n .where(eq(containers.id, input.containerId))\n .limit(1);\n const row = rows[0];\n\n if (!row) {\n return fallback;\n }\n\n return {\n hasSyncedContainer:\n typeof row.metadataDocumentId === \"string\" &&\n row.metadataDocumentId.length > 0,\n localCreatedAt: row.localCreatedAt,\n localUpdatedAt: row.localUpdatedAt,\n organizationId: row.organizationId,\n parentId: row.parentId,\n };\n}\n\nfunction shouldLoadRemoteContainerInfo(input: {\n localContainerInfo: LocalContainerInfoRecord;\n remoteInfoMode: ContainerInfoRemoteMode;\n}): boolean {\n switch (input.remoteInfoMode) {\n case \"always\":\n return true;\n case \"if-synced\":\n return input.localContainerInfo.hasSyncedContainer;\n case \"never\":\n return false;\n }\n}\n\nexport async function loadContainerInfo(input: {\n apiClient: ContainerInfoApi;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | null | undefined;\n execSql?: ExecSql | null;\n loadOrganizationGroups: () => Promise<\n ReadonlyArray<OrganizationGroupSummary>\n >;\n parentId?: string | null;\n remoteInfoMode?: ContainerInfoRemoteMode | undefined;\n}): Promise<ContainerInfo> {\n const localContainerInfo = await loadLocalContainerInfoRecord({\n containerId: input.containerId,\n execSql: input.execSql ?? null,\n parentId: input.parentId ?? null,\n });\n const local = {\n createdAt: localContainerInfo.localCreatedAt,\n updatedAt: localContainerInfo.localUpdatedAt,\n };\n\n if (\n !shouldLoadRemoteContainerInfo({\n localContainerInfo,\n remoteInfoMode: input.remoteInfoMode ?? \"always\",\n })\n ) {\n return {\n local,\n remoteInfo: null,\n };\n }\n\n const [projection, groups, syncCursors] = await Promise.all([\n input.containerProjection\n ? Promise.resolve(input.containerProjection)\n : input.apiClient.getContainerWriterProjection(input.containerId),\n input.loadOrganizationGroups(),\n loadContainerSyncCursors({\n containerId: input.containerId,\n execSql: input.execSql ?? null,\n parentId: localContainerInfo.parentId,\n }),\n ]);\n\n if (!projection) {\n throw new Error(\"Container info could not be loaded.\");\n }\n\n const target = getTargetContainerContext(projection);\n const state = readContainerState(target.manifest);\n\n return {\n local,\n remoteInfo: {\n grantRows: getContainerInfoGrantRows(projection),\n grants: sortContainerInfoGrants(\n state.directGrants.map(toContainerInfoGrant),\n ),\n groups: [...groups],\n security: getContainerInfoSecurityDetails(projection),\n syncCursors,\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deferredDocumentLinks.js","sourceRoot":"","sources":["deferredDocumentLinks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAGhD,KAAmB,EACnB,SAAqC;IAErC,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,MAAM,OAAO,CAAC,GAAG,CACf,SAAS;SACN,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;SAChD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CACxD,CACF,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AACnE,CAAC","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { deriveStableDocumentId } from \"../../data/documents/shared/stableDocumentId\";\n\n/** A deferred create keeps its intended links until its signed adoption verifies. */\nexport async function withoutDeferredDocumentLinks<\n T extends { documentId: string; containerIds: readonly string[] },\n>(\n links: readonly T[],\n summaries: readonly DocumentSummary[],\n): Promise<readonly T[]> {\n const deferredIds = new Set(\n await Promise.all(\n summaries\n .filter((summary) => summary.documentId === null)\n .map((summary) => deriveStableDocumentId(summary.id)),\n ),\n );\n return links.filter((link) => !deferredIds.has(link.documentId));\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentCharacterBlame.js","sourceRoot":"","sources":["documentCharacterBlame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAGL,sBAAsB,GACvB,MAAM,sCAAsC,CAAC;AAE9C,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,8CAA8C;AAC9C,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,eAA8B,EAC9B,QAAqD;IAOrD,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,2BAA2B,CACxC,aAAa,CAAC,eAAe,CAAC,EAC9B,yBAAyB,CAC1B,CAAC;QACF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport { listSnapshotCharBlameSource } from \"@tearleads/loro\";\nimport type { DocumentEditAttributionResponse } from \"@tearleads/validators/response\";\nimport {\n type DocumentBlameRange,\n type DocumentCharacterBlameSummary,\n summarizeDocumentBlame,\n} from \"../../data/documents/editAttribution\";\n\n// Op-id extraction is linear (~1.8µs/char — ~90ms for a 50k snapshot, flat per\n// char), so this cap is a soft guard against pathologically large prose, not a\n// quadratic cliff: above it blame surfaces null rather than doing unbounded\n// synchronous work when the Info panel opens.\nconst MAX_BLAME_CHARACTER_COUNT = 50_000;\n\n/**\n * Rebuild the document's per-character op ids from the locally persisted\n * content snapshot and resolve them against the attribution segments — in a\n * single snapshot reconstruction — into both the per-writer blame summary and\n * the coalesced per-writer ranges. Returns null when blame can't be produced:\n * no local snapshot, a snapshot too large to scan cheaply, or an unreadable\n * snapshot — blame is supplementary and must never block (or blank) the rest\n * of the Info panel, mirroring the attribution fetch's degrade-to-null.\n */\nexport function computeDocumentBlame(\n contentSnapshot: string | null,\n segments: DocumentEditAttributionResponse[\"segments\"],\n): {\n /** Per-writer live-character counts (the Contributors-style rollup). */\n characterBlame: DocumentCharacterBlameSummary;\n /** Contiguous per-writer runs of the current prose (the read-only blame view). */\n blameRanges: DocumentBlameRange[];\n} | null {\n if (!contentSnapshot || contentSnapshot.length === 0) {\n return null;\n }\n try {\n const source = listSnapshotCharBlameSource(\n base64ToBytes(contentSnapshot),\n MAX_BLAME_CHARACTER_COUNT,\n );\n if (source === null) {\n return null;\n }\n return summarizeDocumentBlame(source, segments);\n } catch {\n return null;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentDiscovery.js","sourceRoot":"","sources":["documentDiscovery.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { isDocumentUpdateCreatedEvent } from \"../../data/documents/documentSync\";\nimport { dedupeReferencedPrincipalStates } from \"../../data/keyingProjectionVerification/principalPolicyCache\";\nimport {\n listContainerDocumentLanesFromApi,\n listContainerDocumentsFromWatermarks,\n} from \"./containerDocumentListing\";\nimport { withoutDeferredDocumentLinks } from \"./deferredDocumentLinks\";\nimport { saveAppliedContainerDocumentWatermark } from \"./documentDiscoveryApply\";\nimport {\n collectApplicableDocumentTombstones,\n collectDiscoveredDocumentInputs,\n} from \"./documentDiscoveryInputs\";\nimport { discoverContainerDocumentLanes } from \"./documentDiscoveryLanes\";\nimport type {\n ContainerDocumentDiscoveryApi,\n ContainerParentDiscoveryLane,\n DiscoverAllContainerDocumentsOptions,\n DiscoverContainerDocumentsOptions,\n ListedContainerDocumentsLane,\n RefreshAllContainerDocumentsFromApiOptions,\n RefreshAllContainerDocumentsOptions,\n} from \"./documentDiscoveryTypes\";\nimport { settleContainerDocumentTombstones } from \"./documentTombstoneGate\";\n\nexport type { RefreshAllContainerDocumentsFromApiOptions } from \"./documentDiscoveryTypes\";\n\nconst CONTAINER_PARENT_DISCOVERY_BATCH_SIZE = 4;\n\ntype ContainerParentLaneRequest = Parameters<\n ContainerDocumentDiscoveryApi[\"listContainerParentLanes\"]\n>[0][\"lanes\"][number];\n\ninterface RequestedContainerParentLane {\n lane: ContainerParentDiscoveryLane;\n request: ContainerParentLaneRequest;\n}\n\nasync function listContainerParentLaneBatch(\n listContainerParentLanes: ContainerDocumentDiscoveryApi[\"listContainerParentLanes\"],\n requestedLanes: ReadonlyArray<RequestedContainerParentLane>,\n) {\n const response = await listContainerParentLanes({\n lanes: requestedLanes.map(({ request }) => request),\n });\n if (!response || response.results.length !== requestedLanes.length) {\n return null;\n }\n\n const requestedLaneIds = new Set(\n requestedLanes.map(({ request }) => request.laneId),\n );\n const pagesByLaneId = new Map<\n string,\n (typeof response.results)[number][\"page\"]\n >();\n for (const result of response.results) {\n if (\n !requestedLaneIds.has(result.laneId) ||\n pagesByLaneId.has(result.laneId)\n ) {\n return null;\n }\n pagesByLaneId.set(result.laneId, result.page);\n }\n\n return requestedLanes.map(({ lane, request }) => ({\n lane,\n response: pagesByLaneId.get(request.laneId),\n }));\n}\n\nfunction collectRemoteContainerIds(\n items: ReadonlyArray<{ id: string }>,\n seenContainerIds: Set<string>,\n containerIds: string[],\n): ReadonlyArray<string> {\n for (const { id } of items) {\n if (!seenContainerIds.has(id)) {\n seenContainerIds.add(id);\n containerIds.push(id);\n }\n }\n\n return items.map(({ id }) => id);\n}\n\nexport function hasUndiscoveredDocumentUpdateEvent(\n events: ReadonlyArray<unknown>,\n knownDocumentIds: ReadonlySet<string>,\n): boolean {\n return events.some(\n (event) =>\n isDocumentUpdateCreatedEvent(event) &&\n !knownDocumentIds.has(event.documentId),\n );\n}\n\nexport async function listAllRemoteContainerIds(\n listContainerParentLanes: ContainerDocumentDiscoveryApi[\"listContainerParentLanes\"],\n): Promise<ReadonlyArray<string> | null> {\n const containerIds: string[] = [];\n const queuedParentIds = new Set<string | null>();\n const seenContainerIds = new Set<string>();\n const lanes: ContainerParentDiscoveryLane[] = [];\n let nextLaneId = 0;\n const queueParentLane = (parentId: string | null) => {\n if (queuedParentIds.has(parentId)) {\n return;\n }\n\n queuedParentIds.add(parentId);\n lanes.push({ parentId, watermark: null });\n };\n\n queueParentLane(null);\n\n while (lanes.length > 0) {\n const laneBatch = lanes.splice(0, CONTAINER_PARENT_DISCOVERY_BATCH_SIZE);\n const requestedLanes = laneBatch.map((lane) => ({\n lane,\n request: {\n laneId: `container-parent-${nextLaneId++}`,\n parentId: lane.parentId,\n watermark: lane.watermark,\n },\n }));\n const listedLanes = await listContainerParentLaneBatch(\n listContainerParentLanes,\n requestedLanes,\n );\n if (!listedLanes) {\n return null;\n }\n const continuationLanes: ContainerParentDiscoveryLane[] = [];\n\n for (const { lane, response } of listedLanes) {\n if (!response) {\n return null;\n }\n\n for (const containerId of collectRemoteContainerIds(\n response.items,\n seenContainerIds,\n containerIds,\n )) {\n queueParentLane(containerId);\n }\n\n if (response.hasMore) {\n if (!response.nextWatermark) {\n return null;\n }\n continuationLanes.push({\n parentId: lane.parentId,\n watermark: response.nextWatermark,\n });\n }\n }\n\n lanes.unshift(...continuationLanes);\n }\n\n return containerIds;\n}\n\nexport function listAllRemoteContainerIdsFromApi(\n apiClient: Pick<ContainerDocumentDiscoveryApi, \"listContainerParentLanes\">,\n): Promise<ReadonlyArray<string> | null> {\n return listAllRemoteContainerIds((input) =>\n apiClient.listContainerParentLanes(input),\n );\n}\n\nexport async function discoverContainerDocuments({\n beginDocumentDiscovery,\n listContainerDocumentLanes,\n loadContainerDocumentWatermark,\n ...lane\n}: DiscoverContainerDocumentsOptions): Promise<ReadonlyArray<DocumentSummary> | null> {\n const [outcome] = await discoverContainerDocumentLanes({\n generation: await beginDocumentDiscovery(),\n lanes: [lane],\n listContainerDocumentLanes,\n loadContainerDocumentWatermark,\n });\n if (outcome?.status === \"rejected\") throw outcome.reason;\n return outcome?.value ?? null;\n}\n\nexport function discoverContainerDocumentsFromApi({\n apiClient,\n ...input\n}: Omit<DiscoverContainerDocumentsOptions, \"listContainerDocumentLanes\"> & {\n readonly apiClient: Pick<\n ContainerDocumentDiscoveryApi,\n \"listContainerDocumentLanes\"\n >;\n}): Promise<ReadonlyArray<DocumentSummary> | null> {\n return discoverContainerDocuments({\n ...input,\n listContainerDocumentLanes: (lanes) =>\n listContainerDocumentLanesFromApi(apiClient, lanes),\n });\n}\n\nasync function listDiscoveryLanes(\n input: Parameters<typeof listContainerDocumentsFromWatermarks>[0],\n): Promise<ListedContainerDocumentsLane[]> {\n const listed = await listContainerDocumentsFromWatermarks(input);\n return input.containerIds.map((containerId) => ({\n containerId,\n listedDocuments: listed.get(containerId) ?? null,\n }));\n}\n\nexport async function discoverAllContainerDocuments(\n options: DiscoverAllContainerDocumentsOptions,\n): Promise<ReadonlyArray<DocumentSummary> | null> {\n const {\n cacheReferencedPrincipalPolicies,\n containerIds,\n loadContainerDocumentWatermark,\n listContainerDocumentLanes,\n replaceDocumentLinksBatch,\n saveContainerDocumentWatermark,\n upsertDiscoveredDocuments,\n } = options;\n const uniqueContainerIds = Array.from(new Set(containerIds)).filter(\n (containerId): containerId is string =>\n typeof containerId === \"string\" && containerId.length > 0,\n );\n const generation = await options.beginDocumentDiscovery();\n const listedDocumentsByContainer = await listDiscoveryLanes({\n containerIds: uniqueContainerIds,\n listContainerDocumentLanes,\n loadContainerDocumentWatermark,\n });\n await cacheReferencedPrincipalPolicies?.(\n dedupeReferencedPrincipalStates(\n listedDocumentsByContainer.flatMap(\n ({ listedDocuments }) =>\n listedDocuments?.items.flatMap(\n (document) => document.referencedPrincipals,\n ) ?? [],\n ),\n ),\n );\n const verification = await options.verifyDiscoveredDocuments(\n collectDiscoveredDocumentInputs(listedDocumentsByContainer),\n uniqueContainerIds,\n generation,\n collectApplicableDocumentTombstones(listedDocumentsByContainer),\n );\n if (!(await verification.isCurrent())) return null;\n const discoveredDocumentInputs = verification.inputs;\n const discoveredDocuments =\n discoveredDocumentInputs.length === 0\n ? []\n : await upsertDiscoveredDocuments(discoveredDocumentInputs);\n\n if (discoveredDocumentInputs.length > 0) {\n await replaceDocumentLinksBatch(\n await withoutDeferredDocumentLinks(\n discoveredDocumentInputs.map((input) => ({\n documentId: input.documentId,\n accessEpoch: input.accessEpoch,\n containerIds: input.linkedContainerIds,\n })),\n discoveredDocuments,\n ),\n );\n }\n\n const tombstoneDocumentSummaries = await settleContainerDocumentTombstones({\n containerIds: listedDocumentsByContainer.flatMap(\n ({ containerId, listedDocuments }) =>\n listedDocuments ? [containerId] : [],\n ),\n store: options,\n tombstones: collectApplicableDocumentTombstones(listedDocumentsByContainer),\n });\n\n const complete = await verification.commit();\n if (!(await verification.isCurrent())) return null;\n\n await Promise.all(\n listedDocumentsByContainer.map(({ containerId, listedDocuments }) =>\n listedDocuments\n ? saveAppliedContainerDocumentWatermark({\n containerId,\n listedDocuments,\n saveContainerDocumentWatermark,\n })\n : undefined,\n ),\n );\n\n return !complete &&\n discoveredDocuments.length === 0 &&\n tombstoneDocumentSummaries.length === 0\n ? null\n : [...discoveredDocuments, ...tombstoneDocumentSummaries];\n}\n\nasync function refreshAllContainerDocuments({\n listContainerParentLanes,\n ...input\n}: RefreshAllContainerDocumentsOptions): Promise<ReadonlyArray<DocumentSummary> | null> {\n const containerIds = await listAllRemoteContainerIds(\n listContainerParentLanes,\n );\n if (!containerIds) {\n return null;\n }\n\n return discoverAllContainerDocuments({\n ...input,\n containerIds,\n });\n}\n\nexport function refreshAllContainerDocumentsFromApi({\n apiClient,\n ...input\n}: RefreshAllContainerDocumentsFromApiOptions): Promise<ReadonlyArray<DocumentSummary> | null> {\n return refreshAllContainerDocuments({\n ...input,\n listContainerDocumentLanes: (lanes) =>\n listContainerDocumentLanesFromApi(apiClient, lanes),\n listContainerParentLanes: (input) =>\n apiClient.listContainerParentLanes(input),\n });\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentDiscoveryApply.js","sourceRoot":"","sources":["documentDiscoveryApply.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,8DAA8D,CAAC;AAC/G,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAK5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,yBAAyB,CAAC;AAU5E,MAAM,CAAC,KAAK,UAAU,qCAAqC,CAAC,KAI3D;IACC,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,8BAA8B,EAAE,GACpE,KAAK,CAAC;IACR,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;QACnC,OAAO;IACT,CAAC;IAED,MAAM,8BAA8B,CAClC,WAAW,EACX,eAAe,CAAC,aAAa,CAC9B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAuC,EACvC,UAAkB,EAClB,eAAyC;IAEzC,MAAM,EAAE,WAAW,EAAE,yBAAyB,EAAE,GAAG,OAAO,CAAC;IAC3D,MAAM,OAAO,CAAC,gCAAgC,EAAE,CAC9C,+BAA+B,CAC7B,eAAe,CAAC,KAAK,CAAC,OAAO,CAC3B,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAC5C,CACF,CACF,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,yBAAyB,CAC1D,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACvC,WAAW,EAAE,QAAQ,CAAC,kBAAkB;QACxC,eAAe,EAAE,QAAQ,CAAC,sBAAsB;QAChD,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;QACjC,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,oBAAoB,EAAE,QAAQ,CAAC,oBAAoB;QACnD,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB;KAChD,CAAC,CAAC,EACH,CAAC,WAAW,CAAC,EACb,UAAU,EACV,+BAA+B,CAAC,eAAe,CAAC,CACjD,CAAC;IACF,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC;IAC3C,MAAM,mBAAmB,GAAG,cAAc,CAAC,MAAM;QAC/C,CAAC,CAAC,MAAM,yBAAyB,CAAC,cAAc,CAAC;QACjD,CAAC,CAAC,EAAE,CAAC;IAEP,IAAI,cAAc,CAAC,MAAM;QACvB,MAAM,OAAO,CAAC,yBAAyB,CACrC,MAAM,4BAA4B,CAChC,cAAc,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAChC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,YAAY,EAAE,QAAQ,CAAC,kBAAkB;SAC1C,CAAC,CAAC,EACH,mBAAmB,CACpB,CACF,CAAC;IAEJ,MAAM,0BAA0B,GAAG,MAAM,iCAAiC,CAAC;QACzE,YAAY,EAAE,CAAC,WAAW,CAAC;QAC3B,KAAK,EAAE,OAAO;QACd,UAAU,EAAE,+BAA+B,CAAC,eAAe,CAAC;KAC7D,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,CAAC;IAC7C,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,qCAAqC,CAAC;QAC1C,WAAW;QACX,eAAe;QACf,8BAA8B,EAAE,OAAO,CAAC,8BAA8B;KACvE,CAAC,CAAC;IAEH,IAAI,eAAe,CAAC,aAAa,EAAE,CAAC;QAClC,4EAA4E;QAC5E,OAAO,CAAC,aAAa,EAAE,CACrB,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CACrD,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,QAAQ;QACd,mBAAmB,CAAC,MAAM,KAAK,CAAC;QAChC,0BAA0B,CAAC,MAAM,KAAK,CAAC;QACvC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,GAAG,mBAAmB,EAAE,GAAG,0BAA0B,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { dedupeReferencedPrincipalStates } from \"../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { withoutDeferredDocumentLinks } from \"./deferredDocumentLinks\";\nimport { getApplicableDocumentTombstones } from \"./documentDiscoveryInputs\";\nimport type {\n DiscoverContainerDocumentsOptions,\n ListedContainerDocuments,\n} from \"./documentDiscoveryTypes\";\nimport { settleContainerDocumentTombstones } from \"./documentTombstoneGate\";\n\n/** A discovery lane's local stores; the listing itself is supplied by the caller. */\nexport type ContainerDocumentDiscoveryLane = Omit<\n DiscoverContainerDocumentsOptions,\n | \"beginDocumentDiscovery\"\n | \"listContainerDocumentLanes\"\n | \"loadContainerDocumentWatermark\"\n>;\n\nexport async function saveAppliedContainerDocumentWatermark(input: {\n containerId: string;\n listedDocuments: ListedContainerDocuments;\n saveContainerDocumentWatermark: DiscoverContainerDocumentsOptions[\"saveContainerDocumentWatermark\"];\n}) {\n const { containerId, listedDocuments, saveContainerDocumentWatermark } =\n input;\n if (!listedDocuments.nextWatermark) {\n return;\n }\n\n await saveContainerDocumentWatermark(\n containerId,\n listedDocuments.nextWatermark,\n );\n}\n\n/**\n * Verifies and applies one container's completed listing under a discovery\n * generation captured before the listing request, then advances its\n * watermark. Returns `null` when nothing was applied.\n */\nexport async function applyListedContainerDocuments(\n options: ContainerDocumentDiscoveryLane,\n generation: number,\n listedDocuments: ListedContainerDocuments,\n): Promise<ReadonlyArray<DocumentSummary> | null> {\n const { containerId, upsertDiscoveredDocuments } = options;\n await options.cacheReferencedPrincipalPolicies?.(\n dedupeReferencedPrincipalStates(\n listedDocuments.items.flatMap(\n (document) => document.referencedPrincipals,\n ),\n ),\n );\n\n const verification = await options.verifyDiscoveredDocuments(\n listedDocuments.items.map((document) => ({\n accessEpoch: document.currentAccessEpoch,\n accessStateHash: document.currentAccessStateHash,\n containerId,\n listedContainerIds: [containerId],\n createdAt: document.createdAt,\n documentId: document.id,\n effectiveAccessLevel: document.effectiveAccessLevel,\n linkedContainerIds: document.linkedContainerIds,\n })),\n [containerId],\n generation,\n getApplicableDocumentTombstones(listedDocuments),\n );\n if (!(await verification.isCurrent())) return null;\n const verifiedInputs = verification.inputs;\n const discoveredDocuments = verifiedInputs.length\n ? await upsertDiscoveredDocuments(verifiedInputs)\n : [];\n\n if (verifiedInputs.length)\n await options.replaceDocumentLinksBatch(\n await withoutDeferredDocumentLinks(\n verifiedInputs.map((document) => ({\n documentId: document.documentId,\n accessEpoch: document.accessEpoch,\n containerIds: document.linkedContainerIds,\n })),\n discoveredDocuments,\n ),\n );\n\n const tombstoneDocumentSummaries = await settleContainerDocumentTombstones({\n containerIds: [containerId],\n store: options,\n tombstones: getApplicableDocumentTombstones(listedDocuments),\n });\n\n const complete = await verification.commit();\n if (!(await verification.isCurrent())) return null;\n await saveAppliedContainerDocumentWatermark({\n containerId,\n listedDocuments,\n saveContainerDocumentWatermark: options.saveContainerDocumentWatermark,\n });\n\n if (listedDocuments.isFullListing) {\n // Initial probes consume ids as discovery hints and verify their own heads.\n options.onFullListing?.(\n listedDocuments.items.map((document) => document.id),\n );\n }\n\n return !complete &&\n discoveredDocuments.length === 0 &&\n tombstoneDocumentSummaries.length === 0\n ? null\n : [...discoveredDocuments, ...tombstoneDocumentSummaries];\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentDiscoveryEvidence.js","sourceRoot":"","sources":["documentDiscoveryEvidence.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DiscoveredDocumentInput } from \"../../data/documents/documentSummary\";\nimport type {\n DiscoveredDocumentCandidate,\n DocumentDiscoveryEvidenceStore,\n} from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\nimport { groupPendingDocumentDiscoveries } from \"./documentDiscoveryCandidates\";\nimport type { DiscoverContainerDocumentsOptions } from \"./documentDiscoveryTypes\";\nimport { documentHeadMatchesOrganization } from \"./documentHeadScope\";\nimport type {\n DocumentHeadLinkSetLoader,\n LocalDocumentAccessEpochLoader,\n} from \"./documentTombstoneEvidence\";\nimport {\n HEAD_LINK_SET_LOAD_CONCURRENCY,\n HEAD_LINK_SET_LOADS_PER_RUN,\n} from \"./documentTombstoneEvidence\";\n\nasync function verifyInput(\n input: DiscoveredDocumentCandidate,\n loadHead: DocumentHeadLinkSetLoader,\n loadLocalEpoch: LocalDocumentAccessEpochLoader,\n store: DocumentDiscoveryEvidenceStore,\n generation: number,\n organizationId: string | undefined,\n): Promise<DiscoveredDocumentInput | null | \"unavailable\"> {\n const localEpoch = await loadLocalEpoch(input.documentId).catch(\n () => Number.MAX_SAFE_INTEGER,\n );\n const cached = await store.loadHead(input.documentId, input.accessStateHash);\n const minimumEpoch = Math.max(localEpoch, input.accessEpoch);\n const head =\n cached && cached.accessEpoch >= minimumEpoch\n ? cached\n : await loadHead(\n input.documentId,\n input.accessEpoch >= localEpoch\n ? (input.accessStateHash ?? undefined)\n : undefined,\n );\n if (head === \"not-found\") return null;\n if (!head || head.accessEpoch < Math.max(localEpoch, input.accessEpoch))\n return \"unavailable\";\n if (!documentHeadMatchesOrganization(head, organizationId))\n return \"unavailable\";\n // A stale first lane must not hide a document present in another listed lane.\n const containerId = input.listedContainerIds.find((id) =>\n head.linkedContainerIds.includes(id),\n );\n if (!containerId) {\n // A same-epoch head can predate a link addition. Only the named head or\n // terminal signed purge evidence can settle a candidate without a retry.\n return head.accessEpoch > input.accessEpoch ||\n head.accessStateHash === input.accessStateHash ||\n (!head.accessStateHash && head.accessEpoch === Number.MAX_SAFE_INTEGER)\n ? null\n : \"unavailable\";\n }\n if (!head.accessStateHash) return \"unavailable\";\n if (!(await store.saveHead(input.documentId, head, generation)))\n return \"unavailable\";\n const { listedContainerIds: _listedContainerIds, ...document } = input;\n return {\n ...document,\n containerId,\n accessEpoch: head.accessEpoch,\n accessStateHash: head.accessStateHash,\n linkedContainerIds: head.linkedContainerIds,\n };\n}\n\n/**\n * Persist untrusted candidates before advancing listing watermarks. Each pass\n * checks a bounded batch; unavailable heads back off independently while verified\n * siblings and tombstones still settle. Acknowledgement follows local apply so\n * a crash cannot lose a candidate behind an already advanced listing watermark.\n */\nexport function createDiscoveredDocumentVerifier(\n organizationId: string | undefined,\n loadHead: DocumentHeadLinkSetLoader,\n loadLocalEpoch: LocalDocumentAccessEpochLoader,\n store: DocumentDiscoveryEvidenceStore,\n onPendingDiscovery?: ((delayMs: number) => void) | undefined,\n): DiscoverContainerDocumentsOptions[\"verifyDiscoveredDocuments\"] {\n return async (inputs, containerIds, generation, tombstones = []) => {\n const isCurrent = () => store.isCurrent(generation);\n const lanes = new Set(containerIds);\n const removed = tombstones.filter((row) => lanes.has(row.containerId));\n if (!(await store.stage(inputs, generation, removed)))\n return { inputs: [], isCurrent, commit: async () => true };\n const candidates = groupPendingDocumentDiscoveries(\n await store.pending(containerIds, HEAD_LINK_SET_LOADS_PER_RUN),\n );\n const verified = new Map<string, DiscoveredDocumentInput>();\n const settled: DiscoveredDocumentCandidate[] = [];\n let next = 0;\n const worker = async () => {\n while (next < candidates.length) {\n const group = candidates[next++];\n if (!group) break;\n const { input, rows } = group;\n const result = await verifyInput(\n input,\n loadHead,\n loadLocalEpoch,\n store,\n generation,\n organizationId,\n );\n if (result === \"unavailable\") {\n await Promise.all(rows.map((row) => store.defer(row, generation)));\n } else {\n if (result) verified.set(result.documentId, result);\n settled.push(...rows);\n }\n }\n };\n await Promise.all(\n Array.from(\n { length: Math.min(HEAD_LINK_SET_LOAD_CONCURRENCY, candidates.length) },\n worker,\n ),\n );\n return {\n inputs: [...verified.values()],\n isCurrent,\n commit: async () => {\n await store.acknowledge(settled, generation);\n const retryDelay = await store.retryDelay(containerIds);\n if (retryDelay !== null) onPendingDiscovery?.(retryDelay);\n return retryDelay === null;\n },\n };\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentDiscoveryInputs.js","sourceRoot":"","sources":["documentDiscoveryInputs.ts"],"names":[],"mappings":"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","sourcesContent":["import { uniqueSortedStrings } from \"../../data/documents/shared/readers\";\nimport {\n maxEffectiveAccessLevel,\n normalizeEffectiveAccessLevel,\n} from \"../../data/keying/accessLevel\";\nimport type { DiscoveredDocumentCandidate } from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\nimport type {\n ContainerDocumentTombstone,\n ListedContainerDocument,\n ListedContainerDocuments,\n ListedContainerDocumentsLane,\n} from \"./documentDiscoveryTypes\";\n\nfunction mergeDiscoveredDocumentInputs(\n current: DiscoveredDocumentCandidate,\n next: DiscoveredDocumentCandidate,\n): DiscoveredDocumentCandidate {\n // A lane page carries a complete link set for its epoch. Combining an old\n // root page with a newer trash page must not manufacture a newer root link.\n if (next.accessEpoch !== current.accessEpoch) {\n return {\n ...(next.accessEpoch > current.accessEpoch ? next : current),\n listedContainerIds: uniqueSortedStrings([\n ...current.listedContainerIds,\n ...next.listedContainerIds,\n ]),\n };\n }\n const accessStateHash =\n next.accessEpoch >= current.accessEpoch\n ? next.accessStateHash\n : current.accessStateHash;\n\n return {\n accessEpoch: Math.max(current.accessEpoch, next.accessEpoch),\n ...(accessStateHash === undefined ? {} : { accessStateHash }),\n containerId: current.containerId,\n listedContainerIds: uniqueSortedStrings([\n ...current.listedContainerIds,\n ...next.listedContainerIds,\n ]),\n createdAt:\n current.createdAt.localeCompare(next.createdAt) <= 0\n ? current.createdAt\n : next.createdAt,\n documentId: current.documentId,\n effectiveAccessLevel: maxEffectiveAccessLevel(\n normalizeEffectiveAccessLevel(current.effectiveAccessLevel),\n normalizeEffectiveAccessLevel(next.effectiveAccessLevel),\n ),\n linkedContainerIds: uniqueSortedStrings([\n current.containerId,\n next.containerId,\n ...current.linkedContainerIds,\n ...next.linkedContainerIds,\n ]),\n };\n}\n\nexport function collectDiscoveredDocumentInputs(\n listedDocumentsByContainer: ReadonlyArray<ListedContainerDocumentsLane>,\n): DiscoveredDocumentCandidate[] {\n const discoveredDocumentInputsByDocumentId = new Map<\n string,\n DiscoveredDocumentCandidate\n >();\n\n for (const { containerId, listedDocuments } of listedDocumentsByContainer) {\n if (!listedDocuments) {\n continue;\n }\n\n for (const document of listedDocuments.items) {\n const discoveredDocumentInput: DiscoveredDocumentCandidate = {\n accessEpoch: document.currentAccessEpoch,\n accessStateHash: document.currentAccessStateHash,\n containerId,\n listedContainerIds: [containerId],\n createdAt: document.createdAt,\n documentId: document.id,\n effectiveAccessLevel: normalizeEffectiveAccessLevel(\n document.effectiveAccessLevel,\n ),\n linkedContainerIds: uniqueSortedStrings([\n containerId,\n ...document.linkedContainerIds,\n ]),\n };\n const currentDiscoveredDocumentCandidate =\n discoveredDocumentInputsByDocumentId.get(document.id);\n discoveredDocumentInputsByDocumentId.set(\n document.id,\n currentDiscoveredDocumentCandidate\n ? mergeDiscoveredDocumentInputs(\n currentDiscoveredDocumentCandidate,\n discoveredDocumentInput,\n )\n : discoveredDocumentInput,\n );\n }\n }\n\n return Array.from(discoveredDocumentInputsByDocumentId.values());\n}\n\nexport function getApplicableDocumentTombstones(\n listedDocuments: ListedContainerDocuments,\n): ContainerDocumentTombstone[] {\n const latestItemsByDocumentId = new Map<string, ListedContainerDocument>();\n for (const document of listedDocuments.items) {\n const existingDocument = latestItemsByDocumentId.get(document.id);\n if (\n !existingDocument ||\n existingDocument.updatedAt.localeCompare(document.updatedAt) < 0\n ) {\n latestItemsByDocumentId.set(document.id, document);\n }\n }\n\n return listedDocuments.tombstones.filter((tombstone) => {\n const item = latestItemsByDocumentId.get(tombstone.documentId);\n return (\n !item?.linkedContainerIds.includes(tombstone.containerId) ||\n item.updatedAt.localeCompare(tombstone.updatedAt) < 0\n );\n });\n}\n\nexport function collectApplicableDocumentTombstones(\n lanes: ReadonlyArray<ListedContainerDocumentsLane>,\n): ContainerDocumentTombstone[] {\n return lanes.flatMap(({ listedDocuments }) =>\n listedDocuments ? getApplicableDocumentTombstones(listedDocuments) : [],\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentDiscoveryLanes.js","sourceRoot":"","sources":["documentDiscoveryLanes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oCAAoC,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EACL,6BAA6B,GAE9B,MAAM,0BAA0B,CAAC;AA2BlC,KAAK,UAAU,eAAe,CAC5B,IAAoC,EACpC,UAAkB,EAClB,eAAgD;IAEhD,IAAI,CAAC;QACH,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,eAAe;gBACpB,CAAC,CAAC,MAAM,6BAA6B,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC;gBACxE,CAAC,CAAC,IAAI;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACvE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAOpD;IACC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACxC,IAAI,MAAwE,CAAC;IAC7E,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,oCAAoC,CAAC;YAClD,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;YACzD,0BAA0B,EAAE,KAAK,CAAC,0BAA0B;YAC5D,8BAA8B,EAAE,KAAK,CAAC,8BAA8B;SACrE,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAC9B,CAAC,EAAE,WAAW,EAAE,EAAqC,EAAE,CAAC,CAAC;YACvD,WAAW;YACX,MAAM;YACN,MAAM,EAAE,UAAU;SACnB,CAAC,CACH,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,QAAQ;YAAE,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;QACjE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAwC,EAAE,CAAC;IACzD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,IAAI,EACJ,KAAK,CAAC,UAAU,EAChB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CACrC,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { listContainerDocumentsFromWatermarks } from \"./containerDocumentListing\";\nimport {\n applyListedContainerDocuments,\n type ContainerDocumentDiscoveryLane,\n} from \"./documentDiscoveryApply\";\nimport type {\n ContainerDocumentLaneLister,\n DiscoverContainerDocumentsOptions,\n ListedContainerDocuments,\n} from \"./documentDiscoveryTypes\";\n\nexport type { ContainerDocumentDiscoveryLane } from \"./documentDiscoveryApply\";\n\nexport type ContainerDocumentDiscoveryOutcome =\n | {\n readonly containerId: string;\n readonly status: \"fulfilled\";\n /** `null` when the lane was not fully listed or nothing applied. */\n readonly value: ReadonlyArray<DocumentSummary> | null;\n }\n | {\n readonly containerId: string;\n readonly reason: unknown;\n readonly status: \"rejected\";\n };\n\n/** Lets a caller act on each lane before later lanes apply. */\nexport type ContainerDocumentDiscoveryOutcomeHandler = (\n outcome: ContainerDocumentDiscoveryOutcome,\n) => Promise<void>;\n\nasync function applyListedLane(\n lane: ContainerDocumentDiscoveryLane,\n generation: number,\n listedDocuments: ListedContainerDocuments | null,\n): Promise<ContainerDocumentDiscoveryOutcome> {\n try {\n return {\n containerId: lane.containerId,\n status: \"fulfilled\",\n value: listedDocuments\n ? await applyListedContainerDocuments(lane, generation, listedDocuments)\n : null,\n };\n } catch (reason) {\n return { containerId: lane.containerId, reason, status: \"rejected\" };\n }\n}\n\n/**\n * Discovers several containers with one batched listing, then verifies and\n * applies each lane on its own, in order. The generation must be captured\n * before any lane's scope was read, exactly as for a single discovery: every\n * listing in the batch starts after it, so a reset in between still cancels\n * the batch. One lane's failure never blocks applying the others.\n */\nexport async function discoverContainerDocumentLanes(input: {\n readonly generation: number;\n readonly lanes: ReadonlyArray<ContainerDocumentDiscoveryLane>;\n readonly listContainerDocumentLanes: ContainerDocumentLaneLister;\n readonly loadContainerDocumentWatermark: DiscoverContainerDocumentsOptions[\"loadContainerDocumentWatermark\"];\n /** Awaited after each lane settles, before the next lane applies. */\n readonly onOutcome?: ContainerDocumentDiscoveryOutcomeHandler | undefined;\n}): Promise<ReadonlyArray<ContainerDocumentDiscoveryOutcome>> {\n if (input.lanes.length === 0) return [];\n let listed: Awaited<ReturnType<typeof listContainerDocumentsFromWatermarks>>;\n try {\n listed = await listContainerDocumentsFromWatermarks({\n containerIds: input.lanes.map((lane) => lane.containerId),\n listContainerDocumentLanes: input.listContainerDocumentLanes,\n loadContainerDocumentWatermark: input.loadContainerDocumentWatermark,\n });\n } catch (reason) {\n const rejected = input.lanes.map(\n ({ containerId }): ContainerDocumentDiscoveryOutcome => ({\n containerId,\n reason,\n status: \"rejected\",\n }),\n );\n for (const outcome of rejected) await input.onOutcome?.(outcome);\n return rejected;\n }\n\n const outcomes: ContainerDocumentDiscoveryOutcome[] = [];\n for (const lane of input.lanes) {\n const outcome = await applyListedLane(\n lane,\n input.generation,\n listed.get(lane.containerId) ?? null,\n );\n outcomes.push(outcome);\n await input.onOutcome?.(outcome);\n }\n return outcomes;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentDiscoveryTypes.js","sourceRoot":"","sources":["documentDiscoveryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ListContainerDocumentLanesRequest,\n ListContainerParentLanesRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n EffectiveAccessLevel,\n ReferencedPrincipalStateResponse,\n SyncWatermark,\n} from \"@tearleads/validators/response\";\nimport type {\n DiscoveredDocumentInput,\n DocumentSummary,\n} from \"../../data/documents/documentSummary\";\nimport type { DiscoveredDocumentCandidate } from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\n\nexport interface ListedContainerDocument {\n createdAt: string;\n currentAccessEpoch: number;\n currentAccessStateHash: string;\n effectiveAccessLevel?: EffectiveAccessLevel | undefined;\n id: string;\n linkedContainerIds: string[];\n referencedPrincipals: ReferencedPrincipalStateResponse[];\n updatedAt: string;\n}\n\nexport interface ListContainerDocumentsResponse {\n hasMore: boolean;\n items: ListedContainerDocument[];\n nextWatermark: SyncWatermark | null;\n tombstones: ReadonlyArray<{\n containerId: string;\n documentId: string;\n updatedAt: string;\n }>;\n}\n\nexport interface ListedContainer {\n id: string;\n}\n\nexport interface ListContainersResponse {\n hasMore: boolean;\n items: ListedContainer[];\n nextWatermark: SyncWatermark | null;\n}\n\nexport interface ListContainerParentLanesResponse {\n results: ReadonlyArray<{\n laneId: string;\n page: ListContainersResponse;\n }>;\n}\n\nexport type ContainerDocumentLaneResult =\n | { readonly laneId: string; readonly page: ListContainerDocumentsResponse }\n | {\n readonly failure: { readonly code?: string | undefined };\n readonly laneId: string;\n };\n\nexport interface ContainerDocumentDiscoveryApi {\n readonly listContainerDocumentLanes: (\n input: ListContainerDocumentLanesRequest,\n options?: { readonly reportErrors?: boolean | undefined },\n ) => Promise<{\n readonly results: ReadonlyArray<ContainerDocumentLaneResult>;\n } | null>;\n readonly listContainerParentLanes: (\n input: ListContainerParentLanesRequest,\n ) => Promise<ListContainerParentLanesResponse | null>;\n}\n\n/**\n * One page per lane, aligned with the requested lanes: `null` for a lane the\n * server rejected, or `null` overall when the request itself failed.\n */\nexport type ContainerDocumentLaneLister = (\n lanes: ReadonlyArray<{\n readonly containerId: string;\n readonly watermark: SyncWatermark | null;\n }>,\n) => Promise<ReadonlyArray<ListContainerDocumentsResponse | null> | null>;\n\nexport interface DocumentLinkInput {\n accessEpoch?: number | undefined;\n containerIds: ReadonlyArray<string>;\n documentId: string;\n}\n\nexport type ContainerDocumentTombstone =\n ListContainerDocumentsResponse[\"tombstones\"][number];\n\nexport interface VerifiedContainerDocumentTombstone\n extends ContainerDocumentTombstone {\n /** The verified head's link-set epoch, not below the local document epoch. */\n readonly accessEpoch: number;\n /** The verified head link set; it omits `containerId`. */\n readonly linkedContainerIds: ReadonlyArray<string>;\n}\n\n/**\n * What the document's signed head says about a listing tombstone.\n * - `verified`: the verified head link set omits the container; apply.\n * - `refuted`: the verified head still links the container; keep visible and retry.\n * - `unverified`: no verified head is available; hold, hide, retry later.\n * - `deferred`: not attempted this run (the per-run head-load cap); hold\n * without counting an attempt, so the retry backoff does not grow.\n */\nexport type ContainerDocumentTombstoneVerdict =\n | {\n readonly kind: \"verified\";\n readonly tombstone: VerifiedContainerDocumentTombstone;\n }\n | {\n readonly kind: \"refuted\";\n /** The verified head link set, which contains the container. */\n readonly linkedContainerIds: ReadonlyArray<string>;\n readonly tombstone: ContainerDocumentTombstone;\n }\n | {\n readonly kind: \"unverified\";\n readonly tombstone: ContainerDocumentTombstone;\n }\n | {\n readonly kind: \"deferred\";\n readonly tombstone: ContainerDocumentTombstone;\n };\n\nexport interface HeldContainerDocumentTombstoneInput\n extends ContainerDocumentTombstone {\n /** Held without a verification attempt; the backoff does not advance. */\n readonly deferred?: boolean | undefined;\n /** A verified head still links it; retry the tombstone while keeping it visible. */\n readonly refuted?: boolean | undefined;\n}\n\nexport type ContainerDocumentTombstoneVerifier = (\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n) => Promise<ReadonlyArray<ContainerDocumentTombstoneVerdict>>;\n\nexport type ContainerDocumentPlacement = Pick<\n ContainerDocumentTombstone,\n \"containerId\" | \"documentId\"\n>;\n\nexport interface ContainerDocumentTombstoneHoldStore {\n holdContainerDocumentTombstones: (\n tombstones: ReadonlyArray<HeldContainerDocumentTombstoneInput>,\n ) => Promise<void>;\n /** Held tombstones on these containers that are due for another attempt. */\n listHeldContainerDocumentTombstones: (\n containerIds: ReadonlyArray<string>,\n ) => Promise<ReadonlyArray<ContainerDocumentTombstone>>;\n /** The subset of placements that exist locally (link row or primary). */\n listKnownContainerDocumentPlacements: (\n placements: ReadonlyArray<ContainerDocumentPlacement>,\n ) => Promise<ReadonlyArray<ContainerDocumentPlacement>>;\n refuteContainerDocumentTombstoneHolds: (\n placements: ReadonlyArray<ContainerDocumentPlacement>,\n ) => Promise<void>;\n}\n\nexport interface DiscoverContainerDocumentsOptions\n extends ContainerDocumentTombstoneHoldStore {\n applyContainerDocumentTombstones: (\n tombstones: ReadonlyArray<VerifiedContainerDocumentTombstone>,\n ) => Promise<ReadonlyArray<DocumentSummary>>;\n verifyContainerDocumentTombstones: ContainerDocumentTombstoneVerifier;\n /** Allocate durable local order before fetching a listing. */\n beginDocumentDiscovery: () => Promise<number>;\n /** Persist pending candidates and return only signed placements. */\n verifyDiscoveredDocuments: (\n inputs: ReadonlyArray<DiscoveredDocumentCandidate>,\n containerIds: ReadonlyArray<string>,\n generation: number,\n tombstones?: ReadonlyArray<ContainerDocumentTombstone>,\n ) => Promise<{\n inputs: ReadonlyArray<DiscoveredDocumentInput>;\n /** False once a remote trust reset cancels this listing pass. */\n isCurrent: () => Promise<boolean>;\n /** Acknowledge only after local apply; true means no pending candidates remain. */\n commit: () => Promise<boolean>;\n }>;\n cacheReferencedPrincipalPolicies?: (\n references: ReadonlyArray<ReferencedPrincipalStateResponse>,\n ) => Promise<void>;\n containerId: string;\n /** Completed unwatermarked listing, published only after local apply succeeds. */\n onFullListing?: ((documentIds: ReadonlyArray<string>) => void) | undefined;\n loadContainerDocumentWatermark: (\n containerId: string,\n ) => Promise<SyncWatermark | null>;\n listContainerDocumentLanes: ContainerDocumentLaneLister;\n replaceDocumentLinksBatch: (\n inputs: ReadonlyArray<DocumentLinkInput>,\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\nexport interface ListedContainerDocuments {\n isFullListing: boolean;\n items: ListedContainerDocument[];\n nextWatermark: SyncWatermark | null;\n tombstones: ContainerDocumentTombstone[];\n}\n\nexport interface ContainerParentDiscoveryLane {\n parentId: string | null;\n watermark: SyncWatermark | null;\n}\n\nexport interface ListedContainerDocumentsLane {\n containerId: string;\n listedDocuments: ListedContainerDocuments | null;\n}\n\nexport interface DiscoverAllContainerDocumentsOptions\n extends Omit<DiscoverContainerDocumentsOptions, \"containerId\"> {\n containerIds: ReadonlyArray<string>;\n}\n\nexport interface RefreshAllContainerDocumentsOptions\n extends Omit<DiscoverAllContainerDocumentsOptions, \"containerIds\"> {\n listContainerParentLanes: ContainerDocumentDiscoveryApi[\"listContainerParentLanes\"];\n}\n\nexport interface RefreshAllContainerDocumentsFromApiOptions\n extends Omit<\n RefreshAllContainerDocumentsOptions,\n \"listContainerDocumentLanes\" | \"listContainerParentLanes\"\n > {\n readonly apiClient: Pick<\n ContainerDocumentDiscoveryApi,\n \"listContainerDocumentLanes\" | \"listContainerParentLanes\"\n >;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentFieldBlame.js","sourceRoot":"","sources":["documentFieldBlame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAEL,mBAAmB,GACpB,MAAM,sCAAsC,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,eAA8B,EAC9B,QAAqD;IAErD,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,wBAAwB,CAC3C,aAAa,CAAC,eAAe,CAAC,EAC9B,uBAAuB,CACxB,CAAC;QACF,OAAO,mBAAmB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport { listSnapshotFieldEditors } from \"@tearleads/loro\";\nimport type { DocumentEditAttributionResponse } from \"@tearleads/validators/response\";\nimport { DOCUMENT_FIELDS_MAP_KEY } from \"../../data/documents/documentKinds\";\nimport {\n type DocumentFieldBlame,\n summarizeFieldBlame,\n} from \"../../data/documents/editAttribution\";\n\n/**\n * Per-field \"blame\" for a structured document: read the peer that last set each\n * field from the locally persisted snapshot and resolve it against the\n * attribution segments. Reconstructing the small `fields` map is cheap (no\n * per-character sweep), so this runs its own reconstruction independent of the\n * character-blame path. Returns null when it can't be produced — no local\n * snapshot or an unreadable one — mirroring the character-blame degrade-to-null;\n * a note (or any document without fields) yields an empty array, not null.\n */\nexport function computeFieldBlame(\n contentSnapshot: string | null,\n segments: DocumentEditAttributionResponse[\"segments\"],\n): DocumentFieldBlame[] | null {\n if (!contentSnapshot || contentSnapshot.length === 0) {\n return null;\n }\n try {\n const fieldEditors = listSnapshotFieldEditors(\n base64ToBytes(contentSnapshot),\n DOCUMENT_FIELDS_MAP_KEY,\n );\n return summarizeFieldBlame(fieldEditors, segments);\n } catch {\n return null;\n }\n}\n"]}
@@ -1 +0,0 @@
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"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentInfo.js","sourceRoot":"","sources":["documentInfo.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { exportFullHistorySnapshot } from \"@tearleads/loro\";\nimport type {\n BlobAttachmentSummary,\n ContainerKeyingPathResponse,\n DocumentEditAttributionResponse,\n DocumentWriterProjectionResponse,\n ListDocumentAttachmentsResponse,\n} from \"@tearleads/validators/response\";\nimport { and, eq, isNull } from \"drizzle-orm\";\nimport { DEFAULT_DOCUMENT_KIND } from \"../../data/documents/documentConstants\";\nimport {\n type DocumentBlameRange,\n type DocumentCharacterBlameSummary,\n type DocumentContributor,\n type DocumentFieldBlame,\n summarizeDocumentContributors,\n} from \"../../data/documents/editAttribution\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\nimport {\n documentAttachmentBlobProjection,\n documentPendingAttachments,\n documentProjection,\n} from \"../../data/sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { loadPersistedDocumentContent } from \"../documents/historyContent\";\nimport { computeDocumentBlame } from \"./documentCharacterBlame\";\nimport { computeFieldBlame } from \"./documentFieldBlame\";\nimport type {\n DocumentInfo,\n DocumentInfoAttachment,\n DocumentInfoAuthorizingContainerPath,\n DocumentInfoLocalDetails,\n DocumentInfoRemoteAttachmentBinding,\n DocumentInfoRemoteDetails,\n DocumentInfoRemoteMode,\n} from \"./documentInfoTypes\";\n\nexport type {\n DocumentInfo,\n DocumentInfoAttachment,\n DocumentInfoAuthorizingContainerPath,\n DocumentInfoLocalDetails,\n DocumentInfoRemoteAttachmentBinding,\n DocumentInfoRemoteDetails,\n DocumentInfoRemoteMode,\n} from \"./documentInfoTypes\";\n\ninterface DocumentInfoApi {\n getDocumentEditAttribution: (\n documentId: string,\n requestKey?: string,\n ) => Promise<DocumentEditAttributionResponse | null>;\n getDocumentWriterProjection: (\n documentId: string,\n ) => Promise<DocumentWriterProjectionResponse | null>;\n listDocumentAttachments: (\n documentId: string,\n ) => Promise<ListDocumentAttachmentsResponse | null>;\n}\n\ninterface PendingAttachmentInfoRow {\n byteLength: number;\n createdAt: string;\n localId: string;\n mimeType: string | null;\n name: string;\n slotId: string;\n storageKey: string;\n}\n\ninterface LocalAttachmentInfoRow {\n blobId: string | null;\n byteLength: number;\n localId: string;\n mimeType: string | null;\n slotId: string;\n storageKey: string;\n updatedAt: string;\n}\n\nfunction readRecordString(value: unknown, key: string): string | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const nextValue = Reflect.get(value, key);\n return typeof nextValue === \"string\" && nextValue.length > 0\n ? nextValue\n : null;\n}\n\nfunction readRecordNumber(value: unknown, key: string): number | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const nextValue = Reflect.get(value, key);\n return typeof nextValue === \"number\" && Number.isFinite(nextValue)\n ? nextValue\n : null;\n}\n\nfunction readRecordArrayLength(value: unknown, key: string): number | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n\n const nextValue = Reflect.get(value, key);\n return Array.isArray(nextValue) ? nextValue.length : null;\n}\n\nfunction readStoredManifestHash(\n value: string | null | undefined,\n): string | null {\n if (!value) {\n return null;\n }\n\n try {\n const parsed: unknown = JSON.parse(value);\n return readRecordString(parsed, \"manifestHash\");\n } catch {\n return null;\n }\n}\n\nfunction mapPendingAttachmentRow(\n row: PendingAttachmentInfoRow,\n): DocumentInfoAttachment {\n return {\n attachmentKind: \"pending\",\n blobId: null,\n byteLength: row.byteLength,\n createdAt: row.createdAt,\n localId: row.localId,\n mimeType: row.mimeType,\n name: row.name,\n slotId: row.slotId,\n storageKey: row.storageKey,\n updatedAt: null,\n };\n}\n\nfunction mapLocalAttachmentRow(\n row: LocalAttachmentInfoRow,\n): DocumentInfoAttachment {\n return {\n attachmentKind: \"local\",\n blobId: row.blobId,\n byteLength: row.byteLength,\n createdAt: null,\n localId: row.localId,\n mimeType: row.mimeType,\n name: null,\n slotId: row.slotId,\n storageKey: row.storageKey,\n updatedAt: row.updatedAt,\n };\n}\n\nasync function loadDocumentInfoAttachments(input: {\n execSql: ExecSql;\n localId: string;\n}): Promise<DocumentInfoAttachment[]> {\n const { db } = getClientSQLitePersistenceRuntime(input.execSql);\n const [pendingRows, localRows] = await Promise.all([\n db\n .select({\n byteLength: documentPendingAttachments.byteLength,\n createdAt: documentPendingAttachments.createdAt,\n localId: documentPendingAttachments.localId,\n mimeType: documentPendingAttachments.mimeType,\n name: documentPendingAttachments.name,\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n })\n .from(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, input.localId))\n .orderBy(\n documentPendingAttachments.createdAt,\n documentPendingAttachments.slotId,\n ),\n db\n .select({\n blobId: documentAttachmentBlobProjection.blobId,\n byteLength: documentAttachmentBlobProjection.byteLength,\n localId: documentAttachmentBlobProjection.localId,\n mimeType: documentAttachmentBlobProjection.mimeType,\n slotId: documentAttachmentBlobProjection.slotId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n updatedAt: documentAttachmentBlobProjection.updatedAt,\n })\n .from(documentAttachmentBlobProjection)\n .where(\n and(\n eq(documentAttachmentBlobProjection.localId, input.localId),\n // Unlinked slots keep their row as a pending-detach marker; the\n // document no longer has the attachment, so do not report it.\n isNull(documentAttachmentBlobProjection.detachedAt),\n ),\n )\n .orderBy(\n documentAttachmentBlobProjection.updatedAt,\n documentAttachmentBlobProjection.slotId,\n ),\n ]);\n\n return [\n ...pendingRows.map(mapPendingAttachmentRow),\n ...localRows.map(mapLocalAttachmentRow),\n ];\n}\n\nasync function loadLocalDocumentInfo(input: {\n execSql: ExecSql | null;\n localId: string;\n}): Promise<{\n attachments: DocumentInfoAttachment[];\n contentSnapshot: string | null;\n local: DocumentInfoLocalDetails;\n}> {\n const fallback = {\n attachments: [],\n contentSnapshot: null,\n local: {\n accessEpoch: null,\n accessStateHash: null,\n containerId: null,\n documentId: null,\n documentKind: null,\n hasContentKeyBundle: false,\n hasDocumentKekTargets: false,\n hasDocumentManifestBundle: false,\n lastCommitLsn: null,\n localDocumentManifestHash: null,\n localId: input.localId,\n pendingAttachmentByteLength: 0,\n pendingAttachmentCount: 0,\n pendingUpdateCount: 0,\n title: null,\n updatedAt: null,\n },\n };\n\n if (!input.execSql) {\n return fallback;\n }\n\n await sqlDocumentsPersistence.ensureSchema(input.execSql);\n const { db } = getClientSQLitePersistenceRuntime(input.execSql);\n const [document, pendingUpdates, attachments, projectionRows, contentDoc] =\n await Promise.all([\n sqlDocumentsPersistence.loadDocument(input.execSql, input.localId),\n sqlDocumentsPersistence.listPendingUpdates(input.execSql, input.localId),\n loadDocumentInfoAttachments({\n execSql: input.execSql,\n localId: input.localId,\n }),\n db\n .select({ updatedAt: documentProjection.updatedAt })\n .from(documentProjection)\n .where(eq(documentProjection.localId, input.localId))\n .limit(1),\n loadPersistedDocumentContent({\n execSql: input.execSql,\n localId: input.localId,\n persistence: sqlDocumentsPersistence,\n }).catch(() => null),\n ]);\n\n if (!document) {\n return fallback;\n }\n\n const pendingAttachments = attachments.filter(\n (attachment) => attachment.attachmentKind === \"pending\",\n );\n\n return {\n attachments,\n // Blame reads op-level provenance out of a serialized snapshot; export the\n // durable-history content for it. Degrades to null (blame unavailable)\n // rather than failing the Info panel.\n contentSnapshot: contentDoc\n ? bytesToBase64(exportFullHistorySnapshot(contentDoc))\n : null,\n local: {\n accessEpoch: document.accessEpoch,\n accessStateHash: document.accessStateHash ?? null,\n containerId: document.containerId,\n documentId: document.documentId,\n documentKind: document.documentKind ?? DEFAULT_DOCUMENT_KIND,\n hasContentKeyBundle: Boolean(document.contentKeyBundle),\n hasDocumentKekTargets: Boolean(document.documentKekTargets),\n hasDocumentManifestBundle: Boolean(document.documentManifestBundle),\n lastCommitLsn: document.lastCommitLsn ?? null,\n localDocumentManifestHash: readStoredManifestHash(\n document.documentManifestBundle,\n ),\n localId: document.id,\n pendingAttachmentByteLength: pendingAttachments.reduce(\n (total, attachment) => total + attachment.byteLength,\n 0,\n ),\n pendingAttachmentCount: pendingAttachments.length,\n pendingUpdateCount: pendingUpdates.length,\n title: document.title ?? null,\n updatedAt: projectionRows[0]?.updatedAt ?? null,\n },\n };\n}\n\nfunction shouldLoadRemoteDocumentInfo(input: {\n local: DocumentInfoLocalDetails;\n remoteInfoMode: DocumentInfoRemoteMode;\n}): boolean {\n return input.remoteInfoMode !== \"never\" && Boolean(input.local.documentId);\n}\n\nfunction mapAttachmentBinding(\n binding: BlobAttachmentSummary,\n): DocumentInfoRemoteAttachmentBinding {\n return {\n bindingId: binding.bindingId,\n blobId: binding.blobId,\n slotId: binding.slotId,\n };\n}\n\nfunction mapAuthorizingContainerPath(\n projection: ContainerKeyingPathResponse,\n): DocumentInfoAuthorizingContainerPath {\n const leafBundle = projection.path.at(-1);\n const leafKek = projection.containerKeks.at(-1);\n\n return {\n containerId: projection.containerId,\n containerKeyEpoch: leafKek?.containerKeyEpoch ?? null,\n containerKeyEpochId: leafKek?.containerKeyEpochId ?? null,\n leafManifestHash: leafBundle?.manifestHash ?? null,\n organizationId: projection.organizationId,\n pathLength: projection.path.length,\n };\n}\n\nfunction getDocumentInfoRemoteDetails(input: {\n attachmentBindings: ReadonlyArray<BlobAttachmentSummary>;\n attribution: DocumentEditAttributionResponse | null;\n blameRanges: DocumentBlameRange[] | null;\n characterBlame: DocumentCharacterBlameSummary | null;\n contributors: DocumentContributor[];\n fieldBlame: DocumentFieldBlame[] | null;\n projection: DocumentWriterProjectionResponse;\n}): DocumentInfoRemoteDetails {\n const {\n attachmentBindings,\n attribution,\n blameRanges,\n characterBlame,\n contributors,\n fieldBlame,\n projection,\n } = input;\n const manifestState = projection.documentManifest.state;\n const manifest = projection.documentManifest.manifest;\n\n return {\n activeAttachmentBindings: attachmentBindings.map(mapAttachmentBinding),\n attributionRevision: attribution?.attributionRevision ?? null,\n attributionStatus: attribution\n ? attribution.truncated\n ? \"truncated\"\n : \"available\"\n : \"unavailable\",\n attributionSegments: attribution?.segments ?? [],\n authorizingContainerPaths: projection.authorizingContainerPaths.map(\n mapAuthorizingContainerPath,\n ),\n blameRanges,\n characterBlame,\n fieldBlame,\n contentKeyEpoch: projection.contentKeyBundle.contentKeyEpoch,\n contentKeyTargetCount: projection.contentKeyBundle.targets.length,\n contentKeyTargetHash: projection.contentKeyBundle.targetHash,\n contributors,\n currentManifestHash: projection.documentManifest.manifestHash,\n documentContainerManifestHistoryCount:\n projection.documentContainerManifestHistory.length,\n documentKekTargetCount: projection.documentKekTargets.targets.length,\n documentKeyTargetHash: projection.documentKekTargets.documentKeyTargetHash,\n documentManifestContainerPathCount:\n projection.documentManifestContainerPaths.length,\n documentManifestHistoryCount: projection.documentManifestHistory.length,\n linkedContainerKeyEpochCount:\n projection.documentKekTargets.linkedContainerKeyEpochIds.length,\n linkedContainerManifestCount:\n projection.documentKekTargets.linkedContainerManifestHashes.length,\n linkSetManifestHash: projection.documentKekTargets.linkSetManifestHash,\n manifestEpoch: readRecordNumber(manifest, \"epoch\"),\n previousManifestHash: readRecordString(\n manifestState,\n \"previousManifestHash\",\n ),\n referencedPrincipalCount: readRecordArrayLength(\n manifest,\n \"referencedPrincipalHeads\",\n ),\n };\n}\n\nexport async function loadDocumentInfo(input: {\n apiClient: DocumentInfoApi;\n attributionRequestKey?: string | undefined;\n execSql?: ExecSql | null;\n localId: string;\n reportSecurityIncident: SecurityIncidentReporter;\n remoteInfoMode?: DocumentInfoRemoteMode | undefined;\n}): Promise<DocumentInfo> {\n const { attachments, contentSnapshot, local } = await loadLocalDocumentInfo({\n execSql: input.execSql ?? null,\n localId: input.localId,\n });\n\n if (\n !shouldLoadRemoteDocumentInfo({\n local,\n remoteInfoMode: input.remoteInfoMode ?? \"if-synced\",\n }) ||\n !local.documentId\n ) {\n return { attachments, local, remoteInfo: null };\n }\n\n const attributionPromise = input.apiClient\n .getDocumentEditAttribution(local.documentId, input.attributionRequestKey)\n .catch(async (error: unknown) => {\n await reportAndRethrowKeyingVerificationError(\n error,\n input.reportSecurityIncident,\n {\n objectId: local.documentId ?? input.localId,\n objectKind: \"document\",\n operation: \"document.info.attribution\",\n },\n );\n return null;\n });\n const [projection, attachmentBindings, attribution] = await Promise.all([\n input.apiClient.getDocumentWriterProjection(local.documentId),\n input.apiClient.listDocumentAttachments(local.documentId),\n // Attribution is supplementary: a rejection (network/server) must not block\n // the rest of the document-info load, so swallow it to null (no contributors).\n attributionPromise,\n ]);\n\n if (!projection) {\n throw new Error(\n `Document info projection was unavailable for local document ${input.localId} with remote document ${local.documentId}.`,\n );\n }\n\n const attributionComplete = attribution && !attribution.truncated;\n const attributionSegments = attribution?.segments ?? [];\n const blame = attributionComplete\n ? computeDocumentBlame(contentSnapshot, attributionSegments)\n : null;\n return {\n attachments,\n local,\n remoteInfo: getDocumentInfoRemoteDetails({\n attachmentBindings: attachmentBindings ?? [],\n attribution,\n blameRanges: blame?.blameRanges ?? null,\n characterBlame: blame?.characterBlame ?? null,\n contributors: attributionComplete\n ? summarizeDocumentContributors(attributionSegments)\n : [],\n fieldBlame: attributionComplete\n ? computeFieldBlame(contentSnapshot, attributionSegments)\n : null,\n projection,\n }),\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentInfoTypes.js","sourceRoot":"","sources":["documentInfoTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentEditAttributionResponse } from \"@tearleads/validators/response\";\nimport type { StoredDocumentKind } from \"../../data/documents/documentKinds\";\nimport type {\n DocumentBlameRange,\n DocumentCharacterBlameSummary,\n DocumentContributor,\n DocumentFieldBlame,\n} from \"../../data/documents/editAttribution\";\n\nexport type DocumentInfoRemoteMode = \"if-synced\" | \"never\";\n\nexport interface DocumentInfoLocalDetails {\n accessEpoch: number | null;\n accessStateHash: string | null;\n containerId: string | null;\n documentId: string | null;\n documentKind: StoredDocumentKind | null;\n hasContentKeyBundle: boolean;\n hasDocumentKekTargets: boolean;\n hasDocumentManifestBundle: boolean;\n lastCommitLsn: string | null;\n localDocumentManifestHash: string | null;\n localId: string;\n pendingAttachmentByteLength: number;\n pendingAttachmentCount: number;\n pendingUpdateCount: number;\n title: string | null;\n updatedAt: string | null;\n}\n\nexport interface DocumentInfoAttachment {\n attachmentKind: \"local\" | \"pending\";\n blobId: string | null;\n byteLength: number;\n createdAt: string | null;\n localId: string;\n mimeType: string | null;\n name: string | null;\n slotId: string;\n storageKey: string;\n updatedAt: string | null;\n}\n\nexport interface DocumentInfoRemoteAttachmentBinding {\n bindingId: string;\n blobId: string;\n slotId: string;\n}\n\nexport interface DocumentInfoAuthorizingContainerPath {\n containerId: string;\n containerKeyEpoch: number | null;\n containerKeyEpochId: string | null;\n leafManifestHash: string | null;\n organizationId: string;\n pathLength: number;\n}\n\nexport interface DocumentInfoRemoteDetails {\n activeAttachmentBindings: DocumentInfoRemoteAttachmentBinding[];\n attributionRevision: number | null;\n attributionStatus: \"available\" | \"truncated\" | \"unavailable\";\n attributionSegments: DocumentEditAttributionResponse[\"segments\"];\n authorizingContainerPaths: DocumentInfoAuthorizingContainerPath[];\n /**\n * Contiguous per-writer runs of the current prose — the read-only \"blame\"\n * view that tints each phrase by who wrote it. Shares its `null` conditions\n * (and its single snapshot reconstruction) with {@link characterBlame}.\n */\n blameRanges: DocumentBlameRange[] | null;\n /**\n * Per-writer live-character blame, or `null` when it could not be computed —\n * the document has no local snapshot, the snapshot is too large to extract\n * op ids from cheaply, or the snapshot was unreadable.\n */\n characterBlame: DocumentCharacterBlameSummary | null;\n /**\n * Per-field blame for a structured document (who last set each field), or\n * `null` when it could not be computed. A note yields `[]` (no fields).\n */\n fieldBlame: DocumentFieldBlame[] | null;\n contentKeyEpoch: number;\n contentKeyTargetCount: number;\n contentKeyTargetHash: string;\n contributors: DocumentContributor[];\n currentManifestHash: string;\n documentContainerManifestHistoryCount: number;\n documentKekTargetCount: number;\n documentKeyTargetHash: string;\n documentManifestContainerPathCount: number;\n documentManifestHistoryCount: number;\n linkedContainerKeyEpochCount: number;\n linkedContainerManifestCount: number;\n linkSetManifestHash: string;\n manifestEpoch: number | null;\n previousManifestHash: string | null;\n referencedPrincipalCount: number | null;\n}\n\nexport interface DocumentInfo {\n attachments: DocumentInfoAttachment[];\n local: DocumentInfoLocalDetails;\n remoteInfo: DocumentInfoRemoteDetails | null;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentLinkIntent.js","sourceRoot":"","sources":["documentLinkIntent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { uniqueSortedStrings } from \"../../data/documents/shared/readers\";\nimport { sqlDocumentMoveIntentPersistence } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { sqlDocumentContainerProjectionPersistence as links } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { defaultDocumentsPersistence } from \"../documents\";\nimport { relinkContainerDocumentLocally } from \"./documentLocalRelink\";\nimport type {\n DocumentStructuralMutationHost,\n DocumentStructuralMutationLocalStore,\n DocumentStructuralMutationRuntime,\n SetLinkedContainerIdsForDocument,\n} from \"./documentStructureTypes\";\n\nexport async function addDocumentLinkLocally<TRuntime>(input: {\n currentDocumentStore: DocumentStructuralMutationLocalStore<TRuntime>;\n host: DocumentStructuralMutationHost<TRuntime>;\n note: DocumentSummary & { documentId: string; containerId: string };\n runtime: DocumentStructuralMutationRuntime;\n scheduleSync?: (() => void) | undefined;\n setLinkedContainerIdsForDocument: SetLinkedContainerIdsForDocument;\n targetContainerId: string;\n}): Promise<DocumentSummary | null> {\n const { note, runtime, targetContainerId } = input;\n const persisted = await defaultDocumentsPersistence.loadDocument(\n runtime.infra.execSql,\n note.id,\n );\n if (!persisted) return null;\n const intentId = crypto.randomUUID();\n let linkedContainerIds: readonly string[] = [];\n const linkedNote = await relinkContainerDocumentLocally({\n ...input,\n accessEpoch: persisted.accessEpoch,\n requestSync: false,\n targetContainerId: note.containerId,\n commitSideEffect: async (execSql) => {\n const currentLinks = await links.listLinkedContainerIds(\n execSql,\n note.documentId,\n );\n linkedContainerIds = uniqueSortedStrings([\n ...currentLinks,\n note.containerId,\n targetContainerId,\n ]);\n await sqlDocumentMoveIntentPersistence.enqueueLinkIntent(execSql, {\n id: intentId,\n documentId: note.documentId,\n localId: note.id,\n sourceContainerId: note.containerId,\n targetContainerId,\n });\n await links.replaceDocumentLinks(\n execSql,\n note.documentId,\n linkedContainerIds,\n { moveIntentId: intentId },\n );\n },\n });\n if (!linkedNote) return null;\n input.setLinkedContainerIdsForDocument(note.documentId, linkedContainerIds);\n input.scheduleSync?.();\n runtime.util.log(\n `Container contents: queued note ${note.id} link to ${targetContainerId}`,\n );\n return linkedNote;\n}\n\nexport async function removeDocumentLinkLocally<TRuntime>(\n input: Omit<\n Parameters<typeof addDocumentLinkLocally<TRuntime>>[0],\n \"targetContainerId\"\n > & { removedContainerId: string },\n): Promise<DocumentSummary | null> {\n const { note, runtime, removedContainerId } = input;\n const execSql = runtime.infra.execSql;\n const persisted = await defaultDocumentsPersistence.loadDocument(\n execSql,\n note.id,\n );\n if (!persisted) return null;\n const currentLinks = await links.listLinkedContainerIds(\n execSql,\n note.documentId,\n );\n const remaining = currentLinks.filter((id) => id !== removedContainerId);\n const nextContainerId = remaining.includes(note.containerId)\n ? note.containerId\n : remaining[0];\n if (!nextContainerId || !currentLinks.includes(removedContainerId))\n return null;\n const intentId = crypto.randomUUID();\n let linkedContainerIds: readonly string[] = [];\n const unlinkedNote = await relinkContainerDocumentLocally({\n ...input,\n accessEpoch: persisted.accessEpoch,\n requestSync: false,\n targetContainerId: nextContainerId,\n commitSideEffect: async (transactionExecSql) => {\n linkedContainerIds = (\n await links.listLinkedContainerIds(transactionExecSql, note.documentId)\n ).filter((id) => id !== removedContainerId);\n if (!linkedContainerIds.includes(nextContainerId))\n throw new Error(\"Document placement changed before unlink\");\n await sqlDocumentMoveIntentPersistence.enqueueUnlinkIntent(\n transactionExecSql,\n {\n id: intentId,\n documentId: note.documentId,\n localId: note.id,\n removedContainerId,\n targetContainerId: nextContainerId,\n },\n );\n await links.replaceDocumentLinks(\n transactionExecSql,\n note.documentId,\n linkedContainerIds,\n { moveIntentId: intentId },\n );\n },\n });\n if (!unlinkedNote) return null;\n input.setLinkedContainerIdsForDocument(note.documentId, linkedContainerIds);\n input.scheduleSync?.();\n return unlinkedNote;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documentLinks.js","sourceRoot":"","sources":["documentLinks.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VerifiedDocumentLinkSetManifest } from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n assertDocumentWriterProjectionConsistent,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"../../data/documents/shared/projection\";\nimport { persistedDocumentCreateStateFromWriterProjection } from \"../../data/documents/shared/responses\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport { errorMessage } from \"../../data/shared/errorMessage\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { isDatabaseUnavailableError } from \"../../data/sync/databaseUnavailable\";\nimport {\n type DocumentLinkSetFailureHandler,\n type RelinkRemoteDocumentResult,\n relinkRemoteDocument,\n resolveDocumentCreateAuthor,\n} from \"../documents\";\nimport type { SubtreePurgeRoot } from \"../documents/subtreePurgeScope\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../principals/runtimePolicyWarmer\";\nimport { resolveContainerDocumentMoveUnlinkIds } from \"./documentMoveUnlinkIds\";\nimport type { ContainerContentsWorkflowRuntime } from \"./runtime\";\n\ntype ContainerDocumentLinkApi = Parameters<\n typeof relinkRemoteDocument\n>[0][\"apiClient\"];\ntype ContainerDocumentLinkOperation = Parameters<\n typeof relinkRemoteDocument\n>[0][\"operation\"];\ntype RemoteDocumentPersistedState =\n RelinkRemoteDocumentResult[\"persistedState\"];\n\n// A cold-cache denial must keep its HTTP status: collapsing a 403 to null\n// would leave an access-denied move routinely retriable instead of parking\n// it for the access-restored signal (row 7).\nasync function fetchMoveWriterProjection(input: {\n documentId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n runtime: ContainerDocumentLinkRuntime;\n}): Promise<Awaited<\n ReturnType<ContainerDocumentLinkApi[\"getDocumentWriterProjection\"]>\n> | null> {\n const { apiClient } = input.runtime;\n const result = await apiClient.getDocumentWriterProjectionResult(\n input.documentId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n result.report();\n input.onFailure?.({ message: result.message, status: result.status });\n return null;\n}\n\ninterface ContainerDocumentLinkRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n apiClient: ContainerDocumentLinkApi &\n Pick<\n ContainerContentsWorkflowRuntime[\"apiClient\"],\n \"getPrincipalPolicyPages\" | \"getProjectionPolicyHistoryPages\"\n >;\n}\n\ntype MoveRemoteContainerDocumentStatus = \"complete\" | \"partial\";\n\ninterface MoveRemoteContainerDocumentResult {\n accessEpoch: number | null;\n accessStateHash: string | null;\n linkedContainerIds: readonly string[];\n nextContainerId: string;\n remoteState: RemoteDocumentPersistedState | null;\n status: MoveRemoteContainerDocumentStatus;\n}\n\nexport type { RemoteDocumentPersistedState };\n\nexport async function initializeDocumentLinksSchema(\n execSql: ExecSql,\n): Promise<void> {\n await sqlDocumentContainerProjectionPersistence.ensureSchema(execSql);\n}\n\nexport async function listDocumentLinkedContainerIds(\n execSql: ExecSql,\n documentId: string,\n): Promise<ReadonlyArray<string>> {\n return sqlDocumentContainerProjectionPersistence.listLinkedContainerIds(\n execSql,\n documentId,\n );\n}\n\nexport async function replaceDocumentLinks(\n execSql: ExecSql,\n documentId: string,\n containerIds: ReadonlyArray<string>,\n): Promise<void> {\n await sqlDocumentContainerProjectionPersistence.replaceDocumentLinks(\n execSql,\n documentId,\n containerIds,\n );\n}\n\nfunction resolveActiveDocumentContainerId(\n linkedContainerIds: ReadonlyArray<string>,\n preferredContainerId: string,\n): string | null {\n if (linkedContainerIds.includes(preferredContainerId)) {\n return preferredContainerId;\n }\n\n return linkedContainerIds[0] ?? null;\n}\n\nfunction containerDocumentMoveResult(input: {\n document: RelinkRemoteDocumentResult;\n nextContainerId: string;\n status: MoveRemoteContainerDocumentStatus;\n}): MoveRemoteContainerDocumentResult {\n return {\n accessEpoch: input.document.plan.state.epoch,\n accessStateHash: input.document.response.accessManifest.manifestHash,\n linkedContainerIds: input.document.linkedContainerIds,\n nextContainerId: input.nextContainerId,\n remoteState: input.document.persistedState,\n status: input.status,\n };\n}\n\nasync function containerDocumentAlreadyMovedResult(input: {\n writerProjection: DocumentWriterProjectionResponse;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerDocumentLinkRuntime;\n isCurrent?: (() => boolean) | undefined;\n linkedContainerIds: readonly string[];\n nextContainerId: string;\n status: MoveRemoteContainerDocumentStatus;\n}): Promise<MoveRemoteContainerDocumentResult> {\n const verified: { head?: VerifiedDocumentLinkSetManifest | undefined } = {};\n await assertDocumentWriterProjectionConsistent(input.writerProjection, {\n execSql: input.runtime.infra.execSql,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.isCurrent,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n onVerifiedAuthorization: (authorization) => {\n verified.head = authorization.documentManifestByHash.get(\n input.writerProjection.documentManifest.manifestHash,\n );\n },\n });\n if (!verified.head)\n throw new Error(\"Move replay lacks a verified document head\");\n return {\n accessEpoch: verified.head.state.epoch,\n accessStateHash: verified.head.manifestHash,\n linkedContainerIds: input.linkedContainerIds,\n nextContainerId: input.nextContainerId,\n remoteState: persistedDocumentCreateStateFromWriterProjection(\n input.writerProjection,\n ),\n status: input.status,\n };\n}\n\n/**\n * Hand a link/unlink/move/purge failure to host diagnostics as a real `Error`.\n * The caller's string-only log line stays the fallback for a host without\n * `logError`, so this never logs a second copy of the same failure.\n */\nfunction reportDocumentLinkMutationFailure(\n util: ContainerDocumentLinkRuntime[\"util\"],\n error: unknown,\n): void {\n // `ApiClient` returns `RequestFailure` objects instead of throwing, so\n // offline and 403/404/409 already left through the `!result` branch: a status\n // filter here would be dead code. Only a database lost mid-flight stays quiet.\n if (!util.logError || isDatabaseUnavailableError(error)) return;\n try {\n // A host logger that throws or rejects must not replace the null result or\n // skip the failure handler below.\n void Promise.resolve(\n util.logError(\"Container contents: document link mutation failed\", error),\n ).catch(() => undefined);\n } catch {\n // Hosts may throw synchronously or return a rejected promise.\n }\n}\n\nexport async function relinkRemoteContainerDocument(input: {\n beforeSubmit?: (() => Promise<boolean>) | undefined;\n documentId: string;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n operation: ContainerDocumentLinkOperation;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot?: Uint8Array | undefined;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<RelinkRemoteDocumentResult | null> {\n const {\n documentId,\n noteId,\n operation,\n resolveProjectionUserKey,\n runtime,\n targetContainerId,\n } = input;\n const author = resolveDocumentCreateAuthor(runtime);\n const targetSecretKey = runtime.crypto.encapsulationKeyPair?.secretKey;\n const execSql = runtime.infra.execSql;\n if (input.isCurrent?.() === false) return null;\n if (!author || !targetSecretKey) {\n runtime.util.log(\n \"Container contents: document mutation skipped because the local key context is unavailable\",\n );\n input.onFailure?.({\n message: \"the local key context is unavailable\",\n status: null,\n });\n return null;\n }\n\n try {\n const result = await relinkRemoteDocument({\n beforeSubmit: input.beforeSubmit,\n apiClient: runtime.apiClient,\n author,\n documentId,\n expectedSubtreeRoot: input.expectedSubtreeRoot,\n execSql,\n onFailure: input.onFailure,\n operation,\n resolveProjectionUserKey,\n rotationSnapshot: input.rotationSnapshot,\n stillCurrent: input.isCurrent,\n targetContainerId,\n targetSecretKey,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!result) {\n runtime.util.log(\n `Container contents: failed to ${operation} note ${noteId} ${operation === \"link\" ? \"to\" : \"from\"} container ${targetContainerId}`,\n );\n return null;\n }\n if (input.isCurrent?.() === false) return null;\n\n await sqlDocumentContainerProjectionPersistence.replaceDocumentLinks(\n execSql,\n documentId,\n result.linkedContainerIds,\n { stillCurrent: input.isCurrent },\n );\n\n return result;\n } catch (error) {\n await reportAndRethrowKeyingVerificationError(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: documentId,\n objectKind: \"document\",\n operation: `document.${operation}`,\n },\n );\n const message = errorMessage(error);\n runtime.util.log(\n `Container contents: failed to ${operation} note ${noteId} ${operation === \"link\" ? \"to\" : \"from\"} container ${targetContainerId}: ${message}`,\n );\n // After the keying rethrow above, so a verification failure keeps its\n // security incident instead of being reported twice, and before the failure\n // handler, so a throwing caller callback cannot swallow the report.\n reportDocumentLinkMutationFailure(runtime.util, error);\n input.onFailure?.({ message, status: null });\n return null;\n }\n}\n\nasync function linkRemoteContainerDocument(input: {\n documentId: string;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<RelinkRemoteDocumentResult | null> {\n return relinkRemoteContainerDocument({\n ...input,\n operation: \"link\",\n });\n}\n\nexport async function unlinkRemoteContainerDocument(input: {\n beforeSubmit?: (() => Promise<boolean>) | undefined;\n documentId: string;\n expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot: Uint8Array;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<RelinkRemoteDocumentResult | null> {\n return relinkRemoteContainerDocument({\n ...input,\n operation: \"unlink\",\n });\n}\n\nexport async function moveRemoteContainerDocument(input: {\n linkOnly?: boolean | undefined;\n additionalLinkContainerIds?: readonly string[] | undefined;\n removedLinkContainerIds?: readonly string[] | undefined;\n currentContainerId: string;\n documentId: string;\n isCurrent?: (() => boolean) | undefined;\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n replaceLinkedContainers?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot: Uint8Array;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n}): Promise<MoveRemoteContainerDocumentResult | null> {\n const {\n documentId,\n noteId,\n resolveProjectionUserKey,\n runtime,\n targetContainerId,\n } = input;\n if (input.isCurrent?.() === false) return null;\n const writerProjection = await fetchMoveWriterProjection({\n documentId,\n onFailure: input.onFailure,\n runtime,\n });\n if (!writerProjection || input.isCurrent?.() === false) {\n return null;\n }\n if (writerProjection.documentId !== documentId)\n throw new Error(\"Move replay document id mismatch\");\n const initialLinkedContainerIds =\n readLinkedContainerIdsFromDocumentManifest(writerProjection);\n\n let latestLinkedContainerIds: readonly string[] = initialLinkedContainerIds;\n let latestDocument: RelinkRemoteDocumentResult | null = null;\n for (const linkTarget of new Set([\n ...(input.linkOnly ? [] : [targetContainerId]),\n ...(input.additionalLinkContainerIds ?? []),\n ])) {\n if (latestLinkedContainerIds.includes(linkTarget)) continue;\n const linkedDocument = await linkRemoteContainerDocument({\n documentId,\n isCurrent: input.isCurrent,\n noteId,\n onFailure: input.onFailure,\n resolveProjectionUserKey,\n runtime,\n targetContainerId: linkTarget,\n });\n if (!linkedDocument || input.isCurrent?.() === false) {\n return null;\n }\n\n latestDocument = linkedDocument;\n latestLinkedContainerIds = linkedDocument.linkedContainerIds;\n }\n\n const unlinkContainerIds = resolveContainerDocumentMoveUnlinkIds({\n ...input,\n linkedContainerIds: latestLinkedContainerIds,\n });\n\n const unlinked = await unlinkMovedDocumentSources({\n ...input,\n latestDocument,\n latestLinkedContainerIds,\n unlinkContainerIds,\n });\n if (!unlinked) return null;\n latestDocument = unlinked.latestDocument;\n latestLinkedContainerIds = unlinked.latestLinkedContainerIds;\n\n const nextContainerId = resolveActiveDocumentContainerId(\n latestLinkedContainerIds,\n targetContainerId,\n );\n if (!nextContainerId) {\n return null;\n }\n\n const status =\n unlinked.failedUnlinkContainerIds.length > 0 ? \"partial\" : \"complete\";\n return latestDocument\n ? containerDocumentMoveResult({\n document: latestDocument,\n nextContainerId,\n status,\n })\n : containerDocumentAlreadyMovedResult({\n writerProjection,\n resolveProjectionUserKey,\n runtime,\n isCurrent: input.isCurrent,\n linkedContainerIds: latestLinkedContainerIds,\n nextContainerId,\n status,\n });\n}\n\n// The unlink half of a move: every source is attempted even when an earlier\n// one fails, so one dead source cannot strand the others; a failed unlink\n// leaves the move \"partial\" for the queue to retry.\nasync function unlinkMovedDocumentSources(input: {\n documentId: string;\n isCurrent?: (() => boolean) | undefined;\n latestDocument: RelinkRemoteDocumentResult | null;\n latestLinkedContainerIds: readonly string[];\n noteId: string;\n onFailure?: DocumentLinkSetFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rotationSnapshot: Uint8Array;\n runtime: ContainerDocumentLinkRuntime;\n targetContainerId: string;\n unlinkContainerIds: readonly string[];\n}): Promise<{\n failedUnlinkContainerIds: readonly string[];\n latestDocument: RelinkRemoteDocumentResult | null;\n latestLinkedContainerIds: readonly string[];\n} | null> {\n const { noteId, runtime, targetContainerId } = input;\n let { latestDocument, latestLinkedContainerIds } = input;\n const failedUnlinkContainerIds: string[] = [];\n for (const unlinkContainerId of input.unlinkContainerIds) {\n if (input.isCurrent?.() === false) return null;\n const unlinkedDocument = await unlinkRemoteContainerDocument({\n documentId: input.documentId,\n isCurrent: input.isCurrent,\n noteId,\n onFailure: input.onFailure,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n rotationSnapshot: input.rotationSnapshot,\n runtime,\n targetContainerId: unlinkContainerId,\n });\n if (input.isCurrent?.() === false) return null;\n if (!unlinkedDocument) {\n failedUnlinkContainerIds.push(unlinkContainerId);\n runtime.util.log(\n `Container contents: note ${noteId} was linked to ${targetContainerId} but failed to unlink from ${unlinkContainerId}`,\n );\n continue;\n }\n\n latestDocument = unlinkedDocument;\n latestLinkedContainerIds = unlinkedDocument.linkedContainerIds;\n }\n return { failedUnlinkContainerIds, latestDocument, latestLinkedContainerIds };\n}\n"]}