@tearleads/client-sdk 0.1.82 → 0.1.85
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/data/documents/documentSync.js.map +1 -1
- package/data/documents/shared/crypto.js.map +1 -1
- package/data/documents/shared/types.d.ts +1 -1
- package/data/documents/shared/types.js.map +1 -1
- package/data/persistence/container-contents/containerContentsPersistence.js +2 -2
- package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerContentsPersistenceTypes.d.ts +1 -1
- package/data/persistence/container-contents/containerContentsPersistenceTypes.js.map +1 -1
- package/data/persistence/container-contents/containerDeletionPersistence.js +1 -1
- package/data/persistence/container-contents/containerDeletionPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerDocumentReassignment.js +7 -9
- package/data/persistence/container-contents/containerDocumentReassignment.js.map +1 -1
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js +3 -3
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMetadataPullContinuationPersistence.js +1 -1
- package/data/persistence/container-contents/containerMetadataPullContinuationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMetadataRows.js +4 -20
- package/data/persistence/container-contents/containerMetadataRows.js.map +1 -1
- package/data/persistence/container-contents/containerPendingUpdatePersistence.js +2 -2
- package/data/persistence/container-contents/containerPendingUpdatePersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRebindPersistence.js +4 -17
- package/data/persistence/container-contents/containerRebindPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerReconcilePersistence.js +1 -1
- package/data/persistence/container-contents/containerReconcilePersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRemovalWork.js +1 -1
- package/data/persistence/container-contents/containerRemovalWork.js.map +1 -1
- package/data/persistence/container-contents/containerStructuralRepair.js +5 -11
- package/data/persistence/container-contents/containerStructuralRepair.js.map +1 -1
- package/data/persistence/container-contents/documentContainerProjectionPersistence.js +34 -9
- package/data/persistence/container-contents/documentContainerProjectionPersistence.js.map +1 -1
- package/data/persistence/container-contents/dormantContainerMetadata.js +4 -14
- package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
- package/data/persistence/documents/documentDiscoveryEvidencePersistence.js +5 -9
- package/data/persistence/documents/documentDiscoveryEvidencePersistence.js.map +1 -1
- package/data/persistence/documents/documentDiscoveryReset.d.ts +6 -0
- package/data/persistence/documents/documentProjectionContainers.js +28 -0
- package/data/persistence/documents/documentProjectionContainers.js.map +1 -0
- package/data/persistence/documents/documentsPersistence.js +5 -9
- package/data/persistence/documents/documentsPersistence.js.map +1 -1
- package/data/persistence/documents/internal/containerDocumentTombstones.js +4 -11
- package/data/persistence/documents/internal/containerDocumentTombstones.js.map +1 -1
- package/data/persistence/documents/internal/createDocumentWithHistoryCheckpoint.js +1 -1
- package/data/persistence/documents/internal/createDocumentWithHistoryCheckpoint.js.map +1 -1
- package/data/persistence/documents/internal/discardDocument.js +2 -2
- package/data/persistence/documents/internal/discardDocument.js.map +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js +8 -22
- package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js +3 -3
- package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentPullContinuationPersistence.js +1 -1
- package/data/persistence/documents/internal/documentPullContinuationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentRecordIdentity.js.map +1 -1
- package/data/persistence/documents/internal/documentRows.js.map +1 -1
- package/data/persistence/documents/internal/ensureDocumentsSchema.js +1 -1
- package/data/persistence/documents/internal/ensureDocumentsSchema.js.map +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
- package/data/persistence/documents/internal/rowQueryPersistence.js +1 -1
- package/data/persistence/documents/internal/rowQueryPersistence.js.map +1 -1
- package/data/persistence/documents/internal/syncQueuePersistence.js +2 -2
- package/data/persistence/documents/internal/syncQueuePersistence.js.map +1 -1
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentHistoryPersistence.d.ts +1 -1
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentHistoryPersistence.js +5 -5
- package/data/persistence/documents/records/documentHistoryPersistence.js.map +1 -0
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPendingUpdatePersistence.d.ts +2 -2
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPendingUpdatePersistence.js +2 -2
- package/data/persistence/documents/records/documentPendingUpdatePersistence.js.map +1 -0
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPersistenceTypes.d.ts +2 -2
- package/data/persistence/documents/records/documentPersistenceTypes.js.map +1 -0
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentRecordPersistence.d.ts +1 -1
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentRecordPersistence.js +4 -4
- package/data/persistence/documents/records/documentRecordPersistence.js.map +1 -0
- package/data/persistence/documents/records/documentRowsInTransaction.js +68 -0
- package/data/persistence/documents/records/documentRowsInTransaction.js.map +1 -0
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentSyncFailurePersistence.d.ts +2 -2
- package/data/{sqlite/documentPersistence → persistence/documents/records}/documentSyncFailurePersistence.js +3 -3
- package/data/persistence/documents/records/documentSyncFailurePersistence.js.map +1 -0
- package/data/{sqlite/documentPersistence → persistence/documents/records}/index.d.ts +2 -2
- package/data/{sqlite/documentPersistence → persistence/documents/records}/index.js +4 -4
- package/data/persistence/documents/records/index.js.map +1 -0
- package/data/persistence/documents/types.d.ts +2 -2
- package/data/persistence/documents/types.js.map +1 -1
- package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.d.ts +2 -0
- package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js +9 -0
- package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js.map +1 -1
- package/data/persistence/keyingCheckpoints/keyingCheckpointPersistence.js +9 -0
- package/data/persistence/keyingCheckpoints/keyingCheckpointPersistence.js.map +1 -1
- package/data/persistence/principalPolicy/principalPolicyPersistence.js +3 -9
- package/data/persistence/principalPolicy/principalPolicyPersistence.js.map +1 -1
- package/{workflows/sync/remoteResetPrincipalScope.d.ts → data/persistence/principalPolicy/principalPolicyRemoteReset.d.ts} +1 -1
- package/{workflows/sync/remoteResetPrincipalScope.js → data/persistence/principalPolicy/principalPolicyRemoteReset.js} +16 -13
- package/data/persistence/principalPolicy/principalPolicyRemoteReset.js.map +1 -0
- package/data/persistence/verifiedManifestBundlePersistence.d.ts +2 -0
- package/data/persistence/verifiedManifestBundlePersistence.js +7 -0
- package/data/persistence/verifiedManifestBundlePersistence.js.map +1 -1
- package/data/sqlite/{documentPersistence/documentOrphanBlobReclaims.js → schema/documentOrphanBlobReclaimSchema.js} +1 -1
- package/data/sqlite/schema/documentOrphanBlobReclaimSchema.js.map +1 -0
- package/data/sqlite/schema/index.js +1 -1
- package/data/sqlite/schema/index.js.map +1 -1
- package/data/sqlite/sqliteBindBudget.js +12 -0
- package/data/sqlite/sqliteBindBudget.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/container-state/create/createIntentSeed.js.map +1 -1
- package/workflows/container-contents/container-state/create/createWithMetadataPlan.js.map +1 -1
- package/workflows/container-contents/container-state/types.js.map +1 -1
- package/workflows/container-contents/metadata/index.js.map +1 -1
- package/workflows/container-contents/metadata/metadataEvents.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataEvents.js.map +1 -1
- package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js +1 -1
- package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js.map +1 -1
- package/workflows/container-contents/metadata/metadataRemoteSync.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataRemoteSync.js.map +1 -1
- package/workflows/container-contents/pendingWrites/index.js +1 -1
- package/workflows/container-contents/pendingWrites/index.js.map +1 -1
- package/workflows/container-contents/recovery/accessRestoration.js +1 -1
- package/workflows/container-contents/recovery/accessRestoration.js.map +1 -1
- package/workflows/container-contents/remoteReset/containerRemoteReset.d.ts +185 -0
- package/workflows/container-contents/remoteReset/containerRemoteReset.js +174 -0
- package/workflows/container-contents/remoteReset/containerRemoteReset.js.map +1 -0
- package/workflows/container-contents/remoteReset/remoteResetCursorScope.d.ts +14 -0
- package/workflows/{sync → container-contents/remoteReset}/remoteResetCursorScope.js +2 -2
- package/workflows/container-contents/remoteReset/remoteResetCursorScope.js.map +1 -0
- package/workflows/documents/create/documentCreationPersistence.js.map +1 -1
- package/workflows/documents/create/index.d.ts +1 -1
- package/workflows/documents/create/index.js.map +1 -1
- package/workflows/documents/documentMutationCommit.d.ts +1 -1
- package/workflows/documents/documentMutationCommit.js.map +1 -1
- package/workflows/documents/index.d.ts +2 -2
- package/workflows/documents/index.js +2 -2
- package/workflows/documents/index.js.map +1 -1
- package/workflows/documents/remoteReset/documentRemoteReset.d.ts +56 -0
- package/workflows/documents/remoteReset/documentRemoteReset.js +135 -0
- package/workflows/documents/remoteReset/documentRemoteReset.js.map +1 -0
- package/workflows/{sync → documents/remoteReset}/remoteResetAttachments.js +3 -3
- package/workflows/documents/remoteReset/remoteResetAttachments.js.map +1 -0
- package/workflows/{sync → documents/remoteReset}/remoteResetPlans.d.ts +1 -1
- package/workflows/{sync → documents/remoteReset}/remoteResetPlans.js +7 -7
- package/workflows/documents/remoteReset/remoteResetPlans.js.map +1 -0
- package/workflows/documents/sync/index.js.map +1 -1
- package/workflows/documents/sync/initialSync.d.ts +1 -1
- package/workflows/documents/sync/initialSync.js.map +1 -1
- package/workflows/documents/sync/readOnlySync.d.ts +1 -1
- package/workflows/documents/sync/readOnlySync.js.map +1 -1
- package/workflows/documents/sync/syncAttemptPlanning.js.map +1 -1
- package/workflows/documents/sync/syncAttemptState.d.ts +1 -1
- package/workflows/documents/sync/syncAttemptState.js.map +1 -1
- package/workflows/documents/sync/syncResponseResult.js.map +1 -1
- package/workflows/documents/sync/syncSubmittedResult.js.map +1 -1
- package/workflows/documents/syncFailures/index.js.map +1 -1
- package/workflows/documents/syncPlan/syncContentKeys.d.ts +1 -1
- package/workflows/documents/syncPlan/syncContentKeys.js.map +1 -1
- package/workflows/documents/syncPlan/syncPlanMaterial.js.map +1 -1
- package/workflows/documents/syncPlan/syncPlanRequestBounds.js.map +1 -1
- package/workflows/documents/syncRekeys/syncContainerRekeys.js.map +1 -1
- package/workflows/documents/syncRekeys/syncRecoveryRekey.d.ts +1 -1
- package/workflows/documents/syncRekeys/syncRecoveryRekey.js +1 -1
- package/workflows/documents/syncRekeys/syncRecoveryRekey.js.map +1 -1
- package/workflows/organizations/readModel/listLocalOrganizations.js +1 -1
- package/workflows/organizations/readModel/listLocalOrganizations.js.map +1 -1
- package/workflows/organizations/readModel/organizationRemoteReset.js +25 -0
- package/workflows/organizations/readModel/organizationRemoteReset.js.map +1 -0
- package/workflows/registration/persistRegistrationBootstrap.d.ts +1 -1
- package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
- package/workflows/sync/remoteReset.js +60 -229
- package/workflows/sync/remoteReset.js.map +1 -1
- package/workflows/sync/remoteResetScope.d.ts +7 -10
- package/workflows/sync/remoteResetScope.js +26 -108
- package/workflows/sync/remoteResetScope.js.map +1 -1
- package/data/sqlite/documentPersistence/documentHistoryPersistence.js.map +0 -1
- package/data/sqlite/documentPersistence/documentOrphanBlobReclaims.js.map +0 -1
- package/data/sqlite/documentPersistence/documentPendingUpdatePersistence.js.map +0 -1
- package/data/sqlite/documentPersistence/documentPersistenceTypes.js.map +0 -1
- package/data/sqlite/documentPersistence/documentRecordPersistence.js.map +0 -1
- package/data/sqlite/documentPersistence/documentSyncFailurePersistence.js.map +0 -1
- package/data/sqlite/documentPersistence/index.js.map +0 -1
- package/workflows/sync/remoteResetAttachments.js.map +0 -1
- package/workflows/sync/remoteResetBatches.js +0 -13
- package/workflows/sync/remoteResetBatches.js.map +0 -1
- package/workflows/sync/remoteResetCursorScope.js.map +0 -1
- package/workflows/sync/remoteResetPlans.js.map +0 -1
- package/workflows/sync/remoteResetPrincipalScope.js.map +0 -1
- /package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPersistenceTypes.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentMutationCommit.js","sourceRoot":"","sources":["documentMutationCommit.ts"],"names":[],"mappings":"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","sourcesContent":["import { type encodeVersionVector, getTextValue } from \"@tearleads/loro\";\nimport {\n DEFAULT_DOCUMENT_ACCESS_EPOCH,\n DEFAULT_DOCUMENT_KIND,\n} from \"../../data/documents/documentConstants\";\nimport {\n type DocumentProjectorRegistry,\n type DocumentProjectorRegistryInput,\n readStoredDocumentState,\n} from \"../../data/documents/documentKinds\";\nimport type {\n DocumentsPersistence,\n StoredDocumentRecord,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport type { PendingUpdateFields } from \"../../data/sqlite/documentPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { createInitialDocumentRows } from \"./create/documentCreationPersistence\";\nimport {\n documentSyncSecurityContextMatches,\n type PrepareDocumentMutationInput,\n prepareDocumentMutation,\n} from \"./documentMutationPreparation\";\nimport { refuseDeletedDocumentPersist } from \"./documentPersistGuards\";\n\ntype DocumentContentState = Parameters<typeof encodeVersionVector>[0];\ntype NullableDocumentRuntimeField =\n | \"accessStateHash\"\n | \"lastCommitLsn\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\";\n\nconst MAX_DOCUMENT_MUTATION_COMMIT_ATTEMPTS = 8;\n\nexport interface PersistedDocumentState {\n creationSuperseded?: true;\n historyRestoreState?:\n | Awaited<ReturnType<DocumentsPersistence[\"loadHistoryRestoreState\"]>>\n | undefined;\n pullContinuationSuperseded?: true;\n record: StoredDocumentRecord;\n syncIdentitySuperseded?: true;\n updatedAt?: string | undefined;\n}\n\nexport interface PersistDocumentStateInput\n extends PrepareDocumentMutationInput {\n acceptedPendingUpdateIds?: readonly string[] | undefined;\n attachmentRemoval?:\n | Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n >[1][\"attachmentRemoval\"]\n | undefined;\n attachmentStaging?:\n | Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n >[1][\"attachmentStaging\"]\n | undefined;\n canStartDurableMutation?: (() => boolean) | undefined;\n clearSyncFailure?: boolean | undefined;\n commitSideEffect?: (transactionExecSql: ExecSql) => Promise<void>;\n containerId?: string | null | undefined;\n documentProjectors: DocumentProjectorRegistryInput;\n execSql: ExecSql;\n patch?: Partial<StoredDocumentRecord> | undefined;\n pendingUpdate?: PendingUpdateFields | undefined;\n}\n\nasync function loadSupersededPersistedDocumentState(input: {\n creationSuperseded: boolean;\n execSql: ExecSql;\n localId: string;\n persistence: DocumentsPersistence;\n record: StoredDocumentRecord;\n syncIdentitySuperseded: boolean;\n}): Promise<PersistedDocumentState | null> {\n const { document, historyRestoreState } =\n await input.persistence.loadDocumentWithHistoryRestoreState(\n input.execSql,\n input.localId,\n );\n if (!document) return null;\n const syncIdentitySuperseded =\n input.syncIdentitySuperseded ||\n !documentSyncSecurityContextMatches(document, input.record);\n return {\n ...(input.creationSuperseded ? { creationSuperseded: true as const } : {}),\n historyRestoreState,\n pullContinuationSuperseded: true,\n record: document,\n ...(syncIdentitySuperseded\n ? { syncIdentitySuperseded: true as const }\n : {}),\n };\n}\n\nfunction resolveNullableDocumentRuntimeField(\n patch: Partial<StoredDocumentRecord>,\n key: NullableDocumentRuntimeField,\n currentValue: string | null | undefined,\n resetWhenUnpatched = false,\n): string | null {\n if (Object.hasOwn(patch, key)) return patch[key] ?? null;\n return resetWhenUnpatched ? null : (currentValue ?? null);\n}\n\nfunction resolveStoredDocumentContainerId(input: {\n containerId?: string | null | undefined;\n currentRecord: StoredDocumentRecord | null;\n patch: Partial<StoredDocumentRecord>;\n}): string | null {\n if (Object.hasOwn(input.patch, \"containerId\")) {\n return input.patch.containerId ?? null;\n }\n return input.currentRecord?.containerId ?? input.containerId ?? null;\n}\n\nfunction resolveStoredDocumentPullState(input: {\n currentRecord: StoredDocumentRecord | null;\n patch: Partial<StoredDocumentRecord>;\n securityContextChanged: boolean;\n}): Pick<\n StoredDocumentRecord,\n \"pullContinuation\" | \"pullContinuationRecoveryRequired\"\n> {\n if (Object.hasOwn(input.patch, \"pullContinuation\")) {\n return { pullContinuation: input.patch.pullContinuation ?? null };\n }\n if (input.securityContextChanged) return { pullContinuation: null };\n if (input.currentRecord?.pullContinuationRecoveryRequired) {\n return { pullContinuationRecoveryRequired: true };\n }\n return { pullContinuation: input.currentRecord?.pullContinuation ?? null };\n}\n\nfunction buildStoredDocumentRecord(input: {\n containerId?: string | null | undefined;\n currentDoc: DocumentContentState;\n currentRecord: StoredDocumentRecord | null;\n documentProjectors: DocumentProjectorRegistry;\n localId: string;\n patch: Partial<StoredDocumentRecord>;\n}) {\n const { currentDoc, currentRecord, documentProjectors, localId, patch } =\n input;\n const currentDocumentId = currentRecord?.documentId ?? null;\n const nextDocumentId = patch.documentId ?? currentDocumentId;\n const documentIdChanged = nextDocumentId !== currentDocumentId;\n const currentAccessEpoch =\n currentRecord?.accessEpoch ?? DEFAULT_DOCUMENT_ACCESS_EPOCH;\n const nextAccessEpoch = patch.accessEpoch ?? currentAccessEpoch;\n const securityContextChanged =\n documentIdChanged || nextAccessEpoch !== currentAccessEpoch;\n const documentState = readStoredDocumentState(currentDoc, documentProjectors);\n const record: StoredDocumentRecord = {\n id: currentRecord?.id ?? localId,\n accessEpoch: nextAccessEpoch,\n accessStateHash: resolveNullableDocumentRuntimeField(\n patch,\n \"accessStateHash\",\n currentRecord?.accessStateHash,\n securityContextChanged,\n ),\n containerId: resolveStoredDocumentContainerId({\n containerId: input.containerId,\n currentRecord,\n patch,\n }),\n contentKeyBundle: resolveNullableDocumentRuntimeField(\n patch,\n \"contentKeyBundle\",\n currentRecord?.contentKeyBundle,\n securityContextChanged,\n ),\n documentId: nextDocumentId,\n effectiveAccessLevel:\n patch.effectiveAccessLevel ?? currentRecord?.effectiveAccessLevel ?? null,\n documentKekTargets: resolveNullableDocumentRuntimeField(\n patch,\n \"documentKekTargets\",\n currentRecord?.documentKekTargets,\n securityContextChanged,\n ),\n documentKind: patch.documentKind ?? documentState.documentKind,\n documentManifestBundle: resolveNullableDocumentRuntimeField(\n patch,\n \"documentManifestBundle\",\n currentRecord?.documentManifestBundle,\n securityContextChanged,\n ),\n lastCommitLsn: resolveNullableDocumentRuntimeField(\n patch,\n \"lastCommitLsn\",\n currentRecord?.lastCommitLsn,\n documentIdChanged,\n ),\n snapshotEndVersion:\n patch.snapshotEndVersion ?? currentRecord?.snapshotEndVersion ?? \"\",\n pendingBaseVersion:\n patch.pendingBaseVersion !== undefined\n ? patch.pendingBaseVersion\n : (currentRecord?.pendingBaseVersion ?? null),\n recoveryGeneration:\n patch.recoveryGeneration ?? currentRecord?.recoveryGeneration ?? 0,\n ...resolveStoredDocumentPullState({\n currentRecord,\n patch,\n securityContextChanged,\n }),\n text: patch.text ?? getTextValue(currentDoc),\n title: patch.title ?? documentState.title,\n };\n return { documentState, record };\n}\n\nasync function saveDocumentClientProjection(input: {\n currentRecord: StoredDocumentRecord | null;\n documentProjectors: DocumentProjectorRegistry;\n documentState: ReturnType<typeof readStoredDocumentState>;\n execSql: ExecSql;\n localId: string;\n record: StoredDocumentRecord;\n updatedAt: string;\n}): Promise<void> {\n const previousKind =\n input.currentRecord?.documentKind ?? DEFAULT_DOCUMENT_KIND;\n const nextKind = input.record.documentKind ?? DEFAULT_DOCUMENT_KIND;\n if (previousKind !== nextKind) {\n await input.documentProjectors.deleteStoredDocumentClientProjection({\n documentKind: previousKind,\n execSql: input.execSql,\n localId: input.localId,\n });\n }\n await input.documentProjectors.saveStoredDocumentClientProjection({\n containerId: input.record.containerId,\n documentId: input.record.documentId,\n documentKind: nextKind,\n execSql: input.execSql,\n localId: input.record.id,\n structuredFields: input.documentState.structuredFields,\n text: input.record.text,\n title: input.record.title ?? input.documentState.title,\n updatedAt: input.updatedAt,\n });\n}\n\nasync function settleSupersededDocumentMutation(input: {\n acceptedPendingUpdateIds: readonly string[];\n lockedExecSql: ExecSql;\n mutation: Awaited<ReturnType<typeof prepareDocumentMutation>>;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState | null> {\n const { mutation, persistInput } = input;\n if (!mutation.mutationCurrentRecord) return null;\n const authoritativeRecord = persistInput.expectedSyncState\n ? await persistInput.persistence.settleAcceptedPendingUpdates(\n input.lockedExecSql,\n {\n expectedRecord: persistInput.expectedSyncState.record,\n pendingUpdateIds: input.acceptedPendingUpdateIds,\n },\n )\n : mutation.mutationCurrentRecord;\n if (!authoritativeRecord) return null;\n return loadSupersededPersistedDocumentState({\n creationSuperseded: mutation.creationSuperseded,\n execSql: input.lockedExecSql,\n localId: persistInput.localId,\n persistence: persistInput.persistence,\n record: authoritativeRecord,\n syncIdentitySuperseded: !mutation.securityContextMatches,\n });\n}\n\nasync function loadConcurrentCreationWinner(input: {\n execSql: ExecSql;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState> {\n const winningRecord = await input.persistInput.persistence.loadDocument(\n input.execSql,\n input.persistInput.localId,\n );\n if (!winningRecord) {\n throw new Error(\"Concurrent document creation lost without a winner\");\n }\n const winner = await loadSupersededPersistedDocumentState({\n creationSuperseded: true,\n execSql: input.execSql,\n localId: input.persistInput.localId,\n persistence: input.persistInput.persistence,\n record: winningRecord,\n syncIdentitySuperseded: true,\n });\n if (!winner) {\n throw new Error(\"Concurrent document creation winner disappeared\");\n }\n return winner;\n}\n\nasync function resolveInitialDocumentCreation(input: {\n execSql: ExecSql;\n persistInput: PersistDocumentStateInput;\n record: StoredDocumentRecord;\n savedAt: string | null;\n}): Promise<PersistedDocumentState | null> {\n if (input.savedAt !== null) {\n return { record: input.record, updatedAt: input.savedAt };\n }\n if (\n input.persistInput.canStartDurableMutation &&\n !input.persistInput.canStartDurableMutation()\n ) {\n return null;\n }\n return loadConcurrentCreationWinner({\n execSql: input.execSql,\n persistInput: input.persistInput,\n });\n}\n\nasync function resolveDocumentMutationCommit(input: {\n committed: Awaited<\n ReturnType<DocumentsPersistence[\"commitDocumentMutation\"]>\n >;\n lockedExecSql: ExecSql;\n persistInput: PersistDocumentStateInput;\n record: StoredDocumentRecord;\n}): Promise<PersistedDocumentState | null | \"retry\"> {\n const { committed, persistInput, record } = input;\n if (\n persistInput.canStartDurableMutation &&\n !persistInput.canStartDurableMutation()\n ) {\n return null;\n }\n if (committed.committed) return { record, updatedAt: committed.updatedAt };\n if (!committed.currentRecord) return null;\n if (persistInput.expectedSyncState === undefined) return \"retry\";\n return loadSupersededPersistedDocumentState({\n creationSuperseded: false,\n execSql: input.lockedExecSql,\n localId: persistInput.localId,\n persistence: persistInput.persistence,\n record: committed.currentRecord,\n syncIdentitySuperseded: !documentSyncSecurityContextMatches(\n committed.currentRecord,\n persistInput.expectedSyncState.record,\n ),\n });\n}\n\nasync function commitOnePreparedDocumentMutation(input: {\n acceptedPendingUpdateIds: readonly string[];\n documentProjectors: DocumentProjectorRegistry;\n lockedExecSql: ExecSql;\n mutation: Exclude<\n Awaited<ReturnType<typeof prepareDocumentMutation>>,\n { pullContinuationSuperseded: true }\n >;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState | null | \"retry\"> {\n const { mutation, persistInput } = input;\n const { documentState, record } = buildStoredDocumentRecord({\n containerId: persistInput.containerId,\n currentDoc: persistInput.currentDoc,\n currentRecord: mutation.mutationCurrentRecord,\n documentProjectors: input.documentProjectors,\n localId: persistInput.localId,\n patch: mutation.resolvedPatch,\n });\n if (!mutation.mutationCurrentRecord) {\n const savedAt = await createInitialDocumentRows({\n currentDoc: persistInput.currentDoc,\n execSql: input.lockedExecSql,\n pendingUpdate: persistInput.pendingUpdate,\n persistence: persistInput.persistence,\n record,\n stillCurrent: persistInput.canStartDurableMutation,\n saveClientProjection: (transactionExecSql, updatedAt) =>\n saveDocumentClientProjection({\n currentRecord: null,\n documentProjectors: input.documentProjectors,\n documentState,\n execSql: transactionExecSql,\n localId: persistInput.localId,\n record,\n updatedAt,\n }),\n });\n return resolveInitialDocumentCreation({\n execSql: input.lockedExecSql,\n persistInput,\n record,\n savedAt,\n });\n }\n\n const committed = await persistInput.persistence.commitDocumentMutation(\n input.lockedExecSql,\n {\n acceptedPendingUpdateIds: input.acceptedPendingUpdateIds,\n clearSyncFailure: persistInput.clearSyncFailure,\n ...(persistInput.attachmentRemoval\n ? { attachmentRemoval: persistInput.attachmentRemoval }\n : {}),\n ...(persistInput.attachmentStaging\n ? { attachmentStaging: persistInput.attachmentStaging }\n : {}),\n document: record,\n expectedRecord: mutation.mutationCurrentRecord,\n ...(persistInput.historyCheckpoint\n ? { historyCheckpoint: persistInput.historyCheckpoint }\n : {}),\n ...(persistInput.historyUpdateOrigin\n ? { historyUpdateOrigin: persistInput.historyUpdateOrigin }\n : {}),\n ...(persistInput.historyUpdates\n ? { historyUpdates: persistInput.historyUpdates }\n : {}),\n ...(persistInput.pendingUpdate\n ? { pendingUpdate: persistInput.pendingUpdate }\n : {}),\n settleAcceptedPendingOnConflict:\n persistInput.expectedSyncState !== undefined,\n ...(persistInput.canStartDurableMutation\n ? { stillCurrent: persistInput.canStartDurableMutation }\n : {}),\n },\n async (transactionExecSql, updatedAt) => {\n await saveDocumentClientProjection({\n currentRecord: mutation.mutationCurrentRecord,\n documentProjectors: input.documentProjectors,\n documentState,\n execSql: transactionExecSql,\n localId: persistInput.localId,\n record,\n updatedAt,\n });\n await persistInput.commitSideEffect?.(transactionExecSql);\n },\n );\n return resolveDocumentMutationCommit({\n committed,\n lockedExecSql: input.lockedExecSql,\n persistInput,\n record,\n });\n}\n\nexport async function commitPreparedDocumentState(input: {\n documentProjectors: DocumentProjectorRegistry;\n lockedExecSql: ExecSql;\n patch: Partial<StoredDocumentRecord>;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState | null> {\n const { lockedExecSql, persistInput } = input;\n if (\n await refuseDeletedDocumentPersist({\n currentRecord: persistInput.currentRecord,\n documentProjectors: input.documentProjectors,\n execSql: lockedExecSql,\n localId: persistInput.localId,\n persistence: persistInput.persistence,\n })\n ) {\n return null;\n }\n const acceptedPendingUpdateIds = persistInput.acceptedPendingUpdateIds ?? [];\n for (\n let attempt = 0;\n attempt < MAX_DOCUMENT_MUTATION_COMMIT_ATTEMPTS;\n attempt += 1\n ) {\n const mutation = await prepareDocumentMutation(\n persistInput,\n lockedExecSql,\n input.patch,\n );\n if (mutation.pullContinuationSuperseded) {\n return settleSupersededDocumentMutation({\n acceptedPendingUpdateIds,\n lockedExecSql,\n mutation,\n persistInput,\n });\n }\n const result = await commitOnePreparedDocumentMutation({\n acceptedPendingUpdateIds,\n documentProjectors: input.documentProjectors,\n lockedExecSql,\n mutation,\n persistInput,\n });\n if (result !== \"retry\") return result;\n }\n throw new Error(\n `Document mutation commit gave up after ${MAX_DOCUMENT_MUTATION_COMMIT_ATTEMPTS} concurrent conflicts`,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentMutationCommit.js","sourceRoot":"","sources":["documentMutationCommit.ts"],"names":[],"mappings":"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","sourcesContent":["import { type encodeVersionVector, getTextValue } from \"@tearleads/loro\";\nimport {\n DEFAULT_DOCUMENT_ACCESS_EPOCH,\n DEFAULT_DOCUMENT_KIND,\n} from \"../../data/documents/documentConstants\";\nimport {\n type DocumentProjectorRegistry,\n type DocumentProjectorRegistryInput,\n readStoredDocumentState,\n} from \"../../data/documents/documentKinds\";\nimport type {\n DocumentsPersistence,\n StoredDocumentRecord,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport type { PendingUpdateFields } from \"../../data/persistence/documents/records\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { createInitialDocumentRows } from \"./create/documentCreationPersistence\";\nimport {\n documentSyncSecurityContextMatches,\n type PrepareDocumentMutationInput,\n prepareDocumentMutation,\n} from \"./documentMutationPreparation\";\nimport { refuseDeletedDocumentPersist } from \"./documentPersistGuards\";\n\ntype DocumentContentState = Parameters<typeof encodeVersionVector>[0];\ntype NullableDocumentRuntimeField =\n | \"accessStateHash\"\n | \"lastCommitLsn\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\";\n\nconst MAX_DOCUMENT_MUTATION_COMMIT_ATTEMPTS = 8;\n\nexport interface PersistedDocumentState {\n creationSuperseded?: true;\n historyRestoreState?:\n | Awaited<ReturnType<DocumentsPersistence[\"loadHistoryRestoreState\"]>>\n | undefined;\n pullContinuationSuperseded?: true;\n record: StoredDocumentRecord;\n syncIdentitySuperseded?: true;\n updatedAt?: string | undefined;\n}\n\nexport interface PersistDocumentStateInput\n extends PrepareDocumentMutationInput {\n acceptedPendingUpdateIds?: readonly string[] | undefined;\n attachmentRemoval?:\n | Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n >[1][\"attachmentRemoval\"]\n | undefined;\n attachmentStaging?:\n | Parameters<\n DocumentsPersistence[\"commitDocumentMutation\"]\n >[1][\"attachmentStaging\"]\n | undefined;\n canStartDurableMutation?: (() => boolean) | undefined;\n clearSyncFailure?: boolean | undefined;\n commitSideEffect?: (transactionExecSql: ExecSql) => Promise<void>;\n containerId?: string | null | undefined;\n documentProjectors: DocumentProjectorRegistryInput;\n execSql: ExecSql;\n patch?: Partial<StoredDocumentRecord> | undefined;\n pendingUpdate?: PendingUpdateFields | undefined;\n}\n\nasync function loadSupersededPersistedDocumentState(input: {\n creationSuperseded: boolean;\n execSql: ExecSql;\n localId: string;\n persistence: DocumentsPersistence;\n record: StoredDocumentRecord;\n syncIdentitySuperseded: boolean;\n}): Promise<PersistedDocumentState | null> {\n const { document, historyRestoreState } =\n await input.persistence.loadDocumentWithHistoryRestoreState(\n input.execSql,\n input.localId,\n );\n if (!document) return null;\n const syncIdentitySuperseded =\n input.syncIdentitySuperseded ||\n !documentSyncSecurityContextMatches(document, input.record);\n return {\n ...(input.creationSuperseded ? { creationSuperseded: true as const } : {}),\n historyRestoreState,\n pullContinuationSuperseded: true,\n record: document,\n ...(syncIdentitySuperseded\n ? { syncIdentitySuperseded: true as const }\n : {}),\n };\n}\n\nfunction resolveNullableDocumentRuntimeField(\n patch: Partial<StoredDocumentRecord>,\n key: NullableDocumentRuntimeField,\n currentValue: string | null | undefined,\n resetWhenUnpatched = false,\n): string | null {\n if (Object.hasOwn(patch, key)) return patch[key] ?? null;\n return resetWhenUnpatched ? null : (currentValue ?? null);\n}\n\nfunction resolveStoredDocumentContainerId(input: {\n containerId?: string | null | undefined;\n currentRecord: StoredDocumentRecord | null;\n patch: Partial<StoredDocumentRecord>;\n}): string | null {\n if (Object.hasOwn(input.patch, \"containerId\")) {\n return input.patch.containerId ?? null;\n }\n return input.currentRecord?.containerId ?? input.containerId ?? null;\n}\n\nfunction resolveStoredDocumentPullState(input: {\n currentRecord: StoredDocumentRecord | null;\n patch: Partial<StoredDocumentRecord>;\n securityContextChanged: boolean;\n}): Pick<\n StoredDocumentRecord,\n \"pullContinuation\" | \"pullContinuationRecoveryRequired\"\n> {\n if (Object.hasOwn(input.patch, \"pullContinuation\")) {\n return { pullContinuation: input.patch.pullContinuation ?? null };\n }\n if (input.securityContextChanged) return { pullContinuation: null };\n if (input.currentRecord?.pullContinuationRecoveryRequired) {\n return { pullContinuationRecoveryRequired: true };\n }\n return { pullContinuation: input.currentRecord?.pullContinuation ?? null };\n}\n\nfunction buildStoredDocumentRecord(input: {\n containerId?: string | null | undefined;\n currentDoc: DocumentContentState;\n currentRecord: StoredDocumentRecord | null;\n documentProjectors: DocumentProjectorRegistry;\n localId: string;\n patch: Partial<StoredDocumentRecord>;\n}) {\n const { currentDoc, currentRecord, documentProjectors, localId, patch } =\n input;\n const currentDocumentId = currentRecord?.documentId ?? null;\n const nextDocumentId = patch.documentId ?? currentDocumentId;\n const documentIdChanged = nextDocumentId !== currentDocumentId;\n const currentAccessEpoch =\n currentRecord?.accessEpoch ?? DEFAULT_DOCUMENT_ACCESS_EPOCH;\n const nextAccessEpoch = patch.accessEpoch ?? currentAccessEpoch;\n const securityContextChanged =\n documentIdChanged || nextAccessEpoch !== currentAccessEpoch;\n const documentState = readStoredDocumentState(currentDoc, documentProjectors);\n const record: StoredDocumentRecord = {\n id: currentRecord?.id ?? localId,\n accessEpoch: nextAccessEpoch,\n accessStateHash: resolveNullableDocumentRuntimeField(\n patch,\n \"accessStateHash\",\n currentRecord?.accessStateHash,\n securityContextChanged,\n ),\n containerId: resolveStoredDocumentContainerId({\n containerId: input.containerId,\n currentRecord,\n patch,\n }),\n contentKeyBundle: resolveNullableDocumentRuntimeField(\n patch,\n \"contentKeyBundle\",\n currentRecord?.contentKeyBundle,\n securityContextChanged,\n ),\n documentId: nextDocumentId,\n effectiveAccessLevel:\n patch.effectiveAccessLevel ?? currentRecord?.effectiveAccessLevel ?? null,\n documentKekTargets: resolveNullableDocumentRuntimeField(\n patch,\n \"documentKekTargets\",\n currentRecord?.documentKekTargets,\n securityContextChanged,\n ),\n documentKind: patch.documentKind ?? documentState.documentKind,\n documentManifestBundle: resolveNullableDocumentRuntimeField(\n patch,\n \"documentManifestBundle\",\n currentRecord?.documentManifestBundle,\n securityContextChanged,\n ),\n lastCommitLsn: resolveNullableDocumentRuntimeField(\n patch,\n \"lastCommitLsn\",\n currentRecord?.lastCommitLsn,\n documentIdChanged,\n ),\n snapshotEndVersion:\n patch.snapshotEndVersion ?? currentRecord?.snapshotEndVersion ?? \"\",\n pendingBaseVersion:\n patch.pendingBaseVersion !== undefined\n ? patch.pendingBaseVersion\n : (currentRecord?.pendingBaseVersion ?? null),\n recoveryGeneration:\n patch.recoveryGeneration ?? currentRecord?.recoveryGeneration ?? 0,\n ...resolveStoredDocumentPullState({\n currentRecord,\n patch,\n securityContextChanged,\n }),\n text: patch.text ?? getTextValue(currentDoc),\n title: patch.title ?? documentState.title,\n };\n return { documentState, record };\n}\n\nasync function saveDocumentClientProjection(input: {\n currentRecord: StoredDocumentRecord | null;\n documentProjectors: DocumentProjectorRegistry;\n documentState: ReturnType<typeof readStoredDocumentState>;\n execSql: ExecSql;\n localId: string;\n record: StoredDocumentRecord;\n updatedAt: string;\n}): Promise<void> {\n const previousKind =\n input.currentRecord?.documentKind ?? DEFAULT_DOCUMENT_KIND;\n const nextKind = input.record.documentKind ?? DEFAULT_DOCUMENT_KIND;\n if (previousKind !== nextKind) {\n await input.documentProjectors.deleteStoredDocumentClientProjection({\n documentKind: previousKind,\n execSql: input.execSql,\n localId: input.localId,\n });\n }\n await input.documentProjectors.saveStoredDocumentClientProjection({\n containerId: input.record.containerId,\n documentId: input.record.documentId,\n documentKind: nextKind,\n execSql: input.execSql,\n localId: input.record.id,\n structuredFields: input.documentState.structuredFields,\n text: input.record.text,\n title: input.record.title ?? input.documentState.title,\n updatedAt: input.updatedAt,\n });\n}\n\nasync function settleSupersededDocumentMutation(input: {\n acceptedPendingUpdateIds: readonly string[];\n lockedExecSql: ExecSql;\n mutation: Awaited<ReturnType<typeof prepareDocumentMutation>>;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState | null> {\n const { mutation, persistInput } = input;\n if (!mutation.mutationCurrentRecord) return null;\n const authoritativeRecord = persistInput.expectedSyncState\n ? await persistInput.persistence.settleAcceptedPendingUpdates(\n input.lockedExecSql,\n {\n expectedRecord: persistInput.expectedSyncState.record,\n pendingUpdateIds: input.acceptedPendingUpdateIds,\n },\n )\n : mutation.mutationCurrentRecord;\n if (!authoritativeRecord) return null;\n return loadSupersededPersistedDocumentState({\n creationSuperseded: mutation.creationSuperseded,\n execSql: input.lockedExecSql,\n localId: persistInput.localId,\n persistence: persistInput.persistence,\n record: authoritativeRecord,\n syncIdentitySuperseded: !mutation.securityContextMatches,\n });\n}\n\nasync function loadConcurrentCreationWinner(input: {\n execSql: ExecSql;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState> {\n const winningRecord = await input.persistInput.persistence.loadDocument(\n input.execSql,\n input.persistInput.localId,\n );\n if (!winningRecord) {\n throw new Error(\"Concurrent document creation lost without a winner\");\n }\n const winner = await loadSupersededPersistedDocumentState({\n creationSuperseded: true,\n execSql: input.execSql,\n localId: input.persistInput.localId,\n persistence: input.persistInput.persistence,\n record: winningRecord,\n syncIdentitySuperseded: true,\n });\n if (!winner) {\n throw new Error(\"Concurrent document creation winner disappeared\");\n }\n return winner;\n}\n\nasync function resolveInitialDocumentCreation(input: {\n execSql: ExecSql;\n persistInput: PersistDocumentStateInput;\n record: StoredDocumentRecord;\n savedAt: string | null;\n}): Promise<PersistedDocumentState | null> {\n if (input.savedAt !== null) {\n return { record: input.record, updatedAt: input.savedAt };\n }\n if (\n input.persistInput.canStartDurableMutation &&\n !input.persistInput.canStartDurableMutation()\n ) {\n return null;\n }\n return loadConcurrentCreationWinner({\n execSql: input.execSql,\n persistInput: input.persistInput,\n });\n}\n\nasync function resolveDocumentMutationCommit(input: {\n committed: Awaited<\n ReturnType<DocumentsPersistence[\"commitDocumentMutation\"]>\n >;\n lockedExecSql: ExecSql;\n persistInput: PersistDocumentStateInput;\n record: StoredDocumentRecord;\n}): Promise<PersistedDocumentState | null | \"retry\"> {\n const { committed, persistInput, record } = input;\n if (\n persistInput.canStartDurableMutation &&\n !persistInput.canStartDurableMutation()\n ) {\n return null;\n }\n if (committed.committed) return { record, updatedAt: committed.updatedAt };\n if (!committed.currentRecord) return null;\n if (persistInput.expectedSyncState === undefined) return \"retry\";\n return loadSupersededPersistedDocumentState({\n creationSuperseded: false,\n execSql: input.lockedExecSql,\n localId: persistInput.localId,\n persistence: persistInput.persistence,\n record: committed.currentRecord,\n syncIdentitySuperseded: !documentSyncSecurityContextMatches(\n committed.currentRecord,\n persistInput.expectedSyncState.record,\n ),\n });\n}\n\nasync function commitOnePreparedDocumentMutation(input: {\n acceptedPendingUpdateIds: readonly string[];\n documentProjectors: DocumentProjectorRegistry;\n lockedExecSql: ExecSql;\n mutation: Exclude<\n Awaited<ReturnType<typeof prepareDocumentMutation>>,\n { pullContinuationSuperseded: true }\n >;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState | null | \"retry\"> {\n const { mutation, persistInput } = input;\n const { documentState, record } = buildStoredDocumentRecord({\n containerId: persistInput.containerId,\n currentDoc: persistInput.currentDoc,\n currentRecord: mutation.mutationCurrentRecord,\n documentProjectors: input.documentProjectors,\n localId: persistInput.localId,\n patch: mutation.resolvedPatch,\n });\n if (!mutation.mutationCurrentRecord) {\n const savedAt = await createInitialDocumentRows({\n currentDoc: persistInput.currentDoc,\n execSql: input.lockedExecSql,\n pendingUpdate: persistInput.pendingUpdate,\n persistence: persistInput.persistence,\n record,\n stillCurrent: persistInput.canStartDurableMutation,\n saveClientProjection: (transactionExecSql, updatedAt) =>\n saveDocumentClientProjection({\n currentRecord: null,\n documentProjectors: input.documentProjectors,\n documentState,\n execSql: transactionExecSql,\n localId: persistInput.localId,\n record,\n updatedAt,\n }),\n });\n return resolveInitialDocumentCreation({\n execSql: input.lockedExecSql,\n persistInput,\n record,\n savedAt,\n });\n }\n\n const committed = await persistInput.persistence.commitDocumentMutation(\n input.lockedExecSql,\n {\n acceptedPendingUpdateIds: input.acceptedPendingUpdateIds,\n clearSyncFailure: persistInput.clearSyncFailure,\n ...(persistInput.attachmentRemoval\n ? { attachmentRemoval: persistInput.attachmentRemoval }\n : {}),\n ...(persistInput.attachmentStaging\n ? { attachmentStaging: persistInput.attachmentStaging }\n : {}),\n document: record,\n expectedRecord: mutation.mutationCurrentRecord,\n ...(persistInput.historyCheckpoint\n ? { historyCheckpoint: persistInput.historyCheckpoint }\n : {}),\n ...(persistInput.historyUpdateOrigin\n ? { historyUpdateOrigin: persistInput.historyUpdateOrigin }\n : {}),\n ...(persistInput.historyUpdates\n ? { historyUpdates: persistInput.historyUpdates }\n : {}),\n ...(persistInput.pendingUpdate\n ? { pendingUpdate: persistInput.pendingUpdate }\n : {}),\n settleAcceptedPendingOnConflict:\n persistInput.expectedSyncState !== undefined,\n ...(persistInput.canStartDurableMutation\n ? { stillCurrent: persistInput.canStartDurableMutation }\n : {}),\n },\n async (transactionExecSql, updatedAt) => {\n await saveDocumentClientProjection({\n currentRecord: mutation.mutationCurrentRecord,\n documentProjectors: input.documentProjectors,\n documentState,\n execSql: transactionExecSql,\n localId: persistInput.localId,\n record,\n updatedAt,\n });\n await persistInput.commitSideEffect?.(transactionExecSql);\n },\n );\n return resolveDocumentMutationCommit({\n committed,\n lockedExecSql: input.lockedExecSql,\n persistInput,\n record,\n });\n}\n\nexport async function commitPreparedDocumentState(input: {\n documentProjectors: DocumentProjectorRegistry;\n lockedExecSql: ExecSql;\n patch: Partial<StoredDocumentRecord>;\n persistInput: PersistDocumentStateInput;\n}): Promise<PersistedDocumentState | null> {\n const { lockedExecSql, persistInput } = input;\n if (\n await refuseDeletedDocumentPersist({\n currentRecord: persistInput.currentRecord,\n documentProjectors: input.documentProjectors,\n execSql: lockedExecSql,\n localId: persistInput.localId,\n persistence: persistInput.persistence,\n })\n ) {\n return null;\n }\n const acceptedPendingUpdateIds = persistInput.acceptedPendingUpdateIds ?? [];\n for (\n let attempt = 0;\n attempt < MAX_DOCUMENT_MUTATION_COMMIT_ATTEMPTS;\n attempt += 1\n ) {\n const mutation = await prepareDocumentMutation(\n persistInput,\n lockedExecSql,\n input.patch,\n );\n if (mutation.pullContinuationSuperseded) {\n return settleSupersededDocumentMutation({\n acceptedPendingUpdateIds,\n lockedExecSql,\n mutation,\n persistInput,\n });\n }\n const result = await commitOnePreparedDocumentMutation({\n acceptedPendingUpdateIds,\n documentProjectors: input.documentProjectors,\n lockedExecSql,\n mutation,\n persistInput,\n });\n if (result !== \"retry\") return result;\n }\n throw new Error(\n `Document mutation commit gave up after ${MAX_DOCUMENT_MUTATION_COMMIT_ATTEMPTS} concurrent conflicts`,\n );\n}\n"]}
|
|
@@ -4,8 +4,8 @@ export { selectDocumentSyncOutgoingBatch } from "../../data/documents/shared/syn
|
|
|
4
4
|
export { type DocumentSyncUpdateIsolationError, type IncomingDocumentSyncUpdateValidator, isDocumentSyncUpdateIsolationError, validateDocumentSyncUpdateImports, } from "../../data/documents/shared/sync/documentSyncUpdateIsolation.js";
|
|
5
5
|
export { type DocumentSyncPullContinuation, documentSyncPullContinuationsEqual, readPullContinuation, } from "../../data/documents/shared/sync/syncPagination.js";
|
|
6
6
|
export type { DocumentCreateAuthor, DocumentLinkSetFailureHandler, DocumentLinkSetMutationFailure, RelinkRemoteDocumentResult, } from "../../data/documents/shared/types.js";
|
|
7
|
-
export { clearDocumentSyncFailure, invalidateDocumentSyncPullContinuation, recordDocumentSyncFailure, } from "../../data/
|
|
8
|
-
export { DOCUMENT_HISTORY_COMPACTION_MAX_BYTES, DOCUMENT_HISTORY_COMPACTION_MAX_ROWS, } from "../../data/
|
|
7
|
+
export { clearDocumentSyncFailure, invalidateDocumentSyncPullContinuation, recordDocumentSyncFailure, } from "../../data/persistence/documents/records/index.js";
|
|
8
|
+
export { DOCUMENT_HISTORY_COMPACTION_MAX_BYTES, DOCUMENT_HISTORY_COMPACTION_MAX_ROWS, } from "../../data/persistence/documents/records/documentHistoryPersistence.js";
|
|
9
9
|
export type { ExecSql } from "../../data/sqlite/sqlSchema.js";
|
|
10
10
|
export { settleOutgoingPassAndDecideReArm } from "../../data/sync/outgoingUpdateSettlement.js";
|
|
11
11
|
export { didRegainSyncPrerequisites, isDatabaseUnavailableError, } from "../../data/sync/syncCoordinator.js";
|
|
@@ -3,8 +3,8 @@ export { persistedDocumentCreateStateFromResponse } from "../../data/documents/s
|
|
|
3
3
|
export { selectDocumentSyncOutgoingBatch } from "../../data/documents/shared/sync/documentSyncOutgoingBatch.js";
|
|
4
4
|
export { isDocumentSyncUpdateIsolationError, validateDocumentSyncUpdateImports, } from "../../data/documents/shared/sync/documentSyncUpdateIsolation.js";
|
|
5
5
|
export { documentSyncPullContinuationsEqual, readPullContinuation, } from "../../data/documents/shared/sync/syncPagination.js";
|
|
6
|
-
export { clearDocumentSyncFailure, invalidateDocumentSyncPullContinuation, recordDocumentSyncFailure, } from "../../data/
|
|
7
|
-
export { DOCUMENT_HISTORY_COMPACTION_MAX_BYTES, DOCUMENT_HISTORY_COMPACTION_MAX_ROWS, } from "../../data/
|
|
6
|
+
export { clearDocumentSyncFailure, invalidateDocumentSyncPullContinuation, recordDocumentSyncFailure, } from "../../data/persistence/documents/records/index.js";
|
|
7
|
+
export { DOCUMENT_HISTORY_COMPACTION_MAX_BYTES, DOCUMENT_HISTORY_COMPACTION_MAX_ROWS, } from "../../data/persistence/documents/records/documentHistoryPersistence.js";
|
|
8
8
|
export { settleOutgoingPassAndDecideReArm } from "../../data/sync/outgoingUpdateSettlement.js";
|
|
9
9
|
export { didRegainSyncPrerequisites, isDatabaseUnavailableError, } from "../../data/sync/syncCoordinator.js";
|
|
10
10
|
export { deleteLocalDocumentAttachment, deletePendingDocumentAttachment, markLocalDocumentAttachmentDetached, saveLocalDocumentAttachments, savePendingDocumentAttachment, } from "./attachments/attachmentPersistence.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,wCAAwC,EAAE,MAAM,uCAAuC,CAAC;AACjG,OAAO,EAAE,+BAA+B,EAAE,MAAM,4DAA4D,CAAC;AAC7G,OAAO,EAGL,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,8DAA8D,CAAC;AACtE,OAAO,EAEL,kCAAkC,EAClC,oBAAoB,GACrB,MAAM,iDAAiD,CAAC;AAOzD,OAAO,EACL,wBAAwB,EACxB,sCAAsC,EACtC,yBAAyB,GAC1B,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,wCAAwC,EAAE,MAAM,uCAAuC,CAAC;AACjG,OAAO,EAAE,+BAA+B,EAAE,MAAM,4DAA4D,CAAC;AAC7G,OAAO,EAGL,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,8DAA8D,CAAC;AACtE,OAAO,EAEL,kCAAkC,EAClC,oBAAoB,GACrB,MAAM,iDAAiD,CAAC;AAOzD,OAAO,EACL,wBAAwB,EACxB,sCAAsC,EACtC,yBAAyB,GAC1B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,qCAAqC,EACrC,oCAAoC,GACrC,MAAM,qEAAqE,CAAC;AAE7E,OAAO,EAAE,gCAAgC,EAAE,MAAM,0CAA0C,CAAC;AAC5F,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,mCAAmC,EACnC,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EACL,mCAAmC,EACnC,oBAAoB,EACpB,0CAA0C,GAC3C,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,gCAAgC,EAChC,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,4CAA4C,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,kBAAkB,EAGlB,2BAA2B,EAE3B,+BAA+B,EAK/B,oBAAoB,EAEpB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uCAAuC,EAGvC,qCAAqC,GACtC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAEL,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,8BAA8B,GAM/B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAEL,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mCAAmC,EACnC,iCAAiC,GAElC,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,uCAAuC,EAAE,MAAM,qCAAqC,CAAC;AAC9F,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAEhF,OAAO,EAAE,qCAAqC,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export {\n unwrapContainerKekPath,\n unwrapDocumentContentKeyTarget,\n} from \"../../data/documents/shared/projection\";\nexport { persistedDocumentCreateStateFromResponse } from \"../../data/documents/shared/responses\";\nexport { selectDocumentSyncOutgoingBatch } from \"../../data/documents/shared/sync/documentSyncOutgoingBatch\";\nexport {\n type DocumentSyncUpdateIsolationError,\n type IncomingDocumentSyncUpdateValidator,\n isDocumentSyncUpdateIsolationError,\n validateDocumentSyncUpdateImports,\n} from \"../../data/documents/shared/sync/documentSyncUpdateIsolation\";\nexport {\n type DocumentSyncPullContinuation,\n documentSyncPullContinuationsEqual,\n readPullContinuation,\n} from \"../../data/documents/shared/sync/syncPagination\";\nexport type {\n DocumentCreateAuthor,\n DocumentLinkSetFailureHandler,\n DocumentLinkSetMutationFailure,\n RelinkRemoteDocumentResult,\n} from \"../../data/documents/shared/types\";\nexport {\n clearDocumentSyncFailure,\n invalidateDocumentSyncPullContinuation,\n recordDocumentSyncFailure,\n} from \"../../data/persistence/documents/records\";\nexport {\n DOCUMENT_HISTORY_COMPACTION_MAX_BYTES,\n DOCUMENT_HISTORY_COMPACTION_MAX_ROWS,\n} from \"../../data/persistence/documents/records/documentHistoryPersistence\";\nexport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nexport { settleOutgoingPassAndDecideReArm } from \"../../data/sync/outgoingUpdateSettlement\";\nexport {\n didRegainSyncPrerequisites,\n isDatabaseUnavailableError,\n} from \"../../data/sync/syncCoordinator\";\nexport {\n deleteLocalDocumentAttachment,\n deletePendingDocumentAttachment,\n markLocalDocumentAttachmentDetached,\n saveLocalDocumentAttachments,\n savePendingDocumentAttachment,\n} from \"./attachments/attachmentPersistence\";\nexport { runSerializedDocumentBlobMutation } from \"./attachments/blobMutationLock\";\nexport { reclaimDocumentOrphanBlobs } from \"./attachments/orphanBlobReclaims\";\nexport { resolveDocumentCreateAuthor } from \"./author\";\nexport {\n buildMaterializedDocumentCreatePlan,\n createRemoteDocument,\n documentWriterProjectionFromCreateResponse,\n} from \"./create\";\nexport {\n importDocumentHistoryTailUpdates,\n loadPersistedDocumentContent,\n mergePersistedDocumentHistory,\n} from \"./historyContent\";\nexport { buildMaterializedDocumentLinkSetMutationPlan } from \"./linkSet\";\nexport { relinkRemoteDocument } from \"./linkSet/linkSetRemote\";\nexport {\n enqueuePendingDocumentUpdate,\n listPendingDocumentUpdates,\n} from \"./pendingUpdatePersistence\";\nexport {\n type AttachmentRemovalRows,\n type AttachmentStagingRows,\n DOCUMENTS_APP_KIND,\n type DocumentRecord,\n type DocumentsPersistence,\n defaultDocumentsPersistence,\n type LocalAttachmentRecord,\n loadPersistedDocumentStoreState,\n type PendingAttachmentRecord,\n type PendingAttachmentUploadIdentity,\n type PendingUpdateInsert,\n type PendingUpdateRecord,\n persistDocumentState,\n type RelinkPersistedDocumentInput,\n runSerializedSqlMutation,\n} from \"./persistence\";\nexport {\n createDocumentProjectionUserKeyResolver,\n type DocumentProjectionKeyRuntime,\n type DocumentProjectionUserKeyResolver,\n didDocumentProjectionKeyRuntimeChange,\n} from \"./projectionKeys\";\nexport {\n buildDocumentPurgeRequest,\n purgeRemoteDocument,\n} from \"./purge\";\nexport {\n type DiscardedDocumentShellResult,\n deletePersistedDocument,\n discardPersistedDocumentToShell,\n} from \"./purge/persistedDocumentRemoval\";\nexport {\n createDocumentsWorkflowRuntime,\n type DocumentsWorkflowRuntime,\n type DocumentsWorkflowRuntimeGroups,\n type DocumentsWorkflowRuntimeInfra,\n type DocumentsWorkflowRuntimeInput,\n type DocumentsWorkflowRuntimeInputGroups,\n} from \"./runtime\";\nexport {\n hasDocumentUpdateEvent,\n syncRemoteDocument,\n} from \"./sync\";\nexport { documentCreateSeedCandidate } from \"./sync/initialSync\";\nexport type { SyncRemoteDocumentInput } from \"./sync/readOnlySync\";\nexport type { DocumentSyncContainerRekeyBuilder } from \"./sync/syncAttemptState\";\nexport {\n type DocumentSyncLane,\n registerDocumentSyncLane,\n requestDocumentSyncLaneAndWait,\n} from \"./sync/syncLane\";\nexport {\n DOCUMENT_SYNC_TRACE_FRAGMENT,\n DOCUMENT_SYNC_TRACE_PATTERN,\n} from \"./sync/syncTrace\";\nexport {\n describeDocumentRevalidationFailure,\n describeDocumentSyncSubmitFailure,\n type TerminalSubmitFailureHandler,\n} from \"./syncFailures/syncFailureClassification\";\nexport { shouldClearDocumentSyncFailureAfterPass } from \"./syncFailures/syncFailureClearance\";\nexport { DocumentRawHistoryUnavailableError } from \"./syncPlan/syncContentKeys\";\nexport type { RekeyPendingUpdate } from \"./syncRekeys/syncRecoveryRekey\";\nexport { createDocumentWriterPublicKeyResolver } from \"./writerKeys\";\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ClientSQLiteTransactionScope } from "../../../data/sqlite/sqlitePersistenceRuntime.js";
|
|
2
|
+
import type { ResetAttachmentUpload, ResetDocumentScope, ResetDocumentUpdate } from "./remoteResetPlans.js";
|
|
3
|
+
export { clearDocumentDiscoveryEvidenceOnRemoteReset } from "../../../data/persistence/documents/documentDiscoveryReset.js";
|
|
4
|
+
export { buildResetPlans, type ResetAttachmentUpload, type ResetDocumentUpdate, } from "./remoteResetPlans.js";
|
|
5
|
+
export interface ResetDocumentRow extends ResetDocumentScope {
|
|
6
|
+
readonly documentId: string | null;
|
|
7
|
+
readonly recoveryDocumentId: string | null;
|
|
8
|
+
}
|
|
9
|
+
interface DocumentPlacementRow {
|
|
10
|
+
readonly containerId: string;
|
|
11
|
+
readonly documentId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The documents a reset covers: metadata documents of its folders, documents
|
|
15
|
+
* projected into the organization or its folders, and documents placed in them.
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadDocumentResetScope(input: {
|
|
18
|
+
containerIds: readonly string[];
|
|
19
|
+
organizationId: string;
|
|
20
|
+
placementRows: readonly DocumentPlacementRow[];
|
|
21
|
+
tx: ClientSQLiteTransactionScope;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
documentLocalIds: string[];
|
|
24
|
+
documentRows: ResetDocumentRow[];
|
|
25
|
+
oldDocumentIds: string[];
|
|
26
|
+
}>;
|
|
27
|
+
/** Clears pending attachments (keeping re-queued bytes) and queued updates. */
|
|
28
|
+
export declare function clearDocumentRowsForRemoteReset(input: {
|
|
29
|
+
attachmentUploads: readonly ResetAttachmentUpload[];
|
|
30
|
+
documentLocalIds: readonly string[];
|
|
31
|
+
documentRows: readonly ResetDocumentRow[];
|
|
32
|
+
tx: ClientSQLiteTransactionScope;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Drops each document's server id, keys, manifest, and sync position, keeping
|
|
36
|
+
* the old id for recovery, and moves its projection to `organizationId`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resetDocumentServerIdentity(input: {
|
|
39
|
+
documentLocalIds: readonly string[];
|
|
40
|
+
documentRows: readonly ResetDocumentRow[];
|
|
41
|
+
now: string;
|
|
42
|
+
organizationId: string;
|
|
43
|
+
tx: ClientSQLiteTransactionScope;
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
/** Queues each document's rebuilt local history as one outbox update. */
|
|
46
|
+
export declare function queueDocumentRepublishForRemoteReset(input: {
|
|
47
|
+
documentUpdates: readonly ResetDocumentUpdate[];
|
|
48
|
+
now: string;
|
|
49
|
+
tx: ClientSQLiteTransactionScope;
|
|
50
|
+
}): Promise<void>;
|
|
51
|
+
/** Queues the attachments the documents still advertise for upload. */
|
|
52
|
+
export declare function queueAttachmentReuploadsForRemoteReset(input: {
|
|
53
|
+
attachmentUploads: readonly ResetAttachmentUpload[];
|
|
54
|
+
now: string;
|
|
55
|
+
tx: ClientSQLiteTransactionScope;
|
|
56
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { and, eq, inArray, or } from "drizzle-orm";
|
|
2
|
+
import { queuedUpdateRow, unqueueDocumentScopesInTransaction, } from "../../../data/persistence/documents/records/documentPendingUpdatePersistence.js";
|
|
3
|
+
import { CLEARED_DOCUMENT_SYNC_FAILURE } from "../../../data/persistence/documents/records/documentSyncFailurePersistence.js";
|
|
4
|
+
import { documentAttachmentBlobProjection, documentHistoryUpdates, documentPendingAttachments, documentProjection, documents, } from "../../../data/sqlite/schema/index.js";
|
|
5
|
+
import { remoteResetBatches } from "../../../data/sqlite/sqliteBindBudget.js";
|
|
6
|
+
import { clearResetPendingAttachments } from "./remoteResetAttachments.js";
|
|
7
|
+
// Document Store's part of a remote reset. The sync remote reset calls these in
|
|
8
|
+
// one transaction: it forgets what the server held for the organization's
|
|
9
|
+
// documents, strips their server identity, and queues their local history and
|
|
10
|
+
// attachments to be published again.
|
|
11
|
+
export { clearDocumentDiscoveryEvidenceOnRemoteReset } from "../../../data/persistence/documents/documentDiscoveryReset.js";
|
|
12
|
+
export { buildResetPlans, } from "./remoteResetPlans.js";
|
|
13
|
+
/**
|
|
14
|
+
* The documents a reset covers: metadata documents of its folders, documents
|
|
15
|
+
* projected into the organization or its folders, and documents placed in them.
|
|
16
|
+
*/
|
|
17
|
+
export async function loadDocumentResetScope(input) {
|
|
18
|
+
const { organizationId, tx } = input;
|
|
19
|
+
const containerIdSet = new Set(input.containerIds);
|
|
20
|
+
const [allDocuments, projectionRows] = await Promise.all([
|
|
21
|
+
tx
|
|
22
|
+
.select({
|
|
23
|
+
appKind: documents.appKind,
|
|
24
|
+
documentId: documents.documentId,
|
|
25
|
+
localId: documents.localId,
|
|
26
|
+
recoveryDocumentId: documents.recoveryDocumentId,
|
|
27
|
+
})
|
|
28
|
+
.from(documents),
|
|
29
|
+
tx.select().from(documentProjection),
|
|
30
|
+
]);
|
|
31
|
+
const linkedDocumentIds = new Set(input.placementRows
|
|
32
|
+
.filter((row) => containerIdSet.has(row.containerId))
|
|
33
|
+
.map((row) => row.documentId));
|
|
34
|
+
const projectedLocalIds = new Set(projectionRows
|
|
35
|
+
.filter((row) => (row.containerId !== null && containerIdSet.has(row.containerId)) ||
|
|
36
|
+
row.organizationId === organizationId ||
|
|
37
|
+
(row.documentId !== null && linkedDocumentIds.has(row.documentId)))
|
|
38
|
+
.flatMap((row) => (row.localId ? [row.localId] : [])));
|
|
39
|
+
const documentRows = allDocuments.filter((row) => (row.appKind === "container-metadata" &&
|
|
40
|
+
containerIdSet.has(row.localId)) ||
|
|
41
|
+
(row.appKind === "documents" && projectedLocalIds.has(row.localId)) ||
|
|
42
|
+
(row.documentId !== null && linkedDocumentIds.has(row.documentId)));
|
|
43
|
+
return {
|
|
44
|
+
documentLocalIds: [
|
|
45
|
+
...new Set(documentRows
|
|
46
|
+
.filter((row) => row.appKind === "documents")
|
|
47
|
+
.map((row) => row.localId)),
|
|
48
|
+
],
|
|
49
|
+
documentRows,
|
|
50
|
+
oldDocumentIds: [
|
|
51
|
+
...new Set(documentRows.flatMap((row) => (row.documentId ? [row.documentId] : []))),
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Clears pending attachments (keeping re-queued bytes) and queued updates. */
|
|
56
|
+
export async function clearDocumentRowsForRemoteReset(input) {
|
|
57
|
+
const { tx } = input;
|
|
58
|
+
await clearResetPendingAttachments({
|
|
59
|
+
attachmentUploads: input.attachmentUploads,
|
|
60
|
+
documentLocalIds: input.documentLocalIds,
|
|
61
|
+
tx,
|
|
62
|
+
});
|
|
63
|
+
// Sync failures clear with the document columns in resetDocumentServerIdentity.
|
|
64
|
+
for (const documentBatch of remoteResetBatches(input.documentRows)) {
|
|
65
|
+
await unqueueDocumentScopesInTransaction(tx, documentBatch);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Drops each document's server id, keys, manifest, and sync position, keeping
|
|
70
|
+
* the old id for recovery, and moves its projection to `organizationId`.
|
|
71
|
+
*/
|
|
72
|
+
export async function resetDocumentServerIdentity(input) {
|
|
73
|
+
const { now, tx } = input;
|
|
74
|
+
for (const row of input.documentRows) {
|
|
75
|
+
await tx
|
|
76
|
+
.update(documents)
|
|
77
|
+
.set({
|
|
78
|
+
accessEpoch: 1,
|
|
79
|
+
accessStateHash: null,
|
|
80
|
+
contentKeyBundle: null,
|
|
81
|
+
documentId: null,
|
|
82
|
+
documentKekTargets: null,
|
|
83
|
+
documentManifestBundle: null,
|
|
84
|
+
lastCommitLsn: null,
|
|
85
|
+
pullContinuation: null,
|
|
86
|
+
recoveryDocumentId: row.documentId ?? row.recoveryDocumentId,
|
|
87
|
+
...CLEARED_DOCUMENT_SYNC_FAILURE,
|
|
88
|
+
updatedAt: now,
|
|
89
|
+
})
|
|
90
|
+
.where(and(eq(documents.appKind, row.appKind), eq(documents.localId, row.localId)))
|
|
91
|
+
.run();
|
|
92
|
+
}
|
|
93
|
+
for (const localIdBatch of remoteResetBatches(input.documentLocalIds)) {
|
|
94
|
+
await tx
|
|
95
|
+
.update(documentProjection)
|
|
96
|
+
.set({
|
|
97
|
+
documentId: null,
|
|
98
|
+
organizationId: input.organizationId,
|
|
99
|
+
})
|
|
100
|
+
.where(inArray(documentProjection.localId, localIdBatch))
|
|
101
|
+
.run();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Queues each document's rebuilt local history as one outbox update. */
|
|
105
|
+
export async function queueDocumentRepublishForRemoteReset(input) {
|
|
106
|
+
for (const updateBatch of remoteResetBatches(input.documentUpdates)) {
|
|
107
|
+
await input.tx
|
|
108
|
+
.insert(documentHistoryUpdates)
|
|
109
|
+
.values(updateBatch.map((update) => queuedUpdateRow({
|
|
110
|
+
createdAt: input.now,
|
|
111
|
+
origin: "outbox",
|
|
112
|
+
pendingUpdate: update,
|
|
113
|
+
scope: update,
|
|
114
|
+
updateId: crypto.randomUUID(),
|
|
115
|
+
})))
|
|
116
|
+
.run();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Queues the attachments the documents still advertise for upload. */
|
|
120
|
+
export async function queueAttachmentReuploadsForRemoteReset(input) {
|
|
121
|
+
for (const attachmentBatch of remoteResetBatches(input.attachmentUploads)) {
|
|
122
|
+
await input.tx
|
|
123
|
+
.insert(documentPendingAttachments)
|
|
124
|
+
.values(attachmentBatch.map((attachment) => ({
|
|
125
|
+
...attachment,
|
|
126
|
+
createdAt: input.now,
|
|
127
|
+
})))
|
|
128
|
+
.run();
|
|
129
|
+
await input.tx
|
|
130
|
+
.delete(documentAttachmentBlobProjection)
|
|
131
|
+
.where(or(...attachmentBatch.map((attachment) => and(eq(documentAttachmentBlobProjection.localId, attachment.localId), eq(documentAttachmentBlobProjection.slotId, attachment.slotId)))))
|
|
132
|
+
.run();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=documentRemoteReset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentRemoteReset.js","sourceRoot":"","sources":["documentRemoteReset.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray, or } from \"drizzle-orm\";\nimport {\n queuedUpdateRow,\n unqueueDocumentScopesInTransaction,\n} from \"../../../data/persistence/documents/records/documentPendingUpdatePersistence\";\nimport { CLEARED_DOCUMENT_SYNC_FAILURE } from \"../../../data/persistence/documents/records/documentSyncFailurePersistence\";\nimport {\n documentAttachmentBlobProjection,\n documentHistoryUpdates,\n documentPendingAttachments,\n documentProjection,\n documents,\n} from \"../../../data/sqlite/schema\";\nimport { remoteResetBatches } from \"../../../data/sqlite/sqliteBindBudget\";\nimport type { ClientSQLiteTransactionScope } from \"../../../data/sqlite/sqlitePersistenceRuntime\";\nimport { clearResetPendingAttachments } from \"./remoteResetAttachments\";\nimport type {\n ResetAttachmentUpload,\n ResetDocumentScope,\n ResetDocumentUpdate,\n} from \"./remoteResetPlans\";\n\n// Document Store's part of a remote reset. The sync remote reset calls these in\n// one transaction: it forgets what the server held for the organization's\n// documents, strips their server identity, and queues their local history and\n// attachments to be published again.\nexport { clearDocumentDiscoveryEvidenceOnRemoteReset } from \"../../../data/persistence/documents/documentDiscoveryReset\";\nexport {\n buildResetPlans,\n type ResetAttachmentUpload,\n type ResetDocumentUpdate,\n} from \"./remoteResetPlans\";\n\nexport interface ResetDocumentRow extends ResetDocumentScope {\n readonly documentId: string | null;\n readonly recoveryDocumentId: string | null;\n}\n\ninterface DocumentPlacementRow {\n readonly containerId: string;\n readonly documentId: string;\n}\n\n/**\n * The documents a reset covers: metadata documents of its folders, documents\n * projected into the organization or its folders, and documents placed in them.\n */\nexport async function loadDocumentResetScope(input: {\n containerIds: readonly string[];\n organizationId: string;\n placementRows: readonly DocumentPlacementRow[];\n tx: ClientSQLiteTransactionScope;\n}): Promise<{\n documentLocalIds: string[];\n documentRows: ResetDocumentRow[];\n oldDocumentIds: string[];\n}> {\n const { organizationId, tx } = input;\n const containerIdSet = new Set(input.containerIds);\n const [allDocuments, projectionRows] = await Promise.all([\n tx\n .select({\n appKind: documents.appKind,\n documentId: documents.documentId,\n localId: documents.localId,\n recoveryDocumentId: documents.recoveryDocumentId,\n })\n .from(documents),\n tx.select().from(documentProjection),\n ]);\n const linkedDocumentIds = new Set(\n input.placementRows\n .filter((row) => containerIdSet.has(row.containerId))\n .map((row) => row.documentId),\n );\n const projectedLocalIds = new Set(\n projectionRows\n .filter(\n (row) =>\n (row.containerId !== null && containerIdSet.has(row.containerId)) ||\n row.organizationId === organizationId ||\n (row.documentId !== null && linkedDocumentIds.has(row.documentId)),\n )\n .flatMap((row) => (row.localId ? [row.localId] : [])),\n );\n const documentRows = allDocuments.filter(\n (row) =>\n (row.appKind === \"container-metadata\" &&\n containerIdSet.has(row.localId)) ||\n (row.appKind === \"documents\" && projectedLocalIds.has(row.localId)) ||\n (row.documentId !== null && linkedDocumentIds.has(row.documentId)),\n );\n return {\n documentLocalIds: [\n ...new Set(\n documentRows\n .filter((row) => row.appKind === \"documents\")\n .map((row) => row.localId),\n ),\n ],\n documentRows,\n oldDocumentIds: [\n ...new Set(\n documentRows.flatMap((row) => (row.documentId ? [row.documentId] : [])),\n ),\n ],\n };\n}\n\n/** Clears pending attachments (keeping re-queued bytes) and queued updates. */\nexport async function clearDocumentRowsForRemoteReset(input: {\n attachmentUploads: readonly ResetAttachmentUpload[];\n documentLocalIds: readonly string[];\n documentRows: readonly ResetDocumentRow[];\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { tx } = input;\n await clearResetPendingAttachments({\n attachmentUploads: input.attachmentUploads,\n documentLocalIds: input.documentLocalIds,\n tx,\n });\n // Sync failures clear with the document columns in resetDocumentServerIdentity.\n for (const documentBatch of remoteResetBatches(input.documentRows)) {\n await unqueueDocumentScopesInTransaction(tx, documentBatch);\n }\n}\n\n/**\n * Drops each document's server id, keys, manifest, and sync position, keeping\n * the old id for recovery, and moves its projection to `organizationId`.\n */\nexport async function resetDocumentServerIdentity(input: {\n documentLocalIds: readonly string[];\n documentRows: readonly ResetDocumentRow[];\n now: string;\n organizationId: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const { now, tx } = input;\n for (const row of input.documentRows) {\n await tx\n .update(documents)\n .set({\n accessEpoch: 1,\n accessStateHash: null,\n contentKeyBundle: null,\n documentId: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n lastCommitLsn: null,\n pullContinuation: null,\n recoveryDocumentId: row.documentId ?? row.recoveryDocumentId,\n ...CLEARED_DOCUMENT_SYNC_FAILURE,\n updatedAt: now,\n })\n .where(\n and(\n eq(documents.appKind, row.appKind),\n eq(documents.localId, row.localId),\n ),\n )\n .run();\n }\n for (const localIdBatch of remoteResetBatches(input.documentLocalIds)) {\n await tx\n .update(documentProjection)\n .set({\n documentId: null,\n organizationId: input.organizationId,\n })\n .where(inArray(documentProjection.localId, localIdBatch))\n .run();\n }\n}\n\n/** Queues each document's rebuilt local history as one outbox update. */\nexport async function queueDocumentRepublishForRemoteReset(input: {\n documentUpdates: readonly ResetDocumentUpdate[];\n now: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const updateBatch of remoteResetBatches(input.documentUpdates)) {\n await input.tx\n .insert(documentHistoryUpdates)\n .values(\n updateBatch.map((update) =>\n queuedUpdateRow({\n createdAt: input.now,\n origin: \"outbox\",\n pendingUpdate: update,\n scope: update,\n updateId: crypto.randomUUID(),\n }),\n ),\n )\n .run();\n }\n}\n\n/** Queues the attachments the documents still advertise for upload. */\nexport async function queueAttachmentReuploadsForRemoteReset(input: {\n attachmentUploads: readonly ResetAttachmentUpload[];\n now: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const attachmentBatch of remoteResetBatches(input.attachmentUploads)) {\n await input.tx\n .insert(documentPendingAttachments)\n .values(\n attachmentBatch.map((attachment) => ({\n ...attachment,\n createdAt: input.now,\n })),\n )\n .run();\n await input.tx\n .delete(documentAttachmentBlobProjection)\n .where(\n or(\n ...attachmentBatch.map((attachment) =>\n and(\n eq(documentAttachmentBlobProjection.localId, attachment.localId),\n eq(documentAttachmentBlobProjection.slotId, attachment.slotId),\n ),\n ),\n ),\n )\n .run();\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { inArray } from "drizzle-orm";
|
|
2
|
-
import { queueDocumentAttachmentStorageKeys } from "
|
|
3
|
-
import { documentPendingAttachments } from "
|
|
4
|
-
import { remoteResetBatches } from "
|
|
2
|
+
import { queueDocumentAttachmentStorageKeys } from "../../../data/persistence/documents/internal/orphanSideRows.js";
|
|
3
|
+
import { documentPendingAttachments } from "../../../data/sqlite/schema/index.js";
|
|
4
|
+
import { remoteResetBatches } from "../../../data/sqlite/sqliteBindBudget.js";
|
|
5
5
|
/** Delete reset-scoped pending rows without abandoning dropped local bytes. */
|
|
6
6
|
export async function clearResetPendingAttachments(input) {
|
|
7
7
|
const requeuedKeys = new Set(input.attachmentUploads.map((attachment) => `${attachment.localId}\0${attachment.slotId}`));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remoteResetAttachments.js","sourceRoot":"","sources":["remoteResetAttachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,kCAAkC,EAAE,MAAM,6DAA6D,CAAC;AACjH,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAI3E,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,KAIlD;IACC,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,KAAK,CAAC,iBAAiB,CAAC,GAAG,CACzB,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,KAAK,UAAU,CAAC,MAAM,EAAE,CAC9D,CACF,CAAC;IACF,KAAK,MAAM,YAAY,IAAI,kBAAkB,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,EAAE;aACxB,MAAM,CAAC;YACN,OAAO,EAAE,0BAA0B,CAAC,OAAO;YAC3C,MAAM,EAAE,0BAA0B,CAAC,MAAM;YACzC,UAAU,EAAE,0BAA0B,CAAC,UAAU;SAClD,CAAC;aACD,IAAI,CAAC,0BAA0B,CAAC;aAChC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QACpE,MAAM,kCAAkC,CACtC,KAAK,CAAC,EAAE,EACR,IAAI;aACD,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;aACnE,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAChC,CAAC;QACF,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,0BAA0B,CAAC;aAClC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;aAChE,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC","sourcesContent":["import { inArray } from \"drizzle-orm\";\nimport { queueDocumentAttachmentStorageKeys } from \"../../../data/persistence/documents/internal/orphanSideRows\";\nimport { documentPendingAttachments } from \"../../../data/sqlite/schema\";\nimport { remoteResetBatches } from \"../../../data/sqlite/sqliteBindBudget\";\nimport type { ClientSQLiteTransactionScope } from \"../../../data/sqlite/sqlitePersistenceRuntime\";\nimport type { ResetAttachmentUpload } from \"./remoteResetPlans\";\n\n/** Delete reset-scoped pending rows without abandoning dropped local bytes. */\nexport async function clearResetPendingAttachments(input: {\n readonly attachmentUploads: readonly ResetAttachmentUpload[];\n readonly documentLocalIds: readonly string[];\n readonly tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n const requeuedKeys = new Set(\n input.attachmentUploads.map(\n (attachment) => `${attachment.localId}\\0${attachment.slotId}`,\n ),\n );\n for (const localIdBatch of remoteResetBatches(input.documentLocalIds)) {\n const rows = await input.tx\n .select({\n localId: documentPendingAttachments.localId,\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n })\n .from(documentPendingAttachments)\n .where(inArray(documentPendingAttachments.localId, localIdBatch));\n await queueDocumentAttachmentStorageKeys(\n input.tx,\n rows\n .filter((row) => !requeuedKeys.has(`${row.localId}\\0${row.slotId}`))\n .map((row) => row.storageKey),\n );\n await input.tx\n .delete(documentPendingAttachments)\n .where(inArray(documentPendingAttachments.localId, localIdBatch))\n .run();\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClientSQLiteTransactionScope } from "
|
|
1
|
+
import type { ClientSQLiteTransactionScope } from "../../../data/sqlite/sqlitePersistenceRuntime.js";
|
|
2
2
|
export interface ResetDocumentUpdate {
|
|
3
3
|
readonly appKind: string;
|
|
4
4
|
readonly localId: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { createDocument, exportAllUpdates } from "
|
|
1
|
+
import { createDocument, exportAllUpdates } from "../../../internal/loro/index.js";
|
|
2
2
|
import { and, eq, ne, or, sql } from "drizzle-orm";
|
|
3
|
-
import { getDocumentAttachments, } from "
|
|
4
|
-
import { createPendingUpdateFields } from "
|
|
5
|
-
import { DOCUMENTS_APP_KIND } from "
|
|
6
|
-
import { documentAttachmentBlobProjection, documentHistoryCheckpoints, documentHistoryUpdates, documentPendingAttachments, documents, } from "
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { getDocumentAttachments, } from "../../../data/documents/index.js";
|
|
4
|
+
import { createPendingUpdateFields } from "../../../data/documents/documentSync.js";
|
|
5
|
+
import { DOCUMENTS_APP_KIND } from "../../../data/persistence/documents/documentsPersistence.js";
|
|
6
|
+
import { documentAttachmentBlobProjection, documentHistoryCheckpoints, documentHistoryUpdates, documentPendingAttachments, documents, } from "../../../data/sqlite/schema/index.js";
|
|
7
|
+
import { remoteResetBatches } from "../../../data/sqlite/sqliteBindBudget.js";
|
|
8
|
+
import { importDocumentHistoryTailUpdates } from "../historyContent.js";
|
|
9
9
|
function historyScopeKey(appKind, localId) {
|
|
10
10
|
return `${appKind} ${localId}`;
|
|
11
11
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remoteResetPlans.js","sourceRoot":"","sources":["remoteResetPlans.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDocument, exportAllUpdates } from \"@tearleads/loro\";\nimport { and, eq, ne, or, sql } from \"drizzle-orm\";\nimport {\n type DocumentAttachment,\n getDocumentAttachments,\n} from \"../../../data/documents\";\nimport { createPendingUpdateFields } from \"../../../data/documents/documentSync\";\nimport { DOCUMENTS_APP_KIND } from \"../../../data/persistence/documents/documentsPersistence\";\nimport {\n documentAttachmentBlobProjection,\n documentHistoryCheckpoints,\n documentHistoryUpdates,\n documentPendingAttachments,\n documents,\n} from \"../../../data/sqlite/schema\";\nimport { remoteResetBatches } from \"../../../data/sqlite/sqliteBindBudget\";\nimport type { ClientSQLiteTransactionScope } from \"../../../data/sqlite/sqlitePersistenceRuntime\";\nimport { importDocumentHistoryTailUpdates } from \"../historyContent\";\n\nexport interface ResetDocumentUpdate {\n readonly appKind: string;\n readonly localId: string;\n readonly updateData: string;\n readonly partialStartVersionVector: string;\n readonly partialEndVersionVector: string;\n readonly sourceVersionVector: string | null;\n}\n\nexport interface ResetAttachmentUpload {\n readonly byteLength: number;\n readonly contentSha256: string;\n readonly localId: string;\n readonly mimeType: string | null;\n readonly name: string;\n readonly slotId: string;\n readonly storageKey: string;\n}\n\ntype ResetContentDoc = Awaited<ReturnType<typeof createDocument>>;\n\nfunction historyScopeKey(appKind: string, localId: string): string {\n return `${appKind} ${localId}`;\n}\n\nfunction attachmentScopeKey(localId: string, slotId: string): string {\n return `${localId}\\0${slotId}`;\n}\n\nfunction buildResetUpdate(input: {\n appKind: string;\n doc: ResetContentDoc;\n localId: string;\n}): ResetDocumentUpdate | null {\n const fields = createPendingUpdateFields(exportAllUpdates(input.doc));\n if (!fields) {\n return null;\n }\n\n return {\n appKind: input.appKind,\n localId: input.localId,\n updateData: fields.updateData,\n partialStartVersionVector: fields.partialStartVersionVector,\n partialEndVersionVector: fields.partialEndVersionVector,\n sourceVersionVector: fields.sourceVersionVector ?? null,\n };\n}\n\ninterface ResetHistoryRows {\n checkpointRows: Array<{\n appKind: string;\n localId: string;\n snapshot: string;\n }>;\n tailRows: Array<{\n appKind: string;\n localId: string;\n updateData: string;\n }>;\n}\n\nasync function loadResetHistoryRows(\n db: ClientSQLiteTransactionScope,\n documentScopes?: readonly ResetDocumentScope[],\n): Promise<ResetHistoryRows> {\n const rows: ResetHistoryRows = { checkpointRows: [], tailRows: [] };\n const scopes = documentScopes\n ? [\n ...new Map(\n documentScopes.map((scope) => [\n historyScopeKey(scope.appKind, scope.localId),\n scope,\n ]),\n ).values(),\n ]\n : null;\n for (const scopeBatch of scopes ? remoteResetBatches(scopes) : [null]) {\n // An outbox row only waits to be sent; the content lives in the\n // checkpoint and tail rows (see `documentHistoryUpdates`).\n const notOutbox = ne(documentHistoryUpdates.origin, \"outbox\");\n const scopeTail = scopeBatch\n ? and(\n notOutbox,\n or(\n ...scopeBatch.map((scope) =>\n and(\n eq(documentHistoryUpdates.appKind, scope.appKind),\n eq(documentHistoryUpdates.localId, scope.localId),\n ),\n ),\n ),\n )\n : notOutbox;\n const scopeCheckpoints = scopeBatch\n ? or(\n ...scopeBatch.map((scope) =>\n and(\n eq(documentHistoryCheckpoints.appKind, scope.appKind),\n eq(documentHistoryCheckpoints.localId, scope.localId),\n ),\n ),\n )\n : undefined;\n const tailBatch = await db\n .select({\n appKind: documentHistoryUpdates.appKind,\n localId: documentHistoryUpdates.localId,\n updateData: documentHistoryUpdates.updateData,\n })\n .from(documentHistoryUpdates)\n .where(scopeTail)\n .orderBy(sql`rowid`);\n const checkpointBatch = await db\n .select({\n appKind: documentHistoryCheckpoints.appKind,\n localId: documentHistoryCheckpoints.localId,\n snapshot: documentHistoryCheckpoints.snapshot,\n })\n .from(documentHistoryCheckpoints)\n .where(scopeCheckpoints);\n rows.tailRows.push(...tailBatch);\n rows.checkpointRows.push(...checkpointBatch);\n }\n return rows;\n}\n\n/**\n * Reconstruct every persisted document's content from the durable-history\n * tables (checkpoint + tail) — the only content source. A scope without a\n * checkpoint (a discovered shell that never hydrated) gets no doc: it has no\n * content to republish and no attachments to requeue. The mode-sniffing tail\n * import handles both content kinds — full-history snapshots (documents) and\n * exported-updates blobs (container metadata).\n */\nasync function buildResetContentDocs(\n db: ClientSQLiteTransactionScope,\n documentScopes?: readonly ResetDocumentScope[],\n): Promise<Map<string, ResetContentDoc>> {\n // Read the TAIL before the checkpoints (the same order the restore path\n // uses): a compaction landing between the two reads then yields old-tail +\n // new-checkpoint — a safe superset, since replay is idempotent by op\n // identity — whereas the reverse order could yield an old checkpoint plus\n // an already-emptied tail and republish stale content.\n const { checkpointRows, tailRows } = await loadResetHistoryRows(\n db,\n documentScopes,\n );\n\n const tailByScope = new Map<string, string[]>();\n for (const row of tailRows) {\n const key = historyScopeKey(row.appKind, row.localId);\n const tail = tailByScope.get(key);\n if (tail) {\n tail.push(row.updateData);\n } else {\n tailByScope.set(key, [row.updateData]);\n }\n }\n\n // Rebuild the UNION of checkpoint and tail scopes: a tail-only scope (a\n // crash landed the first edit's tail row before the birth checkpoint) may\n // hold the only durable copy of that edit, and dropping it from the reset\n // would discard it.\n const checkpointByScope = new Map(\n checkpointRows.map((row) => [\n historyScopeKey(row.appKind, row.localId),\n row,\n ]),\n );\n const historyScopes = new Map<string, { appKind: string; localId: string }>();\n for (const row of [...checkpointRows, ...tailRows]) {\n historyScopes.set(historyScopeKey(row.appKind, row.localId), {\n appKind: row.appKind,\n localId: row.localId,\n });\n }\n\n const contentDocByScope = new Map<string, ResetContentDoc>();\n await Promise.all(\n [...historyScopes.entries()].map(async ([key, scope]) => {\n const doc = await createDocument(\n `remote-reset:${scope.appKind}:${scope.localId}`,\n );\n const checkpoint = checkpointByScope.get(key);\n // An empty checkpoint blob (e.g. container metadata saved before any\n // update existed) carries no ops — importing it would throw and fail\n // the whole reset.\n importDocumentHistoryTailUpdates(\n doc,\n [\n ...(checkpoint ? [checkpoint.snapshot] : []),\n ...(tailByScope.get(key) ?? []),\n ].filter((blob) => blob.length > 0),\n );\n contentDocByScope.set(key, doc);\n }),\n );\n return contentDocByScope;\n}\n\nexport interface ResetDocumentScope {\n readonly appKind: string;\n readonly localId: string;\n}\n\nasync function loadResetPlanRows(\n db: ClientSQLiteTransactionScope,\n documentScopes?: readonly ResetDocumentScope[],\n) {\n const selectedScopeKeys = documentScopes\n ? new Set(\n documentScopes.map((scope) =>\n historyScopeKey(scope.appKind, scope.localId),\n ),\n )\n : null;\n const allDocumentRows = await db\n .select({ appKind: documents.appKind, localId: documents.localId })\n .from(documents);\n const documentRows = selectedScopeKeys\n ? allDocumentRows.filter((row) =>\n selectedScopeKeys.has(historyScopeKey(row.appKind, row.localId)),\n )\n : allDocumentRows;\n const [allAttachmentRows, pendingAttachmentRows] = await Promise.all([\n db\n .select({\n byteLength: documentAttachmentBlobProjection.byteLength,\n localId: documentAttachmentBlobProjection.localId,\n mimeType: documentAttachmentBlobProjection.mimeType,\n slotId: documentAttachmentBlobProjection.slotId,\n storageKey: documentAttachmentBlobProjection.storageKey,\n })\n .from(documentAttachmentBlobProjection),\n db\n .select({\n byteLength: documentPendingAttachments.byteLength,\n localId: documentPendingAttachments.localId,\n mimeType: documentPendingAttachments.mimeType,\n slotId: documentPendingAttachments.slotId,\n storageKey: documentPendingAttachments.storageKey,\n })\n .from(documentPendingAttachments),\n ]);\n const selectedDocumentLocalIds = new Set(\n documentRows\n .filter((row) => row.appKind === DOCUMENTS_APP_KIND)\n .map((row) => row.localId),\n );\n const attachmentRows = new Map(\n allAttachmentRows\n .filter((row) => selectedDocumentLocalIds.has(row.localId))\n .map((row) => [attachmentScopeKey(row.localId, row.slotId), row]),\n );\n for (const row of pendingAttachmentRows) {\n if (selectedDocumentLocalIds.has(row.localId)) {\n attachmentRows.set(attachmentScopeKey(row.localId, row.slotId), row);\n }\n }\n return {\n attachmentRows: [...attachmentRows.values()],\n documentRows,\n };\n}\n\nexport async function buildResetPlans(\n db: ClientSQLiteTransactionScope,\n documentScopes?: readonly ResetDocumentScope[],\n): Promise<{\n readonly attachmentUploads: ResetAttachmentUpload[];\n readonly documentUpdates: ResetDocumentUpdate[];\n}> {\n const { attachmentRows, documentRows } = await loadResetPlanRows(\n db,\n documentScopes,\n );\n const contentDocByScope = await buildResetContentDocs(db, documentScopes);\n const documentUpdates = documentRows.flatMap((row) => {\n const doc = contentDocByScope.get(\n historyScopeKey(row.appKind, row.localId),\n );\n if (!doc) {\n return [];\n }\n const update = buildResetUpdate({\n appKind: row.appKind,\n doc,\n localId: row.localId,\n });\n return update ? [update] : [];\n });\n const attachmentIntentMaps = new Map<\n string,\n Map<string, DocumentAttachment>\n >();\n const attachmentLocalIds = [\n ...new Set(attachmentRows.map((attachment) => attachment.localId)),\n ];\n for (const localId of attachmentLocalIds) {\n const doc = contentDocByScope.get(\n historyScopeKey(DOCUMENTS_APP_KIND, localId),\n );\n if (!doc) {\n continue;\n }\n attachmentIntentMaps.set(\n localId,\n new Map(\n getDocumentAttachments(doc).map((attachment) => [\n attachment.slotId,\n attachment,\n ]),\n ),\n );\n }\n\n // A reset re-uploads the local attachments as pending work, and the durable\n // document decides which rows those are: a row whose slot the snapshot no\n // longer advertises belongs to an unlink, and re-queueing it would resurrect\n // an attachment the document dropped. Reading the snapshot rather than the\n // detach marker keeps the two halves of an interrupted unlink consistent —\n // there the marker is set but the snapshot still advertises the slot, and the\n // reset has to upload it to match the document it is about to republish.\n const attachmentUploads = attachmentRows.flatMap((attachment) => {\n const intent = attachmentIntentMaps\n .get(attachment.localId)\n ?.get(attachment.slotId);\n if (intent === undefined) {\n return [];\n }\n\n return [\n {\n byteLength: attachment.byteLength,\n contentSha256: intent.contentSha256,\n localId: attachment.localId,\n mimeType: attachment.mimeType,\n name: intent.name,\n slotId: attachment.slotId,\n storageKey: attachment.storageKey,\n },\n ];\n });\n\n return { attachmentUploads, documentUpdates };\n}\n"]}
|