@tearleads/client-sdk 0.1.42 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/containerDocumentDiscovery.js +71 -29
- package/client/containerDocumentDiscovery.js.map +1 -1
- package/client/deviceFirst.js +4 -5
- package/client/deviceFirst.js.map +1 -1
- package/data/blobs/transferPool.js +35 -8
- package/data/blobs/transferPool.js.map +1 -1
- package/data/containers/shared/projection.js +12 -0
- package/data/containers/shared/projection.js.map +1 -1
- package/data/documents/blob/shared/types.d.ts +2 -3
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/documents/shared/events.js +0 -1
- package/data/documents/shared/events.js.map +1 -1
- package/data/persistence/container-contents/containerContentsPersistence.js +6 -22
- package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js +5 -15
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerPendingUpdatePersistence.js +6 -15
- package/data/persistence/container-contents/containerPendingUpdatePersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRecoveryPersistence.js +3 -4
- package/data/persistence/container-contents/containerRecoveryPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRemovalWork.js +3 -5
- package/data/persistence/container-contents/containerRemovalWork.js.map +1 -1
- package/data/persistence/container-contents/dormantContainerMetadata.js +1 -5
- package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
- package/data/persistence/containers/containerSyncWatermarkPersistence.d.ts +11 -3
- package/data/persistence/containers/containerSyncWatermarkPersistence.js +46 -58
- package/data/persistence/containers/containerSyncWatermarkPersistence.js.map +1 -1
- package/data/persistence/documents/documentsPersistence.js +4 -9
- package/data/persistence/documents/documentsPersistence.js.map +1 -1
- package/data/persistence/documents/internal/discardDocument.js +1 -2
- package/data/persistence/documents/internal/discardDocument.js.map +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js +1 -2
- package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js +17 -25
- package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js +2 -14
- package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
- package/data/persistence/documents/internal/syncQueuePersistence.js +3 -3
- package/data/persistence/documents/internal/syncQueuePersistence.js.map +1 -1
- package/data/sqlite/documentHistoryPersistence.d.ts +9 -3
- package/data/sqlite/documentHistoryPersistence.js +31 -8
- package/data/sqlite/documentHistoryPersistence.js.map +1 -1
- package/data/sqlite/documentPendingUpdatePersistence.d.ts +58 -11
- package/data/sqlite/documentPendingUpdatePersistence.js +137 -63
- package/data/sqlite/documentPendingUpdatePersistence.js.map +1 -1
- package/data/sqlite/documentPersistence.d.ts +1 -1
- package/data/sqlite/documentPersistence.js +1 -1
- package/data/sqlite/documentPersistence.js.map +1 -1
- package/data/sqlite/documentPersistenceTypes.d.ts +2 -2
- package/data/sqlite/documentPersistenceTypes.js.map +1 -1
- package/data/sqlite/documentRecordPersistence.js +5 -4
- package/data/sqlite/documentRecordPersistence.js.map +1 -1
- package/data/sqlite/schema.d.ts +167 -517
- package/data/sqlite/schema.js +68 -82
- package/data/sqlite/schema.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +18 -41
- package/internal/api-client/ApiClient.js +9 -14
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/apiRequestRuntime.d.ts +2 -0
- package/internal/api-client/apiRequestRuntime.js +4 -0
- package/internal/api-client/apiRequestRuntime.js.map +1 -1
- package/internal/api-client/binaryRequestOperationTransport.d.ts +18 -0
- package/internal/api-client/index.d.ts +1 -0
- package/internal/api-client/index.js +1 -0
- package/internal/api-client/index.js.map +1 -1
- package/internal/api-client/operationTransportFactory.d.ts +6 -0
- package/internal/api-client/requestInternals.js +7 -7
- package/internal/api-client/requestInternals.js.map +1 -1
- package/internal/api-client/routes/blobs/get.d.ts +7 -0
- package/internal/api-client/routes/blobs/get.js.map +1 -1
- package/internal/api-client/routes/blobs/multipart.js +1 -11
- package/internal/api-client/routes/blobs/multipart.js.map +1 -1
- package/internal/api-client/routes/blobs/multipartUpload.d.ts +14 -0
- package/internal/api-client/routes/blobs/multipartUpload.js +94 -43
- package/internal/api-client/routes/blobs/multipartUpload.js.map +1 -1
- package/internal/api-client/routes/containers/reads.d.ts +13 -7
- package/internal/api-client/routes/containers/reads.js +36 -15
- package/internal/api-client/routes/containers/reads.js.map +1 -1
- package/internal/api-client/types.d.ts +1 -5
- package/internal/api-client/types.js.map +1 -1
- package/internal/validators/containerReadRefinements.js +15 -5
- package/internal/validators/containerReadRefinements.js.map +1 -1
- package/internal/validators/containerReadSchemas.d.ts +36 -0
- package/internal/validators/containerReadSchemas.js +64 -1
- package/internal/validators/containerReadSchemas.js.map +1 -1
- package/internal/validators/operation/attachments.d.ts +80 -160
- package/internal/validators/operation/auth.d.ts +760 -1664
- package/internal/validators/operation/blobDownloads.js +1 -1
- package/internal/validators/operation/blobDownloads.js.map +1 -1
- package/internal/validators/operation/containerMutations.d.ts +416 -856
- package/internal/validators/operation/containerReads.d.ts +118 -182
- package/internal/validators/operation/containerReads.js +20 -54
- package/internal/validators/operation/containerReads.js.map +1 -1
- package/internal/validators/operation/documentMutations.d.ts +120 -264
- package/internal/validators/operation/documentSync.d.ts +40 -80
- package/internal/validators/operation/index.d.ts +2 -2
- package/internal/validators/operation/index.js +2 -2
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/multipartBlobs.d.ts +70 -190
- package/internal/validators/operation/multipartBlobs.js +2 -24
- package/internal/validators/operation/multipartBlobs.js.map +1 -1
- package/internal/validators/operation/multipartPartUploads.d.ts +5 -5
- package/internal/validators/operation/multipartPartUploads.js +6 -20
- package/internal/validators/operation/multipartPartUploads.js.map +1 -1
- package/internal/validators/operation/organizations.d.ts +882 -1906
- package/internal/validators/operation/principals.d.ts +120 -240
- package/internal/validators/operation/registry.d.ts +3 -4
- package/internal/validators/operation/registry.js +3 -4
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/request/blob.d.ts +100 -201
- package/internal/validators/request/blob.js +6 -13
- package/internal/validators/request/blob.js.map +1 -1
- package/internal/validators/request/container.d.ts +136 -272
- package/internal/validators/request/container.js +16 -10
- package/internal/validators/request/container.js.map +1 -1
- package/internal/validators/request/containerDocumentLanes.d.ts +23 -0
- package/internal/validators/request/containerDocumentLanes.js +23 -0
- package/internal/validators/request/containerDocumentLanes.js.map +1 -0
- package/internal/validators/request/containerManifestRef.d.ts +54 -0
- package/internal/validators/request/containerManifestRef.js +28 -0
- package/internal/validators/request/containerManifestRef.js.map +1 -0
- package/internal/validators/request/containerMetadata.d.ts +160 -368
- package/internal/validators/request/containerParentLanes.js +5 -35
- package/internal/validators/request/containerParentLanes.js.map +1 -1
- package/internal/validators/request/document.d.ts +100 -245
- package/internal/validators/request/document.js +1 -2
- package/internal/validators/request/document.js.map +1 -1
- package/internal/validators/request/documentSyncSchema.d.ts +42 -109
- package/internal/validators/request/documentSyncSchema.js +8 -25
- package/internal/validators/request/documentSyncSchema.js.map +1 -1
- package/internal/validators/request/index.d.ts +2 -1
- package/internal/validators/request/index.js +2 -1
- package/internal/validators/request/index.js.map +1 -1
- package/internal/validators/request/organization.d.ts +160 -320
- package/internal/validators/request/organizationProvisioning.d.ts +2424 -5312
- package/internal/validators/request/principal.d.ts +160 -320
- package/internal/validators/request/registration.d.ts +760 -1664
- package/internal/validators/response/blob.d.ts +48 -27
- package/internal/validators/response/blob.js +3 -10
- package/internal/validators/response/blob.js.map +1 -1
- package/internal/validators/response/containerDocumentLanes.d.ts +82 -0
- package/internal/validators/response/containerDocumentLanes.js +35 -0
- package/internal/validators/response/containerDocumentLanes.js.map +1 -0
- package/internal/validators/response/containerParentLanes.js +3 -15
- package/internal/validators/response/containerParentLanes.js.map +1 -1
- package/internal/validators/response/index.d.ts +3 -2
- package/internal/validators/response/index.js +2 -2
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/util/blob.d.ts +7 -0
- package/internal/validators/util/blob.js +7 -0
- package/internal/validators/util/blob.js.map +1 -1
- package/internal/validators/util/blobTransferSchemas.d.ts +41 -0
- package/internal/validators/util/blobTransferSchemas.js +39 -0
- package/internal/validators/util/blobTransferSchemas.js.map +1 -0
- package/internal/validators/util/containerLimits.d.ts +7 -0
- package/internal/validators/util/containerLimits.js +7 -0
- package/internal/validators/util/containerLimits.js.map +1 -1
- package/internal/validators/util/index.d.ts +2 -1
- package/internal/validators/util/index.js +2 -1
- package/internal/validators/util/index.js.map +1 -1
- package/package.json +1 -1
- package/sync/reconciliation/knownContainerSweep.js +57 -54
- package/sync/reconciliation/knownContainerSweep.js.map +1 -1
- package/sync/reconciliation/reconcileContainer.js +49 -17
- package/sync/reconciliation/reconcileContainer.js.map +1 -1
- package/sync/reconciliation/service.js +44 -16
- package/sync/reconciliation/service.js.map +1 -1
- package/sync/reconciliation/serviceTypes.d.ts +23 -2
- package/sync/reconciliation/serviceTypes.js.map +1 -1
- package/workflows/blobs/multipartFirstParts.js +82 -0
- package/workflows/blobs/multipartFirstParts.js.map +1 -0
- package/workflows/blobs/multipartStageResolution.js +83 -0
- package/workflows/blobs/multipartStageResolution.js.map +1 -0
- package/workflows/blobs/multipartUpload.js +45 -89
- package/workflows/blobs/multipartUpload.js.map +1 -1
- package/workflows/container-contents/containerDocumentListing.js +92 -38
- package/workflows/container-contents/containerDocumentListing.js.map +1 -1
- package/workflows/container-contents/containerPersistence.d.ts +8 -2
- package/workflows/container-contents/containerPersistence.js +6 -7
- package/workflows/container-contents/containerPersistence.js.map +1 -1
- package/workflows/container-contents/documentDiscovery.d.ts +3 -3
- package/workflows/container-contents/documentDiscovery.js +24 -96
- package/workflows/container-contents/documentDiscovery.js.map +1 -1
- package/workflows/container-contents/documentDiscoveryApply.js +65 -0
- package/workflows/container-contents/documentDiscoveryApply.js.map +1 -0
- package/workflows/container-contents/documentDiscoveryLanes.js +53 -0
- package/workflows/container-contents/documentDiscoveryLanes.js.map +1 -0
- package/workflows/container-contents/documentDiscoveryTypes.d.ts +25 -19
- package/workflows/container-contents/documentDiscoveryTypes.js.map +1 -1
- package/workflows/container-contents/documentPriming.js +2 -1
- package/workflows/container-contents/documentPriming.js.map +1 -1
- package/workflows/container-contents/documentQueries/sql.js +4 -4
- package/workflows/container-contents/documentQueries/sql.js.map +1 -1
- package/workflows/container-contents/pendingWrites/deferredTails.js +6 -3
- package/workflows/container-contents/pendingWrites/deferredTails.js.map +1 -1
- package/workflows/container-contents/pendingWrites/sources.js +2 -1
- package/workflows/container-contents/pendingWrites/sources.js.map +1 -1
- package/workflows/container-contents/pendingWrites.js +2 -1
- package/workflows/container-contents/pendingWrites.js.map +1 -1
- package/workflows/container-contents/remoteHydration/laneFetchMarkers.js +11 -17
- package/workflows/container-contents/remoteHydration/laneFetchMarkers.js.map +1 -1
- package/workflows/containers/child/create.js +3 -3
- package/workflows/containers/child/create.js.map +1 -1
- package/workflows/containers/child/move.js +2 -2
- package/workflows/containers/child/move.js.map +1 -1
- package/workflows/containers/child/mutationRequestCore.js +5 -4
- package/workflows/containers/child/mutationRequestCore.js.map +1 -1
- package/workflows/containers/child/recitePlan.js +3 -2
- package/workflows/containers/child/recitePlan.js.map +1 -1
- package/workflows/containers/child/sharePlanCore.js +2 -2
- package/workflows/containers/child/sharePlanCore.js.map +1 -1
- package/workflows/containers/root/create.js +2 -2
- package/workflows/containers/root/create.js.map +1 -1
- package/workflows/registration/provisioningBootstrapBuilders.d.ts +20 -46
- package/workflows/sync/remoteReset.js +9 -9
- package/workflows/sync/remoteReset.js.map +1 -1
- package/workflows/sync/remoteResetCursorScope.js +10 -18
- package/workflows/sync/remoteResetCursorScope.js.map +1 -1
- package/workflows/sync/remoteResetPlans.js +6 -3
- package/workflows/sync/remoteResetPlans.js.map +1 -1
- package/workflows/sync/remoteResetScope.js +4 -11
- package/workflows/sync/remoteResetScope.js.map +1 -1
- package/internal/validators/operation/blobTransferSchemas.js +0 -11
- package/internal/validators/operation/blobTransferSchemas.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentDeletionPersistence.js","sourceRoot":"","sources":["documentDeletionPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray, ne } from \"drizzle-orm\";\nimport { deleteDocumentHistory } from \"../../../sqlite/documentHistoryPersistence\";\nimport {\n clearDocumentSyncFailure,\n deleteDocumentPendingUpdates,\n deleteDocumentRecord,\n loadDocumentRecord,\n} from \"../../../sqlite/documentPersistence\";\nimport { documentIntentLinkTargets } from \"../../../sqlite/documentPlacementIntentSchema\";\nimport {\n documentAttachmentBlobProjection,\n documentContainerProjection,\n documentMoveIntents,\n documentMoveIntentTables,\n documentPendingAttachments,\n documentProjection,\n documentProjectionText,\n documents,\n} from \"../../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../../sqlite/sqlSchema\";\nimport type { StoredDocumentRecord } from \"../types\";\nimport { DOCUMENTS_APP_KIND } from \"./constants\";\nimport { deleteContainerDocumentTombstoneHoldsForDocuments } from \"./containerDocumentTombstoneHolds\";\nimport { sameCanonicalDocumentSecurityIdentity } from \"./documentRecordIdentity\";\nimport { getDocumentScope } from \"./documentRows\";\nimport { queueDocumentAttachmentBlobReclaims } from \"./orphanSideRows\";\n\nasync function deleteStoredDocumentRows(input: {\n existingDocumentId: string | null;\n localId: string;\n lockedExecSql: ExecSql;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { existingDocumentId, localId, lockedExecSql, tx } = input;\n await queueDocumentAttachmentBlobReclaims({\n localWhere: eq(documentAttachmentBlobProjection.localId, localId),\n pendingWhere: eq(documentPendingAttachments.localId, localId),\n tx,\n });\n await tx\n .delete(documentProjection)\n .where(eq(documentProjection.localId, localId))\n .run();\n await tx\n .delete(documentProjectionText)\n .where(eq(documentProjectionText.localId, localId))\n .run();\n await tx\n .delete(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, localId))\n .run();\n await tx\n .delete(documentAttachmentBlobProjection)\n .where(eq(documentAttachmentBlobProjection.localId, localId))\n .run();\n if (existingDocumentId) {\n await tx\n .delete(documentContainerProjection)\n .where(eq(documentContainerProjection.documentId, existingDocumentId))\n .run();\n await deleteContainerDocumentTombstoneHoldsForDocuments(tx, [\n existingDocumentId,\n ]);\n await tx\n .delete(documentIntentLinkTargets)\n .where(\n inArray(\n documentIntentLinkTargets.intentId,\n tx\n .select({ id: documentMoveIntents.id })\n .from(documentMoveIntents)\n .where(eq(documentMoveIntents.documentId, existingDocumentId)),\n ),\n )\n .run();\n await tx\n .delete(documentMoveIntents)\n .where(eq(documentMoveIntents.documentId, existingDocumentId))\n .run();\n }\n const scope = getDocumentScope(localId);\n await deleteDocumentPendingUpdates(lockedExecSql, scope);\n await deleteDocumentHistory(lockedExecSql, scope);\n await clearDocumentSyncFailure(lockedExecSql, scope);\n await deleteDocumentRecord(lockedExecSql, scope);\n}\n\nasync function ensureDocumentDeletionTables(execSql: ExecSql): Promise<void> {\n // Move intents live in the container-contents schema, which document-only\n // callers may not have initialized yet.\n await ensureSqlTables(execSql, documentMoveIntentTables);\n}\n\nasync function hasAnotherDocumentAlias(input: {\n documentId: string;\n localId: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<boolean> {\n const rows = await input.tx\n .select({ localId: documents.localId })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, DOCUMENTS_APP_KIND),\n eq(documents.documentId, input.documentId),\n ne(documents.localId, input.localId),\n ),\n )\n .limit(1);\n return rows.length > 0;\n}\n\nexport async function deleteStoredDocument(\n execSql: ExecSql,\n localId: string,\n): Promise<void> {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureDocumentDeletionTables(lockedExecSql);\n await getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const existingDocument = await loadDocumentRecord(lockedExecSql, {\n appKind: DOCUMENTS_APP_KIND,\n localId,\n });\n await deleteStoredDocumentRows({\n existingDocumentId: existingDocument?.documentId ?? null,\n localId,\n lockedExecSql,\n tx,\n });\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function deleteStoredDocumentIfMatches(\n execSql: ExecSql,\n expectedRecord: StoredDocumentRecord,\n deleteClientProjection: (transactionExecSql: ExecSql) => Promise<void>,\n): Promise<boolean> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureDocumentDeletionTables(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const existingDocument = await loadDocumentRecord(lockedExecSql, {\n appKind: DOCUMENTS_APP_KIND,\n localId: expectedRecord.id,\n });\n if (\n !existingDocument ||\n !sameCanonicalDocumentSecurityIdentity(\n existingDocument,\n expectedRecord,\n )\n ) {\n return false;\n }\n const [placement] = await tx\n .select({ containerId: documentProjection.containerId })\n .from(documentProjection)\n .where(eq(documentProjection.localId, expectedRecord.id))\n .limit(1);\n if ((placement?.containerId ?? null) !== expectedRecord.containerId)\n return false;\n if (\n existingDocument.documentId &&\n (await hasAnotherDocumentAlias({\n documentId: existingDocument.documentId,\n localId: expectedRecord.id,\n tx,\n }))\n ) {\n return false;\n }\n await deleteStoredDocumentRows({\n existingDocumentId: existingDocument.documentId ?? null,\n localId: expectedRecord.id,\n lockedExecSql,\n tx,\n });\n await deleteClientProjection(lockedExecSql);\n return true;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function deleteStoredDocumentSideRowsIfAbsent(\n execSql: ExecSql,\n localId: string,\n expectedDocumentId: string | null,\n deleteClientProjection: (transactionExecSql: ExecSql) => Promise<void>,\n): Promise<boolean> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureDocumentDeletionTables(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const existingDocument = await loadDocumentRecord(lockedExecSql, {\n appKind: DOCUMENTS_APP_KIND,\n localId,\n });\n if (existingDocument) return false;\n if (\n expectedDocumentId &&\n (await hasAnotherDocumentAlias({\n documentId: expectedDocumentId,\n localId,\n tx,\n }))\n ) {\n return false;\n }\n\n await deleteStoredDocumentRows({\n existingDocumentId: expectedDocumentId,\n localId,\n lockedExecSql,\n tx,\n });\n await deleteClientProjection(lockedExecSql);\n return true;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentDeletionPersistence.js","sourceRoot":"","sources":["documentDeletionPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray, ne } from \"drizzle-orm\";\nimport { deleteDocumentHistory } from \"../../../sqlite/documentHistoryPersistence\";\nimport {\n clearDocumentSyncFailure,\n deleteDocumentRecord,\n loadDocumentRecord,\n} from \"../../../sqlite/documentPersistence\";\nimport { documentIntentLinkTargets } from \"../../../sqlite/documentPlacementIntentSchema\";\nimport {\n documentAttachmentBlobProjection,\n documentContainerProjection,\n documentMoveIntents,\n documentMoveIntentTables,\n documentPendingAttachments,\n documentProjection,\n documentProjectionText,\n documents,\n} from \"../../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../../sqlite/sqlSchema\";\nimport type { StoredDocumentRecord } from \"../types\";\nimport { DOCUMENTS_APP_KIND } from \"./constants\";\nimport { deleteContainerDocumentTombstoneHoldsForDocuments } from \"./containerDocumentTombstoneHolds\";\nimport { sameCanonicalDocumentSecurityIdentity } from \"./documentRecordIdentity\";\nimport { getDocumentScope } from \"./documentRows\";\nimport { queueDocumentAttachmentBlobReclaims } from \"./orphanSideRows\";\n\nasync function deleteStoredDocumentRows(input: {\n existingDocumentId: string | null;\n localId: string;\n lockedExecSql: ExecSql;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { existingDocumentId, localId, lockedExecSql, tx } = input;\n await queueDocumentAttachmentBlobReclaims({\n localWhere: eq(documentAttachmentBlobProjection.localId, localId),\n pendingWhere: eq(documentPendingAttachments.localId, localId),\n tx,\n });\n await tx\n .delete(documentProjection)\n .where(eq(documentProjection.localId, localId))\n .run();\n await tx\n .delete(documentProjectionText)\n .where(eq(documentProjectionText.localId, localId))\n .run();\n await tx\n .delete(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, localId))\n .run();\n await tx\n .delete(documentAttachmentBlobProjection)\n .where(eq(documentAttachmentBlobProjection.localId, localId))\n .run();\n if (existingDocumentId) {\n await tx\n .delete(documentContainerProjection)\n .where(eq(documentContainerProjection.documentId, existingDocumentId))\n .run();\n await deleteContainerDocumentTombstoneHoldsForDocuments(tx, [\n existingDocumentId,\n ]);\n await tx\n .delete(documentIntentLinkTargets)\n .where(\n inArray(\n documentIntentLinkTargets.intentId,\n tx\n .select({ id: documentMoveIntents.id })\n .from(documentMoveIntents)\n .where(eq(documentMoveIntents.documentId, existingDocumentId)),\n ),\n )\n .run();\n await tx\n .delete(documentMoveIntents)\n .where(eq(documentMoveIntents.documentId, existingDocumentId))\n .run();\n }\n const scope = getDocumentScope(localId);\n await deleteDocumentHistory(lockedExecSql, scope);\n await clearDocumentSyncFailure(lockedExecSql, scope);\n await deleteDocumentRecord(lockedExecSql, scope);\n}\n\nasync function ensureDocumentDeletionTables(execSql: ExecSql): Promise<void> {\n // Move intents live in the container-contents schema, which document-only\n // callers may not have initialized yet.\n await ensureSqlTables(execSql, documentMoveIntentTables);\n}\n\nasync function hasAnotherDocumentAlias(input: {\n documentId: string;\n localId: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<boolean> {\n const rows = await input.tx\n .select({ localId: documents.localId })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, DOCUMENTS_APP_KIND),\n eq(documents.documentId, input.documentId),\n ne(documents.localId, input.localId),\n ),\n )\n .limit(1);\n return rows.length > 0;\n}\n\nexport async function deleteStoredDocument(\n execSql: ExecSql,\n localId: string,\n): Promise<void> {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureDocumentDeletionTables(lockedExecSql);\n await getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const existingDocument = await loadDocumentRecord(lockedExecSql, {\n appKind: DOCUMENTS_APP_KIND,\n localId,\n });\n await deleteStoredDocumentRows({\n existingDocumentId: existingDocument?.documentId ?? null,\n localId,\n lockedExecSql,\n tx,\n });\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function deleteStoredDocumentIfMatches(\n execSql: ExecSql,\n expectedRecord: StoredDocumentRecord,\n deleteClientProjection: (transactionExecSql: ExecSql) => Promise<void>,\n): Promise<boolean> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureDocumentDeletionTables(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const existingDocument = await loadDocumentRecord(lockedExecSql, {\n appKind: DOCUMENTS_APP_KIND,\n localId: expectedRecord.id,\n });\n if (\n !existingDocument ||\n !sameCanonicalDocumentSecurityIdentity(\n existingDocument,\n expectedRecord,\n )\n ) {\n return false;\n }\n const [placement] = await tx\n .select({ containerId: documentProjection.containerId })\n .from(documentProjection)\n .where(eq(documentProjection.localId, expectedRecord.id))\n .limit(1);\n if ((placement?.containerId ?? null) !== expectedRecord.containerId)\n return false;\n if (\n existingDocument.documentId &&\n (await hasAnotherDocumentAlias({\n documentId: existingDocument.documentId,\n localId: expectedRecord.id,\n tx,\n }))\n ) {\n return false;\n }\n await deleteStoredDocumentRows({\n existingDocumentId: existingDocument.documentId ?? null,\n localId: expectedRecord.id,\n lockedExecSql,\n tx,\n });\n await deleteClientProjection(lockedExecSql);\n return true;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function deleteStoredDocumentSideRowsIfAbsent(\n execSql: ExecSql,\n localId: string,\n expectedDocumentId: string | null,\n deleteClientProjection: (transactionExecSql: ExecSql) => Promise<void>,\n): Promise<boolean> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureDocumentDeletionTables(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const existingDocument = await loadDocumentRecord(lockedExecSql, {\n appKind: DOCUMENTS_APP_KIND,\n localId,\n });\n if (existingDocument) return false;\n if (\n expectedDocumentId &&\n (await hasAnotherDocumentAlias({\n documentId: expectedDocumentId,\n localId,\n tx,\n }))\n ) {\n return false;\n }\n\n await deleteStoredDocumentRows({\n existingDocumentId: expectedDocumentId,\n localId,\n lockedExecSql,\n tx,\n });\n await deleteClientProjection(lockedExecSql);\n return true;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { base64ToBytes } from "../../../../internal/encoding/index.js";
|
|
2
2
|
import { createDocument, importSnapshot, updateMatchesDocumentHistory, } from "../../../../internal/loro/index.js";
|
|
3
|
-
import { and, eq
|
|
3
|
+
import { and, eq } from "drizzle-orm";
|
|
4
4
|
import { documentSyncPullContinuationsEqual } from "../../../documents/shared/pullContinuation.js";
|
|
5
5
|
import { appendDocumentHistoryUpdates, replaceDocumentHistoryCheckpoint, } from "../../../sqlite/documentHistoryPersistence.js";
|
|
6
|
-
import { insertDocumentPendingUpdateWithHistoryInTransaction } from "../../../sqlite/documentPendingUpdatePersistence.js";
|
|
7
|
-
import { documentHistoryUpdates,
|
|
6
|
+
import { insertDocumentPendingUpdateWithHistoryInTransaction, settleQueuedDocumentUpdatesInTransaction, } from "../../../sqlite/documentPendingUpdatePersistence.js";
|
|
7
|
+
import { documentHistoryUpdates, documentSyncFailures, } from "../../../sqlite/schema.js";
|
|
8
8
|
import { getClientSQLitePersistenceRuntime, } from "../../../sqlite/sqlitePersistenceRuntime.js";
|
|
9
9
|
import { runSerializedSqlMutation } from "../../../sqlite/sqlSchema.js";
|
|
10
10
|
import { applyStoredAttachmentRemoval, upsertStoredAttachmentStagingRows, } from "./attachmentStagingPersistence.js";
|
|
@@ -28,13 +28,7 @@ function sameExpectedDocumentRecord(current, expected) {
|
|
|
28
28
|
(current.title ?? null) === (expected.title ?? null));
|
|
29
29
|
}
|
|
30
30
|
async function deleteAcceptedPendingUpdates(tx, localId, ids) {
|
|
31
|
-
|
|
32
|
-
if (uniqueIds.length === 0)
|
|
33
|
-
return;
|
|
34
|
-
await tx
|
|
35
|
-
.delete(documentPendingUpdates)
|
|
36
|
-
.where(and(eq(documentPendingUpdates.appKind, DOCUMENTS_APP_KIND), eq(documentPendingUpdates.localId, localId), inArray(documentPendingUpdates.id, uniqueIds)))
|
|
37
|
-
.run();
|
|
31
|
+
await settleQueuedDocumentUpdatesInTransaction(tx, { appKind: DOCUMENTS_APP_KIND, localId }, ids);
|
|
38
32
|
}
|
|
39
33
|
async function clearSyncFailure(tx, localId) {
|
|
40
34
|
await tx
|
|
@@ -80,6 +74,9 @@ async function appendMutationHistory(execSql, input, tx) {
|
|
|
80
74
|
coveredLocalState.hasUnverifiedHistoryTail) {
|
|
81
75
|
throw new Error("Document recovery found unverified history tail before installation");
|
|
82
76
|
}
|
|
77
|
+
// A queued rotation baseline the recovery snapshot covers is unqueued
|
|
78
|
+
// first so the replacement below can delete it with the covered tail.
|
|
79
|
+
await deleteAcceptedPendingUpdates(tx, input.document.id, coveredLocalState.checkpointIds);
|
|
83
80
|
const checkpointReplaced = await replaceDocumentHistoryCheckpoint(execSql, { appKind: DOCUMENTS_APP_KIND, localId: input.document.id }, {
|
|
84
81
|
...input.historyCheckpoint,
|
|
85
82
|
coveredTailIds: input.historyCheckpoint.pruneCoveredLocalState
|
|
@@ -89,7 +86,6 @@ async function appendMutationHistory(execSql, input, tx) {
|
|
|
89
86
|
if (input.historyCheckpoint.pruneCoveredLocalState && !checkpointReplaced) {
|
|
90
87
|
throw new Error("Document recovery checkpoint was superseded before installation");
|
|
91
88
|
}
|
|
92
|
-
await deleteAcceptedPendingUpdates(tx, input.document.id, coveredLocalState.checkpointIds);
|
|
93
89
|
}
|
|
94
90
|
if (input.historyUpdates && input.historyUpdates.length > 0) {
|
|
95
91
|
await appendDocumentHistoryUpdates(execSql, { appKind: DOCUMENTS_APP_KIND, localId: input.document.id }, input.historyUpdates, input.historyUpdateOrigin ?? "local");
|
|
@@ -99,25 +95,19 @@ async function findCoveredRecoveryLocalState(tx, localId, recoverySnapshot) {
|
|
|
99
95
|
const recoveredDocument = await createDocument(`recovery-tail-verification:${localId}`);
|
|
100
96
|
try {
|
|
101
97
|
importSnapshot(recoveredDocument, base64ToBytes(recoverySnapshot));
|
|
102
|
-
const
|
|
103
|
-
const pendingUpdates = await tx
|
|
104
|
-
.select({
|
|
105
|
-
id: documentPendingUpdates.id,
|
|
106
|
-
sourceVersionVector: documentPendingUpdates.sourceVersionVector,
|
|
107
|
-
updateData: documentPendingUpdates.updateData,
|
|
108
|
-
})
|
|
109
|
-
.from(documentPendingUpdates)
|
|
110
|
-
.where(scope);
|
|
111
|
-
const tail = await tx
|
|
98
|
+
const rows = await tx
|
|
112
99
|
.select({
|
|
113
100
|
id: documentHistoryUpdates.id,
|
|
101
|
+
origin: documentHistoryUpdates.origin,
|
|
102
|
+
sourceVersionVector: documentHistoryUpdates.sourceVersionVector,
|
|
114
103
|
updateData: documentHistoryUpdates.updateData,
|
|
104
|
+
updateId: documentHistoryUpdates.updateId,
|
|
115
105
|
})
|
|
116
106
|
.from(documentHistoryUpdates)
|
|
117
107
|
.where(and(eq(documentHistoryUpdates.appKind, DOCUMENTS_APP_KIND), eq(documentHistoryUpdates.localId, localId)));
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
108
|
+
const pendingUpdates = rows.filter((row) => row.updateId !== null);
|
|
109
|
+
const tail = rows.filter((row) => row.origin !== "outbox");
|
|
110
|
+
const checkpointUpdateData = new Set(pendingUpdates.flatMap((row) => row.sourceVersionVector === null ? [] : [row.updateData]));
|
|
121
111
|
let hasUnverifiedHistoryTail = false;
|
|
122
112
|
const tailIds = tail.flatMap((row) => {
|
|
123
113
|
if (row.id === null) {
|
|
@@ -140,7 +130,9 @@ async function findCoveredRecoveryLocalState(tx, localId, recoverySnapshot) {
|
|
|
140
130
|
return [];
|
|
141
131
|
});
|
|
142
132
|
return {
|
|
143
|
-
checkpointIds: pendingUpdates.flatMap((row) => row.
|
|
133
|
+
checkpointIds: pendingUpdates.flatMap((row) => row.updateId !== null && row.sourceVersionVector !== null
|
|
134
|
+
? [row.updateId]
|
|
135
|
+
: []),
|
|
144
136
|
hasOrdinaryPendingUpdates: pendingUpdates.some((row) => row.sourceVersionVector === null),
|
|
145
137
|
hasUnprunablePendingUpdates: pendingUpdates.some((row) => row.id === null),
|
|
146
138
|
hasUnverifiedHistoryTail,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentMutationPersistence.js","sourceRoot":"","sources":["documentMutationPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,cAAc,EACd,cAAc,EACd,4BAA4B,GAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kCAAkC,EAAE,MAAM,4CAA4C,CAAC;AAChG,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,mDAAmD,EAAE,MAAM,kDAAkD,CAAC;AACvH,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,iCAAiC,GAClC,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EACL,4BAA4B,EAC5B,iCAAiC,GAClC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,SAAS,sBAAsB,CAC7B,OAA6B,EAC7B,QAA8B;IAE9B,OAAO,CACL,CAAC,OAAO,CAAC,kBAAkB,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,IAAI,CAAC,CAAC,CACzE,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,OAA6B,EAC7B,QAA8B;IAE9B,OAAO,CACL,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC/C,sBAAsB,CAAC,OAAO,EAAE,QAAQ,CAAC;QACzC,yBAAyB,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,aAAa,CAAC;QACxE,OAAO,CAAC,kBAAkB,KAAK,QAAQ,CAAC,kBAAkB;QAC1D,yBAAyB,CACvB,OAAO,CAAC,kBAAkB,EAC1B,QAAQ,CAAC,kBAAkB,CAC5B;QACD,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;QACpD,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI,CAAC;QAClE,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;QAC9B,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,CACrD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,4BAA4B,CACzC,EAAgC,EAChC,OAAe,EACf,GAAsB;IAEtB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACnC,MAAM,EAAE;SACL,MAAM,CAAC,sBAAsB,CAAC;SAC9B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,CAAC,EACtD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,EAC3C,OAAO,CAAC,sBAAsB,CAAC,EAAE,EAAE,SAAS,CAAC,CAC9C,CACF;SACA,GAAG,EAAE,CAAC;AACX,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,EAAgC,EAChC,OAAe;IAEf,MAAM,EAAE;SACL,MAAM,CAAC,oBAAoB,CAAC;SAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,CAAC,EACpD,EAAE,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAC1C,CACF;SACA,GAAG,EAAE,CAAC;AACX,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,EAAgC,EAChC,UAAkB,EAClB,aAEqB;IAErB,IAAI,CAAC,aAAa;QAAE,OAAO;IAC3B,MAAM,mDAAmD,CAAC;QACxD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,aAAa;QACb,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,EAAE;QAC3D,EAAE;KACH,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,KAIrC;IACC,IACE,KAAK,CAAC,aAAa;QACnB,KAAK,CAAC,QAAQ,CAAC,+BAA+B;QAC9C,4BAA4B,CAC1B,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,QAAQ,CAAC,cAAc,CAC9B;QACD,sBAAsB,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAC1E,CAAC;QACD,MAAM,4BAA4B,CAChC,KAAK,CAAC,EAAE,EACR,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAC1B,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CACxC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,OAAsE,EACtE,KAAoE,EACpE,EAAgC;IAEhC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC,sBAAsB;YACtE,CAAC,CAAC,MAAM,6BAA6B,CACjC,EAAE,EACF,KAAK,CAAC,QAAQ,CAAC,EAAE,EACjB,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CACjC;YACH,CAAC,CAAC;gBACE,aAAa,EAAE,EAAE;gBACjB,yBAAyB,EAAE,KAAK;gBAChC,2BAA2B,EAAE,KAAK;gBAClC,wBAAwB,EAAE,KAAK;gBAC/B,OAAO,EAAE,EAAE;aACZ,CAAC;QACN,IACE,KAAK,CAAC,iBAAiB,CAAC,sBAAsB;YAC9C,CAAC,iBAAiB,CAAC,yBAAyB;gBAC1C,iBAAiB,CAAC,2BAA2B,CAAC,EAChD,CAAC;YACD,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAC;QACJ,CAAC;QACD,IACE,KAAK,CAAC,iBAAiB,CAAC,sBAAsB;YAC9C,iBAAiB,CAAC,wBAAwB,EAC1C,CAAC;YACD,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE,CAAC;QACJ,CAAC;QACD,MAAM,kBAAkB,GAAG,MAAM,gCAAgC,CAC/D,OAAO,EACP,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAC3D;YACE,GAAG,KAAK,CAAC,iBAAiB;YAC1B,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,sBAAsB;gBAC5D,CAAC,CAAC,iBAAiB,CAAC,OAAO;gBAC3B,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,cAAc;SAC3C,CACF,CAAC;QACF,IAAI,KAAK,CAAC,iBAAiB,CAAC,sBAAsB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;QACJ,CAAC;QACD,MAAM,4BAA4B,CAChC,EAAE,EACF,KAAK,CAAC,QAAQ,CAAC,EAAE,EACjB,iBAAiB,CAAC,aAAa,CAChC,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,4BAA4B,CAChC,OAAO,EACP,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAC3D,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,mBAAmB,IAAI,OAAO,CACrC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,6BAA6B,CAC1C,EAAgC,EAChC,OAAe,EACf,gBAAwB;IAQxB,MAAM,iBAAiB,GAAG,MAAM,cAAc,CAC5C,8BAA8B,OAAO,EAAE,CACxC,CAAC;IACF,IAAI,CAAC;QACH,cAAc,CAAC,iBAAiB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,GAAG,CACf,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,CAAC,EACtD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAC5C,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,EAAE;aAC5B,MAAM,CAAC;YACN,EAAE,EAAE,sBAAsB,CAAC,EAAE;YAC7B,mBAAmB,EAAE,sBAAsB,CAAC,mBAAmB;YAC/D,UAAU,EAAE,sBAAsB,CAAC,UAAU;SAC9C,CAAC;aACD,IAAI,CAAC,sBAAsB,CAAC;aAC5B,KAAK,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,EAAE;aAClB,MAAM,CAAC;YACN,EAAE,EAAE,sBAAsB,CAAC,EAAE;YAC7B,UAAU,EAAE,sBAAsB,CAAC,UAAU;SAC9C,CAAC;aACD,IAAI,CAAC,sBAAsB,CAAC;aAC5B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,CAAC,EACtD,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAC5C,CACF,CAAC;QACJ,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAClC,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7B,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,GAAG,CAAC,mBAAmB,KAAK,IAAI;YACjD,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CACrB,CACF,CAAC;QACF,IAAI,wBAAwB,GAAG,KAAK,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnC,IAAI,GAAG,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;gBACpB,iEAAiE;gBACjE,iEAAiE;gBACjE,wBAAwB,GAAG,IAAI,CAAC;gBAChC,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC;gBACH,IACE,4BAA4B,CAC1B,iBAAiB,EACjB,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAC9B,EACD,CAAC;oBACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,gEAAgE;YAClE,CAAC;YACD,wBAAwB,GAAG,IAAI,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,OAAO;YACL,aAAa,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5C,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,GAAG,CAAC,mBAAmB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CACpE;YACD,yBAAyB,EAAE,cAAc,CAAC,IAAI,CAC5C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,mBAAmB,KAAK,IAAI,CAC1C;YACD,2BAA2B,EAAE,cAAc,CAAC,IAAI,CAC9C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,CACzB;YACD,wBAAwB;YACxB,OAAO;SACR,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AASD,KAAK,UAAU,2BAA2B,CAAC,KAM1C;IACC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC9C,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,YAAY,CAC5C,aAAa,EACb,QAAQ,CAAC,QAAQ,CAAC,EAAE,CACrB,CAAC;IACF,IAAI,QAAQ,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC;QACtD,OAAO,EAAE,SAAS,EAAE,KAAc,EAAE,aAAa,EAAE,CAAC;IACtD,CAAC;IACD,IACE,CAAC,aAAa;QACd,CAAC,0BAA0B,CAAC,aAAa,EAAE,QAAQ,CAAC,cAAc,CAAC,EACnE,CAAC;QACD,MAAM,sBAAsB,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9D,OAAO,EAAE,SAAS,EAAE,KAAc,EAAE,aAAa,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,4BAA4B,CAAC;YACjC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAC7B,OAAO,EAAE,QAAQ,CAAC,iBAAiB;YACnC,EAAE;SACH,CAAC,CAAC;IACL,CAAC;IACD,IAAI,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,iCAAiC,CAAC;YACtC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAC7B,OAAO,EAAE,QAAQ,CAAC,iBAAiB;YACnC,EAAE;SACH,CAAC,CAAC;IACL,CAAC;IACD,MAAM,qBAAqB,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC5E,MAAM,4BAA4B,CAChC,EAAE,EACF,QAAQ,CAAC,QAAQ,CAAC,EAAE,EACpB,QAAQ,CAAC,wBAAwB,CAClC,CAAC;IACF,IAAI,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC9B,MAAM,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAAC;QACnD,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,OAAO,EACL,QAAQ,CAAC,SAAS,KAAK,SAAS;YAC9B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE;QACvC,EAAE;KACH,CAAC,CAAC;IACH,IACE,CAAC,CAAC,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EACzE,CAAC;QACD,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,CAAC,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAC3D,OAAO,EAAE,SAAS,EAAE,IAAa,EAAE,SAAS,EAAE,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,oCAAoC,CAAC,KAKnD;IACC,MAAM,OAAO,GAAG,MAAM,iCAAiC,CACrD,KAAK,CAAC,aAAa,CACpB,CAAC,kBAAkB,CAClB,CAAC,EAAE,EAAE,EAAE,CAAC,2BAA2B,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,EACrD,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,EACnE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CAAC;IACF,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,OAAO;QACL,SAAS,EAAE,KAAc;QACzB,aAAa,EAAE,MAAM,KAAK,CAAC,YAAY,CACrC,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAC3B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAAsE,EACtE,KAAkC,EAClC,oBAA0C,EAC1C,YAAkD;IAElD,OAAO,wBAAwB,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,EAAE,CACzD,oCAAoC,CAAC;QACnC,aAAa;QACb,YAAY;QACZ,QAAQ,EAAE,KAAK;QACf,oBAAoB;KACrB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,OAA4E,EAC5E,KAA0E,EAC1E,YAAkD;IAElD,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAC/D,iCAAiC,CAAC,aAAa,CAAC,CAAC,WAAW,CAC1D,KAAK,EAAE,EAAE,EAAE,EAAE;QACX,MAAM,aAAa,GAAG,MAAM,YAAY,CACtC,aAAa,EACb,KAAK,CAAC,cAAc,CAAC,EAAE,CACxB,CAAC;QACF,IACE,aAAa;YACb,4BAA4B,CAAC,aAAa,EAAE,KAAK,CAAC,cAAc,CAAC;YACjE,sBAAsB,CAAC,aAAa,EAAE,KAAK,CAAC,cAAc,CAAC,EAC3D,CAAC;YACD,MAAM,4BAA4B,CAChC,EAAE,EACF,KAAK,CAAC,cAAc,CAAC,EAAE,EACvB,KAAK,CAAC,gBAAgB,CACvB,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC,EACD,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CACF,CAAC;AACJ,CAAC","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport {\n createDocument,\n importSnapshot,\n updateMatchesDocumentHistory,\n} from \"@tearleads/loro\";\nimport { and, eq, inArray } from \"drizzle-orm\";\nimport { documentSyncPullContinuationsEqual } from \"../../../documents/shared/pullContinuation\";\nimport {\n appendDocumentHistoryUpdates,\n replaceDocumentHistoryCheckpoint,\n} from \"../../../sqlite/documentHistoryPersistence\";\nimport { insertDocumentPendingUpdateWithHistoryInTransaction } from \"../../../sqlite/documentPendingUpdatePersistence\";\nimport {\n documentHistoryUpdates,\n documentPendingUpdates,\n documentSyncFailures,\n} from \"../../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../../sqlite/sqlSchema\";\nimport type { DocumentsPersistence, StoredDocumentRecord } from \"../types\";\nimport {\n applyStoredAttachmentRemoval,\n upsertStoredAttachmentStagingRows,\n} from \"./attachmentStagingPersistence\";\nimport { DOCUMENTS_APP_KIND } from \"./constants\";\nimport {\n sameDocumentSecurityIdentity,\n sameNullableDocumentValue,\n} from \"./documentRecordIdentity\";\nimport { resolveDocumentSaveTimestamp, saveDocumentRows } from \"./documentRows\";\n\nfunction sameRecoveryGeneration(\n current: StoredDocumentRecord,\n expected: StoredDocumentRecord,\n): boolean {\n return (\n (current.recoveryGeneration ?? 0) === (expected.recoveryGeneration ?? 0)\n );\n}\n\nfunction sameExpectedDocumentRecord(\n current: StoredDocumentRecord,\n expected: StoredDocumentRecord,\n): boolean {\n return (\n sameDocumentSecurityIdentity(current, expected) &&\n sameRecoveryGeneration(current, expected) &&\n sameNullableDocumentValue(current.lastCommitLsn, expected.lastCommitLsn) &&\n current.snapshotEndVersion === expected.snapshotEndVersion &&\n sameNullableDocumentValue(\n current.pendingBaseVersion,\n expected.pendingBaseVersion,\n ) &&\n documentSyncPullContinuationsEqual(\n current.pullContinuation,\n expected.pullContinuation,\n ) &&\n Boolean(current.pullContinuationRecoveryRequired) ===\n Boolean(expected.pullContinuationRecoveryRequired) &&\n (current.documentKind ?? null) === (expected.documentKind ?? null) &&\n current.text === expected.text &&\n (current.title ?? null) === (expected.title ?? null)\n );\n}\n\nasync function deleteAcceptedPendingUpdates(\n tx: ClientSQLiteTransactionScope,\n localId: 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, DOCUMENTS_APP_KIND),\n eq(documentPendingUpdates.localId, localId),\n inArray(documentPendingUpdates.id, uniqueIds),\n ),\n )\n .run();\n}\n\nasync function clearSyncFailure(\n tx: ClientSQLiteTransactionScope,\n localId: string,\n): Promise<void> {\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND),\n eq(documentSyncFailures.localId, localId),\n ),\n )\n .run();\n}\n\nasync function insertPendingUpdate(\n tx: ClientSQLiteTransactionScope,\n documentId: string,\n pendingUpdate: Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n >[1][\"pendingUpdate\"],\n): Promise<void> {\n if (!pendingUpdate) return;\n await insertDocumentPendingUpdateWithHistoryInTransaction({\n createdAt: new Date().toISOString(),\n pendingUpdate,\n scope: { appKind: DOCUMENTS_APP_KIND, localId: documentId },\n tx,\n });\n}\n\nasync function settleMutationConflict(input: {\n currentRecord: StoredDocumentRecord | null;\n mutation: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[1];\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n if (\n input.currentRecord &&\n input.mutation.settleAcceptedPendingOnConflict &&\n sameDocumentSecurityIdentity(\n input.currentRecord,\n input.mutation.expectedRecord,\n ) &&\n sameRecoveryGeneration(input.currentRecord, input.mutation.expectedRecord)\n ) {\n await deleteAcceptedPendingUpdates(\n input.tx,\n input.mutation.document.id,\n input.mutation.acceptedPendingUpdateIds,\n );\n }\n}\n\nasync function appendMutationHistory(\n execSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0],\n input: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[1],\n tx: ClientSQLiteTransactionScope,\n): Promise<void> {\n if (input.historyCheckpoint) {\n const coveredLocalState = input.historyCheckpoint.pruneCoveredLocalState\n ? await findCoveredRecoveryLocalState(\n tx,\n input.document.id,\n input.historyCheckpoint.snapshot,\n )\n : {\n checkpointIds: [],\n hasOrdinaryPendingUpdates: false,\n hasUnprunablePendingUpdates: false,\n hasUnverifiedHistoryTail: false,\n tailIds: [],\n };\n if (\n input.historyCheckpoint.pruneCoveredLocalState &&\n (coveredLocalState.hasOrdinaryPendingUpdates ||\n coveredLocalState.hasUnprunablePendingUpdates)\n ) {\n throw new Error(\n \"Document recovery found unproven pending updates before installation\",\n );\n }\n if (\n input.historyCheckpoint.pruneCoveredLocalState &&\n coveredLocalState.hasUnverifiedHistoryTail\n ) {\n throw new Error(\n \"Document recovery found unverified history tail before installation\",\n );\n }\n const checkpointReplaced = await replaceDocumentHistoryCheckpoint(\n execSql,\n { appKind: DOCUMENTS_APP_KIND, localId: input.document.id },\n {\n ...input.historyCheckpoint,\n coveredTailIds: input.historyCheckpoint.pruneCoveredLocalState\n ? coveredLocalState.tailIds\n : input.historyCheckpoint.coveredTailIds,\n },\n );\n if (input.historyCheckpoint.pruneCoveredLocalState && !checkpointReplaced) {\n throw new Error(\n \"Document recovery checkpoint was superseded before installation\",\n );\n }\n await deleteAcceptedPendingUpdates(\n tx,\n input.document.id,\n coveredLocalState.checkpointIds,\n );\n }\n if (input.historyUpdates && input.historyUpdates.length > 0) {\n await appendDocumentHistoryUpdates(\n execSql,\n { appKind: DOCUMENTS_APP_KIND, localId: input.document.id },\n input.historyUpdates,\n input.historyUpdateOrigin ?? \"local\",\n );\n }\n}\n\nasync function findCoveredRecoveryLocalState(\n tx: ClientSQLiteTransactionScope,\n localId: string,\n recoverySnapshot: string,\n): Promise<{\n checkpointIds: string[];\n hasOrdinaryPendingUpdates: boolean;\n hasUnprunablePendingUpdates: boolean;\n hasUnverifiedHistoryTail: boolean;\n tailIds: string[];\n}> {\n const recoveredDocument = await createDocument(\n `recovery-tail-verification:${localId}`,\n );\n try {\n importSnapshot(recoveredDocument, base64ToBytes(recoverySnapshot));\n const scope = and(\n eq(documentPendingUpdates.appKind, DOCUMENTS_APP_KIND),\n eq(documentPendingUpdates.localId, localId),\n );\n const pendingUpdates = await tx\n .select({\n id: documentPendingUpdates.id,\n sourceVersionVector: documentPendingUpdates.sourceVersionVector,\n updateData: documentPendingUpdates.updateData,\n })\n .from(documentPendingUpdates)\n .where(scope);\n const tail = await tx\n .select({\n id: documentHistoryUpdates.id,\n updateData: documentHistoryUpdates.updateData,\n })\n .from(documentHistoryUpdates)\n .where(\n and(\n eq(documentHistoryUpdates.appKind, DOCUMENTS_APP_KIND),\n eq(documentHistoryUpdates.localId, localId),\n ),\n );\n const checkpointUpdateData = new Set(\n pendingUpdates.flatMap((row) =>\n row.id === null || row.sourceVersionVector === null\n ? []\n : [row.updateData],\n ),\n );\n let hasUnverifiedHistoryTail = false;\n const tailIds = tail.flatMap((row) => {\n if (row.id === null) {\n // An unverifiable row identity cannot participate in the guarded\n // delete, so accepting it would leave a stale recovery redirect.\n hasUnverifiedHistoryTail = true;\n return [];\n }\n if (checkpointUpdateData.has(row.updateData)) return [row.id];\n try {\n if (\n updateMatchesDocumentHistory(\n recoveredDocument,\n base64ToBytes(row.updateData),\n )\n ) {\n return [row.id];\n }\n } catch {\n // Fall through: malformed history is not proven by the rebuild.\n }\n hasUnverifiedHistoryTail = true;\n return [];\n });\n return {\n checkpointIds: pendingUpdates.flatMap((row) =>\n row.id !== null && row.sourceVersionVector !== null ? [row.id] : [],\n ),\n hasOrdinaryPendingUpdates: pendingUpdates.some(\n (row) => row.sourceVersionVector === null,\n ),\n hasUnprunablePendingUpdates: pendingUpdates.some(\n (row) => row.id === null,\n ),\n hasUnverifiedHistoryTail,\n tailIds,\n };\n } finally {\n recoveredDocument.free();\n }\n}\n\ntype CommitDocumentMutationInput = Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n>[1];\ntype SaveClientProjection = Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n>[2];\n\nasync function applyStoredDocumentMutation(input: {\n lockedExecSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0];\n mutation: CommitDocumentMutationInput;\n saveClientProjection: SaveClientProjection;\n tx: ClientSQLiteTransactionScope;\n loadDocument: DocumentsPersistence[\"loadDocument\"];\n}) {\n const { lockedExecSql, mutation, tx } = input;\n const currentRecord = await input.loadDocument(\n lockedExecSql,\n mutation.document.id,\n );\n if (mutation.stillCurrent && !mutation.stillCurrent()) {\n return { committed: false as const, currentRecord };\n }\n if (\n !currentRecord ||\n !sameExpectedDocumentRecord(currentRecord, mutation.expectedRecord)\n ) {\n await settleMutationConflict({ currentRecord, mutation, tx });\n return { committed: false as const, currentRecord };\n }\n\n if (mutation.attachmentRemoval) {\n await applyStoredAttachmentRemoval({\n localId: mutation.document.id,\n removal: mutation.attachmentRemoval,\n tx,\n });\n }\n if (mutation.attachmentStaging) {\n await upsertStoredAttachmentStagingRows({\n createdAt: new Date().toISOString(),\n localId: mutation.document.id,\n staging: mutation.attachmentStaging,\n tx,\n });\n }\n await appendMutationHistory(lockedExecSql, mutation, tx);\n await insertPendingUpdate(tx, mutation.document.id, mutation.pendingUpdate);\n await deleteAcceptedPendingUpdates(\n tx,\n mutation.document.id,\n mutation.acceptedPendingUpdateIds,\n );\n if (mutation.clearSyncFailure) {\n await clearSyncFailure(tx, mutation.document.id);\n }\n const updatedAt = await resolveDocumentSaveTimestamp({\n document: mutation.document,\n options:\n mutation.updatedAt === undefined\n ? undefined\n : { updatedAt: mutation.updatedAt },\n tx,\n });\n if (\n !(await saveDocumentRows({ document: mutation.document, tx, updatedAt }))\n ) {\n throw new Error(\n \"Document recovery generation changed before mutation save\",\n );\n }\n await input.saveClientProjection(lockedExecSql, updatedAt);\n return { committed: true as const, updatedAt };\n}\n\nasync function runStoredDocumentMutationTransaction(input: {\n lockedExecSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0];\n mutation: CommitDocumentMutationInput;\n saveClientProjection: SaveClientProjection;\n loadDocument: DocumentsPersistence[\"loadDocument\"];\n}) {\n const outcome = await getClientSQLitePersistenceRuntime(\n input.lockedExecSql,\n ).guardedTransaction(\n (tx) => applyStoredDocumentMutation({ ...input, tx }),\n () => !input.mutation.stillCurrent || input.mutation.stillCurrent(),\n { behavior: \"immediate\" },\n );\n if (outcome.committed && outcome.result) {\n return outcome.result;\n }\n return {\n committed: false as const,\n currentRecord: await input.loadDocument(\n input.lockedExecSql,\n input.mutation.document.id,\n ),\n };\n}\n\nexport async function commitStoredDocumentMutation(\n execSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0],\n input: CommitDocumentMutationInput,\n saveClientProjection: SaveClientProjection,\n loadDocument: DocumentsPersistence[\"loadDocument\"],\n) {\n return runSerializedSqlMutation(execSql, (lockedExecSql) =>\n runStoredDocumentMutationTransaction({\n lockedExecSql,\n loadDocument,\n mutation: input,\n saveClientProjection,\n }),\n );\n}\n\nexport async function settleStoredDocumentPendingUpdates(\n execSql: Parameters<DocumentsPersistence[\"settleAcceptedPendingUpdates\"]>[0],\n input: Parameters<DocumentsPersistence[\"settleAcceptedPendingUpdates\"]>[1],\n loadDocument: DocumentsPersistence[\"loadDocument\"],\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const currentRecord = await loadDocument(\n lockedExecSql,\n input.expectedRecord.id,\n );\n if (\n currentRecord &&\n sameDocumentSecurityIdentity(currentRecord, input.expectedRecord) &&\n sameRecoveryGeneration(currentRecord, input.expectedRecord)\n ) {\n await deleteAcceptedPendingUpdates(\n tx,\n input.expectedRecord.id,\n input.pendingUpdateIds,\n );\n }\n return currentRecord;\n },\n { behavior: \"immediate\" },\n ),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentMutationPersistence.js","sourceRoot":"","sources":["documentMutationPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { base64ToBytes } from \"@tearleads/encoding\";\nimport {\n createDocument,\n importSnapshot,\n updateMatchesDocumentHistory,\n} from \"@tearleads/loro\";\nimport { and, eq } from \"drizzle-orm\";\nimport { documentSyncPullContinuationsEqual } from \"../../../documents/shared/pullContinuation\";\nimport {\n appendDocumentHistoryUpdates,\n replaceDocumentHistoryCheckpoint,\n} from \"../../../sqlite/documentHistoryPersistence\";\nimport {\n insertDocumentPendingUpdateWithHistoryInTransaction,\n settleQueuedDocumentUpdatesInTransaction,\n} from \"../../../sqlite/documentPendingUpdatePersistence\";\nimport {\n documentHistoryUpdates,\n documentSyncFailures,\n} from \"../../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../../sqlite/sqlSchema\";\nimport type { DocumentsPersistence, StoredDocumentRecord } from \"../types\";\nimport {\n applyStoredAttachmentRemoval,\n upsertStoredAttachmentStagingRows,\n} from \"./attachmentStagingPersistence\";\nimport { DOCUMENTS_APP_KIND } from \"./constants\";\nimport {\n sameDocumentSecurityIdentity,\n sameNullableDocumentValue,\n} from \"./documentRecordIdentity\";\nimport { resolveDocumentSaveTimestamp, saveDocumentRows } from \"./documentRows\";\n\nfunction sameRecoveryGeneration(\n current: StoredDocumentRecord,\n expected: StoredDocumentRecord,\n): boolean {\n return (\n (current.recoveryGeneration ?? 0) === (expected.recoveryGeneration ?? 0)\n );\n}\n\nfunction sameExpectedDocumentRecord(\n current: StoredDocumentRecord,\n expected: StoredDocumentRecord,\n): boolean {\n return (\n sameDocumentSecurityIdentity(current, expected) &&\n sameRecoveryGeneration(current, expected) &&\n sameNullableDocumentValue(current.lastCommitLsn, expected.lastCommitLsn) &&\n current.snapshotEndVersion === expected.snapshotEndVersion &&\n sameNullableDocumentValue(\n current.pendingBaseVersion,\n expected.pendingBaseVersion,\n ) &&\n documentSyncPullContinuationsEqual(\n current.pullContinuation,\n expected.pullContinuation,\n ) &&\n Boolean(current.pullContinuationRecoveryRequired) ===\n Boolean(expected.pullContinuationRecoveryRequired) &&\n (current.documentKind ?? null) === (expected.documentKind ?? null) &&\n current.text === expected.text &&\n (current.title ?? null) === (expected.title ?? null)\n );\n}\n\nasync function deleteAcceptedPendingUpdates(\n tx: ClientSQLiteTransactionScope,\n localId: string,\n ids: readonly string[],\n): Promise<void> {\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n { appKind: DOCUMENTS_APP_KIND, localId },\n ids,\n );\n}\n\nasync function clearSyncFailure(\n tx: ClientSQLiteTransactionScope,\n localId: string,\n): Promise<void> {\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND),\n eq(documentSyncFailures.localId, localId),\n ),\n )\n .run();\n}\n\nasync function insertPendingUpdate(\n tx: ClientSQLiteTransactionScope,\n documentId: string,\n pendingUpdate: Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n >[1][\"pendingUpdate\"],\n): Promise<void> {\n if (!pendingUpdate) return;\n await insertDocumentPendingUpdateWithHistoryInTransaction({\n createdAt: new Date().toISOString(),\n pendingUpdate,\n scope: { appKind: DOCUMENTS_APP_KIND, localId: documentId },\n tx,\n });\n}\n\nasync function settleMutationConflict(input: {\n currentRecord: StoredDocumentRecord | null;\n mutation: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[1];\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n if (\n input.currentRecord &&\n input.mutation.settleAcceptedPendingOnConflict &&\n sameDocumentSecurityIdentity(\n input.currentRecord,\n input.mutation.expectedRecord,\n ) &&\n sameRecoveryGeneration(input.currentRecord, input.mutation.expectedRecord)\n ) {\n await deleteAcceptedPendingUpdates(\n input.tx,\n input.mutation.document.id,\n input.mutation.acceptedPendingUpdateIds,\n );\n }\n}\n\nasync function appendMutationHistory(\n execSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0],\n input: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[1],\n tx: ClientSQLiteTransactionScope,\n): Promise<void> {\n if (input.historyCheckpoint) {\n const coveredLocalState = input.historyCheckpoint.pruneCoveredLocalState\n ? await findCoveredRecoveryLocalState(\n tx,\n input.document.id,\n input.historyCheckpoint.snapshot,\n )\n : {\n checkpointIds: [],\n hasOrdinaryPendingUpdates: false,\n hasUnprunablePendingUpdates: false,\n hasUnverifiedHistoryTail: false,\n tailIds: [],\n };\n if (\n input.historyCheckpoint.pruneCoveredLocalState &&\n (coveredLocalState.hasOrdinaryPendingUpdates ||\n coveredLocalState.hasUnprunablePendingUpdates)\n ) {\n throw new Error(\n \"Document recovery found unproven pending updates before installation\",\n );\n }\n if (\n input.historyCheckpoint.pruneCoveredLocalState &&\n coveredLocalState.hasUnverifiedHistoryTail\n ) {\n throw new Error(\n \"Document recovery found unverified history tail before installation\",\n );\n }\n // A queued rotation baseline the recovery snapshot covers is unqueued\n // first so the replacement below can delete it with the covered tail.\n await deleteAcceptedPendingUpdates(\n tx,\n input.document.id,\n coveredLocalState.checkpointIds,\n );\n const checkpointReplaced = await replaceDocumentHistoryCheckpoint(\n execSql,\n { appKind: DOCUMENTS_APP_KIND, localId: input.document.id },\n {\n ...input.historyCheckpoint,\n coveredTailIds: input.historyCheckpoint.pruneCoveredLocalState\n ? coveredLocalState.tailIds\n : input.historyCheckpoint.coveredTailIds,\n },\n );\n if (input.historyCheckpoint.pruneCoveredLocalState && !checkpointReplaced) {\n throw new Error(\n \"Document recovery checkpoint was superseded before installation\",\n );\n }\n }\n if (input.historyUpdates && input.historyUpdates.length > 0) {\n await appendDocumentHistoryUpdates(\n execSql,\n { appKind: DOCUMENTS_APP_KIND, localId: input.document.id },\n input.historyUpdates,\n input.historyUpdateOrigin ?? \"local\",\n );\n }\n}\n\nasync function findCoveredRecoveryLocalState(\n tx: ClientSQLiteTransactionScope,\n localId: string,\n recoverySnapshot: string,\n): Promise<{\n checkpointIds: string[];\n hasOrdinaryPendingUpdates: boolean;\n hasUnprunablePendingUpdates: boolean;\n hasUnverifiedHistoryTail: boolean;\n tailIds: string[];\n}> {\n const recoveredDocument = await createDocument(\n `recovery-tail-verification:${localId}`,\n );\n try {\n importSnapshot(recoveredDocument, base64ToBytes(recoverySnapshot));\n const rows = await tx\n .select({\n id: documentHistoryUpdates.id,\n origin: documentHistoryUpdates.origin,\n sourceVersionVector: documentHistoryUpdates.sourceVersionVector,\n updateData: documentHistoryUpdates.updateData,\n updateId: documentHistoryUpdates.updateId,\n })\n .from(documentHistoryUpdates)\n .where(\n and(\n eq(documentHistoryUpdates.appKind, DOCUMENTS_APP_KIND),\n eq(documentHistoryUpdates.localId, localId),\n ),\n );\n const pendingUpdates = rows.filter((row) => row.updateId !== null);\n const tail = rows.filter((row) => row.origin !== \"outbox\");\n const checkpointUpdateData = new Set(\n pendingUpdates.flatMap((row) =>\n row.sourceVersionVector === null ? [] : [row.updateData],\n ),\n );\n let hasUnverifiedHistoryTail = false;\n const tailIds = tail.flatMap((row) => {\n if (row.id === null) {\n // An unverifiable row identity cannot participate in the guarded\n // delete, so accepting it would leave a stale recovery redirect.\n hasUnverifiedHistoryTail = true;\n return [];\n }\n if (checkpointUpdateData.has(row.updateData)) return [row.id];\n try {\n if (\n updateMatchesDocumentHistory(\n recoveredDocument,\n base64ToBytes(row.updateData),\n )\n ) {\n return [row.id];\n }\n } catch {\n // Fall through: malformed history is not proven by the rebuild.\n }\n hasUnverifiedHistoryTail = true;\n return [];\n });\n return {\n checkpointIds: pendingUpdates.flatMap((row) =>\n row.updateId !== null && row.sourceVersionVector !== null\n ? [row.updateId]\n : [],\n ),\n hasOrdinaryPendingUpdates: pendingUpdates.some(\n (row) => row.sourceVersionVector === null,\n ),\n hasUnprunablePendingUpdates: pendingUpdates.some(\n (row) => row.id === null,\n ),\n hasUnverifiedHistoryTail,\n tailIds,\n };\n } finally {\n recoveredDocument.free();\n }\n}\n\ntype CommitDocumentMutationInput = Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n>[1];\ntype SaveClientProjection = Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n>[2];\n\nasync function applyStoredDocumentMutation(input: {\n lockedExecSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0];\n mutation: CommitDocumentMutationInput;\n saveClientProjection: SaveClientProjection;\n tx: ClientSQLiteTransactionScope;\n loadDocument: DocumentsPersistence[\"loadDocument\"];\n}) {\n const { lockedExecSql, mutation, tx } = input;\n const currentRecord = await input.loadDocument(\n lockedExecSql,\n mutation.document.id,\n );\n if (mutation.stillCurrent && !mutation.stillCurrent()) {\n return { committed: false as const, currentRecord };\n }\n if (\n !currentRecord ||\n !sameExpectedDocumentRecord(currentRecord, mutation.expectedRecord)\n ) {\n await settleMutationConflict({ currentRecord, mutation, tx });\n return { committed: false as const, currentRecord };\n }\n\n if (mutation.attachmentRemoval) {\n await applyStoredAttachmentRemoval({\n localId: mutation.document.id,\n removal: mutation.attachmentRemoval,\n tx,\n });\n }\n if (mutation.attachmentStaging) {\n await upsertStoredAttachmentStagingRows({\n createdAt: new Date().toISOString(),\n localId: mutation.document.id,\n staging: mutation.attachmentStaging,\n tx,\n });\n }\n await appendMutationHistory(lockedExecSql, mutation, tx);\n await insertPendingUpdate(tx, mutation.document.id, mutation.pendingUpdate);\n await deleteAcceptedPendingUpdates(\n tx,\n mutation.document.id,\n mutation.acceptedPendingUpdateIds,\n );\n if (mutation.clearSyncFailure) {\n await clearSyncFailure(tx, mutation.document.id);\n }\n const updatedAt = await resolveDocumentSaveTimestamp({\n document: mutation.document,\n options:\n mutation.updatedAt === undefined\n ? undefined\n : { updatedAt: mutation.updatedAt },\n tx,\n });\n if (\n !(await saveDocumentRows({ document: mutation.document, tx, updatedAt }))\n ) {\n throw new Error(\n \"Document recovery generation changed before mutation save\",\n );\n }\n await input.saveClientProjection(lockedExecSql, updatedAt);\n return { committed: true as const, updatedAt };\n}\n\nasync function runStoredDocumentMutationTransaction(input: {\n lockedExecSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0];\n mutation: CommitDocumentMutationInput;\n saveClientProjection: SaveClientProjection;\n loadDocument: DocumentsPersistence[\"loadDocument\"];\n}) {\n const outcome = await getClientSQLitePersistenceRuntime(\n input.lockedExecSql,\n ).guardedTransaction(\n (tx) => applyStoredDocumentMutation({ ...input, tx }),\n () => !input.mutation.stillCurrent || input.mutation.stillCurrent(),\n { behavior: \"immediate\" },\n );\n if (outcome.committed && outcome.result) {\n return outcome.result;\n }\n return {\n committed: false as const,\n currentRecord: await input.loadDocument(\n input.lockedExecSql,\n input.mutation.document.id,\n ),\n };\n}\n\nexport async function commitStoredDocumentMutation(\n execSql: Parameters<DocumentsPersistence[\"commitDocumentMutation\"]>[0],\n input: CommitDocumentMutationInput,\n saveClientProjection: SaveClientProjection,\n loadDocument: DocumentsPersistence[\"loadDocument\"],\n) {\n return runSerializedSqlMutation(execSql, (lockedExecSql) =>\n runStoredDocumentMutationTransaction({\n lockedExecSql,\n loadDocument,\n mutation: input,\n saveClientProjection,\n }),\n );\n}\n\nexport async function settleStoredDocumentPendingUpdates(\n execSql: Parameters<DocumentsPersistence[\"settleAcceptedPendingUpdates\"]>[0],\n input: Parameters<DocumentsPersistence[\"settleAcceptedPendingUpdates\"]>[1],\n loadDocument: DocumentsPersistence[\"loadDocument\"],\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const currentRecord = await loadDocument(\n lockedExecSql,\n input.expectedRecord.id,\n );\n if (\n currentRecord &&\n sameDocumentSecurityIdentity(currentRecord, input.expectedRecord) &&\n sameRecoveryGeneration(currentRecord, input.expectedRecord)\n ) {\n await deleteAcceptedPendingUpdates(\n tx,\n input.expectedRecord.id,\n input.pendingUpdateIds,\n );\n }\n return currentRecord;\n },\n { behavior: \"immediate\" },\n ),\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { and, asc, eq, inArray, isNotNull, lt, notExists, or, } from "drizzle-orm";
|
|
2
2
|
import { documentOrphanBlobReclaims } from "../../../sqlite/documentOrphanBlobReclaims.js";
|
|
3
|
-
import { documentAttachmentBlobProjection, documentHistoryCheckpoints, documentHistoryUpdates, documentPendingAttachments,
|
|
3
|
+
import { documentAttachmentBlobProjection, documentHistoryCheckpoints, documentHistoryUpdates, documentPendingAttachments, documentSyncFailures, documents, } from "../../../sqlite/schema.js";
|
|
4
4
|
import { getClientSQLitePersistenceRuntime, } from "../../../sqlite/sqlitePersistenceRuntime.js";
|
|
5
5
|
import { runSerializedSqlMutation, } from "../../../sqlite/sqlSchema.js";
|
|
6
6
|
import { DOCUMENTS_APP_KIND } from "./constants.js";
|
|
@@ -68,17 +68,12 @@ async function selectHistorySweepCandidates(tx, olderThan) {
|
|
|
68
68
|
return { checkpoints, updates };
|
|
69
69
|
}
|
|
70
70
|
async function selectWriteSweepCandidates(tx, olderThan) {
|
|
71
|
-
const pendingUpdates = await tx
|
|
72
|
-
.select({ id: documentPendingUpdates.id })
|
|
73
|
-
.from(documentPendingUpdates)
|
|
74
|
-
.where(and(eq(documentPendingUpdates.appKind, DOCUMENTS_APP_KIND), isNotNull(documentPendingUpdates.id), lt(documentPendingUpdates.createdAt, olderThan), hasNoDocument(tx, documentPendingUpdates.localId)))
|
|
75
|
-
.limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);
|
|
76
71
|
const syncFailures = await tx
|
|
77
72
|
.select({ localId: documentSyncFailures.localId })
|
|
78
73
|
.from(documentSyncFailures)
|
|
79
74
|
.where(and(eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND), lt(documentSyncFailures.attemptedAt, olderThan), hasNoDocument(tx, documentSyncFailures.localId)))
|
|
80
75
|
.limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);
|
|
81
|
-
return {
|
|
76
|
+
return { syncFailures };
|
|
82
77
|
}
|
|
83
78
|
async function selectAttachmentSweepCandidates(tx, olderThan) {
|
|
84
79
|
const pending = await tx
|
|
@@ -116,12 +111,6 @@ async function deleteHistorySweepCandidates(tx, candidates) {
|
|
|
116
111
|
}
|
|
117
112
|
}
|
|
118
113
|
async function deleteWriteSweepCandidates(tx, candidates) {
|
|
119
|
-
if (candidates.pendingUpdates.length > 0) {
|
|
120
|
-
await tx
|
|
121
|
-
.delete(documentPendingUpdates)
|
|
122
|
-
.where(inArray(documentPendingUpdates.id, candidates.pendingUpdates.flatMap((row) => row.id === null ? [] : [row.id])))
|
|
123
|
-
.run();
|
|
124
|
-
}
|
|
125
114
|
if (candidates.syncFailures.length > 0) {
|
|
126
115
|
await tx
|
|
127
116
|
.delete(documentSyncFailures)
|
|
@@ -150,7 +139,6 @@ function hasFullSweepBatch(history, writes, attachments) {
|
|
|
150
139
|
return [
|
|
151
140
|
history.checkpoints,
|
|
152
141
|
history.updates,
|
|
153
|
-
writes.pendingUpdates,
|
|
154
142
|
writes.syncFailures,
|
|
155
143
|
attachments.pending,
|
|
156
144
|
attachments.local,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orphanSideRows.js","sourceRoot":"","sources":["orphanSideRows.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n and,\n asc,\n eq,\n inArray,\n isNotNull,\n lt,\n notExists,\n or,\n type SQL,\n} from \"drizzle-orm\";\nimport { documentOrphanBlobReclaims } from \"../../../sqlite/documentOrphanBlobReclaims\";\nimport {\n documentAttachmentBlobProjection,\n documentHistoryCheckpoints,\n documentHistoryUpdates,\n documentPendingAttachments,\n documentPendingUpdates,\n documentSyncFailures,\n documents,\n} from \"../../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n runSerializedSqlMutation,\n} from \"../../../sqlite/sqlSchema\";\nimport { DOCUMENTS_APP_KIND } from \"./constants\";\n\n// Crash residue gets a full day to outlive slow devices and wall-clock skew;\n// canonical-row absence is necessary but never sufficient for fresh writes.\nconst DOCUMENT_ORPHAN_SWEEP_MIN_AGE_MS = 24 * 60 * 60 * 1000;\nconst DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE = 32;\n\ntype DocumentSideLocalIdColumn =\n | typeof documentAttachmentBlobProjection.localId\n | typeof documentHistoryCheckpoints.localId\n | typeof documentHistoryUpdates.localId\n | typeof documentPendingAttachments.localId\n | typeof documentPendingUpdates.localId\n | typeof documentSyncFailures.localId;\n\nfunction requirePredicate(predicate: SQL | undefined): SQL {\n if (!predicate) {\n throw new Error(\"Document orphan cleanup requires a SQL predicate\");\n }\n return predicate;\n}\n\nfunction hasNoDocument(\n tx: ClientSQLiteTransactionScope,\n localId: DocumentSideLocalIdColumn,\n appKind: string | null = DOCUMENTS_APP_KIND,\n): SQL {\n return notExists(\n tx\n .select({ localId: documents.localId })\n .from(documents)\n .where(\n appKind === null\n ? eq(documents.localId, localId)\n : and(eq(documents.appKind, appKind), eq(documents.localId, localId)),\n ),\n );\n}\n\nexport async function queueDocumentAttachmentBlobReclaims(input: {\n localWhere: SQL;\n pendingWhere: SQL;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { localWhere, pendingWhere, tx } = input;\n const [pendingAttachmentRows, localAttachmentRows] = await Promise.all([\n tx\n .select({ storageKey: documentPendingAttachments.storageKey })\n .from(documentPendingAttachments)\n .where(pendingWhere),\n tx\n .select({ storageKey: documentAttachmentBlobProjection.storageKey })\n .from(documentAttachmentBlobProjection)\n .where(localWhere),\n ]);\n const storageKeys = [\n ...new Set(\n [...pendingAttachmentRows, ...localAttachmentRows].map(\n (row) => row.storageKey,\n ),\n ),\n ];\n await queueDocumentAttachmentStorageKeys(tx, storageKeys);\n}\n\nexport async function queueDocumentAttachmentStorageKeys(\n tx: ClientSQLiteTransactionScope,\n storageKeys: ReadonlyArray<string>,\n): Promise<void> {\n if (storageKeys.length > 0) {\n await tx\n .insert(documentOrphanBlobReclaims)\n .values(storageKeys.map((storageKey) => ({ storageKey })))\n .onConflictDoNothing()\n .run();\n }\n}\n\ninterface AttachmentSweepCandidate {\n localId: string;\n slotId: string;\n storageKey: string;\n}\n\nfunction pendingAttachmentCandidatesWhere(\n candidates: ReadonlyArray<AttachmentSweepCandidate>,\n): SQL {\n return requirePredicate(\n or(\n ...candidates.map((candidate) =>\n and(\n eq(documentPendingAttachments.localId, candidate.localId),\n eq(documentPendingAttachments.slotId, candidate.slotId),\n ),\n ),\n ),\n );\n}\n\nfunction localAttachmentCandidatesWhere(\n candidates: ReadonlyArray<AttachmentSweepCandidate>,\n): SQL {\n return requirePredicate(\n or(\n ...candidates.map((candidate) =>\n and(\n eq(documentAttachmentBlobProjection.localId, candidate.localId),\n eq(documentAttachmentBlobProjection.slotId, candidate.slotId),\n ),\n ),\n ),\n );\n}\n\ninterface HistorySweepCandidates {\n checkpoints: ReadonlyArray<{ localId: string }>;\n updates: ReadonlyArray<{ id: string | null }>;\n}\n\ninterface WriteSweepCandidates {\n pendingUpdates: ReadonlyArray<{ id: string | null }>;\n syncFailures: ReadonlyArray<{ localId: string }>;\n}\n\ninterface AttachmentSweepCandidates {\n local: ReadonlyArray<AttachmentSweepCandidate>;\n pending: ReadonlyArray<AttachmentSweepCandidate>;\n}\n\nasync function selectHistorySweepCandidates(\n tx: ClientSQLiteTransactionScope,\n olderThan: string,\n): Promise<HistorySweepCandidates> {\n const checkpoints = await tx\n .select({ localId: documentHistoryCheckpoints.localId })\n .from(documentHistoryCheckpoints)\n .where(\n and(\n eq(documentHistoryCheckpoints.appKind, DOCUMENTS_APP_KIND),\n lt(documentHistoryCheckpoints.updatedAt, olderThan),\n hasNoDocument(tx, documentHistoryCheckpoints.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n const updates = await tx\n .select({ id: documentHistoryUpdates.id })\n .from(documentHistoryUpdates)\n .where(\n and(\n eq(documentHistoryUpdates.appKind, DOCUMENTS_APP_KIND),\n isNotNull(documentHistoryUpdates.id),\n lt(documentHistoryUpdates.createdAt, olderThan),\n hasNoDocument(tx, documentHistoryUpdates.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n return { checkpoints, updates };\n}\n\nasync function selectWriteSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n olderThan: string,\n): Promise<WriteSweepCandidates> {\n const pendingUpdates = await tx\n .select({ id: documentPendingUpdates.id })\n .from(documentPendingUpdates)\n .where(\n and(\n eq(documentPendingUpdates.appKind, DOCUMENTS_APP_KIND),\n isNotNull(documentPendingUpdates.id),\n lt(documentPendingUpdates.createdAt, olderThan),\n hasNoDocument(tx, documentPendingUpdates.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n const syncFailures = await tx\n .select({ localId: documentSyncFailures.localId })\n .from(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND),\n lt(documentSyncFailures.attemptedAt, olderThan),\n hasNoDocument(tx, documentSyncFailures.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n return { pendingUpdates, syncFailures };\n}\n\nasync function selectAttachmentSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n olderThan: string,\n): Promise<AttachmentSweepCandidates> {\n const pending = await tx\n .select({\n localId: documentPendingAttachments.localId,\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n })\n .from(documentPendingAttachments)\n .where(\n and(\n lt(documentPendingAttachments.createdAt, olderThan),\n hasNoDocument(tx, documentPendingAttachments.localId, null),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n const local = await tx\n .select({\n localId: documentAttachmentBlobProjection.localId,\n slotId: documentAttachmentBlobProjection.slotId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n })\n .from(documentAttachmentBlobProjection)\n .where(\n and(\n lt(documentAttachmentBlobProjection.updatedAt, olderThan),\n hasNoDocument(tx, documentAttachmentBlobProjection.localId, null),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n return { local, pending };\n}\n\nasync function deleteHistorySweepCandidates(\n tx: ClientSQLiteTransactionScope,\n candidates: HistorySweepCandidates,\n): Promise<void> {\n if (candidates.checkpoints.length > 0) {\n await tx\n .delete(documentHistoryCheckpoints)\n .where(\n and(\n eq(documentHistoryCheckpoints.appKind, DOCUMENTS_APP_KIND),\n inArray(\n documentHistoryCheckpoints.localId,\n candidates.checkpoints.map((row) => row.localId),\n ),\n ),\n )\n .run();\n }\n if (candidates.updates.length > 0) {\n await tx\n .delete(documentHistoryUpdates)\n .where(\n inArray(\n documentHistoryUpdates.id,\n candidates.updates.flatMap((row) =>\n row.id === null ? [] : [row.id],\n ),\n ),\n )\n .run();\n }\n}\n\nasync function deleteWriteSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n candidates: WriteSweepCandidates,\n): Promise<void> {\n if (candidates.pendingUpdates.length > 0) {\n await tx\n .delete(documentPendingUpdates)\n .where(\n inArray(\n documentPendingUpdates.id,\n candidates.pendingUpdates.flatMap((row) =>\n row.id === null ? [] : [row.id],\n ),\n ),\n )\n .run();\n }\n if (candidates.syncFailures.length > 0) {\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND),\n inArray(\n documentSyncFailures.localId,\n candidates.syncFailures.map((row) => row.localId),\n ),\n ),\n )\n .run();\n }\n}\n\nasync function deleteAttachmentSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n candidates: AttachmentSweepCandidates,\n): Promise<void> {\n await queueDocumentAttachmentStorageKeys(tx, [\n ...new Set(\n [...candidates.pending, ...candidates.local].map((row) => row.storageKey),\n ),\n ]);\n if (candidates.pending.length > 0) {\n await tx\n .delete(documentPendingAttachments)\n .where(pendingAttachmentCandidatesWhere(candidates.pending))\n .run();\n }\n if (candidates.local.length > 0) {\n await tx\n .delete(documentAttachmentBlobProjection)\n .where(localAttachmentCandidatesWhere(candidates.local))\n .run();\n }\n}\n\nfunction hasFullSweepBatch(\n history: HistorySweepCandidates,\n writes: WriteSweepCandidates,\n attachments: AttachmentSweepCandidates,\n): boolean {\n return [\n history.checkpoints,\n history.updates,\n writes.pendingUpdates,\n writes.syncFailures,\n attachments.pending,\n attachments.local,\n ].some((rows) => rows.length === DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n}\n\n/** Remove one bounded batch of aged side writes without a canonical row. */\nexport async function deleteOrphanedDocumentSideRows(\n execSql: ExecSql,\n options: { now?: Date | undefined } = {},\n): Promise<boolean> {\n const olderThan = new Date(\n (options.now?.getTime() ?? Date.now()) - DOCUMENT_ORPHAN_SWEEP_MIN_AGE_MS,\n ).toISOString();\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(async (tx) => {\n const history = await selectHistorySweepCandidates(tx, olderThan);\n const writes = await selectWriteSweepCandidates(tx, olderThan);\n const attachments = await selectAttachmentSweepCandidates(tx, olderThan);\n await deleteHistorySweepCandidates(tx, history);\n await deleteWriteSweepCandidates(tx, writes);\n await deleteAttachmentSweepCandidates(tx, attachments);\n return hasFullSweepBatch(history, writes, attachments);\n }),\n );\n}\n\nexport async function listDocumentOrphanBlobReclaims(\n execSql: ExecSql,\n limit: number,\n): Promise<ReadonlyArray<string>> {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ storageKey: documentOrphanBlobReclaims.storageKey })\n .from(documentOrphanBlobReclaims)\n .orderBy(asc(documentOrphanBlobReclaims.storageKey))\n .limit(limit);\n return rows.map((row) => row.storageKey);\n}\n\nexport async function isDocumentBlobStorageKeyReferenced(\n execSql: ExecSql,\n storageKey: string,\n): Promise<boolean> {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const [pendingRows, localRows] = await Promise.all([\n db\n .select({ storageKey: documentPendingAttachments.storageKey })\n .from(documentPendingAttachments)\n .where(eq(documentPendingAttachments.storageKey, storageKey))\n .limit(1),\n db\n .select({ storageKey: documentAttachmentBlobProjection.storageKey })\n .from(documentAttachmentBlobProjection)\n .where(eq(documentAttachmentBlobProjection.storageKey, storageKey))\n .limit(1),\n ]);\n return pendingRows.length > 0 || localRows.length > 0;\n}\n\nexport async function acknowledgeDocumentOrphanBlobReclaim(\n execSql: ExecSql,\n storageKey: string,\n): Promise<void> {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n await db\n .delete(documentOrphanBlobReclaims)\n .where(eq(documentOrphanBlobReclaims.storageKey, storageKey))\n .run();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"orphanSideRows.js","sourceRoot":"","sources":["orphanSideRows.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n and,\n asc,\n eq,\n inArray,\n isNotNull,\n lt,\n notExists,\n or,\n type SQL,\n} from \"drizzle-orm\";\nimport { documentOrphanBlobReclaims } from \"../../../sqlite/documentOrphanBlobReclaims\";\nimport {\n documentAttachmentBlobProjection,\n documentHistoryCheckpoints,\n documentHistoryUpdates,\n documentPendingAttachments,\n documentSyncFailures,\n documents,\n} from \"../../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n runSerializedSqlMutation,\n} from \"../../../sqlite/sqlSchema\";\nimport { DOCUMENTS_APP_KIND } from \"./constants\";\n\n// Crash residue gets a full day to outlive slow devices and wall-clock skew;\n// canonical-row absence is necessary but never sufficient for fresh writes.\nconst DOCUMENT_ORPHAN_SWEEP_MIN_AGE_MS = 24 * 60 * 60 * 1000;\nconst DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE = 32;\n\ntype DocumentSideLocalIdColumn =\n | typeof documentAttachmentBlobProjection.localId\n | typeof documentHistoryCheckpoints.localId\n | typeof documentHistoryUpdates.localId\n | typeof documentPendingAttachments.localId\n | typeof documentSyncFailures.localId;\n\nfunction requirePredicate(predicate: SQL | undefined): SQL {\n if (!predicate) {\n throw new Error(\"Document orphan cleanup requires a SQL predicate\");\n }\n return predicate;\n}\n\nfunction hasNoDocument(\n tx: ClientSQLiteTransactionScope,\n localId: DocumentSideLocalIdColumn,\n appKind: string | null = DOCUMENTS_APP_KIND,\n): SQL {\n return notExists(\n tx\n .select({ localId: documents.localId })\n .from(documents)\n .where(\n appKind === null\n ? eq(documents.localId, localId)\n : and(eq(documents.appKind, appKind), eq(documents.localId, localId)),\n ),\n );\n}\n\nexport async function queueDocumentAttachmentBlobReclaims(input: {\n localWhere: SQL;\n pendingWhere: SQL;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { localWhere, pendingWhere, tx } = input;\n const [pendingAttachmentRows, localAttachmentRows] = await Promise.all([\n tx\n .select({ storageKey: documentPendingAttachments.storageKey })\n .from(documentPendingAttachments)\n .where(pendingWhere),\n tx\n .select({ storageKey: documentAttachmentBlobProjection.storageKey })\n .from(documentAttachmentBlobProjection)\n .where(localWhere),\n ]);\n const storageKeys = [\n ...new Set(\n [...pendingAttachmentRows, ...localAttachmentRows].map(\n (row) => row.storageKey,\n ),\n ),\n ];\n await queueDocumentAttachmentStorageKeys(tx, storageKeys);\n}\n\nexport async function queueDocumentAttachmentStorageKeys(\n tx: ClientSQLiteTransactionScope,\n storageKeys: ReadonlyArray<string>,\n): Promise<void> {\n if (storageKeys.length > 0) {\n await tx\n .insert(documentOrphanBlobReclaims)\n .values(storageKeys.map((storageKey) => ({ storageKey })))\n .onConflictDoNothing()\n .run();\n }\n}\n\ninterface AttachmentSweepCandidate {\n localId: string;\n slotId: string;\n storageKey: string;\n}\n\nfunction pendingAttachmentCandidatesWhere(\n candidates: ReadonlyArray<AttachmentSweepCandidate>,\n): SQL {\n return requirePredicate(\n or(\n ...candidates.map((candidate) =>\n and(\n eq(documentPendingAttachments.localId, candidate.localId),\n eq(documentPendingAttachments.slotId, candidate.slotId),\n ),\n ),\n ),\n );\n}\n\nfunction localAttachmentCandidatesWhere(\n candidates: ReadonlyArray<AttachmentSweepCandidate>,\n): SQL {\n return requirePredicate(\n or(\n ...candidates.map((candidate) =>\n and(\n eq(documentAttachmentBlobProjection.localId, candidate.localId),\n eq(documentAttachmentBlobProjection.slotId, candidate.slotId),\n ),\n ),\n ),\n );\n}\n\ninterface HistorySweepCandidates {\n checkpoints: ReadonlyArray<{ localId: string }>;\n updates: ReadonlyArray<{ id: string | null }>;\n}\n\ninterface WriteSweepCandidates {\n syncFailures: ReadonlyArray<{ localId: string }>;\n}\n\ninterface AttachmentSweepCandidates {\n local: ReadonlyArray<AttachmentSweepCandidate>;\n pending: ReadonlyArray<AttachmentSweepCandidate>;\n}\n\nasync function selectHistorySweepCandidates(\n tx: ClientSQLiteTransactionScope,\n olderThan: string,\n): Promise<HistorySweepCandidates> {\n const checkpoints = await tx\n .select({ localId: documentHistoryCheckpoints.localId })\n .from(documentHistoryCheckpoints)\n .where(\n and(\n eq(documentHistoryCheckpoints.appKind, DOCUMENTS_APP_KIND),\n lt(documentHistoryCheckpoints.updatedAt, olderThan),\n hasNoDocument(tx, documentHistoryCheckpoints.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n const updates = await tx\n .select({ id: documentHistoryUpdates.id })\n .from(documentHistoryUpdates)\n .where(\n and(\n eq(documentHistoryUpdates.appKind, DOCUMENTS_APP_KIND),\n isNotNull(documentHistoryUpdates.id),\n lt(documentHistoryUpdates.createdAt, olderThan),\n hasNoDocument(tx, documentHistoryUpdates.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n return { checkpoints, updates };\n}\n\nasync function selectWriteSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n olderThan: string,\n): Promise<WriteSweepCandidates> {\n const syncFailures = await tx\n .select({ localId: documentSyncFailures.localId })\n .from(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND),\n lt(documentSyncFailures.attemptedAt, olderThan),\n hasNoDocument(tx, documentSyncFailures.localId),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n return { syncFailures };\n}\n\nasync function selectAttachmentSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n olderThan: string,\n): Promise<AttachmentSweepCandidates> {\n const pending = await tx\n .select({\n localId: documentPendingAttachments.localId,\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n })\n .from(documentPendingAttachments)\n .where(\n and(\n lt(documentPendingAttachments.createdAt, olderThan),\n hasNoDocument(tx, documentPendingAttachments.localId, null),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n const local = await tx\n .select({\n localId: documentAttachmentBlobProjection.localId,\n slotId: documentAttachmentBlobProjection.slotId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n })\n .from(documentAttachmentBlobProjection)\n .where(\n and(\n lt(documentAttachmentBlobProjection.updatedAt, olderThan),\n hasNoDocument(tx, documentAttachmentBlobProjection.localId, null),\n ),\n )\n .limit(DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n return { local, pending };\n}\n\nasync function deleteHistorySweepCandidates(\n tx: ClientSQLiteTransactionScope,\n candidates: HistorySweepCandidates,\n): Promise<void> {\n if (candidates.checkpoints.length > 0) {\n await tx\n .delete(documentHistoryCheckpoints)\n .where(\n and(\n eq(documentHistoryCheckpoints.appKind, DOCUMENTS_APP_KIND),\n inArray(\n documentHistoryCheckpoints.localId,\n candidates.checkpoints.map((row) => row.localId),\n ),\n ),\n )\n .run();\n }\n if (candidates.updates.length > 0) {\n await tx\n .delete(documentHistoryUpdates)\n .where(\n inArray(\n documentHistoryUpdates.id,\n candidates.updates.flatMap((row) =>\n row.id === null ? [] : [row.id],\n ),\n ),\n )\n .run();\n }\n}\n\nasync function deleteWriteSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n candidates: WriteSweepCandidates,\n): Promise<void> {\n if (candidates.syncFailures.length > 0) {\n await tx\n .delete(documentSyncFailures)\n .where(\n and(\n eq(documentSyncFailures.appKind, DOCUMENTS_APP_KIND),\n inArray(\n documentSyncFailures.localId,\n candidates.syncFailures.map((row) => row.localId),\n ),\n ),\n )\n .run();\n }\n}\n\nasync function deleteAttachmentSweepCandidates(\n tx: ClientSQLiteTransactionScope,\n candidates: AttachmentSweepCandidates,\n): Promise<void> {\n await queueDocumentAttachmentStorageKeys(tx, [\n ...new Set(\n [...candidates.pending, ...candidates.local].map((row) => row.storageKey),\n ),\n ]);\n if (candidates.pending.length > 0) {\n await tx\n .delete(documentPendingAttachments)\n .where(pendingAttachmentCandidatesWhere(candidates.pending))\n .run();\n }\n if (candidates.local.length > 0) {\n await tx\n .delete(documentAttachmentBlobProjection)\n .where(localAttachmentCandidatesWhere(candidates.local))\n .run();\n }\n}\n\nfunction hasFullSweepBatch(\n history: HistorySweepCandidates,\n writes: WriteSweepCandidates,\n attachments: AttachmentSweepCandidates,\n): boolean {\n return [\n history.checkpoints,\n history.updates,\n writes.syncFailures,\n attachments.pending,\n attachments.local,\n ].some((rows) => rows.length === DOCUMENT_ORPHAN_SWEEP_BATCH_SIZE);\n}\n\n/** Remove one bounded batch of aged side writes without a canonical row. */\nexport async function deleteOrphanedDocumentSideRows(\n execSql: ExecSql,\n options: { now?: Date | undefined } = {},\n): Promise<boolean> {\n const olderThan = new Date(\n (options.now?.getTime() ?? Date.now()) - DOCUMENT_ORPHAN_SWEEP_MIN_AGE_MS,\n ).toISOString();\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(async (tx) => {\n const history = await selectHistorySweepCandidates(tx, olderThan);\n const writes = await selectWriteSweepCandidates(tx, olderThan);\n const attachments = await selectAttachmentSweepCandidates(tx, olderThan);\n await deleteHistorySweepCandidates(tx, history);\n await deleteWriteSweepCandidates(tx, writes);\n await deleteAttachmentSweepCandidates(tx, attachments);\n return hasFullSweepBatch(history, writes, attachments);\n }),\n );\n}\n\nexport async function listDocumentOrphanBlobReclaims(\n execSql: ExecSql,\n limit: number,\n): Promise<ReadonlyArray<string>> {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ storageKey: documentOrphanBlobReclaims.storageKey })\n .from(documentOrphanBlobReclaims)\n .orderBy(asc(documentOrphanBlobReclaims.storageKey))\n .limit(limit);\n return rows.map((row) => row.storageKey);\n}\n\nexport async function isDocumentBlobStorageKeyReferenced(\n execSql: ExecSql,\n storageKey: string,\n): Promise<boolean> {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const [pendingRows, localRows] = await Promise.all([\n db\n .select({ storageKey: documentPendingAttachments.storageKey })\n .from(documentPendingAttachments)\n .where(eq(documentPendingAttachments.storageKey, storageKey))\n .limit(1),\n db\n .select({ storageKey: documentAttachmentBlobProjection.storageKey })\n .from(documentAttachmentBlobProjection)\n .where(eq(documentAttachmentBlobProjection.storageKey, storageKey))\n .limit(1),\n ]);\n return pendingRows.length > 0 || localRows.length > 0;\n}\n\nexport async function acknowledgeDocumentOrphanBlobReclaim(\n execSql: ExecSql,\n storageKey: string,\n): Promise<void> {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n await db\n .delete(documentOrphanBlobReclaims)\n .where(eq(documentOrphanBlobReclaims.storageKey, storageKey))\n .run();\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { and, eq, isNull } from "drizzle-orm";
|
|
2
2
|
import { appendDocumentHistoryUpdates, listDocumentHistoryTailEntries, loadDocumentHistoryRestoreState, readDocumentHistoryTailSize, replaceDocumentHistoryCheckpoint, } from "../../../sqlite/documentHistoryPersistence.js";
|
|
3
|
-
import {
|
|
3
|
+
import { enqueueDocumentPendingUpdateWithHistory, listDocumentPendingUpdates, rekeyDocumentPendingUpdate, settleDocumentPendingUpdate, unqueueDocumentPendingUpdates, } from "../../../sqlite/documentPersistence.js";
|
|
4
4
|
import { documentAttachmentBlobProjection, documentPendingAttachments, } from "../../../sqlite/schema.js";
|
|
5
5
|
import { getClientSQLitePersistenceRuntime } from "../../../sqlite/sqlitePersistenceRuntime.js";
|
|
6
6
|
import { runSerializedSqlMutation } from "../../../sqlite/sqlSchema.js";
|
|
@@ -169,12 +169,12 @@ export const documentSyncQueuePersistence = {
|
|
|
169
169
|
},
|
|
170
170
|
async deletePendingUpdate(execSql, id) {
|
|
171
171
|
await runSerializedSqlMutation(execSql, async (lockedExecSql) => {
|
|
172
|
-
await
|
|
172
|
+
await settleDocumentPendingUpdate(lockedExecSql, id);
|
|
173
173
|
});
|
|
174
174
|
},
|
|
175
175
|
async deletePendingUpdates(execSql, localId) {
|
|
176
176
|
await runSerializedSqlMutation(execSql, async (lockedExecSql) => {
|
|
177
|
-
await
|
|
177
|
+
await unqueueDocumentPendingUpdates(lockedExecSql, getDocumentScope(localId));
|
|
178
178
|
});
|
|
179
179
|
},
|
|
180
180
|
async deletePendingAttachment(execSql, localId, slotId, storageKey) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncQueuePersistence.js","sourceRoot":"","sources":["syncQueuePersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, isNull } from \"drizzle-orm\";\nimport {\n appendDocumentHistoryUpdates,\n listDocumentHistoryTailEntries,\n loadDocumentHistoryRestoreState,\n readDocumentHistoryTailSize,\n replaceDocumentHistoryCheckpoint,\n} from \"../../../sqlite/documentHistoryPersistence\";\nimport {\n deleteDocumentPendingUpdate,\n deleteDocumentPendingUpdates,\n enqueueDocumentPendingUpdateWithHistory,\n listDocumentPendingUpdates,\n rekeyDocumentPendingUpdate,\n} from \"../../../sqlite/documentPersistence\";\nimport {\n documentAttachmentBlobProjection,\n documentPendingAttachments,\n} from \"../../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../../sqlite/sqlSchema\";\nimport type { DocumentsPersistence } from \"../types\";\nimport {\n buildPendingAttachmentRow,\n mapLocalAttachmentRecord,\n mapPendingAttachmentRecord,\n} from \"./attachmentRows\";\nimport { getDocumentScope } from \"./documentRows\";\nimport { queueDocumentAttachmentStorageKeys } from \"./orphanSideRows\";\n\ntype DocumentSyncQueuePersistence = Pick<\n DocumentsPersistence,\n | \"listPendingUpdates\"\n | \"rekeyPendingUpdate\"\n | \"listPendingAttachments\"\n | \"listLocalAttachments\"\n | \"appendHistoryUpdates\"\n | \"loadHistoryRestoreState\"\n | \"readHistoryTailSize\"\n | \"listHistoryTailEntries\"\n | \"replaceHistoryCheckpoint\"\n | \"enqueuePendingUpdate\"\n | \"saveLocalAttachment\"\n | \"deleteLocalAttachment\"\n | \"markLocalAttachmentDetached\"\n | \"savePendingAttachment\"\n | \"deletePendingUpdate\"\n | \"deletePendingUpdates\"\n | \"deletePendingAttachment\"\n | \"deletePendingAttachments\"\n>;\n\nexport const documentSyncQueuePersistence: DocumentSyncQueuePersistence = {\n async listPendingUpdates(execSql, localId) {\n return listDocumentPendingUpdates(execSql, getDocumentScope(localId));\n },\n async rekeyPendingUpdate(execSql, id) {\n return rekeyDocumentPendingUpdate(execSql, id);\n },\n async listPendingAttachments(execSql, localId) {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({\n localId: documentPendingAttachments.localId,\n slotId: documentPendingAttachments.slotId,\n name: documentPendingAttachments.name,\n mimeType: documentPendingAttachments.mimeType,\n storageKey: documentPendingAttachments.storageKey,\n byteLength: documentPendingAttachments.byteLength,\n contentSha256: documentPendingAttachments.contentSha256,\n uploadBlobId: documentPendingAttachments.uploadBlobId,\n uploadContentKey: documentPendingAttachments.uploadContentKey,\n uploadIv: documentPendingAttachments.uploadIv,\n uploadContentKeyEpoch: documentPendingAttachments.uploadContentKeyEpoch,\n uploadPartSize: documentPendingAttachments.uploadPartSize,\n uploadPlaintextSha256: documentPendingAttachments.uploadPlaintextSha256,\n uploadStageId: documentPendingAttachments.uploadStageId,\n })\n .from(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, localId))\n .orderBy(\n documentPendingAttachments.createdAt,\n documentPendingAttachments.slotId,\n );\n\n return rows.map(mapPendingAttachmentRecord);\n },\n // Detached rows are included on purpose: they are the durable markers the\n // next sync uses to detach the remote binding, so a restart has to restore\n // them alongside the live slots.\n async listLocalAttachments(execSql, localId) {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({\n localId: documentAttachmentBlobProjection.localId,\n slotId: documentAttachmentBlobProjection.slotId,\n blobId: documentAttachmentBlobProjection.blobId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n mimeType: documentAttachmentBlobProjection.mimeType,\n byteLength: documentAttachmentBlobProjection.byteLength,\n contentSha256: documentAttachmentBlobProjection.contentSha256,\n detachedAt: documentAttachmentBlobProjection.detachedAt,\n })\n .from(documentAttachmentBlobProjection)\n .where(eq(documentAttachmentBlobProjection.localId, localId));\n\n return rows.map(mapLocalAttachmentRecord);\n },\n async appendHistoryUpdates(execSql, input) {\n await appendDocumentHistoryUpdates(\n execSql,\n getDocumentScope(input.localId),\n input.updates,\n input.origin,\n );\n },\n async loadHistoryRestoreState(execSql, localId) {\n return loadDocumentHistoryRestoreState(execSql, getDocumentScope(localId));\n },\n async readHistoryTailSize(execSql, localId) {\n return readDocumentHistoryTailSize(execSql, getDocumentScope(localId));\n },\n async listHistoryTailEntries(execSql, localId) {\n return listDocumentHistoryTailEntries(execSql, getDocumentScope(localId));\n },\n async replaceHistoryCheckpoint(execSql, input) {\n await replaceDocumentHistoryCheckpoint(\n execSql,\n getDocumentScope(input.localId),\n {\n coveredTailIds: input.coveredTailIds,\n endVersionVector: input.endVersionVector,\n ...(input.force === undefined ? {} : { force: input.force }),\n snapshot: input.snapshot,\n ...(input.stillCurrent === undefined\n ? {}\n : { stillCurrent: input.stillCurrent }),\n },\n );\n },\n async enqueuePendingUpdate(execSql, pendingUpdate, options) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const pendingUpdateId = await enqueueDocumentPendingUpdateWithHistory(\n lockedExecSql,\n getDocumentScope(pendingUpdate.localId),\n pendingUpdate,\n options,\n );\n return pendingUpdateId !== null;\n });\n },\n async saveLocalAttachment(execSql, attachment) {\n const updatedAt = new Date().toISOString();\n\n await getClientSQLitePersistenceRuntime(execSql).runMutation(async (db) => {\n const attachmentRow = {\n localId: attachment.localId,\n slotId: attachment.slotId,\n blobId: attachment.blobId,\n storageKey: attachment.storageKey,\n mimeType: attachment.mimeType,\n byteLength: attachment.byteLength,\n contentSha256: attachment.contentSha256,\n updatedAt,\n // Written on every save so re-filling a slot clears a stale detach\n // marker instead of inheriting it from the row it replaces.\n detachedAt: attachment.detachedAt,\n };\n await db\n .insert(documentAttachmentBlobProjection)\n .values(attachmentRow)\n .onConflictDoUpdate({\n target: [\n documentAttachmentBlobProjection.localId,\n documentAttachmentBlobProjection.slotId,\n ],\n set: attachmentRow,\n })\n .run();\n });\n },\n async deleteLocalAttachment(execSql, localId, slotId, storageKey) {\n await getClientSQLitePersistenceRuntime(execSql).transaction(async (db) => {\n await db\n .delete(documentAttachmentBlobProjection)\n .where(\n and(\n eq(documentAttachmentBlobProjection.localId, localId),\n eq(documentAttachmentBlobProjection.slotId, slotId),\n eq(documentAttachmentBlobProjection.storageKey, storageKey),\n ),\n )\n .run();\n // Another slot may hold the same hydrated copy; the reclaim deletes\n // the bytes only once no row references them.\n await queueDocumentAttachmentStorageKeys(db, [storageKey]);\n });\n },\n async markLocalAttachmentDetached(execSql, localId, slotId, storageKey) {\n const detachedAt = new Date().toISOString();\n\n await getClientSQLitePersistenceRuntime(execSql).runMutation(async (db) => {\n await db\n .update(documentAttachmentBlobProjection)\n .set({ detachedAt })\n .where(\n and(\n eq(documentAttachmentBlobProjection.localId, localId),\n eq(documentAttachmentBlobProjection.slotId, slotId),\n eq(documentAttachmentBlobProjection.storageKey, storageKey),\n isNull(documentAttachmentBlobProjection.detachedAt),\n ),\n )\n .run();\n });\n },\n async savePendingAttachment(execSql, attachment) {\n const createdAt = new Date().toISOString();\n\n await getClientSQLitePersistenceRuntime(execSql).runMutation(async (db) => {\n const attachmentRow = buildPendingAttachmentRow(attachment, createdAt);\n await db\n .insert(documentPendingAttachments)\n .values(attachmentRow)\n .onConflictDoUpdate({\n target: [\n documentPendingAttachments.localId,\n documentPendingAttachments.slotId,\n ],\n set: {\n name: attachmentRow.name,\n mimeType: attachmentRow.mimeType,\n storageKey: attachmentRow.storageKey,\n byteLength: attachmentRow.byteLength,\n contentSha256: attachmentRow.contentSha256,\n uploadBlobId: attachmentRow.uploadBlobId,\n uploadContentKey: attachmentRow.uploadContentKey,\n uploadIv: attachmentRow.uploadIv,\n uploadContentKeyEpoch: attachmentRow.uploadContentKeyEpoch,\n uploadPartSize: attachmentRow.uploadPartSize,\n uploadPlaintextSha256: attachmentRow.uploadPlaintextSha256,\n uploadStageId: attachmentRow.uploadStageId,\n },\n })\n .run();\n });\n },\n async deletePendingUpdate(execSql, id) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await deleteDocumentPendingUpdate(lockedExecSql, id);\n });\n },\n async deletePendingUpdates(execSql, localId) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await deleteDocumentPendingUpdates(\n lockedExecSql,\n getDocumentScope(localId),\n );\n });\n },\n async deletePendingAttachment(execSql, localId, slotId, storageKey) {\n await getClientSQLitePersistenceRuntime(execSql).transaction(async (db) => {\n await db\n .delete(documentPendingAttachments)\n .where(\n and(\n eq(documentPendingAttachments.localId, localId),\n eq(documentPendingAttachments.slotId, slotId),\n eq(documentPendingAttachments.storageKey, storageKey),\n ),\n )\n .run();\n // A dropped upload may hold the last reference to its staged bytes.\n await queueDocumentAttachmentStorageKeys(db, [storageKey]);\n });\n },\n async deletePendingAttachments(execSql, localId) {\n await getClientSQLitePersistenceRuntime(execSql).transaction(async (db) => {\n const deleted = await db\n .delete(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, localId))\n .returning({ storageKey: documentPendingAttachments.storageKey });\n await queueDocumentAttachmentStorageKeys(\n db,\n deleted.map(({ storageKey }) => storageKey),\n );\n });\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"syncQueuePersistence.js","sourceRoot":"","sources":["syncQueuePersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, isNull } from \"drizzle-orm\";\nimport {\n appendDocumentHistoryUpdates,\n listDocumentHistoryTailEntries,\n loadDocumentHistoryRestoreState,\n readDocumentHistoryTailSize,\n replaceDocumentHistoryCheckpoint,\n} from \"../../../sqlite/documentHistoryPersistence\";\nimport {\n enqueueDocumentPendingUpdateWithHistory,\n listDocumentPendingUpdates,\n rekeyDocumentPendingUpdate,\n settleDocumentPendingUpdate,\n unqueueDocumentPendingUpdates,\n} from \"../../../sqlite/documentPersistence\";\nimport {\n documentAttachmentBlobProjection,\n documentPendingAttachments,\n} from \"../../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../../sqlite/sqlitePersistenceRuntime\";\nimport { runSerializedSqlMutation } from \"../../../sqlite/sqlSchema\";\nimport type { DocumentsPersistence } from \"../types\";\nimport {\n buildPendingAttachmentRow,\n mapLocalAttachmentRecord,\n mapPendingAttachmentRecord,\n} from \"./attachmentRows\";\nimport { getDocumentScope } from \"./documentRows\";\nimport { queueDocumentAttachmentStorageKeys } from \"./orphanSideRows\";\n\ntype DocumentSyncQueuePersistence = Pick<\n DocumentsPersistence,\n | \"listPendingUpdates\"\n | \"rekeyPendingUpdate\"\n | \"listPendingAttachments\"\n | \"listLocalAttachments\"\n | \"appendHistoryUpdates\"\n | \"loadHistoryRestoreState\"\n | \"readHistoryTailSize\"\n | \"listHistoryTailEntries\"\n | \"replaceHistoryCheckpoint\"\n | \"enqueuePendingUpdate\"\n | \"saveLocalAttachment\"\n | \"deleteLocalAttachment\"\n | \"markLocalAttachmentDetached\"\n | \"savePendingAttachment\"\n | \"deletePendingUpdate\"\n | \"deletePendingUpdates\"\n | \"deletePendingAttachment\"\n | \"deletePendingAttachments\"\n>;\n\nexport const documentSyncQueuePersistence: DocumentSyncQueuePersistence = {\n async listPendingUpdates(execSql, localId) {\n return listDocumentPendingUpdates(execSql, getDocumentScope(localId));\n },\n async rekeyPendingUpdate(execSql, id) {\n return rekeyDocumentPendingUpdate(execSql, id);\n },\n async listPendingAttachments(execSql, localId) {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({\n localId: documentPendingAttachments.localId,\n slotId: documentPendingAttachments.slotId,\n name: documentPendingAttachments.name,\n mimeType: documentPendingAttachments.mimeType,\n storageKey: documentPendingAttachments.storageKey,\n byteLength: documentPendingAttachments.byteLength,\n contentSha256: documentPendingAttachments.contentSha256,\n uploadBlobId: documentPendingAttachments.uploadBlobId,\n uploadContentKey: documentPendingAttachments.uploadContentKey,\n uploadIv: documentPendingAttachments.uploadIv,\n uploadContentKeyEpoch: documentPendingAttachments.uploadContentKeyEpoch,\n uploadPartSize: documentPendingAttachments.uploadPartSize,\n uploadPlaintextSha256: documentPendingAttachments.uploadPlaintextSha256,\n uploadStageId: documentPendingAttachments.uploadStageId,\n })\n .from(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, localId))\n .orderBy(\n documentPendingAttachments.createdAt,\n documentPendingAttachments.slotId,\n );\n\n return rows.map(mapPendingAttachmentRecord);\n },\n // Detached rows are included on purpose: they are the durable markers the\n // next sync uses to detach the remote binding, so a restart has to restore\n // them alongside the live slots.\n async listLocalAttachments(execSql, localId) {\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({\n localId: documentAttachmentBlobProjection.localId,\n slotId: documentAttachmentBlobProjection.slotId,\n blobId: documentAttachmentBlobProjection.blobId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n mimeType: documentAttachmentBlobProjection.mimeType,\n byteLength: documentAttachmentBlobProjection.byteLength,\n contentSha256: documentAttachmentBlobProjection.contentSha256,\n detachedAt: documentAttachmentBlobProjection.detachedAt,\n })\n .from(documentAttachmentBlobProjection)\n .where(eq(documentAttachmentBlobProjection.localId, localId));\n\n return rows.map(mapLocalAttachmentRecord);\n },\n async appendHistoryUpdates(execSql, input) {\n await appendDocumentHistoryUpdates(\n execSql,\n getDocumentScope(input.localId),\n input.updates,\n input.origin,\n );\n },\n async loadHistoryRestoreState(execSql, localId) {\n return loadDocumentHistoryRestoreState(execSql, getDocumentScope(localId));\n },\n async readHistoryTailSize(execSql, localId) {\n return readDocumentHistoryTailSize(execSql, getDocumentScope(localId));\n },\n async listHistoryTailEntries(execSql, localId) {\n return listDocumentHistoryTailEntries(execSql, getDocumentScope(localId));\n },\n async replaceHistoryCheckpoint(execSql, input) {\n await replaceDocumentHistoryCheckpoint(\n execSql,\n getDocumentScope(input.localId),\n {\n coveredTailIds: input.coveredTailIds,\n endVersionVector: input.endVersionVector,\n ...(input.force === undefined ? {} : { force: input.force }),\n snapshot: input.snapshot,\n ...(input.stillCurrent === undefined\n ? {}\n : { stillCurrent: input.stillCurrent }),\n },\n );\n },\n async enqueuePendingUpdate(execSql, pendingUpdate, options) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const pendingUpdateId = await enqueueDocumentPendingUpdateWithHistory(\n lockedExecSql,\n getDocumentScope(pendingUpdate.localId),\n pendingUpdate,\n options,\n );\n return pendingUpdateId !== null;\n });\n },\n async saveLocalAttachment(execSql, attachment) {\n const updatedAt = new Date().toISOString();\n\n await getClientSQLitePersistenceRuntime(execSql).runMutation(async (db) => {\n const attachmentRow = {\n localId: attachment.localId,\n slotId: attachment.slotId,\n blobId: attachment.blobId,\n storageKey: attachment.storageKey,\n mimeType: attachment.mimeType,\n byteLength: attachment.byteLength,\n contentSha256: attachment.contentSha256,\n updatedAt,\n // Written on every save so re-filling a slot clears a stale detach\n // marker instead of inheriting it from the row it replaces.\n detachedAt: attachment.detachedAt,\n };\n await db\n .insert(documentAttachmentBlobProjection)\n .values(attachmentRow)\n .onConflictDoUpdate({\n target: [\n documentAttachmentBlobProjection.localId,\n documentAttachmentBlobProjection.slotId,\n ],\n set: attachmentRow,\n })\n .run();\n });\n },\n async deleteLocalAttachment(execSql, localId, slotId, storageKey) {\n await getClientSQLitePersistenceRuntime(execSql).transaction(async (db) => {\n await db\n .delete(documentAttachmentBlobProjection)\n .where(\n and(\n eq(documentAttachmentBlobProjection.localId, localId),\n eq(documentAttachmentBlobProjection.slotId, slotId),\n eq(documentAttachmentBlobProjection.storageKey, storageKey),\n ),\n )\n .run();\n // Another slot may hold the same hydrated copy; the reclaim deletes\n // the bytes only once no row references them.\n await queueDocumentAttachmentStorageKeys(db, [storageKey]);\n });\n },\n async markLocalAttachmentDetached(execSql, localId, slotId, storageKey) {\n const detachedAt = new Date().toISOString();\n\n await getClientSQLitePersistenceRuntime(execSql).runMutation(async (db) => {\n await db\n .update(documentAttachmentBlobProjection)\n .set({ detachedAt })\n .where(\n and(\n eq(documentAttachmentBlobProjection.localId, localId),\n eq(documentAttachmentBlobProjection.slotId, slotId),\n eq(documentAttachmentBlobProjection.storageKey, storageKey),\n isNull(documentAttachmentBlobProjection.detachedAt),\n ),\n )\n .run();\n });\n },\n async savePendingAttachment(execSql, attachment) {\n const createdAt = new Date().toISOString();\n\n await getClientSQLitePersistenceRuntime(execSql).runMutation(async (db) => {\n const attachmentRow = buildPendingAttachmentRow(attachment, createdAt);\n await db\n .insert(documentPendingAttachments)\n .values(attachmentRow)\n .onConflictDoUpdate({\n target: [\n documentPendingAttachments.localId,\n documentPendingAttachments.slotId,\n ],\n set: {\n name: attachmentRow.name,\n mimeType: attachmentRow.mimeType,\n storageKey: attachmentRow.storageKey,\n byteLength: attachmentRow.byteLength,\n contentSha256: attachmentRow.contentSha256,\n uploadBlobId: attachmentRow.uploadBlobId,\n uploadContentKey: attachmentRow.uploadContentKey,\n uploadIv: attachmentRow.uploadIv,\n uploadContentKeyEpoch: attachmentRow.uploadContentKeyEpoch,\n uploadPartSize: attachmentRow.uploadPartSize,\n uploadPlaintextSha256: attachmentRow.uploadPlaintextSha256,\n uploadStageId: attachmentRow.uploadStageId,\n },\n })\n .run();\n });\n },\n async deletePendingUpdate(execSql, id) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await settleDocumentPendingUpdate(lockedExecSql, id);\n });\n },\n async deletePendingUpdates(execSql, localId) {\n await runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await unqueueDocumentPendingUpdates(\n lockedExecSql,\n getDocumentScope(localId),\n );\n });\n },\n async deletePendingAttachment(execSql, localId, slotId, storageKey) {\n await getClientSQLitePersistenceRuntime(execSql).transaction(async (db) => {\n await db\n .delete(documentPendingAttachments)\n .where(\n and(\n eq(documentPendingAttachments.localId, localId),\n eq(documentPendingAttachments.slotId, slotId),\n eq(documentPendingAttachments.storageKey, storageKey),\n ),\n )\n .run();\n // A dropped upload may hold the last reference to its staged bytes.\n await queueDocumentAttachmentStorageKeys(db, [storageKey]);\n });\n },\n async deletePendingAttachments(execSql, localId) {\n await getClientSQLitePersistenceRuntime(execSql).transaction(async (db) => {\n const deleted = await db\n .delete(documentPendingAttachments)\n .where(eq(documentPendingAttachments.localId, localId))\n .returning({ storageKey: documentPendingAttachments.storageKey });\n await queueDocumentAttachmentStorageKeys(\n db,\n deleted.map(({ storageKey }) => storageKey),\n );\n });\n },\n};\n"]}
|
|
@@ -34,6 +34,11 @@ export declare function appendDocumentHistoryUpdates(execSql: ExecSql, scope: Do
|
|
|
34
34
|
* silently ignored.
|
|
35
35
|
*/
|
|
36
36
|
export declare function loadDocumentHistoryRestoreState(execSql: ExecSql, scope: DocumentScope): Promise<DocumentHistoryRestoreState | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Size of the tail compaction can shrink. Queued rows are excluded: they stay
|
|
39
|
+
* until settlement, so counting them would re-export full history on every
|
|
40
|
+
* persist while offline edits wait to sync.
|
|
41
|
+
*/
|
|
37
42
|
export declare function readDocumentHistoryTailSize(execSql: ExecSql, scope: DocumentScope): Promise<{
|
|
38
43
|
byteLength: number;
|
|
39
44
|
hasCheckpoint: boolean;
|
|
@@ -44,9 +49,10 @@ interface DocumentHistoryTailEntry {
|
|
|
44
49
|
readonly updateData: string;
|
|
45
50
|
}
|
|
46
51
|
/**
|
|
47
|
-
* The current tail rows WITH their payloads, so a compactor can
|
|
48
|
-
* row's ops are covered by the snapshot it is about to install
|
|
49
|
-
* pane's append may carry ops this pane's document has not merged
|
|
52
|
+
* The current compactable tail rows WITH their payloads, so a compactor can
|
|
53
|
+
* prove each row's ops are covered by the snapshot it is about to install
|
|
54
|
+
* (another pane's append may carry ops this pane's document has not merged
|
|
55
|
+
* yet). Queued rows are never candidates.
|
|
50
56
|
*/
|
|
51
57
|
export declare function listDocumentHistoryTailEntries(execSql: ExecSql, scope: DocumentScope): Promise<DocumentHistoryTailEntry[]>;
|
|
52
58
|
/**
|