@tearleads/client-sdk 0.1.41 → 0.1.43

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 (235) hide show
  1. package/client/Tearleads.js +3 -0
  2. package/client/Tearleads.js.map +1 -1
  3. package/data/blobs/transferPool.js +35 -8
  4. package/data/blobs/transferPool.js.map +1 -1
  5. package/data/containers/shared/projection.js +12 -0
  6. package/data/containers/shared/projection.js.map +1 -1
  7. package/data/documents/blob/shared/types.d.ts +2 -3
  8. package/data/documents/blob/shared/types.js.map +1 -1
  9. package/data/documents/shared/events.js +0 -1
  10. package/data/documents/shared/events.js.map +1 -1
  11. package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js +2 -0
  12. package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +1 -1
  13. package/data/keyingProjectionVerification/checkpointContext.d.ts +12 -0
  14. package/data/keyingProjectionVerification/checkpointContext.js +16 -0
  15. package/data/keyingProjectionVerification/checkpointContext.js.map +1 -1
  16. package/data/keyingProjectionVerification/containerDestinationVerification.js +3 -1
  17. package/data/keyingProjectionVerification/containerDestinationVerification.js.map +1 -1
  18. package/data/keyingProjectionVerification/containerProjectionVerification.js +12 -6
  19. package/data/keyingProjectionVerification/containerProjectionVerification.js.map +1 -1
  20. package/data/keyingProjectionVerification/documentProjectionVerification.js +10 -4
  21. package/data/keyingProjectionVerification/documentProjectionVerification.js.map +1 -1
  22. package/data/persistence/container-contents/containerContentsPersistence.js +6 -22
  23. package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
  24. package/data/persistence/container-contents/containerMetadataMutationPersistence.js +5 -15
  25. package/data/persistence/container-contents/containerMetadataMutationPersistence.js.map +1 -1
  26. package/data/persistence/container-contents/containerPendingUpdatePersistence.js +6 -15
  27. package/data/persistence/container-contents/containerPendingUpdatePersistence.js.map +1 -1
  28. package/data/persistence/container-contents/containerRecoveryPersistence.js +3 -4
  29. package/data/persistence/container-contents/containerRecoveryPersistence.js.map +1 -1
  30. package/data/persistence/container-contents/containerRemovalWork.js +3 -5
  31. package/data/persistence/container-contents/containerRemovalWork.js.map +1 -1
  32. package/data/persistence/container-contents/dormantContainerMetadata.js +1 -5
  33. package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
  34. package/data/persistence/documents/documentsPersistence.js +4 -9
  35. package/data/persistence/documents/documentsPersistence.js.map +1 -1
  36. package/data/persistence/documents/internal/discardDocument.js +1 -2
  37. package/data/persistence/documents/internal/discardDocument.js.map +1 -1
  38. package/data/persistence/documents/internal/documentDeletionPersistence.js +1 -2
  39. package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
  40. package/data/persistence/documents/internal/documentMutationPersistence.js +17 -25
  41. package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
  42. package/data/persistence/documents/internal/orphanSideRows.js +2 -14
  43. package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
  44. package/data/persistence/documents/internal/syncQueuePersistence.js +3 -3
  45. package/data/persistence/documents/internal/syncQueuePersistence.js.map +1 -1
  46. package/data/persistence/keyingCheckpointAdvancePersistence.js +27 -8
  47. package/data/persistence/keyingCheckpointAdvancePersistence.js.map +1 -1
  48. package/data/persistence/verifiedManifestBundlePersistence.d.ts +45 -0
  49. package/data/persistence/verifiedManifestBundlePersistence.js +282 -0
  50. package/data/persistence/verifiedManifestBundlePersistence.js.map +1 -0
  51. package/data/sqlite/documentHistoryPersistence.d.ts +9 -3
  52. package/data/sqlite/documentHistoryPersistence.js +31 -8
  53. package/data/sqlite/documentHistoryPersistence.js.map +1 -1
  54. package/data/sqlite/documentPendingUpdatePersistence.d.ts +58 -11
  55. package/data/sqlite/documentPendingUpdatePersistence.js +137 -63
  56. package/data/sqlite/documentPendingUpdatePersistence.js.map +1 -1
  57. package/data/sqlite/documentPersistence.d.ts +1 -1
  58. package/data/sqlite/documentPersistence.js +1 -1
  59. package/data/sqlite/documentPersistence.js.map +1 -1
  60. package/data/sqlite/documentPersistenceTypes.d.ts +2 -2
  61. package/data/sqlite/documentPersistenceTypes.js.map +1 -1
  62. package/data/sqlite/documentRecordPersistence.js +5 -4
  63. package/data/sqlite/documentRecordPersistence.js.map +1 -1
  64. package/data/sqlite/schema.d.ts +350 -443
  65. package/data/sqlite/schema.js +49 -47
  66. package/data/sqlite/schema.js.map +1 -1
  67. package/data/sqlite/verifiedManifestBundleSchema.d.ts +174 -0
  68. package/data/sqlite/verifiedManifestBundleSchema.js +36 -0
  69. package/data/sqlite/verifiedManifestBundleSchema.js.map +1 -0
  70. package/internal/api-client/ApiClient.d.ts +17 -19
  71. package/internal/api-client/ApiClient.js +10 -11
  72. package/internal/api-client/ApiClient.js.map +1 -1
  73. package/internal/api-client/binaryRequestOperationTransport.d.ts +18 -0
  74. package/internal/api-client/index.d.ts +2 -1
  75. package/internal/api-client/index.js +1 -1
  76. package/internal/api-client/index.js.map +1 -1
  77. package/internal/api-client/operationTransportFactory.d.ts +6 -0
  78. package/internal/api-client/principalHistoryRequest.js +8 -2
  79. package/internal/api-client/principalHistoryRequest.js.map +1 -1
  80. package/internal/api-client/principalHistoryRequestContext.js +15 -5
  81. package/internal/api-client/principalHistoryRequestContext.js.map +1 -1
  82. package/internal/api-client/routes/blobs/get.d.ts +7 -0
  83. package/internal/api-client/routes/blobs/get.js.map +1 -1
  84. package/internal/api-client/routes/blobs/multipart.js +1 -11
  85. package/internal/api-client/routes/blobs/multipart.js.map +1 -1
  86. package/internal/api-client/routes/blobs/multipartUpload.d.ts +14 -0
  87. package/internal/api-client/routes/blobs/multipartUpload.js +94 -43
  88. package/internal/api-client/routes/blobs/multipartUpload.js.map +1 -1
  89. package/internal/api-client/routes/writerProjections.js +6 -3
  90. package/internal/api-client/routes/writerProjections.js.map +1 -1
  91. package/internal/api-client/verifiedManifestCitations.d.ts +23 -0
  92. package/internal/api-client/verifiedManifestCitations.js +60 -0
  93. package/internal/api-client/verifiedManifestCitations.js.map +1 -0
  94. package/internal/api-client/writerProjectionRequests.js +75 -14
  95. package/internal/api-client/writerProjectionRequests.js.map +1 -1
  96. package/internal/crypto/index.d.ts +0 -1
  97. package/internal/crypto/index.js +0 -1
  98. package/internal/crypto/index.js.map +1 -1
  99. package/internal/validators/knownManifestsRefinements.js +5 -0
  100. package/internal/validators/knownManifestsRefinements.js.map +1 -0
  101. package/internal/validators/operation/attachments.d.ts +80 -160
  102. package/internal/validators/operation/auth.d.ts +760 -1664
  103. package/internal/validators/operation/blobDownloads.js +1 -1
  104. package/internal/validators/operation/blobDownloads.js.map +1 -1
  105. package/internal/validators/operation/containerMutations.d.ts +416 -856
  106. package/internal/validators/operation/documentMutations.d.ts +120 -264
  107. package/internal/validators/operation/documentSync.d.ts +40 -80
  108. package/internal/validators/operation/index.d.ts +1 -1
  109. package/internal/validators/operation/index.js +1 -1
  110. package/internal/validators/operation/index.js.map +1 -1
  111. package/internal/validators/operation/multipartBlobs.d.ts +70 -190
  112. package/internal/validators/operation/multipartBlobs.js +2 -24
  113. package/internal/validators/operation/multipartBlobs.js.map +1 -1
  114. package/internal/validators/operation/multipartPartUploads.d.ts +5 -5
  115. package/internal/validators/operation/multipartPartUploads.js +6 -20
  116. package/internal/validators/operation/multipartPartUploads.js.map +1 -1
  117. package/internal/validators/operation/organizations.d.ts +882 -1906
  118. package/internal/validators/operation/principals.d.ts +120 -240
  119. package/internal/validators/operation/registry.d.ts +1 -2
  120. package/internal/validators/operation/registry.js +1 -2
  121. package/internal/validators/operation/registry.js.map +1 -1
  122. package/internal/validators/operation/writerProjections.d.ts +85 -319
  123. package/internal/validators/operation/writerProjections.js +11 -11
  124. package/internal/validators/operation/writerProjections.js.map +1 -1
  125. package/internal/validators/request/blob.d.ts +100 -201
  126. package/internal/validators/request/blob.js +6 -13
  127. package/internal/validators/request/blob.js.map +1 -1
  128. package/internal/validators/request/container.d.ts +136 -272
  129. package/internal/validators/request/container.js +16 -10
  130. package/internal/validators/request/container.js.map +1 -1
  131. package/internal/validators/request/containerManifestRef.d.ts +54 -0
  132. package/internal/validators/request/containerManifestRef.js +28 -0
  133. package/internal/validators/request/containerManifestRef.js.map +1 -0
  134. package/internal/validators/request/containerMetadata.d.ts +160 -368
  135. package/internal/validators/request/document.d.ts +100 -245
  136. package/internal/validators/request/document.js +1 -2
  137. package/internal/validators/request/document.js.map +1 -1
  138. package/internal/validators/request/documentSyncSchema.d.ts +42 -109
  139. package/internal/validators/request/documentSyncSchema.js +8 -25
  140. package/internal/validators/request/documentSyncSchema.js.map +1 -1
  141. package/internal/validators/request/index.d.ts +1 -1
  142. package/internal/validators/request/index.js +1 -1
  143. package/internal/validators/request/index.js.map +1 -1
  144. package/internal/validators/request/organization.d.ts +160 -320
  145. package/internal/validators/request/organizationProvisioning.d.ts +2424 -5312
  146. package/internal/validators/request/principal.d.ts +160 -320
  147. package/internal/validators/request/registration.d.ts +760 -1664
  148. package/internal/validators/response/blob.d.ts +48 -27
  149. package/internal/validators/response/blob.js +3 -10
  150. package/internal/validators/response/blob.js.map +1 -1
  151. package/internal/validators/response/container.d.ts +429 -20
  152. package/internal/validators/response/container.js +40 -5
  153. package/internal/validators/response/container.js.map +1 -1
  154. package/internal/validators/response/documentMutation.d.ts +440 -20
  155. package/internal/validators/response/documentMutation.js +33 -3
  156. package/internal/validators/response/documentMutation.js.map +1 -1
  157. package/internal/validators/response/index.d.ts +4 -3
  158. package/internal/validators/response/index.js +4 -3
  159. package/internal/validators/response/index.js.map +1 -1
  160. package/internal/validators/response/manifestBundleReferences.js +79 -0
  161. package/internal/validators/response/manifestBundleReferences.js.map +1 -0
  162. package/internal/validators/response/writerProjectionWire.d.ts +19 -0
  163. package/internal/validators/response/writerProjectionWire.js +132 -0
  164. package/internal/validators/response/writerProjectionWire.js.map +1 -0
  165. package/internal/validators/schema.js +20 -0
  166. package/internal/validators/schema.js.map +1 -1
  167. package/internal/validators/util/blob.d.ts +7 -0
  168. package/internal/validators/util/blob.js +7 -0
  169. package/internal/validators/util/blob.js.map +1 -1
  170. package/internal/validators/util/blobTransferSchemas.d.ts +41 -0
  171. package/internal/validators/util/blobTransferSchemas.js +39 -0
  172. package/internal/validators/util/blobTransferSchemas.js.map +1 -0
  173. package/internal/validators/util/containerLimits.d.ts +7 -0
  174. package/internal/validators/util/containerLimits.js +7 -0
  175. package/internal/validators/util/containerLimits.js.map +1 -1
  176. package/internal/validators/util/index.d.ts +3 -2
  177. package/internal/validators/util/index.js +3 -2
  178. package/internal/validators/util/index.js.map +1 -1
  179. package/internal/validators/util/knownManifestWire.d.ts +11 -0
  180. package/internal/validators/util/knownManifestWire.js +28 -0
  181. package/internal/validators/util/knownManifestWire.js.map +1 -0
  182. package/internal/validators/writerProjectionRefinements.js +5 -0
  183. package/internal/validators/writerProjectionRefinements.js.map +1 -1
  184. package/package.json +1 -1
  185. package/workflows/blobs/multipartFirstParts.js +82 -0
  186. package/workflows/blobs/multipartFirstParts.js.map +1 -0
  187. package/workflows/blobs/multipartStageResolution.js +83 -0
  188. package/workflows/blobs/multipartStageResolution.js.map +1 -0
  189. package/workflows/blobs/multipartUpload.js +45 -89
  190. package/workflows/blobs/multipartUpload.js.map +1 -1
  191. package/workflows/container-contents/documentPriming.js +2 -1
  192. package/workflows/container-contents/documentPriming.js.map +1 -1
  193. package/workflows/container-contents/documentQueries/sql.js +4 -4
  194. package/workflows/container-contents/documentQueries/sql.js.map +1 -1
  195. package/workflows/container-contents/pendingWrites/deferredTails.js +6 -3
  196. package/workflows/container-contents/pendingWrites/deferredTails.js.map +1 -1
  197. package/workflows/container-contents/pendingWrites/sources.js +2 -1
  198. package/workflows/container-contents/pendingWrites/sources.js.map +1 -1
  199. package/workflows/container-contents/pendingWrites.js +2 -1
  200. package/workflows/container-contents/pendingWrites.js.map +1 -1
  201. package/workflows/containers/child/create.js +3 -3
  202. package/workflows/containers/child/create.js.map +1 -1
  203. package/workflows/containers/child/move.js +2 -2
  204. package/workflows/containers/child/move.js.map +1 -1
  205. package/workflows/containers/child/mutationRequestCore.js +5 -4
  206. package/workflows/containers/child/mutationRequestCore.js.map +1 -1
  207. package/workflows/containers/child/recitePlan.js +3 -2
  208. package/workflows/containers/child/recitePlan.js.map +1 -1
  209. package/workflows/containers/child/sharePlanCore.js +2 -2
  210. package/workflows/containers/child/sharePlanCore.js.map +1 -1
  211. package/workflows/containers/root/create.js +2 -2
  212. package/workflows/containers/root/create.js.map +1 -1
  213. package/workflows/registration/provisioningBootstrapBuilders.d.ts +20 -51
  214. package/workflows/sync/remoteReset.js +11 -9
  215. package/workflows/sync/remoteReset.js.map +1 -1
  216. package/workflows/sync/remoteResetPlans.js +6 -3
  217. package/workflows/sync/remoteResetPlans.js.map +1 -1
  218. package/internal/api-client/projectionHistoryTransport.js +0 -107
  219. package/internal/api-client/projectionHistoryTransport.js.map +0 -1
  220. package/internal/api-client/verifiedProjectionHistory.d.ts +0 -4
  221. package/internal/api-client/verifiedProjectionHistory.js +0 -12
  222. package/internal/api-client/verifiedProjectionHistory.js.map +0 -1
  223. package/internal/crypto/projectionHistory.d.ts +0 -14
  224. package/internal/crypto/projectionHistory.js +0 -90
  225. package/internal/crypto/projectionHistory.js.map +0 -1
  226. package/internal/crypto/projectionHistorySlots.d.ts +0 -13
  227. package/internal/crypto/projectionHistorySlots.js +0 -81
  228. package/internal/crypto/projectionHistorySlots.js.map +0 -1
  229. package/internal/validators/operation/blobTransferSchemas.js +0 -11
  230. package/internal/validators/operation/blobTransferSchemas.js.map +0 -1
  231. package/internal/validators/projectionHistoryRefinements.js +0 -5
  232. package/internal/validators/projectionHistoryRefinements.js.map +0 -1
  233. package/internal/validators/util/projectionHistoryWire.d.ts +0 -23
  234. package/internal/validators/util/projectionHistoryWire.js +0 -33
  235. package/internal/validators/util/projectionHistoryWire.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"containerMetadataMutationPersistence.js","sourceRoot":"","sources":["containerMetadataMutationPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray } from \"drizzle-orm\";\nimport {\n assertHeldContainerBinding,\n heldContainerBinding,\n} from \"../../containers/containerBinding\";\nimport { documentSyncPullContinuationsEqual } from \"../../documents/shared/pullContinuation\";\nimport {\n enqueueDocumentPendingUpdate,\n type PendingUpdateFields,\n} from \"../../sqlite/documentPersistence\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n documentPendingUpdates,\n documentSyncFailures,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport {\n type ContainerRecord,\n loadContainerById,\n} from \"../containers/containerPersistence\";\nimport type {\n ContainerContentsPersistence,\n ContainerMetadataRecord,\n StoredContainerState,\n} from \"./containerContentsPersistenceTypes\";\nimport { settleContainerCreateIntentRevision } from \"./containerCreateIntentSettlement\";\nimport {\n ContainerCreateIntentSupersededError,\n deleteContainerMoveIntentRevision,\n} from \"./containerIntentPersistence\";\nimport {\n getContainerMetadataScope,\n saveContainerContentsContainerRows,\n selectContainerMetadataRecord,\n} from \"./containerMetadataRows\";\nimport { CONTAINER_METADATA_APP_KIND } from \"./dormantContainerMetadata\";\n\nfunction sameNullableValue(\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean {\n return (left ?? null) === (right ?? null);\n}\n\nfunction committedMetadataMutationResult(input: {\n container: ContainerRecord;\n createIntentSettled: boolean;\n moveIntentSettled: boolean;\n}) {\n return {\n committed: true as const,\n container: input.container,\n ...(input.createIntentSettled\n ? { createIntentSettled: true as const }\n : {}),\n ...(input.moveIntentSettled ? { moveIntentSettled: true as const } : {}),\n };\n}\n\nfunction sameMetadataSecurityIdentity(\n current: ContainerMetadataRecord,\n expected: ContainerMetadataRecord,\n): boolean {\n return (\n current.id === expected.id &&\n current.documentId === expected.documentId &&\n current.accessEpoch === expected.accessEpoch &&\n sameNullableValue(current.accessStateHash, expected.accessStateHash) &&\n sameNullableValue(current.contentKeyBundle, expected.contentKeyBundle) &&\n sameNullableValue(\n current.documentKekTargets,\n expected.documentKekTargets,\n ) &&\n sameNullableValue(\n current.documentManifestBundle,\n expected.documentManifestBundle,\n )\n );\n}\n\nfunction sameMetadataRecord(\n current: ContainerMetadataRecord,\n expected: ContainerMetadataRecord,\n): boolean {\n return (\n sameMetadataSecurityIdentity(current, expected) &&\n sameNullableValue(current.lastCommitLsn, expected.lastCommitLsn) &&\n current.metadataUpdates === expected.metadataUpdates &&\n current.snapshotEndVersion === expected.snapshotEndVersion &&\n documentSyncPullContinuationsEqual(\n current.pullContinuation,\n expected.pullContinuation,\n ) &&\n Boolean(current.pullContinuationRecoveryRequired) ===\n Boolean(expected.pullContinuationRecoveryRequired)\n );\n}\n\nfunction sameContainerRecord(\n current: ContainerRecord,\n expected: ContainerRecord,\n): boolean {\n return (\n current.id === expected.id &&\n current.parentId === expected.parentId &&\n current.organizationId === expected.organizationId &&\n current.metadataDocumentId === expected.metadataDocumentId &&\n (current.systemSlot ?? null) === (expected.systemSlot ?? null) &&\n (current.effectiveAccessLevel ?? null) ===\n (expected.effectiveAccessLevel ?? null) &&\n (current.localUpdatedAt ?? null) === (expected.localUpdatedAt ?? null) &&\n (current.serverCreatedAt ?? null) === (expected.serverCreatedAt ?? null) &&\n (current.serverUpdatedAt ?? null) === (expected.serverUpdatedAt ?? null) &&\n current.name === expected.name &&\n (current.icon ?? null) === (expected.icon ?? null)\n );\n}\n\nasync function loadStoredContainerState(\n execSql: Parameters<\n ContainerContentsPersistence[\"loadContainerMetadataState\"]\n >[0],\n containerId: string,\n): Promise<StoredContainerState | null> {\n const container = await loadContainerById(execSql, containerId);\n if (!container) return null;\n return {\n container,\n record: await selectContainerMetadataRecord(execSql, containerId),\n };\n}\n\nasync function deleteAcceptedPendingUpdates(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n ids: readonly string[],\n): Promise<void> {\n const uniqueIds = [...new Set(ids)];\n if (uniqueIds.length === 0) return;\n await tx\n .delete(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, CONTAINER_METADATA_APP_KIND),\n eq(documentPendingUpdates.localId, containerId),\n inArray(documentPendingUpdates.id, uniqueIds),\n ),\n )\n .run();\n}\n\nasync function clearSyncFailure(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n): Promise<void> {\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, CONTAINER_METADATA_APP_KIND),\n eq(documentSyncFailures.localId, containerId),\n ),\n )\n .run();\n}\n\nasync function hasPendingUpdates(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n): Promise<boolean> {\n const rows = await tx\n .select({ id: documentPendingUpdates.id })\n .from(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, CONTAINER_METADATA_APP_KIND),\n eq(documentPendingUpdates.localId, containerId),\n ),\n )\n .limit(1);\n return rows.length > 0;\n}\n\nasync function hasPendingStructuralIntent(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n): Promise<boolean> {\n const pendingCreates = await tx\n .select({ id: containerCreateIntents.id })\n .from(containerCreateIntents)\n .where(\n and(\n eq(containerCreateIntents.containerId, containerId),\n eq(containerCreateIntents.syncStatus, \"pending\"),\n ),\n )\n .limit(1);\n if (pendingCreates.length > 0) return true;\n\n const unsyncedMoves = await tx\n .select({ id: containerMoveIntents.id })\n .from(containerMoveIntents)\n .where(eq(containerMoveIntents.containerId, containerId))\n .limit(1);\n return unsyncedMoves.length > 0;\n}\n\nasync function enqueuePendingUpdate(\n execSql: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[0],\n containerId: string,\n pendingUpdate: PendingUpdateFields | undefined,\n): Promise<void> {\n if (!pendingUpdate) return;\n await enqueueDocumentPendingUpdate(\n execSql,\n getContainerMetadataScope(containerId),\n pendingUpdate,\n );\n}\n\ntype CommitMetadataMutationInput = Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n>[1];\n\nfunction staleServerMutationResult(\n currentState: StoredContainerState | null,\n input: CommitMetadataMutationInput,\n) {\n const incomingServerUpdatedAt =\n input.saveOptions?.serverTimestamps?.updatedAt;\n const hasOlderContainerTimestamp =\n incomingServerUpdatedAt != null &&\n currentState?.container.serverUpdatedAt != null &&\n currentState.container.serverUpdatedAt > incomingServerUpdatedAt;\n const hasOlderMetadataAccessEpoch =\n currentState?.record != null &&\n currentState.record.documentId === input.record.documentId &&\n currentState.record.accessEpoch > input.record.accessEpoch;\n return currentState?.record &&\n (hasOlderContainerTimestamp || hasOlderMetadataAccessEpoch)\n ? {\n committed: false as const,\n currentState,\n staleServerState: true as const,\n }\n : null;\n}\n\nfunction metadataMutationStateMatches(\n currentState: StoredContainerState | null,\n input: CommitMetadataMutationInput,\n): currentState is StoredContainerState & {\n record: ContainerMetadataRecord;\n} {\n return Boolean(\n currentState?.record &&\n sameContainerRecord(currentState.container, input.expectedContainer) &&\n sameMetadataRecord(currentState.record, input.expectedRecord),\n );\n}\n\nasync function rejectMetadataMutationConflict(input: {\n currentState: StoredContainerState | null;\n mutation: CommitMetadataMutationInput;\n tx: ClientSQLiteTransactionScope;\n}) {\n const { currentState, mutation, tx } = input;\n if (\n currentState?.record &&\n mutation.settleAcceptedPendingOnConflict &&\n sameMetadataSecurityIdentity(currentState.record, mutation.expectedRecord)\n ) {\n await deleteAcceptedPendingUpdates(\n tx,\n mutation.container.id,\n mutation.acceptedPendingUpdateIds,\n );\n }\n return { committed: false as const, currentState };\n}\n\nasync function prepareContainerMutationWrite(input: {\n currentContainer: ContainerRecord;\n mutation: CommitMetadataMutationInput;\n tx: ClientSQLiteTransactionScope;\n}): Promise<{ container: ContainerRecord; localUpdatedAt: string }> {\n const { currentContainer, mutation, tx } = input;\n const requestedLocalUpdatedAt =\n mutation.saveOptions?.localUpdatedAt ??\n mutation.saveOptions?.updatedAt ??\n new Date().toISOString();\n const preserveDurableStructure =\n mutation.preserveDurableStructureWhenPending === true &&\n (await hasPendingStructuralIntent(tx, mutation.container.id));\n // Syncing metadata is not a local edit. Preserve the durable edit clock,\n // including an edit another pane made while this request was in flight.\n const localUpdatedAt =\n preserveDurableStructure || mutation.settleAcceptedPendingOnConflict\n ? (currentContainer.localUpdatedAt ?? requestedLocalUpdatedAt)\n : requestedLocalUpdatedAt;\n const structurallyRebasedContainer = preserveDurableStructure\n ? { ...mutation.container, parentId: currentContainer.parentId }\n : mutation.container;\n const didSettleOutgoing =\n mutation.acceptedPendingUpdateIds.length > 0 &&\n !(await hasPendingUpdates(tx, mutation.container.id)) &&\n !(await hasPendingStructuralIntent(tx, mutation.container.id));\n // Only container responses establish the server's structural clock. A\n // metadata acknowledgement supplies no such timestamp; marking it with our\n // wall clock would make later valid listings appear stale forever.\n return {\n container: structurallyRebasedContainer,\n localUpdatedAt: didSettleOutgoing\n ? (currentContainer.serverUpdatedAt ?? localUpdatedAt)\n : localUpdatedAt,\n };\n}\n\n/** Server acknowledgements and listings cannot rebind a held folder. */\nfunction assertMutationKeepsHeldBinding(\n currentState: StoredContainerState & { record: ContainerMetadataRecord },\n input: CommitMetadataMutationInput,\n): void {\n const recordDocumentIds =\n input.record.documentId === currentState.record.documentId\n ? []\n : [input.record.documentId];\n assertHeldContainerBinding(heldContainerBinding(currentState), {\n organizationId: input.container.organizationId,\n metadataDocumentIds: [\n input.container.metadataDocumentId,\n ...recordDocumentIds,\n ],\n });\n}\n\nexport async function commitStoredMetadataMutation(\n execSql: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[0],\n input: Parameters<ContainerContentsPersistence[\"commitMetadataMutation\"]>[1],\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const outcome = await getClientSQLitePersistenceRuntime(\n lockedExecSql,\n ).guardedTransaction(\n async (tx) => {\n const currentState = await loadStoredContainerState(\n lockedExecSql,\n input.container.id,\n );\n const staleServerResult = staleServerMutationResult(\n currentState,\n input,\n );\n if (staleServerResult) return staleServerResult;\n if (!metadataMutationStateMatches(currentState, input)) {\n return rejectMetadataMutationConflict({\n currentState,\n mutation: input,\n tx,\n });\n }\n assertMutationKeepsHeldBinding(currentState, input);\n\n await enqueuePendingUpdate(\n lockedExecSql,\n input.container.id,\n input.pendingUpdate,\n );\n await deleteAcceptedPendingUpdates(\n tx,\n input.container.id,\n input.acceptedPendingUpdateIds,\n );\n if (input.clearSyncFailure) {\n await clearSyncFailure(tx, input.container.id);\n }\n const { container, localUpdatedAt } =\n await prepareContainerMutationWrite({\n currentContainer: currentState.container,\n mutation: input,\n tx,\n });\n const savedContainer = await saveContainerContentsContainerRows({\n container,\n createIntent: input.saveOptions?.createIntent,\n localUpdatedAt,\n moveIntent: input.saveOptions?.moveIntent,\n record: input.record,\n serverTimestamps: input.saveOptions?.serverTimestamps,\n tx,\n });\n if (\n input.createIntentSettlement &&\n (await settleContainerCreateIntentRevision({\n ...input.createIntentSettlement,\n tx,\n })) === \"superseded\"\n ) {\n throw new ContainerCreateIntentSupersededError();\n }\n if (input.moveIntentSettlement) {\n if (\n !(await deleteContainerMoveIntentRevision({\n ...input.moveIntentSettlement,\n tx,\n }))\n ) {\n throw new Error(\n \"Container move intent was superseded before local settlement\",\n );\n }\n }\n return committedMetadataMutationResult({\n container: savedContainer,\n createIntentSettled: input.createIntentSettlement !== undefined,\n moveIntentSettled: input.moveIntentSettlement !== undefined,\n });\n },\n () => !input.stillCurrent || input.stillCurrent(),\n { behavior: \"immediate\" },\n );\n if (outcome.committed && outcome.result) {\n return outcome.result;\n }\n return {\n committed: false as const,\n currentState: await loadStoredContainerState(\n lockedExecSql,\n input.container.id,\n ),\n };\n });\n}\n\nexport async function settleStoredMetadataPendingUpdates(\n execSql: Parameters<\n ContainerContentsPersistence[\"settleAcceptedMetadataPendingUpdates\"]\n >[0],\n input: Parameters<\n ContainerContentsPersistence[\"settleAcceptedMetadataPendingUpdates\"]\n >[1],\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const outcome = await getClientSQLitePersistenceRuntime(\n lockedExecSql,\n ).guardedTransaction(\n async (tx) => {\n const currentState = await loadStoredContainerState(\n lockedExecSql,\n input.containerId,\n );\n if (\n currentState?.record &&\n sameMetadataSecurityIdentity(\n currentState.record,\n input.expectedRecord,\n )\n ) {\n await deleteAcceptedPendingUpdates(\n tx,\n input.containerId,\n input.pendingUpdateIds,\n );\n }\n return currentState;\n },\n () => !input.stillCurrent || input.stillCurrent(),\n { behavior: \"immediate\" },\n );\n return outcome.committed ? outcome.result : null;\n });\n}\n"]}
1
+ {"version":3,"file":"containerMetadataMutationPersistence.js","sourceRoot":"","sources":["containerMetadataMutationPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,kCAAkC,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EACL,wBAAwB,EACxB,wCAAwC,GACzC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,4BAA4B,GAE7B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,iCAAiC,GAClC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAEL,iBAAiB,GAClB,MAAM,oCAAoC,CAAC;AAM5C,OAAO,EAAE,mCAAmC,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EACL,oCAAoC,EACpC,iCAAiC,GAClC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,yBAAyB,EACzB,kCAAkC,EAClC,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE,SAAS,iBAAiB,CACxB,IAA+B,EAC/B,KAAgC;IAEhC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,+BAA+B,CAAC,KAIxC;IACC,OAAO;QACL,SAAS,EAAE,IAAa;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,GAAG,CAAC,KAAK,CAAC,mBAAmB;YAC3B,CAAC,CAAC,EAAE,mBAAmB,EAAE,IAAa,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CACnC,OAAgC,EAChC,QAAiC;IAEjC,OAAO,CACL,OAAO,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE;QAC1B,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;QAC1C,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW;QAC5C,iBAAiB,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,eAAe,CAAC;QACpE,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,CAAC;QACtE,iBAAiB,CACf,OAAO,CAAC,kBAAkB,EAC1B,QAAQ,CAAC,kBAAkB,CAC5B;QACD,iBAAiB,CACf,OAAO,CAAC,sBAAsB,EAC9B,QAAQ,CAAC,sBAAsB,CAChC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,OAAgC,EAChC,QAAiC;IAEjC,OAAO,CACL,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC/C,iBAAiB,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,aAAa,CAAC;QAChE,OAAO,CAAC,eAAe,KAAK,QAAQ,CAAC,eAAe;QACpD,OAAO,CAAC,kBAAkB,KAAK,QAAQ,CAAC,kBAAkB;QAC1D,kCAAkC,CAChC,OAAO,CAAC,gBAAgB,EACxB,QAAQ,CAAC,gBAAgB,CAC1B;QACD,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC;YAC/C,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CACrD,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,OAAwB,EACxB,QAAyB;IAEzB,OAAO,CACL,OAAO,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE;QAC1B,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;QACtC,OAAO,CAAC,cAAc,KAAK,QAAQ,CAAC,cAAc;QAClD,OAAO,CAAC,kBAAkB,KAAK,QAAQ,CAAC,kBAAkB;QAC1D,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC;QAC9D,CAAC,OAAO,CAAC,oBAAoB,IAAI,IAAI,CAAC;YACpC,CAAC,QAAQ,CAAC,oBAAoB,IAAI,IAAI,CAAC;QACzC,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC;QACtE,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC;QACxE,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,IAAI,IAAI,CAAC;QACxE,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;QAC9B,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,CACnD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,OAEI,EACJ,WAAmB;IAEnB,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChE,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO;QACL,SAAS;QACT,MAAM,EAAE,MAAM,6BAA6B,CAAC,OAAO,EAAE,WAAW,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,4BAA4B,CACzC,EAAgC,EAChC,WAAmB,EACnB,GAAsB;IAEtB,MAAM,wCAAwC,CAC5C,EAAE,EACF,yBAAyB,CAAC,WAAW,CAAC,EACtC,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,EAAgC,EAChC,WAAmB;IAEnB,MAAM,EAAE;SACL,MAAM,CAAC,oBAAoB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,CAAC,EAC7D,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,CAC9C,CACF;SACA,GAAG,EAAE,CAAC;AACX,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,EAAgC,EAChC,WAAmB;IAEnB,OAAO,wBAAwB,CAAC,EAAE,EAAE,yBAAyB,CAAC,WAAW,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,EAAgC,EAChC,WAAmB;IAEnB,MAAM,cAAc,GAAG,MAAM,EAAE;SAC5B,MAAM,CAAC,EAAE,EAAE,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC;SACzC,IAAI,CAAC,sBAAsB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,WAAW,EAAE,WAAW,CAAC,EACnD,EAAE,CAAC,sBAAsB,CAAC,UAAU,EAAE,SAAS,CAAC,CACjD,CACF;SACA,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,aAAa,GAAG,MAAM,EAAE;SAC3B,MAAM,CAAC,EAAE,EAAE,EAAE,oBAAoB,CAAC,EAAE,EAAE,CAAC;SACvC,IAAI,CAAC,oBAAoB,CAAC;SAC1B,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;SACxD,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAEI,EACJ,WAAmB,EACnB,aAA8C;IAE9C,IAAI,CAAC,aAAa;QAAE,OAAO;IAC3B,MAAM,4BAA4B,CAChC,OAAO,EACP,yBAAyB,CAAC,WAAW,CAAC,EACtC,aAAa,CACd,CAAC;AACJ,CAAC;AAMD,SAAS,yBAAyB,CAChC,YAAyC,EACzC,KAAkC;IAElC,MAAM,uBAAuB,GAC3B,KAAK,CAAC,WAAW,EAAE,gBAAgB,EAAE,SAAS,CAAC;IACjD,MAAM,0BAA0B,GAC9B,uBAAuB,IAAI,IAAI;QAC/B,YAAY,EAAE,SAAS,CAAC,eAAe,IAAI,IAAI;QAC/C,YAAY,CAAC,SAAS,CAAC,eAAe,GAAG,uBAAuB,CAAC;IACnE,MAAM,2BAA2B,GAC/B,YAAY,EAAE,MAAM,IAAI,IAAI;QAC5B,YAAY,CAAC,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,MAAM,CAAC,UAAU;QAC1D,YAAY,CAAC,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;IAC7D,OAAO,YAAY,EAAE,MAAM;QACzB,CAAC,0BAA0B,IAAI,2BAA2B,CAAC;QAC3D,CAAC,CAAC;YACE,SAAS,EAAE,KAAc;YACzB,YAAY;YACZ,gBAAgB,EAAE,IAAa;SAChC;QACH,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,4BAA4B,CACnC,YAAyC,EACzC,KAAkC;IAIlC,OAAO,OAAO,CACZ,YAAY,EAAE,MAAM;QAClB,mBAAmB,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,iBAAiB,CAAC;QACpE,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAChE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,8BAA8B,CAAC,KAI7C;IACC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC7C,IACE,YAAY,EAAE,MAAM;QACpB,QAAQ,CAAC,+BAA+B;QACxC,4BAA4B,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC1E,CAAC;QACD,MAAM,4BAA4B,CAChC,EAAE,EACF,QAAQ,CAAC,SAAS,CAAC,EAAE,EACrB,QAAQ,CAAC,wBAAwB,CAClC,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,KAAc,EAAE,YAAY,EAAE,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,6BAA6B,CAAC,KAI5C;IACC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IACjD,MAAM,uBAAuB,GAC3B,QAAQ,CAAC,WAAW,EAAE,cAAc;QACpC,QAAQ,CAAC,WAAW,EAAE,SAAS;QAC/B,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3B,MAAM,wBAAwB,GAC5B,QAAQ,CAAC,mCAAmC,KAAK,IAAI;QACrD,CAAC,MAAM,0BAA0B,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IAChE,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,cAAc,GAClB,wBAAwB,IAAI,QAAQ,CAAC,+BAA+B;QAClE,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,IAAI,uBAAuB,CAAC;QAC9D,CAAC,CAAC,uBAAuB,CAAC;IAC9B,MAAM,4BAA4B,GAAG,wBAAwB;QAC3D,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,EAAE;QAChE,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;IACvB,MAAM,iBAAiB,GACrB,QAAQ,CAAC,wBAAwB,CAAC,MAAM,GAAG,CAAC;QAC5C,CAAC,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,MAAM,0BAA0B,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,sEAAsE;IACtE,2EAA2E;IAC3E,mEAAmE;IACnE,OAAO;QACL,SAAS,EAAE,4BAA4B;QACvC,cAAc,EAAE,iBAAiB;YAC/B,CAAC,CAAC,CAAC,gBAAgB,CAAC,eAAe,IAAI,cAAc,CAAC;YACtD,CAAC,CAAC,cAAc;KACnB,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,SAAS,8BAA8B,CACrC,YAAwE,EACxE,KAAkC;IAElC,MAAM,iBAAiB,GACrB,KAAK,CAAC,MAAM,CAAC,UAAU,KAAK,YAAY,CAAC,MAAM,CAAC,UAAU;QACxD,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChC,0BAA0B,CAAC,oBAAoB,CAAC,YAAY,CAAC,EAAE;QAC7D,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc;QAC9C,mBAAmB,EAAE;YACnB,KAAK,CAAC,SAAS,CAAC,kBAAkB;YAClC,GAAG,iBAAiB;SACrB;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAEI,EACJ,KAA4E;IAE5E,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;QAC/D,MAAM,OAAO,GAAG,MAAM,iCAAiC,CACrD,aAAa,CACd,CAAC,kBAAkB,CAClB,KAAK,EAAE,EAAE,EAAE,EAAE;YACX,MAAM,YAAY,GAAG,MAAM,wBAAwB,CACjD,aAAa,EACb,KAAK,CAAC,SAAS,CAAC,EAAE,CACnB,CAAC;YACF,MAAM,iBAAiB,GAAG,yBAAyB,CACjD,YAAY,EACZ,KAAK,CACN,CAAC;YACF,IAAI,iBAAiB;gBAAE,OAAO,iBAAiB,CAAC;YAChD,IAAI,CAAC,4BAA4B,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;gBACvD,OAAO,8BAA8B,CAAC;oBACpC,YAAY;oBACZ,QAAQ,EAAE,KAAK;oBACf,EAAE;iBACH,CAAC,CAAC;YACL,CAAC;YACD,8BAA8B,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;YAEpD,MAAM,oBAAoB,CACxB,aAAa,EACb,KAAK,CAAC,SAAS,CAAC,EAAE,EAClB,KAAK,CAAC,aAAa,CACpB,CAAC;YACF,MAAM,4BAA4B,CAChC,EAAE,EACF,KAAK,CAAC,SAAS,CAAC,EAAE,EAClB,KAAK,CAAC,wBAAwB,CAC/B,CAAC;YACF,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC3B,MAAM,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACjD,CAAC;YACD,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GACjC,MAAM,6BAA6B,CAAC;gBAClC,gBAAgB,EAAE,YAAY,CAAC,SAAS;gBACxC,QAAQ,EAAE,KAAK;gBACf,EAAE;aACH,CAAC,CAAC;YACL,MAAM,cAAc,GAAG,MAAM,kCAAkC,CAAC;gBAC9D,SAAS;gBACT,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE,YAAY;gBAC7C,cAAc;gBACd,UAAU,EAAE,KAAK,CAAC,WAAW,EAAE,UAAU;gBACzC,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,gBAAgB,EAAE,KAAK,CAAC,WAAW,EAAE,gBAAgB;gBACrD,EAAE;aACH,CAAC,CAAC;YACH,IACE,KAAK,CAAC,sBAAsB;gBAC5B,CAAC,MAAM,mCAAmC,CAAC;oBACzC,GAAG,KAAK,CAAC,sBAAsB;oBAC/B,EAAE;iBACH,CAAC,CAAC,KAAK,YAAY,EACpB,CAAC;gBACD,MAAM,IAAI,oCAAoC,EAAE,CAAC;YACnD,CAAC;YACD,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;gBAC/B,IACE,CAAC,CAAC,MAAM,iCAAiC,CAAC;oBACxC,GAAG,KAAK,CAAC,oBAAoB;oBAC7B,EAAE;iBACH,CAAC,CAAC,EACH,CAAC;oBACD,MAAM,IAAI,KAAK,CACb,8DAA8D,CAC/D,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,+BAA+B,CAAC;gBACrC,SAAS,EAAE,cAAc;gBACzB,mBAAmB,EAAE,KAAK,CAAC,sBAAsB,KAAK,SAAS;gBAC/D,iBAAiB,EAAE,KAAK,CAAC,oBAAoB,KAAK,SAAS;aAC5D,CAAC,CAAC;QACL,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,EAAE,EACjD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CAAC;QACF,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,MAAM,CAAC;QACxB,CAAC;QACD,OAAO;YACL,SAAS,EAAE,KAAc;YACzB,YAAY,EAAE,MAAM,wBAAwB,CAC1C,aAAa,EACb,KAAK,CAAC,SAAS,CAAC,EAAE,CACnB;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,OAEI,EACJ,KAEI;IAEJ,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;QAC/D,MAAM,OAAO,GAAG,MAAM,iCAAiC,CACrD,aAAa,CACd,CAAC,kBAAkB,CAClB,KAAK,EAAE,EAAE,EAAE,EAAE;YACX,MAAM,YAAY,GAAG,MAAM,wBAAwB,CACjD,aAAa,EACb,KAAK,CAAC,WAAW,CAClB,CAAC;YACF,IACE,YAAY,EAAE,MAAM;gBACpB,4BAA4B,CAC1B,YAAY,CAAC,MAAM,EACnB,KAAK,CAAC,cAAc,CACrB,EACD,CAAC;gBACD,MAAM,4BAA4B,CAChC,EAAE,EACF,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,gBAAgB,CACvB,CAAC;YACJ,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,EAAE,EACjD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CAAC;QACF,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { and, eq } from \"drizzle-orm\";\nimport {\n assertHeldContainerBinding,\n heldContainerBinding,\n} from \"../../containers/containerBinding\";\nimport { documentSyncPullContinuationsEqual } from \"../../documents/shared/pullContinuation\";\nimport {\n hasQueuedDocumentUpdates,\n settleQueuedDocumentUpdatesInTransaction,\n} from \"../../sqlite/documentPendingUpdatePersistence\";\nimport {\n enqueueDocumentPendingUpdate,\n type PendingUpdateFields,\n} from \"../../sqlite/documentPersistence\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n documentSyncFailures,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport {\n type ContainerRecord,\n loadContainerById,\n} from \"../containers/containerPersistence\";\nimport type {\n ContainerContentsPersistence,\n ContainerMetadataRecord,\n StoredContainerState,\n} from \"./containerContentsPersistenceTypes\";\nimport { settleContainerCreateIntentRevision } from \"./containerCreateIntentSettlement\";\nimport {\n ContainerCreateIntentSupersededError,\n deleteContainerMoveIntentRevision,\n} from \"./containerIntentPersistence\";\nimport {\n getContainerMetadataScope,\n saveContainerContentsContainerRows,\n selectContainerMetadataRecord,\n} from \"./containerMetadataRows\";\nimport { CONTAINER_METADATA_APP_KIND } from \"./dormantContainerMetadata\";\n\nfunction sameNullableValue(\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean {\n return (left ?? null) === (right ?? null);\n}\n\nfunction committedMetadataMutationResult(input: {\n container: ContainerRecord;\n createIntentSettled: boolean;\n moveIntentSettled: boolean;\n}) {\n return {\n committed: true as const,\n container: input.container,\n ...(input.createIntentSettled\n ? { createIntentSettled: true as const }\n : {}),\n ...(input.moveIntentSettled ? { moveIntentSettled: true as const } : {}),\n };\n}\n\nfunction sameMetadataSecurityIdentity(\n current: ContainerMetadataRecord,\n expected: ContainerMetadataRecord,\n): boolean {\n return (\n current.id === expected.id &&\n current.documentId === expected.documentId &&\n current.accessEpoch === expected.accessEpoch &&\n sameNullableValue(current.accessStateHash, expected.accessStateHash) &&\n sameNullableValue(current.contentKeyBundle, expected.contentKeyBundle) &&\n sameNullableValue(\n current.documentKekTargets,\n expected.documentKekTargets,\n ) &&\n sameNullableValue(\n current.documentManifestBundle,\n expected.documentManifestBundle,\n )\n );\n}\n\nfunction sameMetadataRecord(\n current: ContainerMetadataRecord,\n expected: ContainerMetadataRecord,\n): boolean {\n return (\n sameMetadataSecurityIdentity(current, expected) &&\n sameNullableValue(current.lastCommitLsn, expected.lastCommitLsn) &&\n current.metadataUpdates === expected.metadataUpdates &&\n current.snapshotEndVersion === expected.snapshotEndVersion &&\n documentSyncPullContinuationsEqual(\n current.pullContinuation,\n expected.pullContinuation,\n ) &&\n Boolean(current.pullContinuationRecoveryRequired) ===\n Boolean(expected.pullContinuationRecoveryRequired)\n );\n}\n\nfunction sameContainerRecord(\n current: ContainerRecord,\n expected: ContainerRecord,\n): boolean {\n return (\n current.id === expected.id &&\n current.parentId === expected.parentId &&\n current.organizationId === expected.organizationId &&\n current.metadataDocumentId === expected.metadataDocumentId &&\n (current.systemSlot ?? null) === (expected.systemSlot ?? null) &&\n (current.effectiveAccessLevel ?? null) ===\n (expected.effectiveAccessLevel ?? null) &&\n (current.localUpdatedAt ?? null) === (expected.localUpdatedAt ?? null) &&\n (current.serverCreatedAt ?? null) === (expected.serverCreatedAt ?? null) &&\n (current.serverUpdatedAt ?? null) === (expected.serverUpdatedAt ?? null) &&\n current.name === expected.name &&\n (current.icon ?? null) === (expected.icon ?? null)\n );\n}\n\nasync function loadStoredContainerState(\n execSql: Parameters<\n ContainerContentsPersistence[\"loadContainerMetadataState\"]\n >[0],\n containerId: string,\n): Promise<StoredContainerState | null> {\n const container = await loadContainerById(execSql, containerId);\n if (!container) return null;\n return {\n container,\n record: await selectContainerMetadataRecord(execSql, containerId),\n };\n}\n\nasync function deleteAcceptedPendingUpdates(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n ids: readonly string[],\n): Promise<void> {\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n getContainerMetadataScope(containerId),\n ids,\n );\n}\n\nasync function clearSyncFailure(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n): Promise<void> {\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, CONTAINER_METADATA_APP_KIND),\n eq(documentSyncFailures.localId, containerId),\n ),\n )\n .run();\n}\n\nasync function hasPendingUpdates(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n): Promise<boolean> {\n return hasQueuedDocumentUpdates(tx, getContainerMetadataScope(containerId));\n}\n\nasync function hasPendingStructuralIntent(\n tx: ClientSQLiteTransactionScope,\n containerId: string,\n): Promise<boolean> {\n const pendingCreates = await tx\n .select({ id: containerCreateIntents.id })\n .from(containerCreateIntents)\n .where(\n and(\n eq(containerCreateIntents.containerId, containerId),\n eq(containerCreateIntents.syncStatus, \"pending\"),\n ),\n )\n .limit(1);\n if (pendingCreates.length > 0) return true;\n\n const unsyncedMoves = await tx\n .select({ id: containerMoveIntents.id })\n .from(containerMoveIntents)\n .where(eq(containerMoveIntents.containerId, containerId))\n .limit(1);\n return unsyncedMoves.length > 0;\n}\n\nasync function enqueuePendingUpdate(\n execSql: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[0],\n containerId: string,\n pendingUpdate: PendingUpdateFields | undefined,\n): Promise<void> {\n if (!pendingUpdate) return;\n await enqueueDocumentPendingUpdate(\n execSql,\n getContainerMetadataScope(containerId),\n pendingUpdate,\n );\n}\n\ntype CommitMetadataMutationInput = Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n>[1];\n\nfunction staleServerMutationResult(\n currentState: StoredContainerState | null,\n input: CommitMetadataMutationInput,\n) {\n const incomingServerUpdatedAt =\n input.saveOptions?.serverTimestamps?.updatedAt;\n const hasOlderContainerTimestamp =\n incomingServerUpdatedAt != null &&\n currentState?.container.serverUpdatedAt != null &&\n currentState.container.serverUpdatedAt > incomingServerUpdatedAt;\n const hasOlderMetadataAccessEpoch =\n currentState?.record != null &&\n currentState.record.documentId === input.record.documentId &&\n currentState.record.accessEpoch > input.record.accessEpoch;\n return currentState?.record &&\n (hasOlderContainerTimestamp || hasOlderMetadataAccessEpoch)\n ? {\n committed: false as const,\n currentState,\n staleServerState: true as const,\n }\n : null;\n}\n\nfunction metadataMutationStateMatches(\n currentState: StoredContainerState | null,\n input: CommitMetadataMutationInput,\n): currentState is StoredContainerState & {\n record: ContainerMetadataRecord;\n} {\n return Boolean(\n currentState?.record &&\n sameContainerRecord(currentState.container, input.expectedContainer) &&\n sameMetadataRecord(currentState.record, input.expectedRecord),\n );\n}\n\nasync function rejectMetadataMutationConflict(input: {\n currentState: StoredContainerState | null;\n mutation: CommitMetadataMutationInput;\n tx: ClientSQLiteTransactionScope;\n}) {\n const { currentState, mutation, tx } = input;\n if (\n currentState?.record &&\n mutation.settleAcceptedPendingOnConflict &&\n sameMetadataSecurityIdentity(currentState.record, mutation.expectedRecord)\n ) {\n await deleteAcceptedPendingUpdates(\n tx,\n mutation.container.id,\n mutation.acceptedPendingUpdateIds,\n );\n }\n return { committed: false as const, currentState };\n}\n\nasync function prepareContainerMutationWrite(input: {\n currentContainer: ContainerRecord;\n mutation: CommitMetadataMutationInput;\n tx: ClientSQLiteTransactionScope;\n}): Promise<{ container: ContainerRecord; localUpdatedAt: string }> {\n const { currentContainer, mutation, tx } = input;\n const requestedLocalUpdatedAt =\n mutation.saveOptions?.localUpdatedAt ??\n mutation.saveOptions?.updatedAt ??\n new Date().toISOString();\n const preserveDurableStructure =\n mutation.preserveDurableStructureWhenPending === true &&\n (await hasPendingStructuralIntent(tx, mutation.container.id));\n // Syncing metadata is not a local edit. Preserve the durable edit clock,\n // including an edit another pane made while this request was in flight.\n const localUpdatedAt =\n preserveDurableStructure || mutation.settleAcceptedPendingOnConflict\n ? (currentContainer.localUpdatedAt ?? requestedLocalUpdatedAt)\n : requestedLocalUpdatedAt;\n const structurallyRebasedContainer = preserveDurableStructure\n ? { ...mutation.container, parentId: currentContainer.parentId }\n : mutation.container;\n const didSettleOutgoing =\n mutation.acceptedPendingUpdateIds.length > 0 &&\n !(await hasPendingUpdates(tx, mutation.container.id)) &&\n !(await hasPendingStructuralIntent(tx, mutation.container.id));\n // Only container responses establish the server's structural clock. A\n // metadata acknowledgement supplies no such timestamp; marking it with our\n // wall clock would make later valid listings appear stale forever.\n return {\n container: structurallyRebasedContainer,\n localUpdatedAt: didSettleOutgoing\n ? (currentContainer.serverUpdatedAt ?? localUpdatedAt)\n : localUpdatedAt,\n };\n}\n\n/** Server acknowledgements and listings cannot rebind a held folder. */\nfunction assertMutationKeepsHeldBinding(\n currentState: StoredContainerState & { record: ContainerMetadataRecord },\n input: CommitMetadataMutationInput,\n): void {\n const recordDocumentIds =\n input.record.documentId === currentState.record.documentId\n ? []\n : [input.record.documentId];\n assertHeldContainerBinding(heldContainerBinding(currentState), {\n organizationId: input.container.organizationId,\n metadataDocumentIds: [\n input.container.metadataDocumentId,\n ...recordDocumentIds,\n ],\n });\n}\n\nexport async function commitStoredMetadataMutation(\n execSql: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[0],\n input: Parameters<ContainerContentsPersistence[\"commitMetadataMutation\"]>[1],\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const outcome = await getClientSQLitePersistenceRuntime(\n lockedExecSql,\n ).guardedTransaction(\n async (tx) => {\n const currentState = await loadStoredContainerState(\n lockedExecSql,\n input.container.id,\n );\n const staleServerResult = staleServerMutationResult(\n currentState,\n input,\n );\n if (staleServerResult) return staleServerResult;\n if (!metadataMutationStateMatches(currentState, input)) {\n return rejectMetadataMutationConflict({\n currentState,\n mutation: input,\n tx,\n });\n }\n assertMutationKeepsHeldBinding(currentState, input);\n\n await enqueuePendingUpdate(\n lockedExecSql,\n input.container.id,\n input.pendingUpdate,\n );\n await deleteAcceptedPendingUpdates(\n tx,\n input.container.id,\n input.acceptedPendingUpdateIds,\n );\n if (input.clearSyncFailure) {\n await clearSyncFailure(tx, input.container.id);\n }\n const { container, localUpdatedAt } =\n await prepareContainerMutationWrite({\n currentContainer: currentState.container,\n mutation: input,\n tx,\n });\n const savedContainer = await saveContainerContentsContainerRows({\n container,\n createIntent: input.saveOptions?.createIntent,\n localUpdatedAt,\n moveIntent: input.saveOptions?.moveIntent,\n record: input.record,\n serverTimestamps: input.saveOptions?.serverTimestamps,\n tx,\n });\n if (\n input.createIntentSettlement &&\n (await settleContainerCreateIntentRevision({\n ...input.createIntentSettlement,\n tx,\n })) === \"superseded\"\n ) {\n throw new ContainerCreateIntentSupersededError();\n }\n if (input.moveIntentSettlement) {\n if (\n !(await deleteContainerMoveIntentRevision({\n ...input.moveIntentSettlement,\n tx,\n }))\n ) {\n throw new Error(\n \"Container move intent was superseded before local settlement\",\n );\n }\n }\n return committedMetadataMutationResult({\n container: savedContainer,\n createIntentSettled: input.createIntentSettlement !== undefined,\n moveIntentSettled: input.moveIntentSettlement !== undefined,\n });\n },\n () => !input.stillCurrent || input.stillCurrent(),\n { behavior: \"immediate\" },\n );\n if (outcome.committed && outcome.result) {\n return outcome.result;\n }\n return {\n committed: false as const,\n currentState: await loadStoredContainerState(\n lockedExecSql,\n input.container.id,\n ),\n };\n });\n}\n\nexport async function settleStoredMetadataPendingUpdates(\n execSql: Parameters<\n ContainerContentsPersistence[\"settleAcceptedMetadataPendingUpdates\"]\n >[0],\n input: Parameters<\n ContainerContentsPersistence[\"settleAcceptedMetadataPendingUpdates\"]\n >[1],\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const outcome = await getClientSQLitePersistenceRuntime(\n lockedExecSql,\n ).guardedTransaction(\n async (tx) => {\n const currentState = await loadStoredContainerState(\n lockedExecSql,\n input.containerId,\n );\n if (\n currentState?.record &&\n sameMetadataSecurityIdentity(\n currentState.record,\n input.expectedRecord,\n )\n ) {\n await deleteAcceptedPendingUpdates(\n tx,\n input.containerId,\n input.pendingUpdateIds,\n );\n }\n return currentState;\n },\n () => !input.stillCurrent || input.stillCurrent(),\n { behavior: \"immediate\" },\n );\n return outcome.committed ? outcome.result : null;\n });\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { and, asc, eq, inArray, isNotNull } from "drizzle-orm";
2
- import { deleteDocumentPendingUpdate, deleteDocumentPendingUpdates, enqueueDocumentPendingUpdate, listDocumentPendingUpdates, rekeyDocumentPendingUpdate, } from "../../sqlite/documentPersistence.js";
3
- import { documentPendingUpdates, documents } from "../../sqlite/schema.js";
2
+ import { listLocalIdsWithQueuedUpdates } from "../../sqlite/documentPendingUpdatePersistence.js";
3
+ import { enqueueDocumentPendingUpdate, listDocumentPendingUpdates, rekeyDocumentPendingUpdate, settleDocumentPendingUpdate, unqueueDocumentPendingUpdates, } from "../../sqlite/documentPersistence.js";
4
+ import { documents } from "../../sqlite/schema.js";
4
5
  import { getClientSQLitePersistenceRuntime } from "../../sqlite/sqlitePersistenceRuntime.js";
5
6
  import { runSerializedSqlMutation } from "../../sqlite/sqlSchema.js";
6
7
  import { getContainerMetadataScope } from "./containerMetadataRows.js";
@@ -8,12 +9,12 @@ import { CONTAINER_METADATA_APP_KIND } from "./dormantContainerMetadata.js";
8
9
  export const containerPendingUpdatePersistence = {
9
10
  async deletePendingUpdate(execSql, id) {
10
11
  await runSerializedSqlMutation(execSql, async (lockedExecSql) => {
11
- await deleteDocumentPendingUpdate(lockedExecSql, id);
12
+ await settleDocumentPendingUpdate(lockedExecSql, id);
12
13
  });
13
14
  },
14
15
  async deletePendingUpdates(execSql, containerId) {
15
16
  await runSerializedSqlMutation(execSql, async (lockedExecSql) => {
16
- await deleteDocumentPendingUpdates(lockedExecSql, getContainerMetadataScope(containerId));
17
+ await unqueueDocumentPendingUpdates(lockedExecSql, getContainerMetadataScope(containerId));
17
18
  });
18
19
  },
19
20
  async enqueuePendingUpdate(execSql, input) {
@@ -28,17 +29,7 @@ export const containerPendingUpdatePersistence = {
28
29
  return rekeyDocumentPendingUpdate(execSql, id);
29
30
  },
30
31
  async listContainerIdsWithPendingUpdates(execSql, containerIds) {
31
- const uniqueContainerIds = Array.from(new Set(containerIds));
32
- if (uniqueContainerIds.length === 0) {
33
- return [];
34
- }
35
- const { db } = getClientSQLitePersistenceRuntime(execSql);
36
- const rows = await db
37
- .selectDistinct({ containerId: documentPendingUpdates.localId })
38
- .from(documentPendingUpdates)
39
- .where(and(eq(documentPendingUpdates.appKind, CONTAINER_METADATA_APP_KIND), inArray(documentPendingUpdates.localId, uniqueContainerIds)))
40
- .orderBy(asc(documentPendingUpdates.localId));
41
- return rows.map((row) => row.containerId);
32
+ return listLocalIdsWithQueuedUpdates(getClientSQLitePersistenceRuntime(execSql).db, CONTAINER_METADATA_APP_KIND, containerIds);
42
33
  },
43
34
  async listContainerIdsWithPullContinuations(execSql, containerIds) {
44
35
  const uniqueContainerIds = Array.from(new Set(containerIds));
@@ -1 +1 @@
1
- {"version":3,"file":"containerPendingUpdatePersistence.js","sourceRoot":"","sources":["containerPendingUpdatePersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, asc, eq, inArray, isNotNull } from \"drizzle-orm\";\nimport {\n deleteDocumentPendingUpdate,\n deleteDocumentPendingUpdates,\n enqueueDocumentPendingUpdate,\n listDocumentPendingUpdates,\n rekeyDocumentPendingUpdate,\n} from \"../../sqlite/documentPersistence\";\nimport { documentPendingUpdates, documents } from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport type { ContainerContentsPersistence } from \"./containerContentsPersistenceTypes\";\nimport { getContainerMetadataScope } from \"./containerMetadataRows\";\nimport { CONTAINER_METADATA_APP_KIND } from \"./dormantContainerMetadata\";\n\ntype ContainerPendingUpdatePersistence = Pick<\n ContainerContentsPersistence,\n | \"deletePendingUpdate\"\n | \"deletePendingUpdates\"\n | \"enqueuePendingUpdate\"\n | \"listPendingUpdates\"\n | \"rekeyPendingUpdate\"\n | \"listContainerIdsWithPendingUpdates\"\n | \"listContainerIdsWithPullContinuations\"\n>;\n\nexport const containerPendingUpdatePersistence: ContainerPendingUpdatePersistence =\n {\n async deletePendingUpdate(execSql, id) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await deleteDocumentPendingUpdate(lockedExecSql, id);\n });\n },\n async deletePendingUpdates(execSql, containerId) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await deleteDocumentPendingUpdates(\n lockedExecSql,\n getContainerMetadataScope(containerId),\n );\n });\n },\n async enqueuePendingUpdate(execSql, input) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n return enqueueDocumentPendingUpdate(\n lockedExecSql,\n getContainerMetadataScope(input.containerId),\n input,\n );\n });\n },\n async listPendingUpdates(execSql, containerId) {\n return listDocumentPendingUpdates(\n execSql,\n getContainerMetadataScope(containerId),\n );\n },\n async rekeyPendingUpdate(execSql, id) {\n return rekeyDocumentPendingUpdate(execSql, id);\n },\n async listContainerIdsWithPendingUpdates(execSql, containerIds) {\n const uniqueContainerIds = Array.from(new Set(containerIds));\n if (uniqueContainerIds.length === 0) {\n return [];\n }\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .selectDistinct({ containerId: documentPendingUpdates.localId })\n .from(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentPendingUpdates.localId, uniqueContainerIds),\n ),\n )\n .orderBy(asc(documentPendingUpdates.localId));\n\n return rows.map((row) => row.containerId);\n },\n async listContainerIdsWithPullContinuations(execSql, containerIds) {\n const uniqueContainerIds = Array.from(new Set(containerIds));\n if (uniqueContainerIds.length === 0) {\n return [];\n }\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ containerId: documents.localId })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documents.localId, uniqueContainerIds),\n isNotNull(documents.pullContinuation),\n ),\n )\n .orderBy(asc(documents.localId));\n\n return rows.map((row) => row.containerId);\n },\n };\n"]}
1
+ {"version":3,"file":"containerPendingUpdatePersistence.js","sourceRoot":"","sources":["containerPendingUpdatePersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, asc, eq, inArray, isNotNull } from \"drizzle-orm\";\nimport { listLocalIdsWithQueuedUpdates } from \"../../sqlite/documentPendingUpdatePersistence\";\nimport {\n enqueueDocumentPendingUpdate,\n listDocumentPendingUpdates,\n rekeyDocumentPendingUpdate,\n settleDocumentPendingUpdate,\n unqueueDocumentPendingUpdates,\n} from \"../../sqlite/documentPersistence\";\nimport { documents } from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport type { ContainerContentsPersistence } from \"./containerContentsPersistenceTypes\";\nimport { getContainerMetadataScope } from \"./containerMetadataRows\";\nimport { CONTAINER_METADATA_APP_KIND } from \"./dormantContainerMetadata\";\n\ntype ContainerPendingUpdatePersistence = Pick<\n ContainerContentsPersistence,\n | \"deletePendingUpdate\"\n | \"deletePendingUpdates\"\n | \"enqueuePendingUpdate\"\n | \"listPendingUpdates\"\n | \"rekeyPendingUpdate\"\n | \"listContainerIdsWithPendingUpdates\"\n | \"listContainerIdsWithPullContinuations\"\n>;\n\nexport const containerPendingUpdatePersistence: ContainerPendingUpdatePersistence =\n {\n async deletePendingUpdate(execSql, id) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await settleDocumentPendingUpdate(lockedExecSql, id);\n });\n },\n async deletePendingUpdates(execSql, containerId) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await unqueueDocumentPendingUpdates(\n lockedExecSql,\n getContainerMetadataScope(containerId),\n );\n });\n },\n async enqueuePendingUpdate(execSql, input) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n return enqueueDocumentPendingUpdate(\n lockedExecSql,\n getContainerMetadataScope(input.containerId),\n input,\n );\n });\n },\n async listPendingUpdates(execSql, containerId) {\n return listDocumentPendingUpdates(\n execSql,\n getContainerMetadataScope(containerId),\n );\n },\n async rekeyPendingUpdate(execSql, id) {\n return rekeyDocumentPendingUpdate(execSql, id);\n },\n async listContainerIdsWithPendingUpdates(execSql, containerIds) {\n return listLocalIdsWithQueuedUpdates(\n getClientSQLitePersistenceRuntime(execSql).db,\n CONTAINER_METADATA_APP_KIND,\n containerIds,\n );\n },\n async listContainerIdsWithPullContinuations(execSql, containerIds) {\n const uniqueContainerIds = Array.from(new Set(containerIds));\n if (uniqueContainerIds.length === 0) {\n return [];\n }\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ containerId: documents.localId })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documents.localId, uniqueContainerIds),\n isNotNull(documents.pullContinuation),\n ),\n )\n .orderBy(asc(documents.localId));\n\n return rows.map((row) => row.containerId);\n },\n };\n"]}
@@ -23,10 +23,9 @@ async function recoverySnapshot(execSql, containerId, organizationId) {
23
23
  "document_id, recovery_document_id, recovery_generation, snapshot_end_version, pending_base_version",
24
24
  ],
25
25
  ["document_history_checkpoints", "snapshot, end_version_vector"],
26
- ["document_history_updates", "id, update_data, origin"],
27
26
  [
28
- "document_pending_updates",
29
- "id, update_data, partial_start_version_vector, partial_end_version_vector, source_version_vector",
27
+ "document_history_updates",
28
+ "id, update_data, origin, update_id, partial_start_version_vector, partial_end_version_vector, source_version_vector",
30
29
  ],
31
30
  ]) {
32
31
  metadata.push(await execSql(`SELECT ${columns} FROM ${table} WHERE app_kind = 'container-metadata' AND local_id = ? ORDER BY rowid`, [containerId]));
@@ -41,7 +40,7 @@ async function recoverySnapshot(execSql, containerId, organizationId) {
41
40
  const revision = await toFingerprint(new TextEncoder().encode(JSON.stringify([dormant, metadata, creates, moves, links, targets])));
42
41
  return {
43
42
  revision,
44
- pendingUpdateCount: metadata[3]?.length ?? 0,
43
+ pendingUpdateCount: (metadata[2] ?? []).filter((row) => Reflect.get(row, "update_id") !== null).length,
45
44
  hasStructuralIntent: creates.length + moves.length + links.length > 0,
46
45
  };
47
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"containerRecoveryPersistence.js","sourceRoot":"","sources":["containerRecoveryPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAEL,eAAe,EACf,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,+BAA+B,EAAE,MAAM,gCAAgC,CAAC;AACjF,OAAO,EAAE,kCAAkC,EAAE,MAAM,iCAAiC,CAAC;AACrF,OAAO,EAAE,gDAAgD,EAAE,MAAM,6BAA6B,CAAC;AAC/F,OAAO,EAAE,sCAAsC,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,gDAAgD,EAAE,MAAM,4BAA4B,CAAC;AAE9F,6EAA6E;AAC7E,0EAA0E;AAC1E,KAAK,UAAU,gBAAgB,CAC7B,OAAgB,EAChB,WAAmB,EACnB,cAAsB;IAEtB,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,OAAO,CAC7B;;2DAEuD,EACvD,CAAC,WAAW,EAAE,cAAc,EAAE,WAAW,CAAC,CAC3C,CAAC;IACF,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI;QAC7B;YACE,WAAW;YACX,oGAAoG;SACrG;QACD,CAAC,8BAA8B,EAAE,8BAA8B,CAAC;QAChE,CAAC,0BAA0B,EAAE,yBAAyB,CAAC;QACvD;YACE,0BAA0B;YAC1B,kGAAkG;SACnG;KACF,EAAE,CAAC;QACF,QAAQ,CAAC,IAAI,CACX,MAAM,OAAO,CACX,UAAU,OAAO,SAAS,KAAK,wEAAwE,EACvG,CAAC,WAAW,CAAC,CACd,CACF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAC3B,6OAA6O,EAC7O,CAAC,WAAW,CAAC,CACd,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,OAAO,CACzB,wJAAwJ,EACxJ,CAAC,WAAW,CAAC,CACd,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,OAAO,CACzB;4FACwF,EACxF,CAAC,WAAW,EAAE,WAAW,CAAC,CAC3B,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,OAAO,CAC3B;;+HAE2H,EAC3H,CAAC,WAAW,EAAE,WAAW,CAAC,CAC3B,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,IAAI,WAAW,EAAE,CAAC,MAAM,CACtB,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CACpE,CACF,CAAC;IACF,OAAO;QACL,QAAQ;QACR,kBAAkB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC;QAC5C,mBAAmB,EAAE,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;KACtE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAgB,EAChB,cAA6B;IAE7B,IAAI,CAAC,cAAc;QAAE,OAAO,EAAE,CAAC;IAC/B,MAAM,+BAA+B,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5D,MAAM,eAAe,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;IACzD,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CACxD,iCAAiC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAC/D,MAAM,IAAI,GAAG,MAAM,MAAM,CACvB;sDAC8C,EAC9C,CAAC,cAAc,CAAC,CACjB,CAAC;QACF,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;YAC7D,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CACrC,MAAM,EACN,WAAW,EACX,cAAc,CACf,CAAC;YACF,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,MAAM,MAAM,GACV,MAAM,+BAA+B,CAAC,2BAA2B,CAC/D,MAAM,EACN,WAAW,CACZ,CAAC;YACJ,MAAM,CAAC,IAAI,CAAC;gBACV,WAAW;gBACX,cAAc;gBACd,GAAG,QAAQ;gBACX,eAAe,EAAE,MAAM,EAAE,eAAe,IAAI,EAAE;aAC/C,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,OAAgB,EAChB,KAIC;IAED,MAAM,+BAA+B,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5D,MAAM,eAAe,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;IACzD,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CACxD,iCAAiC,CAAC,MAAM,CAAC,CAAC,WAAW,CACnD,KAAK,EAAE,EAAE,EAAE,EAAE;QACX,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,MAAM,EACN,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,cAAc,CACrB,CAAC;QACF,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAClE,MAAM,kCAAkC,CAAC;YACvC,EAAE;YACF,QAAQ,EAAE;gBACR;oBACE,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,MAAM,EAAE,SAAS;oBACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC;aACF;SACF,CAAC,CAAC;QACH,MAAM,gDAAgD,CAAC;YACrD,EAAE;YACF,QAAQ,EAAE;gBACR;oBACE,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,MAAM,EAAE,SAAS;oBACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC;aACF;SACF,CAAC,CAAC;QACH,MAAM,sCAAsC,CAAC;YAC3C,EAAE;YACF,YAAY,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;SAClC,CAAC,CAAC;QACH,MAAM,EAAE;aACL,MAAM,CAAC,sBAAsB,CAAC;aAC9B,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;aAChE,GAAG,EAAE,CAAC;QACT,MAAM,EAAE;aACL,MAAM,CAAC,oBAAoB,CAAC;aAC5B,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;aAC9D,GAAG,EAAE,CAAC;QACT,MAAM,gDAAgD,CAAC,EAAE,EAAE;YACzD,KAAK,CAAC,WAAW;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,EACD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAAgB,EAChB,cAA6B;IAE7B,IAAI,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IAClC,MAAM,+BAA+B,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,MAAM,OAAO,CACxB;gHAC4G,EAC5G,CAAC,cAAc,CAAC,CACjB,CAAC;IACF,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAgB,EAChB,cAA6B;IAE7B,IAAI,CAAC,cAAc;QAAE,OAAO,EAAE,CAAC;IAC/B,MAAM,+BAA+B,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,MAAM,OAAO,CACxB;;;;kBAIc,EACd,CAAC,cAAc,CAAC,CACjB,CAAC;IACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import { toFingerprint } from \"@tearleads/crypto\";\nimport { eq } from \"drizzle-orm\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n documentMoveIntentTables,\n} from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../sqlite/sqlSchema\";\nimport { sqlContainerContentsPersistence } from \"./containerContentsPersistence\";\nimport { recordContainerHydrationTombstones } from \"./containerHydrationPersistence\";\nimport { repairDocumentsForRemovedContainersInTransaction } from \"./containerStructuralRepair\";\nimport { discardLinkIntentsForRemovedContainers } from \"./documentLinkRemovalRepair\";\nimport { deleteContainerMetadataDocumentRowsInTransaction } from \"./dormantContainerMetadata\";\n\n// The token covers all local work the user is agreeing to discard, including\n// shared link intents. A second pane's edit invalidates the confirmation.\nasync function recoverySnapshot(\n execSql: ExecSql,\n containerId: string,\n organizationId: string,\n) {\n const [dormant] = await execSql(\n `SELECT container_id, organization_id FROM dormant_container_metadata\n WHERE container_id = ? AND organization_id = ?\n AND NOT EXISTS (SELECT 1 FROM containers WHERE id = ?)`,\n [containerId, organizationId, containerId],\n );\n if (!dormant) return null;\n const metadata = [];\n for (const [table, columns] of [\n [\n \"documents\",\n \"document_id, recovery_document_id, recovery_generation, snapshot_end_version, pending_base_version\",\n ],\n [\"document_history_checkpoints\", \"snapshot, end_version_vector\"],\n [\"document_history_updates\", \"id, update_data, origin\"],\n [\n \"document_pending_updates\",\n \"id, update_data, partial_start_version_vector, partial_end_version_vector, source_version_vector\",\n ],\n ]) {\n metadata.push(\n await execSql(\n `SELECT ${columns} FROM ${table} WHERE app_kind = 'container-metadata' AND local_id = ? ORDER BY rowid`,\n [containerId],\n ),\n );\n }\n const creates = await execSql(\n \"SELECT id, container_id, parent_container_id, intent_type, remote_container_id, remote_metadata_document_id, remote_metadata_access_state_hash FROM container_create_intents WHERE container_id = ? AND sync_status = 'pending' ORDER BY id\",\n [containerId],\n );\n const moves = await execSql(\n \"SELECT id, container_id, parent_container_id, previous_parent_container_id, intent_type FROM container_move_intents WHERE container_id = ? ORDER BY id\",\n [containerId],\n );\n const links = await execSql(\n `SELECT id, local_id, document_id, target_container_id, source_container_id, replace_linked_containers, intent_type FROM document_move_intents WHERE target_container_id = ? OR id IN\n (SELECT intent_id FROM document_intent_link_targets WHERE container_id = ?) ORDER BY id`,\n [containerId, containerId],\n );\n const targets = await execSql(\n `SELECT intent_id, operation, container_id FROM document_intent_link_targets WHERE intent_id IN\n (SELECT id FROM document_move_intents WHERE target_container_id = ? OR id IN\n (SELECT intent_id FROM document_intent_link_targets WHERE container_id = ?)) ORDER BY intent_id, container_id, operation`,\n [containerId, containerId],\n );\n const revision = await toFingerprint(\n new TextEncoder().encode(\n JSON.stringify([dormant, metadata, creates, moves, links, targets]),\n ),\n );\n return {\n revision,\n pendingUpdateCount: metadata[3]?.length ?? 0,\n hasStructuralIntent: creates.length + moves.length + links.length > 0,\n };\n}\n\nexport async function listRetainedContainerMetadata(\n execSql: ExecSql,\n organizationId: string | null,\n) {\n if (!organizationId) return [];\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, documentMoveIntentTables);\n return runSerializedSqlMutation(execSql, async (locked) =>\n getClientSQLitePersistenceRuntime(locked).transaction(async () => {\n const rows = await locked(\n `SELECT container_id FROM dormant_container_metadata\n WHERE organization_id = ? ORDER BY container_id`,\n [organizationId],\n );\n const result = [];\n for (const row of rows) {\n const containerId = String(Reflect.get(row, \"container_id\"));\n const snapshot = await recoverySnapshot(\n locked,\n containerId,\n organizationId,\n );\n if (!snapshot) continue;\n const record =\n await sqlContainerContentsPersistence.loadContainerMetadataRecord(\n locked,\n containerId,\n );\n result.push({\n containerId,\n organizationId,\n ...snapshot,\n metadataUpdates: record?.metadataUpdates ?? \"\",\n });\n }\n return result;\n }),\n );\n}\n\n/** Explicit local discard, never called by remote discovery. */\nexport async function discardRetainedContainerMetadata(\n execSql: ExecSql,\n input: {\n containerId: string;\n organizationId: string;\n revision: string;\n },\n): Promise<boolean> {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, documentMoveIntentTables);\n return runSerializedSqlMutation(execSql, async (locked) =>\n getClientSQLitePersistenceRuntime(locked).transaction(\n async (tx) => {\n const current = await recoverySnapshot(\n locked,\n input.containerId,\n input.organizationId,\n );\n if (!current || current.revision !== input.revision) return false;\n await recordContainerHydrationTombstones({\n tx,\n removals: [\n {\n containerId: input.containerId,\n reason: \"deleted\",\n updatedAt: new Date().toISOString(),\n },\n ],\n });\n await repairDocumentsForRemovedContainersInTransaction({\n tx,\n removals: [\n {\n containerId: input.containerId,\n reason: \"deleted\",\n updatedAt: new Date().toISOString(),\n },\n ],\n });\n await discardLinkIntentsForRemovedContainers({\n tx,\n containerIds: [input.containerId],\n });\n await tx\n .delete(containerCreateIntents)\n .where(eq(containerCreateIntents.containerId, input.containerId))\n .run();\n await tx\n .delete(containerMoveIntents)\n .where(eq(containerMoveIntents.containerId, input.containerId))\n .run();\n await deleteContainerMetadataDocumentRowsInTransaction(tx, [\n input.containerId,\n ]);\n return true;\n },\n { behavior: \"immediate\" },\n ),\n );\n}\n\nexport async function hasRetainedContainerMetadata(\n execSql: ExecSql,\n organizationId: string | null,\n): Promise<boolean> {\n if (!organizationId) return false;\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n `SELECT 1 FROM dormant_container_metadata d\n WHERE d.organization_id = ? AND NOT EXISTS (SELECT 1 FROM containers c WHERE c.id = d.container_id) LIMIT 1`,\n [organizationId],\n );\n return rows.length > 0;\n}\n\n/** Existing local folders whose queued move points at an unavailable parent. */\nexport async function listRecoveryFolderMoveIds(\n execSql: ExecSql,\n organizationId: string | null,\n): Promise<string[]> {\n if (!organizationId) return [];\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n `SELECT c.id FROM containers c JOIN container_move_intents i\n ON i.container_id = c.id AND i.parent_container_id = c.parent_id\n WHERE c.organization_id = ? AND i.sync_status IN ('pending', 'blocked')\n AND NOT EXISTS (SELECT 1 FROM containers p WHERE p.id = c.parent_id)\n ORDER BY c.id`,\n [organizationId],\n );\n return rows.map((row) => String(Reflect.get(row, \"id\")));\n}\n"]}
1
+ {"version":3,"file":"containerRecoveryPersistence.js","sourceRoot":"","sources":["containerRecoveryPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { toFingerprint } from \"@tearleads/crypto\";\nimport { eq } from \"drizzle-orm\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n documentMoveIntentTables,\n} from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../sqlite/sqlSchema\";\nimport { sqlContainerContentsPersistence } from \"./containerContentsPersistence\";\nimport { recordContainerHydrationTombstones } from \"./containerHydrationPersistence\";\nimport { repairDocumentsForRemovedContainersInTransaction } from \"./containerStructuralRepair\";\nimport { discardLinkIntentsForRemovedContainers } from \"./documentLinkRemovalRepair\";\nimport { deleteContainerMetadataDocumentRowsInTransaction } from \"./dormantContainerMetadata\";\n\n// The token covers all local work the user is agreeing to discard, including\n// shared link intents. A second pane's edit invalidates the confirmation.\nasync function recoverySnapshot(\n execSql: ExecSql,\n containerId: string,\n organizationId: string,\n) {\n const [dormant] = await execSql(\n `SELECT container_id, organization_id FROM dormant_container_metadata\n WHERE container_id = ? AND organization_id = ?\n AND NOT EXISTS (SELECT 1 FROM containers WHERE id = ?)`,\n [containerId, organizationId, containerId],\n );\n if (!dormant) return null;\n const metadata = [];\n for (const [table, columns] of [\n [\n \"documents\",\n \"document_id, recovery_document_id, recovery_generation, snapshot_end_version, pending_base_version\",\n ],\n [\"document_history_checkpoints\", \"snapshot, end_version_vector\"],\n [\n \"document_history_updates\",\n \"id, update_data, origin, update_id, partial_start_version_vector, partial_end_version_vector, source_version_vector\",\n ],\n ]) {\n metadata.push(\n await execSql(\n `SELECT ${columns} FROM ${table} WHERE app_kind = 'container-metadata' AND local_id = ? ORDER BY rowid`,\n [containerId],\n ),\n );\n }\n const creates = await execSql(\n \"SELECT id, container_id, parent_container_id, intent_type, remote_container_id, remote_metadata_document_id, remote_metadata_access_state_hash FROM container_create_intents WHERE container_id = ? AND sync_status = 'pending' ORDER BY id\",\n [containerId],\n );\n const moves = await execSql(\n \"SELECT id, container_id, parent_container_id, previous_parent_container_id, intent_type FROM container_move_intents WHERE container_id = ? ORDER BY id\",\n [containerId],\n );\n const links = await execSql(\n `SELECT id, local_id, document_id, target_container_id, source_container_id, replace_linked_containers, intent_type FROM document_move_intents WHERE target_container_id = ? OR id IN\n (SELECT intent_id FROM document_intent_link_targets WHERE container_id = ?) ORDER BY id`,\n [containerId, containerId],\n );\n const targets = await execSql(\n `SELECT intent_id, operation, container_id FROM document_intent_link_targets WHERE intent_id IN\n (SELECT id FROM document_move_intents WHERE target_container_id = ? OR id IN\n (SELECT intent_id FROM document_intent_link_targets WHERE container_id = ?)) ORDER BY intent_id, container_id, operation`,\n [containerId, containerId],\n );\n const revision = await toFingerprint(\n new TextEncoder().encode(\n JSON.stringify([dormant, metadata, creates, moves, links, targets]),\n ),\n );\n return {\n revision,\n pendingUpdateCount: (metadata[2] ?? []).filter(\n (row) => Reflect.get(row, \"update_id\") !== null,\n ).length,\n hasStructuralIntent: creates.length + moves.length + links.length > 0,\n };\n}\n\nexport async function listRetainedContainerMetadata(\n execSql: ExecSql,\n organizationId: string | null,\n) {\n if (!organizationId) return [];\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, documentMoveIntentTables);\n return runSerializedSqlMutation(execSql, async (locked) =>\n getClientSQLitePersistenceRuntime(locked).transaction(async () => {\n const rows = await locked(\n `SELECT container_id FROM dormant_container_metadata\n WHERE organization_id = ? ORDER BY container_id`,\n [organizationId],\n );\n const result = [];\n for (const row of rows) {\n const containerId = String(Reflect.get(row, \"container_id\"));\n const snapshot = await recoverySnapshot(\n locked,\n containerId,\n organizationId,\n );\n if (!snapshot) continue;\n const record =\n await sqlContainerContentsPersistence.loadContainerMetadataRecord(\n locked,\n containerId,\n );\n result.push({\n containerId,\n organizationId,\n ...snapshot,\n metadataUpdates: record?.metadataUpdates ?? \"\",\n });\n }\n return result;\n }),\n );\n}\n\n/** Explicit local discard, never called by remote discovery. */\nexport async function discardRetainedContainerMetadata(\n execSql: ExecSql,\n input: {\n containerId: string;\n organizationId: string;\n revision: string;\n },\n): Promise<boolean> {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, documentMoveIntentTables);\n return runSerializedSqlMutation(execSql, async (locked) =>\n getClientSQLitePersistenceRuntime(locked).transaction(\n async (tx) => {\n const current = await recoverySnapshot(\n locked,\n input.containerId,\n input.organizationId,\n );\n if (!current || current.revision !== input.revision) return false;\n await recordContainerHydrationTombstones({\n tx,\n removals: [\n {\n containerId: input.containerId,\n reason: \"deleted\",\n updatedAt: new Date().toISOString(),\n },\n ],\n });\n await repairDocumentsForRemovedContainersInTransaction({\n tx,\n removals: [\n {\n containerId: input.containerId,\n reason: \"deleted\",\n updatedAt: new Date().toISOString(),\n },\n ],\n });\n await discardLinkIntentsForRemovedContainers({\n tx,\n containerIds: [input.containerId],\n });\n await tx\n .delete(containerCreateIntents)\n .where(eq(containerCreateIntents.containerId, input.containerId))\n .run();\n await tx\n .delete(containerMoveIntents)\n .where(eq(containerMoveIntents.containerId, input.containerId))\n .run();\n await deleteContainerMetadataDocumentRowsInTransaction(tx, [\n input.containerId,\n ]);\n return true;\n },\n { behavior: \"immediate\" },\n ),\n );\n}\n\nexport async function hasRetainedContainerMetadata(\n execSql: ExecSql,\n organizationId: string | null,\n): Promise<boolean> {\n if (!organizationId) return false;\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n `SELECT 1 FROM dormant_container_metadata d\n WHERE d.organization_id = ? AND NOT EXISTS (SELECT 1 FROM containers c WHERE c.id = d.container_id) LIMIT 1`,\n [organizationId],\n );\n return rows.length > 0;\n}\n\n/** Existing local folders whose queued move points at an unavailable parent. */\nexport async function listRecoveryFolderMoveIds(\n execSql: ExecSql,\n organizationId: string | null,\n): Promise<string[]> {\n if (!organizationId) return [];\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n `SELECT c.id FROM containers c JOIN container_move_intents i\n ON i.container_id = c.id AND i.parent_container_id = c.parent_id\n WHERE c.organization_id = ? AND i.sync_status IN ('pending', 'blocked')\n AND NOT EXISTS (SELECT 1 FROM containers p WHERE p.id = c.parent_id)\n ORDER BY c.id`,\n [organizationId],\n );\n return rows.map((row) => String(Reflect.get(row, \"id\")));\n}\n"]}
@@ -1,12 +1,10 @@
1
1
  import { and, eq, inArray } from "drizzle-orm";
2
+ import { listLocalIdsWithQueuedUpdates } from "../../sqlite/documentPendingUpdatePersistence.js";
2
3
  import { documentIntentLinkTargets } from "../../sqlite/documentPlacementIntentSchema.js";
3
- import { containerCreateIntents, containerMoveIntents, documentMoveIntents, documentPendingUpdates, } from "../../sqlite/schema.js";
4
+ import { containerCreateIntents, containerMoveIntents, documentMoveIntents, } from "../../sqlite/schema.js";
4
5
  /** Only local work makes removed metadata a recovery item; clean cache is disposable. */
5
6
  export async function containerIdsWithRemovalWork(tx, ids) {
6
- const pending = await tx
7
- .select({ id: documentPendingUpdates.localId })
8
- .from(documentPendingUpdates)
9
- .where(and(eq(documentPendingUpdates.appKind, "container-metadata"), inArray(documentPendingUpdates.localId, ids)));
7
+ const pending = (await listLocalIdsWithQueuedUpdates(tx, "container-metadata", ids)).map((id) => ({ id }));
10
8
  const creates = await tx
11
9
  .select({ id: containerCreateIntents.containerId })
12
10
  .from(containerCreateIntents)
@@ -1 +1 @@
1
- {"version":3,"file":"containerRemovalWork.js","sourceRoot":"","sources":["containerRemovalWork.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,EAAgC,EAChC,GAAa;IAEb,MAAM,OAAO,GAAG,MAAM,EAAE;SACrB,MAAM,CAAC,EAAE,EAAE,EAAE,sBAAsB,CAAC,OAAO,EAAE,CAAC;SAC9C,IAAI,CAAC,sBAAsB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,CAAC,EACxD,OAAO,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,CAC7C,CACF,CAAC;IACJ,MAAM,OAAO,GAAG,MAAM,EAAE;SACrB,MAAM,CAAC,EAAE,EAAE,EAAE,sBAAsB,CAAC,WAAW,EAAE,CAAC;SAClD,IAAI,CAAC,sBAAsB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,UAAU,EAAE,SAAS,CAAC,EAChD,OAAO,CAAC,sBAAsB,CAAC,WAAW,EAAE,GAAG,CAAC,CACjD,CACF,CAAC;IACJ,MAAM,KAAK,GAAG,MAAM,EAAE;SACnB,MAAM,CAAC,EAAE,EAAE,EAAE,oBAAoB,CAAC,WAAW,EAAE,CAAC;SAChD,IAAI,CAAC,oBAAoB,CAAC;SAC1B,KAAK,CACJ,GAAG,CACD,OAAO,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,EAChE,OAAO,CAAC,oBAAoB,CAAC,WAAW,EAAE,GAAG,CAAC,CAC/C,CACF,CAAC;IACJ,MAAM,UAAU,GAAG,MAAM,EAAE;SACxB,MAAM,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,iBAAiB,EAAE,CAAC;SACrD,IAAI,CAAC,mBAAmB,CAAC;SACzB,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,MAAM,EAAE;SACnB,MAAM,CAAC,EAAE,EAAE,EAAE,yBAAyB,CAAC,WAAW,EAAE,CAAC;SACrD,IAAI,CAAC,yBAAyB,CAAC;SAC/B,KAAK,CAAC,OAAO,CAAC,yBAAyB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9D,OAAO;QACL,GAAG,IAAI,GAAG,CACR,CAAC,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAC7D,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAChB,CACF;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { and, eq, inArray } from \"drizzle-orm\";\nimport { documentIntentLinkTargets } from \"../../sqlite/documentPlacementIntentSchema\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n documentMoveIntents,\n documentPendingUpdates,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\n\n/** Only local work makes removed metadata a recovery item; clean cache is disposable. */\nexport async function containerIdsWithRemovalWork(\n tx: ClientSQLiteTransactionScope,\n ids: string[],\n): Promise<string[]> {\n const pending = await tx\n .select({ id: documentPendingUpdates.localId })\n .from(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, \"container-metadata\"),\n inArray(documentPendingUpdates.localId, ids),\n ),\n );\n const creates = await tx\n .select({ id: containerCreateIntents.containerId })\n .from(containerCreateIntents)\n .where(\n and(\n eq(containerCreateIntents.syncStatus, \"pending\"),\n inArray(containerCreateIntents.containerId, ids),\n ),\n );\n const moves = await tx\n .select({ id: containerMoveIntents.containerId })\n .from(containerMoveIntents)\n .where(\n and(\n inArray(containerMoveIntents.syncStatus, [\"pending\", \"blocked\"]),\n inArray(containerMoveIntents.containerId, ids),\n ),\n );\n const placements = await tx\n .select({ id: documentMoveIntents.targetContainerId })\n .from(documentMoveIntents)\n .where(inArray(documentMoveIntents.targetContainerId, ids));\n const links = await tx\n .select({ id: documentIntentLinkTargets.containerId })\n .from(documentIntentLinkTargets)\n .where(inArray(documentIntentLinkTargets.containerId, ids));\n return [\n ...new Set(\n [...pending, ...creates, ...moves, ...placements, ...links].map(\n (row) => row.id,\n ),\n ),\n ];\n}\n"]}
1
+ {"version":3,"file":"containerRemovalWork.js","sourceRoot":"","sources":["containerRemovalWork.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,6BAA6B,EAAE,MAAM,+CAA+C,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,EAAgC,EAChC,GAAa;IAEb,MAAM,OAAO,GAAG,CACd,MAAM,6BAA6B,CAAC,EAAE,EAAE,oBAAoB,EAAE,GAAG,CAAC,CACnE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,EAAE;SACrB,MAAM,CAAC,EAAE,EAAE,EAAE,sBAAsB,CAAC,WAAW,EAAE,CAAC;SAClD,IAAI,CAAC,sBAAsB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,UAAU,EAAE,SAAS,CAAC,EAChD,OAAO,CAAC,sBAAsB,CAAC,WAAW,EAAE,GAAG,CAAC,CACjD,CACF,CAAC;IACJ,MAAM,KAAK,GAAG,MAAM,EAAE;SACnB,MAAM,CAAC,EAAE,EAAE,EAAE,oBAAoB,CAAC,WAAW,EAAE,CAAC;SAChD,IAAI,CAAC,oBAAoB,CAAC;SAC1B,KAAK,CACJ,GAAG,CACD,OAAO,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,EAChE,OAAO,CAAC,oBAAoB,CAAC,WAAW,EAAE,GAAG,CAAC,CAC/C,CACF,CAAC;IACJ,MAAM,UAAU,GAAG,MAAM,EAAE;SACxB,MAAM,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,iBAAiB,EAAE,CAAC;SACrD,IAAI,CAAC,mBAAmB,CAAC;SACzB,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,MAAM,EAAE;SACnB,MAAM,CAAC,EAAE,EAAE,EAAE,yBAAyB,CAAC,WAAW,EAAE,CAAC;SACrD,IAAI,CAAC,yBAAyB,CAAC;SAC/B,KAAK,CAAC,OAAO,CAAC,yBAAyB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9D,OAAO;QACL,GAAG,IAAI,GAAG,CACR,CAAC,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAC7D,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAChB,CACF;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { and, eq, inArray } from \"drizzle-orm\";\nimport { listLocalIdsWithQueuedUpdates } from \"../../sqlite/documentPendingUpdatePersistence\";\nimport { documentIntentLinkTargets } from \"../../sqlite/documentPlacementIntentSchema\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n documentMoveIntents,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\n\n/** Only local work makes removed metadata a recovery item; clean cache is disposable. */\nexport async function containerIdsWithRemovalWork(\n tx: ClientSQLiteTransactionScope,\n ids: string[],\n): Promise<string[]> {\n const pending = (\n await listLocalIdsWithQueuedUpdates(tx, \"container-metadata\", ids)\n ).map((id) => ({ id }));\n const creates = await tx\n .select({ id: containerCreateIntents.containerId })\n .from(containerCreateIntents)\n .where(\n and(\n eq(containerCreateIntents.syncStatus, \"pending\"),\n inArray(containerCreateIntents.containerId, ids),\n ),\n );\n const moves = await tx\n .select({ id: containerMoveIntents.containerId })\n .from(containerMoveIntents)\n .where(\n and(\n inArray(containerMoveIntents.syncStatus, [\"pending\", \"blocked\"]),\n inArray(containerMoveIntents.containerId, ids),\n ),\n );\n const placements = await tx\n .select({ id: documentMoveIntents.targetContainerId })\n .from(documentMoveIntents)\n .where(inArray(documentMoveIntents.targetContainerId, ids));\n const links = await tx\n .select({ id: documentIntentLinkTargets.containerId })\n .from(documentIntentLinkTargets)\n .where(inArray(documentIntentLinkTargets.containerId, ids));\n return [\n ...new Set(\n [...pending, ...creates, ...moves, ...placements, ...links].map(\n (row) => row.id,\n ),\n ),\n ];\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { and, eq, inArray, sql } from "drizzle-orm";
2
- import { documentHistoryCheckpoints, documentHistoryUpdates, documentPendingUpdates, documentSyncFailures, documents, dormantContainerMetadata, } from "../../sqlite/schema.js";
2
+ import { documentHistoryCheckpoints, documentHistoryUpdates, documentSyncFailures, documents, dormantContainerMetadata, } from "../../sqlite/schema.js";
3
3
  export const CONTAINER_METADATA_APP_KIND = "container-metadata";
4
4
  export async function retainDormantContainerMetadataInTransaction(tx, retained) {
5
5
  if (retained.length === 0) {
@@ -44,10 +44,6 @@ export async function deleteContainerMetadataDocumentRowsInTransaction(tx, conta
44
44
  .delete(documentHistoryUpdates)
45
45
  .where(and(eq(documentHistoryUpdates.appKind, CONTAINER_METADATA_APP_KIND), inArray(documentHistoryUpdates.localId, ids)))
46
46
  .run();
47
- await tx
48
- .delete(documentPendingUpdates)
49
- .where(and(eq(documentPendingUpdates.appKind, CONTAINER_METADATA_APP_KIND), inArray(documentPendingUpdates.localId, ids)))
50
- .run();
51
47
  await tx
52
48
  .delete(documentSyncFailures)
53
49
  .where(and(eq(documentSyncFailures.appKind, CONTAINER_METADATA_APP_KIND), inArray(documentSyncFailures.localId, ids)))
@@ -1 +1 @@
1
- {"version":3,"file":"dormantContainerMetadata.js","sourceRoot":"","sources":["dormantContainerMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray, sql } from \"drizzle-orm\";\nimport {\n documentHistoryCheckpoints,\n documentHistoryUpdates,\n documentPendingUpdates,\n documentSyncFailures,\n documents,\n dormantContainerMetadata,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\n\nexport const CONTAINER_METADATA_APP_KIND = \"container-metadata\";\n\ninterface DormantContainerMetadataRetention {\n readonly containerId: string;\n readonly organizationId: string;\n readonly retainedAt: string;\n}\n\nexport async function retainDormantContainerMetadataInTransaction(\n tx: ClientSQLiteTransactionScope,\n retained: ReadonlyArray<DormantContainerMetadataRetention>,\n): Promise<void> {\n if (retained.length === 0) {\n return;\n }\n\n await tx\n .insert(dormantContainerMetadata)\n .values([...retained])\n .onConflictDoUpdate({\n target: dormantContainerMetadata.containerId,\n set: {\n organizationId: sql`excluded.organization_id`,\n retainedAt: sql`excluded.retained_at`,\n },\n })\n .run();\n}\n\nexport async function clearDormantContainerMetadataInTransaction(\n tx: ClientSQLiteTransactionScope,\n containerIds: ReadonlyArray<string>,\n): Promise<void> {\n if (containerIds.length === 0) {\n return;\n }\n await tx\n .delete(dormantContainerMetadata)\n .where(inArray(dormantContainerMetadata.containerId, [...containerIds]))\n .run();\n}\n\n/** Delete every durable row owned by a container-metadata document scope. */\nexport async function deleteContainerMetadataDocumentRowsInTransaction(\n tx: ClientSQLiteTransactionScope,\n containerIds: ReadonlyArray<string>,\n): Promise<void> {\n const ids = [...containerIds];\n if (ids.length === 0) {\n return;\n }\n await tx\n .delete(documents)\n .where(\n and(\n eq(documents.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documents.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentHistoryCheckpoints)\n .where(\n and(\n eq(documentHistoryCheckpoints.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentHistoryCheckpoints.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentHistoryUpdates)\n .where(\n and(\n eq(documentHistoryUpdates.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentHistoryUpdates.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentPendingUpdates.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentSyncFailures.localId, ids),\n ),\n )\n .run();\n await clearDormantContainerMetadataInTransaction(tx, ids);\n}\n"]}
1
+ {"version":3,"file":"dormantContainerMetadata.js","sourceRoot":"","sources":["dormantContainerMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,oBAAoB,EACpB,SAAS,EACT,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,CAAC,MAAM,2BAA2B,GAAG,oBAAoB,CAAC;AAQhE,MAAM,CAAC,KAAK,UAAU,2CAA2C,CAC/D,EAAgC,EAChC,QAA0D;IAE1D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,MAAM,EAAE;SACL,MAAM,CAAC,wBAAwB,CAAC;SAChC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;SACrB,kBAAkB,CAAC;QAClB,MAAM,EAAE,wBAAwB,CAAC,WAAW;QAC5C,GAAG,EAAE;YACH,cAAc,EAAE,GAAG,CAAA,0BAA0B;YAC7C,UAAU,EAAE,GAAG,CAAA,sBAAsB;SACtC;KACF,CAAC;SACD,GAAG,EAAE,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0CAA0C,CAC9D,EAAgC,EAChC,YAAmC;IAEnC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,MAAM,EAAE;SACL,MAAM,CAAC,wBAAwB,CAAC;SAChC,KAAK,CAAC,OAAO,CAAC,wBAAwB,CAAC,WAAW,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;SACvE,GAAG,EAAE,CAAC;AACX,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,gDAAgD,CACpE,EAAgC,EAChC,YAAmC;IAEnC,MAAM,GAAG,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAC9B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,EAAE;SACL,MAAM,CAAC,SAAS,CAAC;SACjB,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,2BAA2B,CAAC,EAClD,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAChC,CACF;SACA,GAAG,EAAE,CAAC;IACT,MAAM,EAAE;SACL,MAAM,CAAC,0BAA0B,CAAC;SAClC,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,CAAC,EACnE,OAAO,CAAC,0BAA0B,CAAC,OAAO,EAAE,GAAG,CAAC,CACjD,CACF;SACA,GAAG,EAAE,CAAC;IACT,MAAM,EAAE;SACL,MAAM,CAAC,sBAAsB,CAAC;SAC9B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,2BAA2B,CAAC,EAC/D,OAAO,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,CAC7C,CACF;SACA,GAAG,EAAE,CAAC;IACT,MAAM,EAAE;SACL,MAAM,CAAC,oBAAoB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,CAAC,EAC7D,OAAO,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,CAC3C,CACF;SACA,GAAG,EAAE,CAAC;IACT,MAAM,0CAA0C,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAC5D,CAAC","sourcesContent":["import { and, eq, inArray, sql } from \"drizzle-orm\";\nimport {\n documentHistoryCheckpoints,\n documentHistoryUpdates,\n documentSyncFailures,\n documents,\n dormantContainerMetadata,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\n\nexport const CONTAINER_METADATA_APP_KIND = \"container-metadata\";\n\ninterface DormantContainerMetadataRetention {\n readonly containerId: string;\n readonly organizationId: string;\n readonly retainedAt: string;\n}\n\nexport async function retainDormantContainerMetadataInTransaction(\n tx: ClientSQLiteTransactionScope,\n retained: ReadonlyArray<DormantContainerMetadataRetention>,\n): Promise<void> {\n if (retained.length === 0) {\n return;\n }\n\n await tx\n .insert(dormantContainerMetadata)\n .values([...retained])\n .onConflictDoUpdate({\n target: dormantContainerMetadata.containerId,\n set: {\n organizationId: sql`excluded.organization_id`,\n retainedAt: sql`excluded.retained_at`,\n },\n })\n .run();\n}\n\nexport async function clearDormantContainerMetadataInTransaction(\n tx: ClientSQLiteTransactionScope,\n containerIds: ReadonlyArray<string>,\n): Promise<void> {\n if (containerIds.length === 0) {\n return;\n }\n await tx\n .delete(dormantContainerMetadata)\n .where(inArray(dormantContainerMetadata.containerId, [...containerIds]))\n .run();\n}\n\n/** Delete every durable row owned by a container-metadata document scope. */\nexport async function deleteContainerMetadataDocumentRowsInTransaction(\n tx: ClientSQLiteTransactionScope,\n containerIds: ReadonlyArray<string>,\n): Promise<void> {\n const ids = [...containerIds];\n if (ids.length === 0) {\n return;\n }\n await tx\n .delete(documents)\n .where(\n and(\n eq(documents.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documents.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentHistoryCheckpoints)\n .where(\n and(\n eq(documentHistoryCheckpoints.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentHistoryCheckpoints.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentHistoryUpdates)\n .where(\n and(\n eq(documentHistoryUpdates.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentHistoryUpdates.localId, ids),\n ),\n )\n .run();\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, CONTAINER_METADATA_APP_KIND),\n inArray(documentSyncFailures.localId, ids),\n ),\n )\n .run();\n await clearDormantContainerMetadataInTransaction(tx, ids);\n}\n"]}
@@ -2,8 +2,9 @@ import { KeyingVerificationError } from "../../../internal/crypto/index.js";
2
2
  import { and, desc, eq, inArray, notInArray, or } from "drizzle-orm";
3
3
  import { DEFAULT_DOCUMENT_KIND } from "../../documents/documentConstants.js";
4
4
  import { HIDDEN_DOCUMENT_SUMMARY_KINDS, } from "../../documents/documentSummary.js";
5
+ import { settleQueuedDocumentUpdatesInTransaction } from "../../sqlite/documentPendingUpdatePersistence.js";
5
6
  import { findLocalIdByDocumentId } from "../../sqlite/documentPersistence.js";
6
- import { documentPendingUpdates, documentProjection, documentPurgeCheckpoints, documents, } from "../../sqlite/schema.js";
7
+ import { documentProjection, documentPurgeCheckpoints, documents, } from "../../sqlite/schema.js";
7
8
  import { getClientSQLitePersistenceRuntime, } from "../../sqlite/sqlitePersistenceRuntime.js";
8
9
  import { runSerializedSqlMutation } from "../../sqlite/sqlSchema.js";
9
10
  import { DOCUMENTS_APP_KIND } from "./internal/constants.js";
@@ -16,7 +17,7 @@ import { loadStoredDocumentWithHistoryRestoreState } from "./internal/documentHi
16
17
  import { commitStoredDocumentMutation, settleStoredDocumentPendingUpdates, } from "./internal/documentMutationPersistence.js";
17
18
  import { documentSummaryJoin, documentSummarySelection, getProjectionUpdatedAt, mapDocumentSummary, toDocumentSummary, } from "./internal/documentProjectionRows.js";
18
19
  import { invalidateStoredDocumentPullContinuation } from "./internal/documentPullContinuationPersistence.js";
19
- import { resolveDocumentSaveTimestamp, saveDocumentRows, } from "./internal/documentRows.js";
20
+ import { getDocumentScope, resolveDocumentSaveTimestamp, saveDocumentRows, } from "./internal/documentRows.js";
20
21
  import { resolvePersistedAccessStateHash, resolvePersistedDocumentRuntimeState, } from "./internal/documentRuntimeState.js";
21
22
  import { loadStoredDocumentStoreState } from "./internal/documentStoreStatePersistence.js";
22
23
  import { listDocumentSummaries } from "./internal/documentSummaryQueries.js";
@@ -188,7 +189,6 @@ export const sqlDocumentsPersistence = {
188
189
  }, { behavior: "immediate" }));
189
190
  },
190
191
  async saveDocumentAndDeletePendingUpdates(execSql, document, pendingUpdateIds, options) {
191
- const uniquePendingUpdateIds = [...new Set(pendingUpdateIds)];
192
192
  return runSerializedSqlMutation(execSql, async (lockedExecSql) => getClientSQLitePersistenceRuntime(lockedExecSql).transaction(async (tx) => {
193
193
  const updatedAt = await resolveDocumentSaveTimestamp({
194
194
  document,
@@ -202,12 +202,7 @@ export const sqlDocumentsPersistence = {
202
202
  });
203
203
  if (!saved)
204
204
  return updatedAt;
205
- if (uniquePendingUpdateIds.length > 0) {
206
- await tx
207
- .delete(documentPendingUpdates)
208
- .where(and(eq(documentPendingUpdates.appKind, DOCUMENTS_APP_KIND), eq(documentPendingUpdates.localId, document.id), inArray(documentPendingUpdates.id, uniquePendingUpdateIds)))
209
- .run();
210
- }
205
+ await settleQueuedDocumentUpdatesInTransaction(tx, getDocumentScope(document.id), pendingUpdateIds);
211
206
  return updatedAt;
212
207
  }, { behavior: "immediate" }));
213
208
  },
@@ -1 +1 @@
1
- {"version":3,"file":"documentsPersistence.js","sourceRoot":"","sources":["documentsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { and, desc, eq, inArray, notInArray, or, type SQL } from \"drizzle-orm\";\nimport { DEFAULT_DOCUMENT_KIND } from \"../../documents/documentConstants\";\nimport {\n type DiscoveredDocumentInput,\n type DocumentSummary,\n HIDDEN_DOCUMENT_SUMMARY_KINDS,\n} from \"../../documents/documentSummary\";\nimport { findLocalIdByDocumentId } from \"../../sqlite/documentPersistence\";\nimport {\n documentPendingUpdates,\n documentProjection,\n documentPurgeCheckpoints,\n documents,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nimport { applyContainerDocumentTombstonesWithExec } from \"./internal/containerDocumentTombstones\";\nimport { createStoredDocumentWithHistoryCheckpoint } from \"./internal/createDocumentWithHistoryCheckpoint\";\nimport { discardStoredDocumentToShell } from \"./internal/discardDocument\";\nimport { resolveDiscoveredDocumentPlacement } from \"./internal/discoveredDocumentPlacement\";\nimport {\n deleteStoredDocument,\n deleteStoredDocumentIfMatches,\n deleteStoredDocumentSideRowsIfAbsent,\n} from \"./internal/documentDeletionPersistence\";\nimport { loadStoredDocumentWithHistoryRestoreState } from \"./internal/documentHistoryStatePersistence\";\nimport {\n commitStoredDocumentMutation,\n settleStoredDocumentPendingUpdates,\n} from \"./internal/documentMutationPersistence\";\nimport {\n documentSummaryJoin,\n documentSummarySelection,\n getProjectionUpdatedAt,\n mapDocumentSummary,\n toDocumentSummary,\n} from \"./internal/documentProjectionRows\";\nimport { invalidateStoredDocumentPullContinuation } from \"./internal/documentPullContinuationPersistence\";\nimport {\n resolveDocumentSaveTimestamp,\n saveDocumentRows,\n} from \"./internal/documentRows\";\nimport {\n resolvePersistedAccessStateHash,\n resolvePersistedDocumentRuntimeState,\n} from \"./internal/documentRuntimeState\";\nimport { loadStoredDocumentStoreState } from \"./internal/documentStoreStatePersistence\";\nimport { listDocumentSummaries } from \"./internal/documentSummaryQueries\";\nimport { ensureDocumentsSchema } from \"./internal/ensureDocumentsSchema\";\nimport { saveHydratedAttachment } from \"./internal/hydratedAttachmentPersistence\";\nimport {\n acknowledgeDocumentOrphanBlobReclaim,\n deleteOrphanedDocumentSideRows,\n isDocumentBlobStorageKeyReferenced,\n listDocumentOrphanBlobReclaims,\n} from \"./internal/orphanSideRows\";\nimport {\n loadPendingCreateSummary,\n mapPendingCreateLocalIds,\n} from \"./internal/pendingCreateAdoption\";\nimport { documentRowQueryPersistence } from \"./internal/rowQueryPersistence\";\nimport { documentSyncQueuePersistence } from \"./internal/syncQueuePersistence\";\nimport type {\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nexport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nexport type {\n AttachmentRemovalRows,\n AttachmentStagingRows,\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n PendingAttachmentUploadIdentity,\n PendingUpdateInsert,\n PendingUpdateRecord,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nconst DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE = \"Syncing document...\";\n\nasync function upsertDiscoveredDocumentWithExec(\n execSql: ExecSql,\n input: DiscoveredDocumentInput,\n pendingCreates: ReadonlyMap<string, string>,\n tx: ClientSQLiteTransactionScope,\n): Promise<DocumentSummary> {\n const [purgeCheckpoint] = await tx\n .select({ documentId: documentPurgeCheckpoints.documentId })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, input.documentId))\n .limit(1);\n if (purgeCheckpoint) {\n throw new KeyingVerificationError(\n \"rollback\",\n \"Document discovery targets a permanently purged document\",\n );\n }\n const existingLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n input.documentId,\n );\n const localId = existingLocalId ?? input.documentId;\n const pendingLocalId = pendingCreates.get(input.documentId);\n if (!existingLocalId && pendingLocalId) {\n const pending = await loadPendingCreateSummary(execSql, pendingLocalId);\n if (!pending) throw new Error(\"Pending create projection is unavailable\");\n return pending;\n }\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n localId,\n );\n const placement = await resolveDiscoveredDocumentPlacement(\n tx,\n existingDocument,\n input,\n );\n\n const nextDocument: StoredDocumentRecord = {\n id: localId,\n documentId: input.documentId,\n documentKind: existingDocument?.documentKind ?? DEFAULT_DOCUMENT_KIND,\n text: existingDocument?.text ?? \"\",\n title: existingDocument?.title ?? DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE,\n snapshotEndVersion: existingDocument?.snapshotEndVersion ?? \"\",\n recoveryGeneration: existingDocument?.recoveryGeneration ?? 0,\n ...placement,\n effectiveAccessLevel:\n input.effectiveAccessLevel ??\n existingDocument?.effectiveAccessLevel ??\n null,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: placement.accessEpoch,\n documentId: input.documentId,\n }),\n };\n\n const saveOptions =\n existingDocument === null || existingDocument === undefined\n ? { updatedAt: input.createdAt }\n : undefined;\n const updatedAt = await resolveDocumentSaveTimestamp({\n document: nextDocument,\n options: saveOptions,\n tx,\n });\n if (!(await saveDocumentRows({ document: nextDocument, tx, updatedAt }))) {\n throw new Error(\"Document recovery generation changed during discovery\");\n }\n\n return toDocumentSummary(nextDocument, updatedAt);\n}\n\nasync function relinkPersistedDocumentWithExec(\n execSql: ExecSql,\n input: RelinkPersistedDocumentInput,\n): Promise<DocumentSummary | null> {\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n input.localId,\n );\n if (!existingDocument) {\n return null;\n }\n\n const nextAccessEpoch = Math.max(\n existingDocument.accessEpoch,\n input.accessEpoch,\n );\n const nextDocument: StoredDocumentRecord = {\n ...existingDocument,\n accessEpoch: nextAccessEpoch,\n accessStateHash: resolvePersistedAccessStateHash(existingDocument, {\n accessEpoch: nextAccessEpoch,\n accessStateHash: input.accessStateHash,\n documentId: input.documentId,\n }),\n containerId: input.containerId,\n documentId: input.documentId,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: nextAccessEpoch,\n documentId: input.documentId,\n }),\n };\n\n await sqlDocumentsPersistence.saveDocument(execSql, nextDocument);\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const updatedAtRows = await db\n .select({ updatedAt: documentProjection.updatedAt })\n .from(documentProjection)\n .where(eq(documentProjection.localId, input.localId))\n .limit(1);\n\n return toDocumentSummary(\n nextDocument,\n getProjectionUpdatedAt(updatedAtRows[0]),\n );\n}\n\nexport async function upsertDiscoveredDocuments(\n execSql: ExecSql,\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const pendingCreates = await mapPendingCreateLocalIds(lockedExecSql);\n const nextSummaries: DocumentSummary[] = [];\n\n for (const input of inputs) {\n nextSummaries.push(\n await upsertDiscoveredDocumentWithExec(\n lockedExecSql,\n input,\n pendingCreates,\n tx,\n ),\n );\n }\n\n return nextSummaries;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function applyContainerDocumentTombstones(\n execSql: ExecSql,\n tombstones: ReadonlyArray<ContainerDocumentTombstoneInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return applyContainerDocumentTombstonesWithExec(lockedExecSql, tombstones);\n });\n}\n\nexport async function listDocumentsByContainerIdsOrDocumentIds(\n execSql: ExecSql,\n input: {\n containerIds: ReadonlyArray<string>;\n documentIds: ReadonlyArray<string>;\n },\n): Promise<DocumentSummary[]> {\n const uniqueContainerIds = Array.from(new Set(input.containerIds));\n const uniqueDocumentIds = Array.from(new Set(input.documentIds));\n if (uniqueContainerIds.length === 0 && uniqueDocumentIds.length === 0) {\n return [];\n }\n\n const filters: SQL[] = [];\n if (uniqueContainerIds.length > 0) {\n filters.push(inArray(documentProjection.containerId, uniqueContainerIds));\n }\n\n if (uniqueDocumentIds.length > 0) {\n filters.push(inArray(documentProjection.documentId, uniqueDocumentIds));\n }\n\n const whereCondition = filters.length === 1 ? filters[0] : or(...filters);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(documentSummarySelection)\n .from(documentProjection)\n .leftJoin(documents, documentSummaryJoin)\n .where(\n and(\n whereCondition,\n notInArray(documentProjection.documentKind, [\n ...HIDDEN_DOCUMENT_SUMMARY_KINDS,\n ]),\n ),\n )\n .orderBy(\n desc(documentProjection.updatedAt),\n desc(documentProjection.localId),\n );\n\n return rows.map(mapDocumentSummary);\n}\n\nexport const sqlDocumentsPersistence: DocumentsPersistence = {\n orphanBlobs: {\n acknowledge: acknowledgeDocumentOrphanBlobReclaim,\n isReferenced: isDocumentBlobStorageKeyReferenced,\n list: listDocumentOrphanBlobReclaims,\n sweep: deleteOrphanedDocumentSideRows,\n },\n ...documentRowQueryPersistence,\n ...documentSyncQueuePersistence,\n supportsAtomicRecoveryHistoryPruning: true,\n saveHydratedAttachment,\n createDocumentWithHistoryCheckpoint:\n createStoredDocumentWithHistoryCheckpoint,\n commitDocumentMutation: (execSql, input, saveClientProjection) =>\n commitStoredDocumentMutation(\n execSql,\n input,\n saveClientProjection,\n sqlDocumentsPersistence.loadDocument,\n ),\n settleAcceptedPendingUpdates: (execSql, input) =>\n settleStoredDocumentPendingUpdates(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n ),\n ensureSchema: ensureDocumentsSchema,\n listDocumentSummaries,\n listDocumentsByContainerIdsOrDocumentIds,\n invalidatePullContinuation: (execSql, input) =>\n invalidateStoredDocumentPullContinuation(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n sqlDocumentsPersistence.loadHistoryRestoreState,\n ),\n loadDocumentWithHistoryRestoreState: (execSql, localId) =>\n loadStoredDocumentWithHistoryRestoreState(\n execSql,\n localId,\n sqlDocumentsPersistence,\n ),\n loadDocumentStoreState: (execSql, localId) =>\n loadStoredDocumentStoreState(execSql, localId, sqlDocumentsPersistence),\n async saveDocument(execSql, document, options) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n async saveDocumentAndDeletePendingUpdates(\n execSql,\n document,\n pendingUpdateIds,\n options,\n ) {\n const uniquePendingUpdateIds = [...new Set(pendingUpdateIds)];\n\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n const saved = await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n if (!saved) return updatedAt;\n if (uniquePendingUpdateIds.length > 0) {\n await tx\n .delete(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, DOCUMENTS_APP_KIND),\n eq(documentPendingUpdates.localId, document.id),\n inArray(documentPendingUpdates.id, uniquePendingUpdateIds),\n ),\n )\n .run();\n }\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n deleteDocument: deleteStoredDocument,\n deleteDocumentIfMatches: deleteStoredDocumentIfMatches,\n deleteDocumentSideRowsIfAbsent: deleteStoredDocumentSideRowsIfAbsent,\n async discardDocumentToShell(\n execSql,\n localId,\n expectedDocumentId,\n documentProjectors,\n ): Promise<DiscardDocumentToShellResult> {\n return discardStoredDocumentToShell({\n documentProjectors,\n execSql,\n expectedDocumentId,\n localId,\n persistence: sqlDocumentsPersistence,\n });\n },\n async upsertDiscoveredDocument(execSql, input) {\n const [nextSummary] = await upsertDiscoveredDocuments(execSql, [input]);\n if (!nextSummary) {\n throw new Error(\"Failed to upsert discovered document\");\n }\n\n return nextSummary;\n },\n async relinkPersistedDocument(execSql, input) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n () => relinkPersistedDocumentWithExec(lockedExecSql, input),\n { behavior: \"immediate\" },\n );\n });\n },\n};\n"]}
1
+ {"version":3,"file":"documentsPersistence.js","sourceRoot":"","sources":["documentsPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAY,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAGL,6BAA6B,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,wCAAwC,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,SAAS,GACV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,iCAAiC,GAClC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAgB,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,wCAAwC,EAAE,MAAM,wCAAwC,CAAC;AAClG,OAAO,EAAE,yCAAyC,EAAE,MAAM,gDAAgD,CAAC;AAC3G,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,kCAAkC,EAAE,MAAM,wCAAwC,CAAC;AAC5F,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,oCAAoC,GACrC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,yCAAyC,EAAE,MAAM,4CAA4C,CAAC;AACvG,OAAO,EACL,4BAA4B,EAC5B,kCAAkC,GACnC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,wCAAwC,EAAE,MAAM,gDAAgD,CAAC;AAC1G,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,+BAA+B,EAC/B,oCAAoC,GACrC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EACL,oCAAoC,EACpC,8BAA8B,EAC9B,kCAAkC,EAClC,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAS/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAgB1D,MAAM,qCAAqC,GAAG,qBAAqB,CAAC;AAEpE,KAAK,UAAU,gCAAgC,CAC7C,OAAgB,EAChB,KAA8B,EAC9B,cAA2C,EAC3C,EAAgC;IAEhC,MAAM,CAAC,eAAe,CAAC,GAAG,MAAM,EAAE;SAC/B,MAAM,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,UAAU,EAAE,CAAC;SAC3D,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;SAChE,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,IAAI,uBAAuB,CAC/B,UAAU,EACV,0DAA0D,CAC3D,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,MAAM,uBAAuB,CACnD,OAAO,EACP,kBAAkB,EAClB,KAAK,CAAC,UAAU,CACjB,CAAC;IACF,MAAM,OAAO,GAAG,eAAe,IAAI,KAAK,CAAC,UAAU,CAAC;IACpD,MAAM,cAAc,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5D,IAAI,CAAC,eAAe,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1E,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,uBAAuB,CAAC,YAAY,CACjE,OAAO,EACP,OAAO,CACR,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,kCAAkC,CACxD,EAAE,EACF,gBAAgB,EAChB,KAAK,CACN,CAAC;IAEF,MAAM,YAAY,GAAyB;QACzC,EAAE,EAAE,OAAO;QACX,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,YAAY,EAAE,gBAAgB,EAAE,YAAY,IAAI,qBAAqB;QACrE,IAAI,EAAE,gBAAgB,EAAE,IAAI,IAAI,EAAE;QAClC,KAAK,EAAE,gBAAgB,EAAE,KAAK,IAAI,qCAAqC;QACvE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,IAAI,EAAE;QAC9D,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,IAAI,CAAC;QAC7D,GAAG,SAAS;QACZ,oBAAoB,EAClB,KAAK,CAAC,oBAAoB;YAC1B,gBAAgB,EAAE,oBAAoB;YACtC,IAAI;QACN,GAAG,oCAAoC,CAAC,gBAAgB,EAAE;YACxD,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;KACH,CAAC;IAEF,MAAM,WAAW,GACf,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,SAAS;QACzD,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE;QAChC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC;QACnD,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,WAAW;QACpB,EAAE;KACH,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,+BAA+B,CAC5C,OAAgB,EAChB,KAAmC;IAEnC,MAAM,gBAAgB,GAAG,MAAM,uBAAuB,CAAC,YAAY,CACjE,OAAO,EACP,KAAK,CAAC,OAAO,CACd,CAAC;IACF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAC9B,gBAAgB,CAAC,WAAW,EAC5B,KAAK,CAAC,WAAW,CAClB,CAAC;IACF,MAAM,YAAY,GAAyB;QACzC,GAAG,gBAAgB;QACnB,WAAW,EAAE,eAAe;QAC5B,eAAe,EAAE,+BAA+B,CAAC,gBAAgB,EAAE;YACjE,WAAW,EAAE,eAAe;YAC5B,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;QACF,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,GAAG,oCAAoC,CAAC,gBAAgB,EAAE;YACxD,WAAW,EAAE,eAAe;YAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;KACH,CAAC;IAEF,MAAM,uBAAuB,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAElE,MAAM,EAAE,EAAE,EAAE,GAAG,iCAAiC,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,MAAM,EAAE;SAC3B,MAAM,CAAC,EAAE,SAAS,EAAE,kBAAkB,CAAC,SAAS,EAAE,CAAC;SACnD,IAAI,CAAC,kBAAkB,CAAC;SACxB,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;SACpD,KAAK,CAAC,CAAC,CAAC,CAAC;IAEZ,OAAO,iBAAiB,CACtB,YAAY,EACZ,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAgB,EAChB,MAA8C;IAE9C,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;QAC/D,MAAM,uBAAuB,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAC1D,OAAO,iCAAiC,CAAC,aAAa,CAAC,CAAC,WAAW,CACjE,KAAK,EAAE,EAAE,EAAE,EAAE;YACX,MAAM,cAAc,GAAG,MAAM,wBAAwB,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,aAAa,GAAsB,EAAE,CAAC;YAE5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,aAAa,CAAC,IAAI,CAChB,MAAM,gCAAgC,CACpC,aAAa,EACb,KAAK,EACL,cAAc,EACd,EAAE,CACH,CACF,CAAC;YACJ,CAAC;YAED,OAAO,aAAa,CAAC;QACvB,CAAC,EACD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,OAAgB,EAChB,UAA0D;IAE1D,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;QAC/D,MAAM,uBAAuB,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAC1D,OAAO,wCAAwC,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAC5D,OAAgB,EAChB,KAGC;IAED,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IACnE,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IACjE,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAU,EAAE,CAAC;IAC1B,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC;IAC1E,MAAM,EAAE,EAAE,EAAE,GAAG,iCAAiC,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,EAAE;SAClB,MAAM,CAAC,wBAAwB,CAAC;SAChC,IAAI,CAAC,kBAAkB,CAAC;SACxB,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;SACxC,KAAK,CACJ,GAAG,CACD,cAAc,EACd,UAAU,CAAC,kBAAkB,CAAC,YAAY,EAAE;QAC1C,GAAG,6BAA6B;KACjC,CAAC,CACH,CACF;SACA,OAAO,CACN,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAClC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CACjC,CAAC;IAEJ,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAyB;IAC3D,WAAW,EAAE;QACX,WAAW,EAAE,oCAAoC;QACjD,YAAY,EAAE,kCAAkC;QAChD,IAAI,EAAE,8BAA8B;QACpC,KAAK,EAAE,8BAA8B;KACtC;IACD,GAAG,2BAA2B;IAC9B,GAAG,4BAA4B;IAC/B,oCAAoC,EAAE,IAAI;IAC1C,sBAAsB;IACtB,mCAAmC,EACjC,yCAAyC;IAC3C,sBAAsB,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,CAC/D,4BAA4B,CAC1B,OAAO,EACP,KAAK,EACL,oBAAoB,EACpB,uBAAuB,CAAC,YAAY,CACrC;IACH,4BAA4B,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAC/C,kCAAkC,CAChC,OAAO,EACP,KAAK,EACL,uBAAuB,CAAC,YAAY,CACrC;IACH,YAAY,EAAE,qBAAqB;IACnC,qBAAqB;IACrB,wCAAwC;IACxC,0BAA0B,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAC7C,wCAAwC,CACtC,OAAO,EACP,KAAK,EACL,uBAAuB,CAAC,YAAY,EACpC,uBAAuB,CAAC,uBAAuB,CAChD;IACH,mCAAmC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CACxD,yCAAyC,CACvC,OAAO,EACP,OAAO,EACP,uBAAuB,CACxB;IACH,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAC3C,4BAA4B,CAAC,OAAO,EAAE,OAAO,EAAE,uBAAuB,CAAC;IACzE,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO;QAC3C,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAC/D,iCAAiC,CAAC,aAAa,CAAC,CAAC,WAAW,CAC1D,KAAK,EAAE,EAAE,EAAE,EAAE;YACX,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC;gBACnD,QAAQ;gBACR,OAAO;gBACP,EAAE;aACH,CAAC,CAAC;YACH,MAAM,gBAAgB,CAAC;gBACrB,QAAQ;gBACR,EAAE;gBACF,SAAS;aACV,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CACF,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,mCAAmC,CACvC,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,OAAO;QAEP,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAC/D,iCAAiC,CAAC,aAAa,CAAC,CAAC,WAAW,CAC1D,KAAK,EAAE,EAAE,EAAE,EAAE;YACX,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC;gBACnD,QAAQ;gBACR,OAAO;gBACP,EAAE;aACH,CAAC,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;gBACnC,QAAQ;gBACR,EAAE;gBACF,SAAS;aACV,CAAC,CAAC;YACH,IAAI,CAAC,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC7B,MAAM,wCAAwC,CAC5C,EAAE,EACF,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAC7B,gBAAgB,CACjB,CAAC;YACF,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,oBAAoB;IACpC,uBAAuB,EAAE,6BAA6B;IACtD,8BAA8B,EAAE,oCAAoC;IACpE,KAAK,CAAC,sBAAsB,CAC1B,OAAO,EACP,OAAO,EACP,kBAAkB,EAClB,kBAAkB;QAElB,OAAO,4BAA4B,CAAC;YAClC,kBAAkB;YAClB,OAAO;YACP,kBAAkB;YAClB,OAAO;YACP,WAAW,EAAE,uBAAuB;SACrC,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,wBAAwB,CAAC,OAAO,EAAE,KAAK;QAC3C,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,uBAAuB,CAAC,OAAO,EAAE,KAAK;QAC1C,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE;YAC/D,MAAM,uBAAuB,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;YAC1D,OAAO,iCAAiC,CAAC,aAAa,CAAC,CAAC,WAAW,CACjE,GAAG,EAAE,CAAC,+BAA+B,CAAC,aAAa,EAAE,KAAK,CAAC,EAC3D,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { and, desc, eq, inArray, notInArray, or, type SQL } from \"drizzle-orm\";\nimport { DEFAULT_DOCUMENT_KIND } from \"../../documents/documentConstants\";\nimport {\n type DiscoveredDocumentInput,\n type DocumentSummary,\n HIDDEN_DOCUMENT_SUMMARY_KINDS,\n} from \"../../documents/documentSummary\";\nimport { settleQueuedDocumentUpdatesInTransaction } from \"../../sqlite/documentPendingUpdatePersistence\";\nimport { findLocalIdByDocumentId } from \"../../sqlite/documentPersistence\";\nimport {\n documentProjection,\n documentPurgeCheckpoints,\n documents,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nimport { applyContainerDocumentTombstonesWithExec } from \"./internal/containerDocumentTombstones\";\nimport { createStoredDocumentWithHistoryCheckpoint } from \"./internal/createDocumentWithHistoryCheckpoint\";\nimport { discardStoredDocumentToShell } from \"./internal/discardDocument\";\nimport { resolveDiscoveredDocumentPlacement } from \"./internal/discoveredDocumentPlacement\";\nimport {\n deleteStoredDocument,\n deleteStoredDocumentIfMatches,\n deleteStoredDocumentSideRowsIfAbsent,\n} from \"./internal/documentDeletionPersistence\";\nimport { loadStoredDocumentWithHistoryRestoreState } from \"./internal/documentHistoryStatePersistence\";\nimport {\n commitStoredDocumentMutation,\n settleStoredDocumentPendingUpdates,\n} from \"./internal/documentMutationPersistence\";\nimport {\n documentSummaryJoin,\n documentSummarySelection,\n getProjectionUpdatedAt,\n mapDocumentSummary,\n toDocumentSummary,\n} from \"./internal/documentProjectionRows\";\nimport { invalidateStoredDocumentPullContinuation } from \"./internal/documentPullContinuationPersistence\";\nimport {\n getDocumentScope,\n resolveDocumentSaveTimestamp,\n saveDocumentRows,\n} from \"./internal/documentRows\";\nimport {\n resolvePersistedAccessStateHash,\n resolvePersistedDocumentRuntimeState,\n} from \"./internal/documentRuntimeState\";\nimport { loadStoredDocumentStoreState } from \"./internal/documentStoreStatePersistence\";\nimport { listDocumentSummaries } from \"./internal/documentSummaryQueries\";\nimport { ensureDocumentsSchema } from \"./internal/ensureDocumentsSchema\";\nimport { saveHydratedAttachment } from \"./internal/hydratedAttachmentPersistence\";\nimport {\n acknowledgeDocumentOrphanBlobReclaim,\n deleteOrphanedDocumentSideRows,\n isDocumentBlobStorageKeyReferenced,\n listDocumentOrphanBlobReclaims,\n} from \"./internal/orphanSideRows\";\nimport {\n loadPendingCreateSummary,\n mapPendingCreateLocalIds,\n} from \"./internal/pendingCreateAdoption\";\nimport { documentRowQueryPersistence } from \"./internal/rowQueryPersistence\";\nimport { documentSyncQueuePersistence } from \"./internal/syncQueuePersistence\";\nimport type {\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nexport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nexport type {\n AttachmentRemovalRows,\n AttachmentStagingRows,\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n PendingAttachmentUploadIdentity,\n PendingUpdateInsert,\n PendingUpdateRecord,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nconst DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE = \"Syncing document...\";\n\nasync function upsertDiscoveredDocumentWithExec(\n execSql: ExecSql,\n input: DiscoveredDocumentInput,\n pendingCreates: ReadonlyMap<string, string>,\n tx: ClientSQLiteTransactionScope,\n): Promise<DocumentSummary> {\n const [purgeCheckpoint] = await tx\n .select({ documentId: documentPurgeCheckpoints.documentId })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, input.documentId))\n .limit(1);\n if (purgeCheckpoint) {\n throw new KeyingVerificationError(\n \"rollback\",\n \"Document discovery targets a permanently purged document\",\n );\n }\n const existingLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n input.documentId,\n );\n const localId = existingLocalId ?? input.documentId;\n const pendingLocalId = pendingCreates.get(input.documentId);\n if (!existingLocalId && pendingLocalId) {\n const pending = await loadPendingCreateSummary(execSql, pendingLocalId);\n if (!pending) throw new Error(\"Pending create projection is unavailable\");\n return pending;\n }\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n localId,\n );\n const placement = await resolveDiscoveredDocumentPlacement(\n tx,\n existingDocument,\n input,\n );\n\n const nextDocument: StoredDocumentRecord = {\n id: localId,\n documentId: input.documentId,\n documentKind: existingDocument?.documentKind ?? DEFAULT_DOCUMENT_KIND,\n text: existingDocument?.text ?? \"\",\n title: existingDocument?.title ?? DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE,\n snapshotEndVersion: existingDocument?.snapshotEndVersion ?? \"\",\n recoveryGeneration: existingDocument?.recoveryGeneration ?? 0,\n ...placement,\n effectiveAccessLevel:\n input.effectiveAccessLevel ??\n existingDocument?.effectiveAccessLevel ??\n null,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: placement.accessEpoch,\n documentId: input.documentId,\n }),\n };\n\n const saveOptions =\n existingDocument === null || existingDocument === undefined\n ? { updatedAt: input.createdAt }\n : undefined;\n const updatedAt = await resolveDocumentSaveTimestamp({\n document: nextDocument,\n options: saveOptions,\n tx,\n });\n if (!(await saveDocumentRows({ document: nextDocument, tx, updatedAt }))) {\n throw new Error(\"Document recovery generation changed during discovery\");\n }\n\n return toDocumentSummary(nextDocument, updatedAt);\n}\n\nasync function relinkPersistedDocumentWithExec(\n execSql: ExecSql,\n input: RelinkPersistedDocumentInput,\n): Promise<DocumentSummary | null> {\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n input.localId,\n );\n if (!existingDocument) {\n return null;\n }\n\n const nextAccessEpoch = Math.max(\n existingDocument.accessEpoch,\n input.accessEpoch,\n );\n const nextDocument: StoredDocumentRecord = {\n ...existingDocument,\n accessEpoch: nextAccessEpoch,\n accessStateHash: resolvePersistedAccessStateHash(existingDocument, {\n accessEpoch: nextAccessEpoch,\n accessStateHash: input.accessStateHash,\n documentId: input.documentId,\n }),\n containerId: input.containerId,\n documentId: input.documentId,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: nextAccessEpoch,\n documentId: input.documentId,\n }),\n };\n\n await sqlDocumentsPersistence.saveDocument(execSql, nextDocument);\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const updatedAtRows = await db\n .select({ updatedAt: documentProjection.updatedAt })\n .from(documentProjection)\n .where(eq(documentProjection.localId, input.localId))\n .limit(1);\n\n return toDocumentSummary(\n nextDocument,\n getProjectionUpdatedAt(updatedAtRows[0]),\n );\n}\n\nexport async function upsertDiscoveredDocuments(\n execSql: ExecSql,\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const pendingCreates = await mapPendingCreateLocalIds(lockedExecSql);\n const nextSummaries: DocumentSummary[] = [];\n\n for (const input of inputs) {\n nextSummaries.push(\n await upsertDiscoveredDocumentWithExec(\n lockedExecSql,\n input,\n pendingCreates,\n tx,\n ),\n );\n }\n\n return nextSummaries;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function applyContainerDocumentTombstones(\n execSql: ExecSql,\n tombstones: ReadonlyArray<ContainerDocumentTombstoneInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return applyContainerDocumentTombstonesWithExec(lockedExecSql, tombstones);\n });\n}\n\nexport async function listDocumentsByContainerIdsOrDocumentIds(\n execSql: ExecSql,\n input: {\n containerIds: ReadonlyArray<string>;\n documentIds: ReadonlyArray<string>;\n },\n): Promise<DocumentSummary[]> {\n const uniqueContainerIds = Array.from(new Set(input.containerIds));\n const uniqueDocumentIds = Array.from(new Set(input.documentIds));\n if (uniqueContainerIds.length === 0 && uniqueDocumentIds.length === 0) {\n return [];\n }\n\n const filters: SQL[] = [];\n if (uniqueContainerIds.length > 0) {\n filters.push(inArray(documentProjection.containerId, uniqueContainerIds));\n }\n\n if (uniqueDocumentIds.length > 0) {\n filters.push(inArray(documentProjection.documentId, uniqueDocumentIds));\n }\n\n const whereCondition = filters.length === 1 ? filters[0] : or(...filters);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(documentSummarySelection)\n .from(documentProjection)\n .leftJoin(documents, documentSummaryJoin)\n .where(\n and(\n whereCondition,\n notInArray(documentProjection.documentKind, [\n ...HIDDEN_DOCUMENT_SUMMARY_KINDS,\n ]),\n ),\n )\n .orderBy(\n desc(documentProjection.updatedAt),\n desc(documentProjection.localId),\n );\n\n return rows.map(mapDocumentSummary);\n}\n\nexport const sqlDocumentsPersistence: DocumentsPersistence = {\n orphanBlobs: {\n acknowledge: acknowledgeDocumentOrphanBlobReclaim,\n isReferenced: isDocumentBlobStorageKeyReferenced,\n list: listDocumentOrphanBlobReclaims,\n sweep: deleteOrphanedDocumentSideRows,\n },\n ...documentRowQueryPersistence,\n ...documentSyncQueuePersistence,\n supportsAtomicRecoveryHistoryPruning: true,\n saveHydratedAttachment,\n createDocumentWithHistoryCheckpoint:\n createStoredDocumentWithHistoryCheckpoint,\n commitDocumentMutation: (execSql, input, saveClientProjection) =>\n commitStoredDocumentMutation(\n execSql,\n input,\n saveClientProjection,\n sqlDocumentsPersistence.loadDocument,\n ),\n settleAcceptedPendingUpdates: (execSql, input) =>\n settleStoredDocumentPendingUpdates(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n ),\n ensureSchema: ensureDocumentsSchema,\n listDocumentSummaries,\n listDocumentsByContainerIdsOrDocumentIds,\n invalidatePullContinuation: (execSql, input) =>\n invalidateStoredDocumentPullContinuation(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n sqlDocumentsPersistence.loadHistoryRestoreState,\n ),\n loadDocumentWithHistoryRestoreState: (execSql, localId) =>\n loadStoredDocumentWithHistoryRestoreState(\n execSql,\n localId,\n sqlDocumentsPersistence,\n ),\n loadDocumentStoreState: (execSql, localId) =>\n loadStoredDocumentStoreState(execSql, localId, sqlDocumentsPersistence),\n async saveDocument(execSql, document, options) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n async saveDocumentAndDeletePendingUpdates(\n execSql,\n document,\n pendingUpdateIds,\n options,\n ) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n const saved = await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n if (!saved) return updatedAt;\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n getDocumentScope(document.id),\n pendingUpdateIds,\n );\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n deleteDocument: deleteStoredDocument,\n deleteDocumentIfMatches: deleteStoredDocumentIfMatches,\n deleteDocumentSideRowsIfAbsent: deleteStoredDocumentSideRowsIfAbsent,\n async discardDocumentToShell(\n execSql,\n localId,\n expectedDocumentId,\n documentProjectors,\n ): Promise<DiscardDocumentToShellResult> {\n return discardStoredDocumentToShell({\n documentProjectors,\n execSql,\n expectedDocumentId,\n localId,\n persistence: sqlDocumentsPersistence,\n });\n },\n async upsertDiscoveredDocument(execSql, input) {\n const [nextSummary] = await upsertDiscoveredDocuments(execSql, [input]);\n if (!nextSummary) {\n throw new Error(\"Failed to upsert discovered document\");\n }\n\n return nextSummary;\n },\n async relinkPersistedDocument(execSql, input) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n () => relinkPersistedDocumentWithExec(lockedExecSql, input),\n { behavior: \"immediate\" },\n );\n });\n },\n};\n"]}
@@ -2,7 +2,7 @@ import { and, eq, isNotNull } from "drizzle-orm";
2
2
  import { DEFAULT_DOCUMENT_KIND } from "../../../documents/documentConstants.js";
3
3
  import { resolveDocumentProjectorRegistry, } from "../../../documents/documentKinds.js";
4
4
  import { deleteDocumentHistory } from "../../../sqlite/documentHistoryPersistence.js";
5
- import { clearDocumentSyncFailure, deleteDocumentPendingUpdates, } from "../../../sqlite/documentPersistence.js";
5
+ import { clearDocumentSyncFailure } from "../../../sqlite/documentPersistence.js";
6
6
  import { documentAttachmentBlobProjection, documentMoveIntents, documentMoveIntentTables, documentPendingAttachments, } from "../../../sqlite/schema.js";
7
7
  import { getClientSQLitePersistenceRuntime, } from "../../../sqlite/sqlitePersistenceRuntime.js";
8
8
  import { ensureSqlTables, runSerializedSqlMutation, } from "../../../sqlite/sqlSchema.js";
@@ -64,7 +64,6 @@ async function loadDiscardCandidate(input) {
64
64
  // after a re-pull restores it, leaving the attachment permanently invisible.
65
65
  async function clearDiscardedDocumentRows(input) {
66
66
  const { candidate, localId, lockedExecSql, tx } = input;
67
- await deleteDocumentPendingUpdates(lockedExecSql, getDocumentScope(localId));
68
67
  await tx
69
68
  .delete(documentPendingAttachments)
70
69
  .where(eq(documentPendingAttachments.localId, localId))