@tearleads/client-sdk 0.1.78 → 0.1.80
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/deviceFirst/index.d.ts +1 -1
- package/client/deviceFirst/index.js +1 -1
- package/client/deviceFirst/index.js.map +1 -1
- package/client/runtime/principalMutationApi.js +1 -1
- package/client/runtime/principalMutationApi.js.map +1 -1
- package/client/runtime/principalMutationDispatch.js +1 -1
- package/client/runtime/principalMutationDispatch.js.map +1 -1
- package/client/runtime/rootContainerAdoption.js.map +1 -1
- package/client/runtime/workflowRuntime.d.ts +1 -1
- package/client/runtime/workflowRuntime.js.map +1 -1
- package/client/session/sessionPurgeRecovery.js +1 -1
- package/client/session/sessionPurgeRecovery.js.map +1 -1
- package/data/blobs/attachments/projection.js +2 -3
- package/data/blobs/attachments/projection.js.map +1 -1
- package/data/documents/documentConstants.d.ts +1 -0
- package/data/documents/documentConstants.js +1 -0
- package/data/documents/documentConstants.js.map +1 -1
- package/data/documents/shared/containerKek/containerKekEntryVerification.d.ts +3 -0
- package/data/documents/shared/containerKek/index.d.ts +5 -0
- package/data/documents/shared/containerKek/index.js +9 -0
- package/data/documents/shared/containerKek/index.js.map +1 -0
- package/data/documents/shared/projection/index.d.ts +1 -1
- package/data/documents/shared/projection/index.js +1 -1
- package/data/documents/shared/projection/index.js.map +1 -1
- package/data/{sync → documents/shared/sync}/documentSyncOutgoingBatch.d.ts +1 -1
- package/data/{sync → documents/shared/sync}/documentSyncOutgoingBatch.js +1 -1
- package/data/documents/shared/sync/syncResponseAuthorization.js +1 -1
- package/data/documents/shared/sync/syncResponseAuthorization.js.map +1 -1
- package/data/keyingProjectionVerification/container/containerCreateManifest.d.ts +12 -0
- package/data/keyingProjectionVerification/container/containerDestinationVerification.d.ts +16 -0
- package/data/keyingProjectionVerification/index.d.ts +4 -0
- package/data/keyingProjectionVerification/index.js +5 -1
- package/data/keyingProjectionVerification/index.js.map +1 -1
- package/data/keyingProjectionVerification/principalPolicy/mergeProjectionPolicyEvidence.d.ts +3 -0
- package/data/keyingProjectionVerification/principalPolicy/principalPolicyVerification.d.ts +24 -0
- package/data/persistence/container-contents/documentPlacement.js +1 -1
- package/data/persistence/container-contents/documentPlacement.js.map +1 -1
- package/data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js +1 -1
- package/data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js.map +1 -1
- package/data/persistence/documents/documentsPersistence.d.ts +1 -1
- package/data/persistence/documents/documentsPersistence.js +2 -3
- package/data/persistence/documents/documentsPersistence.js.map +1 -1
- package/data/persistence/documents/internal/containerDocumentTombstones.js +1 -1
- 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/documentDeletionPersistence.js +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentProjectionRows.js +1 -2
- package/data/persistence/documents/internal/documentProjectionRows.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/documentRows.js +1 -2
- package/data/persistence/documents/internal/documentRows.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/pendingCreateAdoption.js +1 -1
- package/data/persistence/documents/internal/pendingCreateAdoption.js.map +1 -1
- package/data/persistence/documents/internal/rowQueryPersistence.js +1 -1
- package/data/persistence/documents/internal/rowQueryPersistence.js.map +1 -1
- package/package.json +1 -1
- package/stores/local-projection/localProjectionStore.d.ts +1 -1
- package/stores/local-projection/localProjectionStore.js +1 -1
- package/stores/local-projection/localProjectionStore.js.map +1 -1
- package/stores/local-projection/registry.d.ts +1 -1
- package/stores/local-projection/registry.js.map +1 -1
- package/stores/local-projection/types.d.ts +1 -1
- package/stores/local-projection/types.js.map +1 -1
- package/workflows/blobs/hydration/decrypt.js +1 -2
- package/workflows/blobs/hydration/decrypt.js.map +1 -1
- package/workflows/blobs/hydration/hydrate.d.ts +1 -1
- package/workflows/blobs/hydration/hydrate.js.map +1 -1
- package/workflows/container-contents/container-state/create/createAdoption.js +1 -2
- package/workflows/container-contents/container-state/create/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/purge/purgeTreeScope.js +1 -1
- package/workflows/container-contents/container-state/purge/purgeTreeScope.js.map +1 -1
- package/workflows/container-contents/info/documentInfo.js +1 -1
- package/workflows/container-contents/info/documentInfo.js.map +1 -1
- package/workflows/container-contents/metadata/index.js +1 -2
- package/workflows/container-contents/metadata/index.js.map +1 -1
- package/workflows/container-contents/metadata/metadataMutationPreparation.js +1 -1
- package/workflows/container-contents/metadata/metadataMutationPreparation.js.map +1 -1
- package/workflows/container-contents/metadata/metadataPullContinuationInvalidation.js +1 -1
- package/workflows/container-contents/metadata/metadataPullContinuationInvalidation.js.map +1 -1
- package/workflows/container-contents/metadata/metadataSyncErrors.js +1 -1
- package/workflows/container-contents/metadata/metadataSyncErrors.js.map +1 -1
- package/workflows/container-contents/metadata/metadataSyncSettlement.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataSyncSettlement.js.map +1 -1
- package/workflows/container-contents/metadata/metadataTypes.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataTypes.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/remoteHydration/destination/verifiedDestination.js +1 -3
- package/workflows/container-contents/remoteHydration/destination/verifiedDestination.js.map +1 -1
- package/workflows/containers/child/create/index.js +1 -1
- package/workflows/containers/child/create/index.js.map +1 -1
- package/workflows/containers/child/move/moveRotation.js +1 -1
- package/workflows/containers/child/move/moveRotation.js.map +1 -1
- package/workflows/containers/child/move/moveWraps.js +1 -1
- package/workflows/containers/child/move/moveWraps.js.map +1 -1
- package/workflows/containers/child/rekey/rekeyProjection.js +1 -1
- package/workflows/containers/child/rekey/rekeyProjection.js.map +1 -1
- package/workflows/containers/child/rotation/rotationContext.js +1 -2
- package/workflows/containers/child/rotation/rotationContext.js.map +1 -1
- package/workflows/containers/child/share/shareAncestorRepair.js +1 -2
- package/workflows/containers/child/share/shareAncestorRepair.js.map +1 -1
- package/workflows/containers/index.d.ts +2 -3
- package/workflows/containers/index.js +1 -2
- package/workflows/containers/index.js.map +1 -1
- package/workflows/containers/writeRefusal.js +1 -1
- package/workflows/containers/writeRefusal.js.map +1 -1
- package/workflows/documents/index.d.ts +1 -1
- package/workflows/documents/index.js +1 -1
- package/workflows/documents/index.js.map +1 -1
- package/workflows/documents/linkSet/linkSetProjectionSeed.js +1 -1
- package/workflows/documents/linkSet/linkSetProjectionSeed.js.map +1 -1
- package/workflows/documents/sync/readOnlySync.js +1 -1
- package/workflows/documents/sync/readOnlySync.js.map +1 -1
- package/workflows/documents/sync/syncAttemptPlanning.js +1 -1
- package/workflows/documents/sync/syncAttemptPlanning.js.map +1 -1
- package/workflows/documents/syncPlan/syncPlanMaterial.js +1 -1
- package/workflows/documents/syncPlan/syncPlanMaterial.js.map +1 -1
- package/workflows/documents/syncPlan/syncPlanRequestBounds.js +1 -1
- package/workflows/documents/syncPlan/syncPlanRequestBounds.js.map +1 -1
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js +1 -1
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js.map +1 -1
- package/workflows/organizations/groupMetadata/groupMetadataAccess.js +1 -1
- package/workflows/organizations/groupMetadata/groupMetadataAccess.js.map +1 -1
- package/workflows/organizations/provisioning/createOrganization.d.ts +1 -1
- package/workflows/organizations/provisioning/createOrganization.js +1 -1
- package/workflows/organizations/provisioning/createOrganization.js.map +1 -1
- package/workflows/organizations/provisioning/organizationProvisioningAttempt.d.ts +1 -1
- package/workflows/organizations/provisioning/organizationProvisioningAttempt.js.map +1 -1
- package/workflows/organizations/readModel/listLocalOrganizations.js +1 -1
- package/workflows/organizations/readModel/listLocalOrganizations.js.map +1 -1
- package/workflows/registration/index.d.ts +2 -1
- package/workflows/registration/index.js +2 -1
- package/workflows/registration/index.js.map +1 -1
- package/workflows/registration/organizationProvisioning.d.ts +39 -0
- package/workflows/registration/organizationProvisioning.js +211 -0
- package/workflows/registration/organizationProvisioning.js.map +1 -0
- package/workflows/registration/organizationProvisioningArtifacts.d.ts +2 -3
- package/workflows/registration/organizationProvisioningArtifacts.js.map +1 -1
- package/workflows/registration/provisioningBootstrapBuilders.d.ts +3 -3
- package/workflows/registration/provisioningBootstrapBuilders.js +3 -4
- package/workflows/registration/provisioningBootstrapBuilders.js.map +1 -1
- package/workflows/registration/registerIdentity.d.ts +2 -39
- package/workflows/registration/registerIdentity.js +2 -207
- package/workflows/registration/registerIdentity.js.map +1 -1
- package/workflows/sync/remoteResetPlans.js +2 -2
- package/workflows/sync/remoteResetPlans.js.map +1 -1
- package/data/persistence/documents/internal/constants.d.ts +0 -1
- package/data/persistence/documents/internal/constants.js +0 -2
- package/data/persistence/documents/internal/constants.js.map +0 -1
- /package/data/{sync → documents/shared/sync}/documentSyncOutgoingBatch.js.map +0 -0
|
@@ -4,7 +4,7 @@ import { type DocumentWriterProjectionAuthorization, type PrincipalPolicyCache }
|
|
|
4
4
|
import type { ExecSql } from "../../../sqlite/sqlSchema.js";
|
|
5
5
|
export { unwrapContainerKekPath } from "../containerKek/containerKekPath.js";
|
|
6
6
|
export { ContainerKekHistoryUnavailableError } from "../containerKek/containerKekPathHistory.js";
|
|
7
|
-
export { buildRotatedDocumentContentKeyBundle, collectContainerKeksForDocumentSync, DocumentContentKeyUnavailableError, DocumentHistoryUnavailableError, unwrapDocumentContentKeyFromBundle, unwrapDocumentContentKeyFromWriterProjection, unwrapDocumentContentKeyTarget, wrapDocumentContentKeyForCreate, } from "./projectionContentKeys.js";
|
|
7
|
+
export { buildRotatedDocumentContentKeyBundle, collectContainerKeksForDocumentSync, DocumentContentKeyUnavailableError, DocumentHistoryUnavailableError, unwrapContentKeyTargetForKind, unwrapDocumentContentKeyFromBundle, unwrapDocumentContentKeyFromWriterProjection, unwrapDocumentContentKeyTarget, wrapDocumentContentKeyForCreate, } from "./projectionContentKeys.js";
|
|
8
8
|
export { authorizingContainerPathRefs, authorizingContainerPathRefsForLinkSet, containerPathRefs, currentDocumentTargets, deriveDocumentCreateTargets, deriveDocumentTargetFromProjection, mergeTargetEnvelopes, readLinkedContainerIdsFromDocumentManifest, verifiedDocumentWrapTargets, } from "./projectionTargets.js";
|
|
9
9
|
import type { ProjectionVerificationOptions } from "../types.js";
|
|
10
10
|
declare function assertDocumentWriterProjectionConsistentInternal(writerProjection: DocumentWriterProjectionResponse, input: ProjectionVerificationOptions & {
|
|
@@ -6,7 +6,7 @@ import { assertDocumentManifestBundleConsistent, normalizeDocumentKekTargetRespo
|
|
|
6
6
|
import { currentDocumentTargets, deriveDocumentTargetFromProjection, readLinkedContainerIdsFromDocumentManifest, } from "./projectionTargets.js";
|
|
7
7
|
export { unwrapContainerKekPath } from "../containerKek/containerKekPath.js";
|
|
8
8
|
export { ContainerKekHistoryUnavailableError } from "../containerKek/containerKekPathHistory.js";
|
|
9
|
-
export { buildRotatedDocumentContentKeyBundle, collectContainerKeksForDocumentSync, DocumentContentKeyUnavailableError, DocumentHistoryUnavailableError, unwrapDocumentContentKeyFromBundle, unwrapDocumentContentKeyFromWriterProjection, unwrapDocumentContentKeyTarget, wrapDocumentContentKeyForCreate, } from "./projectionContentKeys.js";
|
|
9
|
+
export { buildRotatedDocumentContentKeyBundle, collectContainerKeksForDocumentSync, DocumentContentKeyUnavailableError, DocumentHistoryUnavailableError, unwrapContentKeyTargetForKind, unwrapDocumentContentKeyFromBundle, unwrapDocumentContentKeyFromWriterProjection, unwrapDocumentContentKeyTarget, wrapDocumentContentKeyForCreate, } from "./projectionContentKeys.js";
|
|
10
10
|
export { authorizingContainerPathRefs, authorizingContainerPathRefsForLinkSet, containerPathRefs, currentDocumentTargets, deriveDocumentCreateTargets, deriveDocumentTargetFromProjection, mergeTargetEnvelopes, readLinkedContainerIdsFromDocumentManifest, verifiedDocumentWrapTargets, } from "./projectionTargets.js";
|
|
11
11
|
import { resolveProjectionVerifier } from "../types.js";
|
|
12
12
|
function assertSortedStringsEqual(left, right, message) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DocumentContentKeyTarget,\n VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { computeDocumentContentKeyTargetHash } from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n type DocumentWriterProjectionAuthorization,\n type PrincipalPolicyCache,\n verifyDocumentWriterProjectionAuthorization,\n} from \"../../../keyingProjectionVerification\";\nimport { throwKeyingVerificationShapeFailure } from \"../../../keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../shared/errorMessage\";\nimport type { ExecSql } from \"../../../sqlite/sqlSchema\";\nimport {\n assertDocumentManifestBundleConsistent,\n normalizeDocumentKekTargetResponse,\n sortDocumentTargets,\n targetEnvelopeReference,\n targetKey,\n uniqueSortedStrings,\n} from \"../readers\";\nimport {\n currentDocumentTargets,\n deriveDocumentTargetFromProjection,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"./projectionTargets\";\n\nexport { unwrapContainerKekPath } from \"../containerKek/containerKekPath\";\nexport { ContainerKekHistoryUnavailableError } from \"../containerKek/containerKekPathHistory\";\nexport {\n buildRotatedDocumentContentKeyBundle,\n collectContainerKeksForDocumentSync,\n DocumentContentKeyUnavailableError,\n DocumentHistoryUnavailableError,\n unwrapDocumentContentKeyFromBundle,\n unwrapDocumentContentKeyFromWriterProjection,\n unwrapDocumentContentKeyTarget,\n wrapDocumentContentKeyForCreate,\n} from \"./projectionContentKeys\";\nexport {\n authorizingContainerPathRefs,\n authorizingContainerPathRefsForLinkSet,\n containerPathRefs,\n currentDocumentTargets,\n deriveDocumentCreateTargets,\n deriveDocumentTargetFromProjection,\n mergeTargetEnvelopes,\n readLinkedContainerIdsFromDocumentManifest,\n verifiedDocumentWrapTargets,\n} from \"./projectionTargets\";\n\nimport type { ProjectionVerificationOptions } from \"../types\";\nimport { resolveProjectionVerifier } from \"../types\";\n\nfunction assertSortedStringsEqual(\n left: readonly string[],\n right: readonly string[],\n message: string,\n): void {\n if (\n left.length !== right.length ||\n left.some((value, index) => value !== right[index])\n ) {\n throw new Error(message);\n }\n}\n\nfunction assertAuthorizingContainerPathsMatchDocumentTargets(input: {\n targets: readonly DocumentContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n}): void {\n if (input.writerProjection.authorizingContainerPaths.length === 0) {\n throw new Error(\"Document writer projection authorization paths missing\");\n }\n\n const targetKeys = new Set(input.targets.map(targetKey));\n for (const [\n index,\n projection,\n ] of input.writerProjection.authorizingContainerPaths.entries()) {\n let projectionTarget: DocumentContentKeyTarget;\n try {\n projectionTarget = deriveDocumentTargetFromProjection(projection);\n } catch (error) {\n throw new Error(\n `Document writer projection authorization path[${index}] is invalid: ${errorMessage(error)}`,\n );\n }\n\n if (targetKeys.has(targetKey(projectionTarget))) {\n continue;\n }\n\n // Bind server-supplied KEK paths to committed document targets before\n // using any unwrapped path KEK for document content-key material.\n throw new Error(\n `Document writer projection authorization path[${index}] is not a document target`,\n );\n }\n}\n\nfunction assertDocumentTargetsCoverLinkedContainers(\n targets: readonly DocumentContentKeyTarget[],\n writerProjection: DocumentWriterProjectionResponse,\n): void {\n // One target per linked container: a second epoch for the same container\n // would let a re-wrap land on a KEK a revoked member still holds.\n if (\n new Set(targets.map((target) => target.containerId)).size !== targets.length\n ) {\n throw new Error(\n \"Document writer projection targets name a linked container more than once\",\n );\n }\n assertSortedStringsEqual(\n uniqueSortedStrings(targets.map((target) => target.containerId)),\n readLinkedContainerIdsFromDocumentManifest(writerProjection),\n \"Document writer projection targets do not match linked containers\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerManifestHashes,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerManifestHash)),\n \"Document writer projection target manifest summary mismatch\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerKeyEpochIds,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerKeyEpochId)),\n \"Document writer projection target KEK summary mismatch\",\n );\n}\n\nasync function assertProjectionContentKeyBundleConsistent(\n writerProjection: DocumentWriterProjectionResponse,\n staleContentKeyBundle: boolean,\n): Promise<void> {\n const { manifestHash } = writerProjection.documentManifest;\n if (writerProjection.contentKeyBundle.linkSetManifestHash !== manifestHash) {\n // A stale bundle may lag the link-set head, but it must still descend\n // from this document's manifest chain.\n if (\n !staleContentKeyBundle ||\n !writerProjection.documentManifestHistory.some(\n (bundle) =>\n bundle.manifestHash ===\n writerProjection.contentKeyBundle.linkSetManifestHash,\n )\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n }\n\n if (!staleContentKeyBundle) {\n if (\n writerProjection.documentKekTargets.documentKeyTargetHash !==\n writerProjection.contentKeyBundle.targetHash\n ) {\n throw new Error(\"Document writer projection target hash mismatch\");\n }\n return;\n }\n\n // The stale bundle cannot match the current targets; pin it to its own\n // canonical hash instead so a tampered envelope set still fails closed.\n const staleBundleTargetHash = await computeDocumentContentKeyTargetHash(\n sortDocumentTargets(\n writerProjection.contentKeyBundle.targets.map(targetEnvelopeReference),\n ),\n );\n if (staleBundleTargetHash !== writerProjection.contentKeyBundle.targetHash) {\n throw new Error(\n \"Document writer projection stale bundle target hash is not canonical\",\n );\n }\n}\n\nasync function assertDocumentWriterProjectionConsistentInternal(\n writerProjection: DocumentWriterProjectionResponse,\n input: ProjectionVerificationOptions & {\n /**\n * Accept a projection whose content-key bundle is marked stale (wrapped\n * to superseded KEK targets after e.g. a revoke rotation). Document sync\n * opts in to heal the bundle. Attachment reads opt in because their DEK\n * is independent and opens through verified retained container KEKs.\n */\n allowStaleContentKeyBundle?: boolean | undefined;\n execSql?: ExecSql | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n onVerifiedAuthorization?:\n | ((authorization: DocumentWriterProjectionAuthorization) => void)\n | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n stillCurrent?: (() => boolean) | undefined;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n },\n): Promise<DocumentContentKeyTarget[]> {\n const resolveProjectionUserKey = resolveProjectionVerifier(\n input,\n \"Document writer projection\",\n );\n if (\n input.trustedLocalProjection !== true &&\n resolveProjectionUserKey !== null\n ) {\n const authorization = await verifyDocumentWriterProjectionAuthorization({\n execSql: input.execSql,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n principalPolicyCache: input.principalPolicyCache,\n projection: writerProjection,\n resolveUserKey: resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n verifiedByHash: input.verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n input.onVerifiedAuthorization?.(authorization);\n }\n\n const staleContentKeyBundle = writerProjection.contentKeyBundleStale === true;\n if (staleContentKeyBundle && input.allowStaleContentKeyBundle !== true) {\n throw new Error(\"Document writer projection content-key bundle is stale\");\n }\n\n const manifestIdentity = await assertDocumentManifestBundleConsistent({\n bundle: writerProjection.documentManifest,\n label: \"Document writer projection manifest\",\n });\n const { documentId } = manifestIdentity;\n if (\n writerProjection.documentId !== documentId ||\n writerProjection.documentKekTargets.documentId !== documentId ||\n writerProjection.contentKeyBundle.documentId !== documentId\n ) {\n throw new Error(\"Document writer projection document id mismatch\");\n }\n if (\n writerProjection.documentKekTargets.linkSetManifestHash !==\n writerProjection.documentManifest.manifestHash\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n await assertProjectionContentKeyBundleConsistent(\n writerProjection,\n staleContentKeyBundle,\n );\n\n const targets = staleContentKeyBundle\n ? normalizeDocumentKekTargetResponse(writerProjection.documentKekTargets)\n : currentDocumentTargets(writerProjection);\n const canonicalTargetHash =\n await computeDocumentContentKeyTargetHash(targets);\n if (\n canonicalTargetHash !==\n writerProjection.documentKekTargets.documentKeyTargetHash\n ) {\n throw new Error(\"Document writer projection target hash is not canonical\");\n }\n\n assertDocumentTargetsCoverLinkedContainers(targets, writerProjection);\n assertAuthorizingContainerPathsMatchDocumentTargets({\n targets,\n writerProjection,\n });\n\n return targets;\n}\n\nexport async function assertDocumentWriterProjectionConsistent(\n ...input: Parameters<typeof assertDocumentWriterProjectionConsistentInternal>\n): ReturnType<typeof assertDocumentWriterProjectionConsistentInternal> {\n try {\n return await assertDocumentWriterProjectionConsistentInternal(...input);\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DocumentContentKeyTarget,\n VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { computeDocumentContentKeyTargetHash } from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n type DocumentWriterProjectionAuthorization,\n type PrincipalPolicyCache,\n verifyDocumentWriterProjectionAuthorization,\n} from \"../../../keyingProjectionVerification\";\nimport { throwKeyingVerificationShapeFailure } from \"../../../keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../shared/errorMessage\";\nimport type { ExecSql } from \"../../../sqlite/sqlSchema\";\nimport {\n assertDocumentManifestBundleConsistent,\n normalizeDocumentKekTargetResponse,\n sortDocumentTargets,\n targetEnvelopeReference,\n targetKey,\n uniqueSortedStrings,\n} from \"../readers\";\nimport {\n currentDocumentTargets,\n deriveDocumentTargetFromProjection,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"./projectionTargets\";\n\nexport { unwrapContainerKekPath } from \"../containerKek/containerKekPath\";\nexport { ContainerKekHistoryUnavailableError } from \"../containerKek/containerKekPathHistory\";\nexport {\n buildRotatedDocumentContentKeyBundle,\n collectContainerKeksForDocumentSync,\n DocumentContentKeyUnavailableError,\n DocumentHistoryUnavailableError,\n unwrapContentKeyTargetForKind,\n unwrapDocumentContentKeyFromBundle,\n unwrapDocumentContentKeyFromWriterProjection,\n unwrapDocumentContentKeyTarget,\n wrapDocumentContentKeyForCreate,\n} from \"./projectionContentKeys\";\nexport {\n authorizingContainerPathRefs,\n authorizingContainerPathRefsForLinkSet,\n containerPathRefs,\n currentDocumentTargets,\n deriveDocumentCreateTargets,\n deriveDocumentTargetFromProjection,\n mergeTargetEnvelopes,\n readLinkedContainerIdsFromDocumentManifest,\n verifiedDocumentWrapTargets,\n} from \"./projectionTargets\";\n\nimport type { ProjectionVerificationOptions } from \"../types\";\nimport { resolveProjectionVerifier } from \"../types\";\n\nfunction assertSortedStringsEqual(\n left: readonly string[],\n right: readonly string[],\n message: string,\n): void {\n if (\n left.length !== right.length ||\n left.some((value, index) => value !== right[index])\n ) {\n throw new Error(message);\n }\n}\n\nfunction assertAuthorizingContainerPathsMatchDocumentTargets(input: {\n targets: readonly DocumentContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n}): void {\n if (input.writerProjection.authorizingContainerPaths.length === 0) {\n throw new Error(\"Document writer projection authorization paths missing\");\n }\n\n const targetKeys = new Set(input.targets.map(targetKey));\n for (const [\n index,\n projection,\n ] of input.writerProjection.authorizingContainerPaths.entries()) {\n let projectionTarget: DocumentContentKeyTarget;\n try {\n projectionTarget = deriveDocumentTargetFromProjection(projection);\n } catch (error) {\n throw new Error(\n `Document writer projection authorization path[${index}] is invalid: ${errorMessage(error)}`,\n );\n }\n\n if (targetKeys.has(targetKey(projectionTarget))) {\n continue;\n }\n\n // Bind server-supplied KEK paths to committed document targets before\n // using any unwrapped path KEK for document content-key material.\n throw new Error(\n `Document writer projection authorization path[${index}] is not a document target`,\n );\n }\n}\n\nfunction assertDocumentTargetsCoverLinkedContainers(\n targets: readonly DocumentContentKeyTarget[],\n writerProjection: DocumentWriterProjectionResponse,\n): void {\n // One target per linked container: a second epoch for the same container\n // would let a re-wrap land on a KEK a revoked member still holds.\n if (\n new Set(targets.map((target) => target.containerId)).size !== targets.length\n ) {\n throw new Error(\n \"Document writer projection targets name a linked container more than once\",\n );\n }\n assertSortedStringsEqual(\n uniqueSortedStrings(targets.map((target) => target.containerId)),\n readLinkedContainerIdsFromDocumentManifest(writerProjection),\n \"Document writer projection targets do not match linked containers\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerManifestHashes,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerManifestHash)),\n \"Document writer projection target manifest summary mismatch\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerKeyEpochIds,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerKeyEpochId)),\n \"Document writer projection target KEK summary mismatch\",\n );\n}\n\nasync function assertProjectionContentKeyBundleConsistent(\n writerProjection: DocumentWriterProjectionResponse,\n staleContentKeyBundle: boolean,\n): Promise<void> {\n const { manifestHash } = writerProjection.documentManifest;\n if (writerProjection.contentKeyBundle.linkSetManifestHash !== manifestHash) {\n // A stale bundle may lag the link-set head, but it must still descend\n // from this document's manifest chain.\n if (\n !staleContentKeyBundle ||\n !writerProjection.documentManifestHistory.some(\n (bundle) =>\n bundle.manifestHash ===\n writerProjection.contentKeyBundle.linkSetManifestHash,\n )\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n }\n\n if (!staleContentKeyBundle) {\n if (\n writerProjection.documentKekTargets.documentKeyTargetHash !==\n writerProjection.contentKeyBundle.targetHash\n ) {\n throw new Error(\"Document writer projection target hash mismatch\");\n }\n return;\n }\n\n // The stale bundle cannot match the current targets; pin it to its own\n // canonical hash instead so a tampered envelope set still fails closed.\n const staleBundleTargetHash = await computeDocumentContentKeyTargetHash(\n sortDocumentTargets(\n writerProjection.contentKeyBundle.targets.map(targetEnvelopeReference),\n ),\n );\n if (staleBundleTargetHash !== writerProjection.contentKeyBundle.targetHash) {\n throw new Error(\n \"Document writer projection stale bundle target hash is not canonical\",\n );\n }\n}\n\nasync function assertDocumentWriterProjectionConsistentInternal(\n writerProjection: DocumentWriterProjectionResponse,\n input: ProjectionVerificationOptions & {\n /**\n * Accept a projection whose content-key bundle is marked stale (wrapped\n * to superseded KEK targets after e.g. a revoke rotation). Document sync\n * opts in to heal the bundle. Attachment reads opt in because their DEK\n * is independent and opens through verified retained container KEKs.\n */\n allowStaleContentKeyBundle?: boolean | undefined;\n execSql?: ExecSql | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n onVerifiedAuthorization?:\n | ((authorization: DocumentWriterProjectionAuthorization) => void)\n | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n stillCurrent?: (() => boolean) | undefined;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n },\n): Promise<DocumentContentKeyTarget[]> {\n const resolveProjectionUserKey = resolveProjectionVerifier(\n input,\n \"Document writer projection\",\n );\n if (\n input.trustedLocalProjection !== true &&\n resolveProjectionUserKey !== null\n ) {\n const authorization = await verifyDocumentWriterProjectionAuthorization({\n execSql: input.execSql,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n principalPolicyCache: input.principalPolicyCache,\n projection: writerProjection,\n resolveUserKey: resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n verifiedByHash: input.verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n input.onVerifiedAuthorization?.(authorization);\n }\n\n const staleContentKeyBundle = writerProjection.contentKeyBundleStale === true;\n if (staleContentKeyBundle && input.allowStaleContentKeyBundle !== true) {\n throw new Error(\"Document writer projection content-key bundle is stale\");\n }\n\n const manifestIdentity = await assertDocumentManifestBundleConsistent({\n bundle: writerProjection.documentManifest,\n label: \"Document writer projection manifest\",\n });\n const { documentId } = manifestIdentity;\n if (\n writerProjection.documentId !== documentId ||\n writerProjection.documentKekTargets.documentId !== documentId ||\n writerProjection.contentKeyBundle.documentId !== documentId\n ) {\n throw new Error(\"Document writer projection document id mismatch\");\n }\n if (\n writerProjection.documentKekTargets.linkSetManifestHash !==\n writerProjection.documentManifest.manifestHash\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n await assertProjectionContentKeyBundleConsistent(\n writerProjection,\n staleContentKeyBundle,\n );\n\n const targets = staleContentKeyBundle\n ? normalizeDocumentKekTargetResponse(writerProjection.documentKekTargets)\n : currentDocumentTargets(writerProjection);\n const canonicalTargetHash =\n await computeDocumentContentKeyTargetHash(targets);\n if (\n canonicalTargetHash !==\n writerProjection.documentKekTargets.documentKeyTargetHash\n ) {\n throw new Error(\"Document writer projection target hash is not canonical\");\n }\n\n assertDocumentTargetsCoverLinkedContainers(targets, writerProjection);\n assertAuthorizingContainerPathsMatchDocumentTargets({\n targets,\n writerProjection,\n });\n\n return targets;\n}\n\nexport async function assertDocumentWriterProjectionConsistent(\n ...input: Parameters<typeof assertDocumentWriterProjectionConsistentInternal>\n): ReturnType<typeof assertDocumentWriterProjectionConsistentInternal> {\n try {\n return await assertDocumentWriterProjectionConsistentInternal(...input);\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MAX_DOCUMENT_SYNC_OUTGOING_UPDATES, MAX_DOCUMENT_SYNC_REQUEST_BYTES, } from "
|
|
1
|
+
import { MAX_DOCUMENT_SYNC_OUTGOING_UPDATES, MAX_DOCUMENT_SYNC_REQUEST_BYTES, } from "../../../../internal/validators/util/index.js";
|
|
2
2
|
export class DocumentSyncRequestLimitError extends Error {
|
|
3
3
|
name = "DocumentSyncRequestLimitError";
|
|
4
4
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computeDocumentContentKeyTargetHash, makeVerifiedDocumentKekTargets, } from "../../../../internal/crypto/index.js";
|
|
2
|
-
import { resolveEventContainerPaths } from "../../../keyingProjectionVerification/
|
|
2
|
+
import { resolveEventContainerPaths } from "../../../keyingProjectionVerification/index.js";
|
|
3
3
|
import { sortDocumentTargets } from "../readers.js";
|
|
4
4
|
export async function documentWriteAuthorizationForHeader(input) {
|
|
5
5
|
const source = input.plan.documentWriterAuthorization;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncResponseAuthorization.js","sourceRoot":"","sources":["syncResponseAuthorization.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EAEnC,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"syncResponseAuthorization.js","sourceRoot":"","sources":["syncResponseAuthorization.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeDocumentContentKeyTargetHash,\n type DocumentContentKeyTarget,\n makeVerifiedDocumentKekTargets,\n} from \"@tearleads/crypto\";\nimport type { DocumentSyncResponse } from \"@tearleads/validators/response\";\nimport { resolveEventContainerPaths } from \"../../../keyingProjectionVerification\";\nimport { sortDocumentTargets } from \"../readers\";\nimport type { DocumentSyncPlan } from \"../types\";\n\nexport async function documentWriteAuthorizationForHeader(input: {\n readonly allowMissingAuthorization: boolean;\n readonly dependencyManifestHashes: readonly string[];\n readonly authorizationTargets: readonly DocumentContentKeyTarget[];\n readonly contentKeyBundle: DocumentSyncResponse[\"contentKeyBundle\"];\n readonly manifestHash: string;\n readonly plan: Pick<\n DocumentSyncPlan,\n \"documentId\" | \"organizationId\" | \"documentWriterAuthorization\"\n >;\n readonly targetHash: string;\n}) {\n const source = input.plan.documentWriterAuthorization;\n if (!source) {\n if (input.allowMissingAuthorization) {\n return null;\n }\n throw new Error(\n \"Document sync response lacks verified writer-authorization material\",\n );\n }\n const documentManifest = source.documentManifestByHash.get(\n input.manifestHash,\n );\n if (!documentManifest) {\n throw new Error(\n \"Document sync response write manifest is not in verified history\",\n );\n }\n if (input.contentKeyBundle.documentId !== input.plan.documentId) {\n throw new Error(\n \"Document sync response content-key bundle belongs to another document\",\n );\n }\n\n const targets = sortDocumentTargets(input.authorizationTargets);\n if (\n (await computeDocumentContentKeyTargetHash(targets)) !== input.targetHash\n ) {\n throw new Error(\"Document sync response write targets are not canonical\");\n }\n const linkedContainerIds = new Set(documentManifest.state.linkedContainerIds);\n if (\n targets.length !== linkedContainerIds.size ||\n targets.some((target) => !linkedContainerIds.has(target.containerId))\n ) {\n throw new Error(\n \"Document sync response write targets do not match the signed link set\",\n );\n }\n\n const { dependencyContainerPaths } = resolveEventContainerPaths({\n containerPathByManifestHash: source.containerPathByManifestHash,\n dependencyManifestHashes: input.dependencyManifestHashes,\n });\n // A writer needs one committed target, and can be unable to read another\n // linked container. Validate the targets that are cited without inventing\n // paths for uncited targets or dropping signed ancestor evidence.\n for (const target of targets) {\n const path = dependencyContainerPaths.find(\n (candidate) =>\n candidate.at(-1)?.manifestHash === target.containerManifestHash,\n );\n if (!path) continue;\n const leaf = path.at(-1);\n if (\n !leaf ||\n leaf.state.containerId !== target.containerId ||\n leaf.state.organizationId !== input.plan.organizationId ||\n leaf.state.containerKeyEpochId !== target.containerKeyEpochId\n ) {\n throw new Error(\n \"Document sync response write target lacks a verified container path\",\n );\n }\n }\n const authorizingContainerPaths = dependencyContainerPaths;\n const documentKekTargets = makeVerifiedDocumentKekTargets({\n documentId: input.contentKeyBundle.documentId,\n documentKeyTargetHash: input.targetHash,\n linkedContainerKeyEpochIds: targets.map(\n (target) => target.containerKeyEpochId,\n ),\n linkedContainerManifestHashes: targets.map(\n (target) => target.containerManifestHash,\n ),\n linkSetManifestHash: input.manifestHash,\n targets,\n });\n return {\n authorizingContainerPaths,\n documentKekTargets,\n documentManifest,\n principalPolicies: source.principalPolicies,\n };\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type VerifiedContainerAccessManifest } from "../../../internal/crypto/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Walk a verified head back to its epoch-1 `container.create`. Head
|
|
4
|
+
* verification already verified every predecessor it cites (a head is only
|
|
5
|
+
* accepted once its previous manifest verified), so the lineage is present in
|
|
6
|
+
* `verifiedByHash`; a gap means the served projection was incomplete.
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifiedContainerCreateManifest(input: {
|
|
9
|
+
readonly head: VerifiedContainerAccessManifest;
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;
|
|
12
|
+
}): VerifiedContainerAccessManifest;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { VerifiedContainerAccessManifest } from "../../../internal/crypto/index.js";
|
|
2
|
+
import type { ContainerWriterProjectionResponse } from "../../../internal/validators/response/index.js";
|
|
3
|
+
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
4
|
+
import type { ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer } from "../types.js";
|
|
5
|
+
/** Authenticate immutable destination roles without advancing write-authority pins. */
|
|
6
|
+
export declare function verifyContainerDestinationProjection(input: {
|
|
7
|
+
readonly execSql: ExecSql;
|
|
8
|
+
readonly projection: ContainerWriterProjectionResponse;
|
|
9
|
+
readonly resolveUserKey: ProjectionUserKeyResolver;
|
|
10
|
+
readonly stillCurrent?: (() => boolean) | undefined;
|
|
11
|
+
readonly warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
readonly path: VerifiedContainerAccessManifest[];
|
|
14
|
+
/** Every manifest verified on the way, including each head's lineage. */
|
|
15
|
+
readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;
|
|
16
|
+
}>;
|
|
@@ -4,6 +4,10 @@ export { readAccessEvent, readRecordString, readRequiredRecordValue, } from "./r
|
|
|
4
4
|
export type { PrincipalPolicyCache, ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer, } from "./types.js";
|
|
5
5
|
export { isProjectionVerificationCancelledError, nullOnProjectionVerificationCancellation, } from "./types.js";
|
|
6
6
|
export declare function requireProjectionUserKeyResolver(resolveProjectionUserKey: ProjectionUserKeyResolver | null | undefined, label: string): ProjectionUserKeyResolver;
|
|
7
|
+
export { verifiedContainerCreateManifest } from "./container/containerCreateManifest.js";
|
|
8
|
+
export { verifyContainerDestinationProjection } from "./container/containerDestinationVerification.js";
|
|
7
9
|
export { collectContainerWriterProjectionPrincipalPolicies, verifyContainerWriterProjection, } from "./container/containerProjectionVerification.js";
|
|
8
10
|
export { type DocumentWriterProjectionAuthorization, verifyDocumentWriterProjection, verifyDocumentWriterProjectionAuthorization, } from "./document/documentProjectionVerification.js";
|
|
9
11
|
export { verifyDocumentPurgeProof, verifyDocumentPurgeProofBaseline, } from "./documentPurge/documentPurgeProofVerification.js";
|
|
12
|
+
export { mergeProjectionPolicyEvidence } from "./principalPolicy/mergeProjectionPolicyEvidence.js";
|
|
13
|
+
export { isPrincipalPolicyNotCachedError } from "./principalPolicy/principalPolicyVerification.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { requireTrustedUserIdentityResolver } from "../trustedUserIdentity/
|
|
1
|
+
import { requireTrustedUserIdentityResolver } from "../trustedUserIdentity/index.js";
|
|
2
2
|
export { resolveEventContainerPaths } from "./document/documentDependencyPaths.js";
|
|
3
3
|
export { readAccessEvent, readRecordString, readRequiredRecordValue, } from "./readers.js";
|
|
4
4
|
export { isProjectionVerificationCancelledError, nullOnProjectionVerificationCancellation, } from "./types.js";
|
|
@@ -10,7 +10,11 @@ export function requireProjectionUserKeyResolver(resolveProjectionUserKey, label
|
|
|
10
10
|
// provides the untrusted-shape and wrong-user guards (with identity caching).
|
|
11
11
|
return requireTrustedUserIdentityResolver(resolveProjectionUserKey);
|
|
12
12
|
}
|
|
13
|
+
export { verifiedContainerCreateManifest } from "./container/containerCreateManifest.js";
|
|
14
|
+
export { verifyContainerDestinationProjection } from "./container/containerDestinationVerification.js";
|
|
13
15
|
export { collectContainerWriterProjectionPrincipalPolicies, verifyContainerWriterProjection, } from "./container/containerProjectionVerification.js";
|
|
14
16
|
export { verifyDocumentWriterProjection, verifyDocumentWriterProjectionAuthorization, } from "./document/documentProjectionVerification.js";
|
|
15
17
|
export { verifyDocumentPurgeProof, verifyDocumentPurgeProofBaseline, } from "./documentPurge/documentPurgeProofVerification.js";
|
|
18
|
+
export { mergeProjectionPolicyEvidence } from "./principalPolicy/mergeProjectionPolicyEvidence.js";
|
|
19
|
+
export { isPrincipalPolicyNotCachedError } from "./principalPolicy/principalPolicyVerification.js";
|
|
16
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,wBAAwB,CAAC;AAG5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAOnB,OAAO,EACL,sCAAsC,EACtC,wCAAwC,GACzC,MAAM,SAAS,CAAC;AAEjB,MAAM,UAAU,gCAAgC,CAC9C,wBAAsE,EACtE,KAAa;IAEb,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,uCAAuC,CAAC,CAAC;IACnE,CAAC;IAED,sEAAsE;IACtE,8EAA8E;IAC9E,OAAO,kCAAkC,CAAC,wBAAwB,CAAC,CAAC;AACtE,CAAC;AAED,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,oCAAoC,EAAE,MAAM,8CAA8C,CAAC;AACpG,OAAO,EACL,iDAAiD,EACjD,+BAA+B,GAChC,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAEL,8BAA8B,EAC9B,2CAA2C,GAC5C,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,wBAAwB,EACxB,gCAAgC,GACjC,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAChG,OAAO,EAAE,+BAA+B,EAAE,MAAM,+CAA+C,CAAC","sourcesContent":["import { requireTrustedUserIdentityResolver } from \"../trustedUserIdentity\";\nimport type { ProjectionUserKeyResolver } from \"./types\";\n\nexport { resolveEventContainerPaths } from \"./document/documentDependencyPaths\";\nexport {\n readAccessEvent,\n readRecordString,\n readRequiredRecordValue,\n} from \"./readers\";\n\nexport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"./types\";\nexport {\n isProjectionVerificationCancelledError,\n nullOnProjectionVerificationCancellation,\n} from \"./types\";\n\nexport function requireProjectionUserKeyResolver(\n resolveProjectionUserKey: ProjectionUserKeyResolver | null | undefined,\n label: string,\n): ProjectionUserKeyResolver {\n if (!resolveProjectionUserKey) {\n throw new Error(`${label} requires projection key verification`);\n }\n\n // A ProjectionUserKey is a TrustedUserIdentity, so the shared adapter\n // provides the untrusted-shape and wrong-user guards (with identity caching).\n return requireTrustedUserIdentityResolver(resolveProjectionUserKey);\n}\n\nexport { verifiedContainerCreateManifest } from \"./container/containerCreateManifest\";\nexport { verifyContainerDestinationProjection } from \"./container/containerDestinationVerification\";\nexport {\n collectContainerWriterProjectionPrincipalPolicies,\n verifyContainerWriterProjection,\n} from \"./container/containerProjectionVerification\";\nexport {\n type DocumentWriterProjectionAuthorization,\n verifyDocumentWriterProjection,\n verifyDocumentWriterProjectionAuthorization,\n} from \"./document/documentProjectionVerification\";\nexport {\n verifyDocumentPurgeProof,\n verifyDocumentPurgeProofBaseline,\n} from \"./documentPurge/documentPurgeProofVerification\";\nexport { mergeProjectionPolicyEvidence } from \"./principalPolicy/mergeProjectionPolicyEvidence\";\nexport { isPrincipalPolicyNotCachedError } from \"./principalPolicy/principalPolicyVerification\";\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ProjectionPolicyEvidenceResponse } from "../../../internal/validators/response/index.js";
|
|
2
|
+
/** Combine proof material when locally composing projections; verification follows. */
|
|
3
|
+
export declare function mergeProjectionPolicyEvidence(evidence: readonly ProjectionPolicyEvidenceResponse[]): ProjectionPolicyEvidenceResponse;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ReferencedPrincipalHead } from "../../../internal/crypto/index.js";
|
|
2
|
+
import type { PrincipalPolicyCurrentEvidence } from "../../principals/principalPolicyEvidence.js";
|
|
3
|
+
import { type ProjectionCheckpointContext } from "../checkpoints/checkpointContext.js";
|
|
4
|
+
import type { PrincipalPolicyCache, ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer } from "../types.js";
|
|
5
|
+
/**
|
|
6
|
+
* A referenced principal policy is not in the local store and warming could
|
|
7
|
+
* not fetch it this pass — a transient cold-cache condition, typical for a
|
|
8
|
+
* member whose access arrives via a group policy the device has not hydrated
|
|
9
|
+
* yet. Sync passes discriminate on this type to defer the affected container
|
|
10
|
+
* and retry on a later trigger, rather than failing the whole pass.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PrincipalPolicyNotCachedError extends Error {
|
|
13
|
+
constructor(referenceLabel: string);
|
|
14
|
+
}
|
|
15
|
+
export declare function isPrincipalPolicyNotCachedError(error: unknown): boolean;
|
|
16
|
+
export declare function collectReferencedPrincipalPolicies(input: {
|
|
17
|
+
checkpointContext: ProjectionCheckpointContext;
|
|
18
|
+
organizationId: string;
|
|
19
|
+
principalPolicyCache: PrincipalPolicyCache;
|
|
20
|
+
references: readonly ReferencedPrincipalHead[];
|
|
21
|
+
resolveUserKey: ProjectionUserKeyResolver;
|
|
22
|
+
stillCurrent?: (() => boolean) | undefined;
|
|
23
|
+
warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;
|
|
24
|
+
}): Promise<PrincipalPolicyCurrentEvidence[]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { and, eq, inArray } from "drizzle-orm";
|
|
2
|
+
import { DOCUMENTS_APP_KIND } from "../../documents/documentConstants.js";
|
|
2
3
|
import { documents, inLocalIntentLane, LOCAL_INTENT_LANES, localIntents, } from "../../sqlite/schema/index.js";
|
|
3
|
-
import { DOCUMENTS_APP_KIND } from "../documents/internal/constants.js";
|
|
4
4
|
export async function loadDocumentMovePlacement(tx, documentId) {
|
|
5
5
|
const [intent] = await tx
|
|
6
6
|
.select({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentPlacement.js","sourceRoot":"","sources":["documentPlacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"documentPlacement.js","sourceRoot":"","sources":["documentPlacement.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, inArray } from \"drizzle-orm\";\nimport { DOCUMENTS_APP_KIND } from \"../../documents/documentConstants\";\nimport {\n documents,\n inLocalIntentLane,\n LOCAL_INTENT_LANES,\n localIntents,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\n\nexport interface DocumentPlacementInput {\n documentId: string;\n containerIds: ReadonlyArray<string>;\n accessEpoch?: number | undefined;\n}\n\nexport interface DocumentPlacementWriteOptions {\n stillCurrent?: (() => boolean) | undefined;\n moveIntentId?: string | undefined;\n}\n\nexport async function loadDocumentMovePlacement(\n tx: ClientSQLiteTransactionScope,\n documentId: string,\n) {\n const [intent] = await tx\n .select({\n id: localIntents.id,\n intentType: localIntents.intentType,\n targetContainerId: localIntents.targetContainerId,\n })\n .from(localIntents)\n .where(\n and(\n inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement),\n eq(localIntents.subjectId, documentId),\n ),\n )\n .limit(1);\n return intent;\n}\n\n/** Check at commit time: neither intermediate replay nor discovery owns a pending move. */\nexport async function filterWritableDocumentPlacements(\n tx: ClientSQLiteTransactionScope,\n inputs: readonly DocumentPlacementInput[],\n options?: DocumentPlacementWriteOptions,\n): Promise<readonly DocumentPlacementInput[]> {\n const ids = inputs.map((input) => input.documentId);\n const intents = new Map(\n (\n await tx\n .select({\n documentId: localIntents.subjectId,\n id: localIntents.id,\n })\n .from(localIntents)\n .where(\n and(\n inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement),\n inArray(localIntents.subjectId, ids),\n ),\n )\n ).map((row) => [row.documentId, row.id]),\n );\n const versionedIds = inputs\n .filter((input) => input.accessEpoch !== undefined)\n .map((input) => input.documentId);\n const epochs = new Map<string, number>();\n if (versionedIds.length > 0) {\n const rows = await tx\n .select({\n documentId: documents.documentId,\n accessEpoch: documents.accessEpoch,\n })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, DOCUMENTS_APP_KIND),\n inArray(documents.documentId, versionedIds),\n ),\n );\n for (const row of rows)\n if (row.documentId)\n epochs.set(\n row.documentId,\n Math.max(epochs.get(row.documentId) ?? 0, row.accessEpoch),\n );\n }\n return inputs.filter((input) => {\n if (options?.moveIntentId)\n return intents.get(input.documentId) === options.moveIntentId;\n if (intents.has(input.documentId)) return false;\n return (\n input.accessEpoch === undefined ||\n input.accessEpoch >= (epochs.get(input.documentId) ?? 0)\n );\n });\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { and, eq, max } from "drizzle-orm";
|
|
2
|
+
import { DOCUMENTS_APP_KIND } from "../../documents/documentConstants.js";
|
|
2
3
|
import { containerDocumentTombstoneHolds, documentContainerProjectionTables, documents, documentTables, } from "../../sqlite/schema/index.js";
|
|
3
4
|
import { getClientSQLitePersistenceRuntime } from "../../sqlite/sqlitePersistenceRuntime.js";
|
|
4
5
|
import { ensureSqlTables, runSerializedSqlMutation, } from "../../sqlite/sqlSchema.js";
|
|
5
|
-
import { DOCUMENTS_APP_KIND } from "./internal/constants.js";
|
|
6
6
|
import { deleteContainerDocumentTombstoneHoldRows, holdContainerDocumentTombstonesInTransaction, listContainerDocumentTombstoneHoldsForDocumentsInTransaction, listContainerDocumentTombstoneHoldsInTransaction, listKnownContainerDocumentPlacementsInTransaction, partitionContainerDocumentTombstoneHolds, } from "./internal/containerDocumentTombstoneHolds.js";
|
|
7
7
|
export { containerDocumentPlacementKey, deleteContainerDocumentTombstoneHoldRowsForLinks, deleteContainerDocumentTombstoneHoldsForContainers, deleteContainerDocumentTombstoneHoldsForDocuments, } from "./internal/containerDocumentTombstoneHolds.js";
|
|
8
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerDocumentTombstoneHoldsPersistence.js","sourceRoot":"","sources":["containerDocumentTombstoneHoldsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, max } from \"drizzle-orm\";\nimport {\n containerDocumentTombstoneHolds,\n documentContainerProjectionTables,\n documents,\n documentTables,\n} from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../sqlite/sqlSchema\";\nimport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nimport {\n type ContainerDocumentPlacementKey,\n type ContainerDocumentTombstoneHoldRow,\n deleteContainerDocumentTombstoneHoldRows,\n type HeldContainerDocumentTombstone,\n holdContainerDocumentTombstonesInTransaction,\n listContainerDocumentTombstoneHoldsForDocumentsInTransaction,\n listContainerDocumentTombstoneHoldsInTransaction,\n listKnownContainerDocumentPlacementsInTransaction,\n partitionContainerDocumentTombstoneHolds,\n} from \"./internal/containerDocumentTombstoneHolds\";\n\nexport {\n type ContainerDocumentPlacementKey,\n containerDocumentPlacementKey,\n deleteContainerDocumentTombstoneHoldRowsForLinks,\n deleteContainerDocumentTombstoneHoldsForContainers,\n deleteContainerDocumentTombstoneHoldsForDocuments,\n type HeldContainerDocumentTombstone,\n} from \"./internal/containerDocumentTombstoneHolds\";\n\n/**\n * Retry backoff for a held tombstone: fifteen minutes after the first failed\n * verification, doubling on every further failure up to 32 hours. An\n * honest hold that can never verify (the requester lost read access to the\n * document, or it was purged elsewhere) would otherwise cost a head fetch on\n * every discovery of its container for as long as the container exists.\n */\nexport const HELD_TOMBSTONE_RETRY_INTERVAL_MS = 15 * 60 * 1000;\nconst HELD_TOMBSTONE_MAX_BACKOFF_DOUBLINGS = 7;\n\nexport function heldTombstoneRetryDelayMs(attempts: number): number {\n const doublings = Math.min(\n Math.max(attempts, 1) - 1,\n HELD_TOMBSTONE_MAX_BACKOFF_DOUBLINGS,\n );\n return HELD_TOMBSTONE_RETRY_INTERVAL_MS * 2 ** doublings;\n}\n\nfunction isHoldDue(\n hold: ContainerDocumentTombstoneHoldRow,\n now: Date,\n): boolean {\n return (\n Date.parse(hold.updatedAt) + heldTombstoneRetryDelayMs(hold.attempts) <=\n now.getTime()\n );\n}\n\nexport async function holdContainerDocumentTombstones(\n execSql: ExecSql,\n tombstones: ReadonlyArray<HeldContainerDocumentTombstone>,\n now = new Date().toISOString(),\n): Promise<void> {\n if (tombstones.length === 0) return;\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(lockedExecSql);\n await db.transaction((tx) =>\n holdContainerDocumentTombstonesInTransaction(tx, tombstones, now),\n );\n });\n}\n\nexport async function refuteContainerDocumentTombstoneHolds(\n execSql: ExecSql,\n placements: ReadonlyArray<ContainerDocumentPlacementKey>,\n): Promise<void> {\n if (placements.length === 0) return;\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(lockedExecSql);\n await db.transaction(async (tx) => {\n for (const placement of placements) {\n await tx\n .update(containerDocumentTombstoneHolds)\n .set({ hidden: false })\n .where(\n and(\n eq(\n containerDocumentTombstoneHolds.containerId,\n placement.containerId,\n ),\n eq(\n containerDocumentTombstoneHolds.documentId,\n placement.documentId,\n ),\n ),\n )\n .run();\n }\n });\n });\n}\n\nexport async function listContainerDocumentTombstoneHolds(\n execSql: ExecSql,\n containerIds: ReadonlyArray<string>,\n): Promise<ContainerDocumentTombstoneHoldRow[]> {\n if (containerIds.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n return listContainerDocumentTombstoneHoldsInTransaction(db, containerIds);\n}\n\nexport async function listContainerDocumentTombstoneHoldsForDocuments(\n execSql: ExecSql,\n documentIds: ReadonlyArray<string>,\n): Promise<ContainerDocumentPlacementKey[]> {\n if (documentIds.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n return listContainerDocumentTombstoneHoldsForDocumentsInTransaction(\n db,\n documentIds,\n );\n}\n\nexport async function listKnownContainerDocumentPlacements(\n execSql: ExecSql,\n placements: ReadonlyArray<ContainerDocumentPlacementKey>,\n): Promise<ContainerDocumentPlacementKey[]> {\n if (placements.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n return listKnownContainerDocumentPlacementsInTransaction(db, placements);\n}\n\n/**\n * The held tombstones on the given containers that are due for another\n * verification attempt. Holds whose placement is gone are pruned first; that\n * is the only write, and it is taken under the mutation lock only when there\n * is something to prune.\n */\nexport async function listRetryableHeldContainerDocumentTombstones(\n execSql: ExecSql,\n containerIds: ReadonlyArray<string>,\n now = new Date(),\n): Promise<HeldContainerDocumentTombstone[]> {\n if (containerIds.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const { live, orphaned } = await partitionContainerDocumentTombstoneHolds(\n db,\n await listContainerDocumentTombstoneHoldsInTransaction(db, containerIds),\n );\n if (orphaned.length > 0) {\n // Re-check under the lock: a hold re-created between the unlocked read\n // and this write is hiding a placement again and must survive.\n await runSerializedSqlMutation(execSql, (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).db.transaction(\n async (tx) =>\n deleteContainerDocumentTombstoneHoldRows(\n tx,\n (await partitionContainerDocumentTombstoneHolds(tx, orphaned))\n .orphaned,\n ),\n ),\n );\n }\n return live\n .filter((hold) => isHoldDue(hold, now))\n .map((hold) => ({\n containerId: hold.containerId,\n documentId: hold.documentId,\n updatedAt: hold.tombstonedAt,\n }));\n}\n\n/** Ordinary-document floors must exclude unsigned container-metadata epochs. */\nexport async function loadLocalDocumentAccessEpoch(\n execSql: ExecSql,\n documentId: string,\n): Promise<number> {\n await ensureSqlTables(execSql, documentTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const [row] = await db\n .select({ accessEpoch: max(documents.accessEpoch) })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, DOCUMENTS_APP_KIND),\n eq(documents.documentId, documentId),\n ),\n );\n return row?.accessEpoch ?? 0;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"containerDocumentTombstoneHoldsPersistence.js","sourceRoot":"","sources":["containerDocumentTombstoneHoldsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, max } from \"drizzle-orm\";\nimport { DOCUMENTS_APP_KIND } from \"../../documents/documentConstants\";\nimport {\n containerDocumentTombstoneHolds,\n documentContainerProjectionTables,\n documents,\n documentTables,\n} from \"../../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../sqlite/sqlSchema\";\nimport {\n type ContainerDocumentPlacementKey,\n type ContainerDocumentTombstoneHoldRow,\n deleteContainerDocumentTombstoneHoldRows,\n type HeldContainerDocumentTombstone,\n holdContainerDocumentTombstonesInTransaction,\n listContainerDocumentTombstoneHoldsForDocumentsInTransaction,\n listContainerDocumentTombstoneHoldsInTransaction,\n listKnownContainerDocumentPlacementsInTransaction,\n partitionContainerDocumentTombstoneHolds,\n} from \"./internal/containerDocumentTombstoneHolds\";\n\nexport {\n type ContainerDocumentPlacementKey,\n containerDocumentPlacementKey,\n deleteContainerDocumentTombstoneHoldRowsForLinks,\n deleteContainerDocumentTombstoneHoldsForContainers,\n deleteContainerDocumentTombstoneHoldsForDocuments,\n type HeldContainerDocumentTombstone,\n} from \"./internal/containerDocumentTombstoneHolds\";\n\n/**\n * Retry backoff for a held tombstone: fifteen minutes after the first failed\n * verification, doubling on every further failure up to 32 hours. An\n * honest hold that can never verify (the requester lost read access to the\n * document, or it was purged elsewhere) would otherwise cost a head fetch on\n * every discovery of its container for as long as the container exists.\n */\nexport const HELD_TOMBSTONE_RETRY_INTERVAL_MS = 15 * 60 * 1000;\nconst HELD_TOMBSTONE_MAX_BACKOFF_DOUBLINGS = 7;\n\nexport function heldTombstoneRetryDelayMs(attempts: number): number {\n const doublings = Math.min(\n Math.max(attempts, 1) - 1,\n HELD_TOMBSTONE_MAX_BACKOFF_DOUBLINGS,\n );\n return HELD_TOMBSTONE_RETRY_INTERVAL_MS * 2 ** doublings;\n}\n\nfunction isHoldDue(\n hold: ContainerDocumentTombstoneHoldRow,\n now: Date,\n): boolean {\n return (\n Date.parse(hold.updatedAt) + heldTombstoneRetryDelayMs(hold.attempts) <=\n now.getTime()\n );\n}\n\nexport async function holdContainerDocumentTombstones(\n execSql: ExecSql,\n tombstones: ReadonlyArray<HeldContainerDocumentTombstone>,\n now = new Date().toISOString(),\n): Promise<void> {\n if (tombstones.length === 0) return;\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(lockedExecSql);\n await db.transaction((tx) =>\n holdContainerDocumentTombstonesInTransaction(tx, tombstones, now),\n );\n });\n}\n\nexport async function refuteContainerDocumentTombstoneHolds(\n execSql: ExecSql,\n placements: ReadonlyArray<ContainerDocumentPlacementKey>,\n): Promise<void> {\n if (placements.length === 0) return;\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(lockedExecSql);\n await db.transaction(async (tx) => {\n for (const placement of placements) {\n await tx\n .update(containerDocumentTombstoneHolds)\n .set({ hidden: false })\n .where(\n and(\n eq(\n containerDocumentTombstoneHolds.containerId,\n placement.containerId,\n ),\n eq(\n containerDocumentTombstoneHolds.documentId,\n placement.documentId,\n ),\n ),\n )\n .run();\n }\n });\n });\n}\n\nexport async function listContainerDocumentTombstoneHolds(\n execSql: ExecSql,\n containerIds: ReadonlyArray<string>,\n): Promise<ContainerDocumentTombstoneHoldRow[]> {\n if (containerIds.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n return listContainerDocumentTombstoneHoldsInTransaction(db, containerIds);\n}\n\nexport async function listContainerDocumentTombstoneHoldsForDocuments(\n execSql: ExecSql,\n documentIds: ReadonlyArray<string>,\n): Promise<ContainerDocumentPlacementKey[]> {\n if (documentIds.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n return listContainerDocumentTombstoneHoldsForDocumentsInTransaction(\n db,\n documentIds,\n );\n}\n\nexport async function listKnownContainerDocumentPlacements(\n execSql: ExecSql,\n placements: ReadonlyArray<ContainerDocumentPlacementKey>,\n): Promise<ContainerDocumentPlacementKey[]> {\n if (placements.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n return listKnownContainerDocumentPlacementsInTransaction(db, placements);\n}\n\n/**\n * The held tombstones on the given containers that are due for another\n * verification attempt. Holds whose placement is gone are pruned first; that\n * is the only write, and it is taken under the mutation lock only when there\n * is something to prune.\n */\nexport async function listRetryableHeldContainerDocumentTombstones(\n execSql: ExecSql,\n containerIds: ReadonlyArray<string>,\n now = new Date(),\n): Promise<HeldContainerDocumentTombstone[]> {\n if (containerIds.length === 0) return [];\n await ensureSqlTables(execSql, documentContainerProjectionTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const { live, orphaned } = await partitionContainerDocumentTombstoneHolds(\n db,\n await listContainerDocumentTombstoneHoldsInTransaction(db, containerIds),\n );\n if (orphaned.length > 0) {\n // Re-check under the lock: a hold re-created between the unlocked read\n // and this write is hiding a placement again and must survive.\n await runSerializedSqlMutation(execSql, (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).db.transaction(\n async (tx) =>\n deleteContainerDocumentTombstoneHoldRows(\n tx,\n (await partitionContainerDocumentTombstoneHolds(tx, orphaned))\n .orphaned,\n ),\n ),\n );\n }\n return live\n .filter((hold) => isHoldDue(hold, now))\n .map((hold) => ({\n containerId: hold.containerId,\n documentId: hold.documentId,\n updatedAt: hold.tombstonedAt,\n }));\n}\n\n/** Ordinary-document floors must exclude unsigned container-metadata epochs. */\nexport async function loadLocalDocumentAccessEpoch(\n execSql: ExecSql,\n documentId: string,\n): Promise<number> {\n await ensureSqlTables(execSql, documentTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const [row] = await db\n .select({ accessEpoch: max(documents.accessEpoch) })\n .from(documents)\n .where(\n and(\n eq(documents.appKind, DOCUMENTS_APP_KIND),\n eq(documents.documentId, documentId),\n ),\n );\n return row?.accessEpoch ?? 0;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type DiscoveredDocumentInput, type DocumentSummary } from "../../documents/documentSummary.js";
|
|
2
2
|
import { type ExecSql } from "../../sqlite/sqlSchema.js";
|
|
3
3
|
import type { ContainerDocumentTombstoneInput, DocumentsPersistence } from "./types.js";
|
|
4
|
-
export { DOCUMENTS_APP_KIND } from "
|
|
4
|
+
export { DOCUMENTS_APP_KIND } from "../../documents/documentConstants.js";
|
|
5
5
|
export type { AttachmentRemovalRows, AttachmentStagingRows, ContainerDocumentTombstoneInput, DiscardDocumentToShellResult, DocumentsPersistence, LocalAttachmentRecord, PendingAttachmentRecord, PendingAttachmentUploadIdentity, PendingUpdateInsert, PendingUpdateRecord, RelinkPersistedDocumentInput, StoredDocumentRecord, } from "./types.js";
|
|
6
6
|
export declare function upsertDiscoveredDocuments(execSql: ExecSql, inputs: ReadonlyArray<DiscoveredDocumentInput>): Promise<DocumentSummary[]>;
|
|
7
7
|
export declare function applyContainerDocumentTombstones(execSql: ExecSql, tombstones: ReadonlyArray<ContainerDocumentTombstoneInput>): Promise<DocumentSummary[]>;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { KeyingVerificationError } from "../../../internal/crypto/index.js";
|
|
2
2
|
import { and, desc, eq, inArray, notInArray, or } from "drizzle-orm";
|
|
3
|
-
import { DEFAULT_DOCUMENT_KIND } from "../../documents/documentConstants.js";
|
|
3
|
+
import { DEFAULT_DOCUMENT_KIND, DOCUMENTS_APP_KIND, } from "../../documents/documentConstants.js";
|
|
4
4
|
import { HIDDEN_DOCUMENT_SUMMARY_KINDS, } from "../../documents/documentSummary.js";
|
|
5
5
|
import { findLocalIdByDocumentId } from "../../sqlite/documentPersistence/index.js";
|
|
6
6
|
import { settleQueuedDocumentUpdatesInTransaction } from "../../sqlite/documentPersistence/documentPendingUpdatePersistence.js";
|
|
7
7
|
import { documentProjection, documentPurgeCheckpoints, documents, } from "../../sqlite/schema/index.js";
|
|
8
8
|
import { getClientSQLitePersistenceRuntime, } from "../../sqlite/sqlitePersistenceRuntime.js";
|
|
9
9
|
import { runSerializedSqlMutation } from "../../sqlite/sqlSchema.js";
|
|
10
|
-
import { DOCUMENTS_APP_KIND } from "./internal/constants.js";
|
|
11
10
|
import { applyContainerDocumentTombstonesWithExec } from "./internal/containerDocumentTombstones.js";
|
|
12
11
|
import { createStoredDocumentWithHistoryCheckpoint } from "./internal/createDocumentWithHistoryCheckpoint.js";
|
|
13
12
|
import { discardStoredDocumentToShell } from "./internal/discardDocument.js";
|
|
@@ -27,7 +26,7 @@ import { acknowledgeDocumentOrphanBlobReclaim, deleteOrphanedDocumentSideRows, i
|
|
|
27
26
|
import { loadPendingCreateSummary, mapPendingCreateLocalIds, } from "./internal/pendingCreateAdoption.js";
|
|
28
27
|
import { documentRowQueryPersistence } from "./internal/rowQueryPersistence.js";
|
|
29
28
|
import { documentSyncQueuePersistence } from "./internal/syncQueuePersistence.js";
|
|
30
|
-
export { DOCUMENTS_APP_KIND } from "
|
|
29
|
+
export { DOCUMENTS_APP_KIND } from "../../documents/documentConstants.js";
|
|
31
30
|
const DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE = "Syncing document...";
|
|
32
31
|
async function upsertDiscoveredDocumentWithExec(execSql, input, pendingCreates, tx) {
|
|
33
32
|
const [purgeCheckpoint] = await tx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentsPersistence.js","sourceRoot":"","sources":["documentsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { and, desc, eq, inArray, notInArray, or, type SQL } from \"drizzle-orm\";\nimport { DEFAULT_DOCUMENT_KIND } from \"../../documents/documentConstants\";\nimport {\n type DiscoveredDocumentInput,\n type DocumentSummary,\n HIDDEN_DOCUMENT_SUMMARY_KINDS,\n} from \"../../documents/documentSummary\";\nimport { findLocalIdByDocumentId } from \"../../sqlite/documentPersistence\";\nimport { settleQueuedDocumentUpdatesInTransaction } from \"../../sqlite/documentPersistence/documentPendingUpdatePersistence\";\nimport {\n documentProjection,\n documentPurgeCheckpoints,\n documents,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nimport { applyContainerDocumentTombstonesWithExec } from \"./internal/containerDocumentTombstones\";\nimport { createStoredDocumentWithHistoryCheckpoint } from \"./internal/createDocumentWithHistoryCheckpoint\";\nimport { discardStoredDocumentToShell } from \"./internal/discardDocument\";\nimport { resolveDiscoveredDocumentPlacement } from \"./internal/discoveredDocumentPlacement\";\nimport {\n deleteStoredDocument,\n deleteStoredDocumentIfMatches,\n deleteStoredDocumentSideRowsIfAbsent,\n} from \"./internal/documentDeletionPersistence\";\nimport { loadStoredDocumentWithHistoryRestoreState } from \"./internal/documentHistoryStatePersistence\";\nimport {\n commitStoredDocumentMutation,\n settleStoredDocumentPendingUpdates,\n} from \"./internal/documentMutationPersistence\";\nimport {\n documentSummaryJoin,\n documentSummarySelection,\n getProjectionUpdatedAt,\n mapDocumentSummary,\n toDocumentSummary,\n} from \"./internal/documentProjectionRows\";\nimport { invalidateStoredDocumentPullContinuation } from \"./internal/documentPullContinuationPersistence\";\nimport {\n getDocumentScope,\n resolveDocumentSaveTimestamp,\n saveDocumentRows,\n} from \"./internal/documentRows\";\nimport {\n resolvePersistedAccessStateHash,\n resolvePersistedDocumentRuntimeState,\n} from \"./internal/documentRuntimeState\";\nimport { loadStoredDocumentStoreState } from \"./internal/documentStoreStatePersistence\";\nimport { listDocumentSummaries } from \"./internal/documentSummaryQueries\";\nimport { ensureDocumentsSchema } from \"./internal/ensureDocumentsSchema\";\nimport { saveHydratedAttachment } from \"./internal/hydratedAttachmentPersistence\";\nimport {\n acknowledgeDocumentOrphanBlobReclaim,\n deleteOrphanedDocumentSideRows,\n isDocumentBlobStorageKeyReferenced,\n listDocumentOrphanBlobReclaims,\n} from \"./internal/orphanSideRows\";\nimport {\n loadPendingCreateSummary,\n mapPendingCreateLocalIds,\n} from \"./internal/pendingCreateAdoption\";\nimport { documentRowQueryPersistence } from \"./internal/rowQueryPersistence\";\nimport { documentSyncQueuePersistence } from \"./internal/syncQueuePersistence\";\nimport type {\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nexport { DOCUMENTS_APP_KIND } from \"./internal/constants\";\nexport type {\n AttachmentRemovalRows,\n AttachmentStagingRows,\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n PendingAttachmentUploadIdentity,\n PendingUpdateInsert,\n PendingUpdateRecord,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nconst DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE = \"Syncing document...\";\n\nasync function upsertDiscoveredDocumentWithExec(\n execSql: ExecSql,\n input: DiscoveredDocumentInput,\n pendingCreates: ReadonlyMap<string, string>,\n tx: ClientSQLiteTransactionScope,\n): Promise<DocumentSummary> {\n const [purgeCheckpoint] = await tx\n .select({ documentId: documentPurgeCheckpoints.documentId })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, input.documentId))\n .limit(1);\n if (purgeCheckpoint) {\n throw new KeyingVerificationError(\n \"rollback\",\n \"Document discovery targets a permanently purged document\",\n );\n }\n const existingLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n input.documentId,\n );\n const localId = existingLocalId ?? input.documentId;\n const pendingLocalId = pendingCreates.get(input.documentId);\n if (!existingLocalId && pendingLocalId) {\n const pending = await loadPendingCreateSummary(execSql, pendingLocalId);\n if (!pending) throw new Error(\"Pending create projection is unavailable\");\n return pending;\n }\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n localId,\n );\n const placement = await resolveDiscoveredDocumentPlacement(\n tx,\n existingDocument,\n input,\n );\n\n const nextDocument: StoredDocumentRecord = {\n id: localId,\n documentId: input.documentId,\n documentKind: existingDocument?.documentKind ?? DEFAULT_DOCUMENT_KIND,\n text: existingDocument?.text ?? \"\",\n title: existingDocument?.title ?? DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE,\n snapshotEndVersion: existingDocument?.snapshotEndVersion ?? \"\",\n recoveryGeneration: existingDocument?.recoveryGeneration ?? 0,\n ...placement,\n effectiveAccessLevel:\n input.effectiveAccessLevel ??\n existingDocument?.effectiveAccessLevel ??\n null,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: placement.accessEpoch,\n documentId: input.documentId,\n }),\n };\n\n const saveOptions =\n existingDocument === null || existingDocument === undefined\n ? { updatedAt: input.createdAt }\n : undefined;\n const updatedAt = await resolveDocumentSaveTimestamp({\n document: nextDocument,\n options: saveOptions,\n tx,\n });\n if (!(await saveDocumentRows({ document: nextDocument, tx, updatedAt }))) {\n throw new Error(\"Document recovery generation changed during discovery\");\n }\n\n return toDocumentSummary(nextDocument, updatedAt);\n}\n\nasync function relinkPersistedDocumentWithExec(\n execSql: ExecSql,\n input: RelinkPersistedDocumentInput,\n): Promise<DocumentSummary | null> {\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n input.localId,\n );\n if (!existingDocument) {\n return null;\n }\n\n const nextAccessEpoch = Math.max(\n existingDocument.accessEpoch,\n input.accessEpoch,\n );\n const nextDocument: StoredDocumentRecord = {\n ...existingDocument,\n accessEpoch: nextAccessEpoch,\n accessStateHash: resolvePersistedAccessStateHash(existingDocument, {\n accessEpoch: nextAccessEpoch,\n accessStateHash: input.accessStateHash,\n documentId: input.documentId,\n }),\n containerId: input.containerId,\n documentId: input.documentId,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: nextAccessEpoch,\n documentId: input.documentId,\n }),\n };\n\n await sqlDocumentsPersistence.saveDocument(execSql, nextDocument);\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const updatedAtRows = await db\n .select({ updatedAt: documentProjection.updatedAt })\n .from(documentProjection)\n .where(eq(documentProjection.localId, input.localId))\n .limit(1);\n\n return toDocumentSummary(\n nextDocument,\n getProjectionUpdatedAt(updatedAtRows[0]),\n );\n}\n\nexport async function upsertDiscoveredDocuments(\n execSql: ExecSql,\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const pendingCreates = await mapPendingCreateLocalIds(lockedExecSql);\n const nextSummaries: DocumentSummary[] = [];\n\n for (const input of inputs) {\n nextSummaries.push(\n await upsertDiscoveredDocumentWithExec(\n lockedExecSql,\n input,\n pendingCreates,\n tx,\n ),\n );\n }\n\n return nextSummaries;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function applyContainerDocumentTombstones(\n execSql: ExecSql,\n tombstones: ReadonlyArray<ContainerDocumentTombstoneInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return applyContainerDocumentTombstonesWithExec(lockedExecSql, tombstones);\n });\n}\n\nexport async function listDocumentsByContainerIdsOrDocumentIds(\n execSql: ExecSql,\n input: {\n containerIds: ReadonlyArray<string>;\n documentIds: ReadonlyArray<string>;\n },\n): Promise<DocumentSummary[]> {\n const uniqueContainerIds = Array.from(new Set(input.containerIds));\n const uniqueDocumentIds = Array.from(new Set(input.documentIds));\n if (uniqueContainerIds.length === 0 && uniqueDocumentIds.length === 0) {\n return [];\n }\n\n const filters: SQL[] = [];\n if (uniqueContainerIds.length > 0) {\n filters.push(inArray(documentProjection.containerId, uniqueContainerIds));\n }\n\n if (uniqueDocumentIds.length > 0) {\n filters.push(inArray(documentProjection.documentId, uniqueDocumentIds));\n }\n\n const whereCondition = filters.length === 1 ? filters[0] : or(...filters);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(documentSummarySelection)\n .from(documentProjection)\n .leftJoin(documents, documentSummaryJoin)\n .where(\n and(\n whereCondition,\n notInArray(documentProjection.documentKind, [\n ...HIDDEN_DOCUMENT_SUMMARY_KINDS,\n ]),\n ),\n )\n .orderBy(\n desc(documentProjection.updatedAt),\n desc(documentProjection.localId),\n );\n\n return rows.map(mapDocumentSummary);\n}\n\nexport const sqlDocumentsPersistence: DocumentsPersistence = {\n orphanBlobs: {\n acknowledge: acknowledgeDocumentOrphanBlobReclaim,\n isReferenced: isDocumentBlobStorageKeyReferenced,\n list: listDocumentOrphanBlobReclaims,\n sweep: deleteOrphanedDocumentSideRows,\n },\n ...documentRowQueryPersistence,\n ...documentSyncQueuePersistence,\n supportsAtomicRecoveryHistoryPruning: true,\n saveHydratedAttachment,\n createDocumentWithHistoryCheckpoint:\n createStoredDocumentWithHistoryCheckpoint,\n commitDocumentMutation: (execSql, input, saveClientProjection) =>\n commitStoredDocumentMutation(\n execSql,\n input,\n saveClientProjection,\n sqlDocumentsPersistence.loadDocument,\n ),\n settleAcceptedPendingUpdates: (execSql, input) =>\n settleStoredDocumentPendingUpdates(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n ),\n ensureSchema: ensureDocumentsSchema,\n listDocumentSummaries,\n listDocumentsByContainerIdsOrDocumentIds,\n invalidatePullContinuation: (execSql, input) =>\n invalidateStoredDocumentPullContinuation(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n sqlDocumentsPersistence.loadHistoryRestoreState,\n ),\n loadDocumentWithHistoryRestoreState: (execSql, localId) =>\n loadStoredDocumentWithHistoryRestoreState(\n execSql,\n localId,\n sqlDocumentsPersistence,\n ),\n loadDocumentStoreState: (execSql, localId) =>\n loadStoredDocumentStoreState(execSql, localId, sqlDocumentsPersistence),\n async saveDocument(execSql, document, options) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n async saveDocumentAndDeletePendingUpdates(\n execSql,\n document,\n pendingUpdateIds,\n options,\n ) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n const saved = await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n if (!saved) return updatedAt;\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n getDocumentScope(document.id),\n pendingUpdateIds,\n );\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n deleteDocument: deleteStoredDocument,\n deleteDocumentIfMatches: deleteStoredDocumentIfMatches,\n deleteDocumentSideRowsIfAbsent: deleteStoredDocumentSideRowsIfAbsent,\n async discardDocumentToShell(\n execSql,\n localId,\n expectedDocumentId,\n documentProjectors,\n ): Promise<DiscardDocumentToShellResult> {\n return discardStoredDocumentToShell({\n documentProjectors,\n execSql,\n expectedDocumentId,\n localId,\n persistence: sqlDocumentsPersistence,\n });\n },\n async upsertDiscoveredDocument(execSql, input) {\n const [nextSummary] = await upsertDiscoveredDocuments(execSql, [input]);\n if (!nextSummary) {\n throw new Error(\"Failed to upsert discovered document\");\n }\n\n return nextSummary;\n },\n async relinkPersistedDocument(execSql, input) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n () => relinkPersistedDocumentWithExec(lockedExecSql, input),\n { behavior: \"immediate\" },\n );\n });\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"documentsPersistence.js","sourceRoot":"","sources":["documentsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { and, desc, eq, inArray, notInArray, or, type SQL } from \"drizzle-orm\";\nimport {\n DEFAULT_DOCUMENT_KIND,\n DOCUMENTS_APP_KIND,\n} from \"../../documents/documentConstants\";\nimport {\n type DiscoveredDocumentInput,\n type DocumentSummary,\n HIDDEN_DOCUMENT_SUMMARY_KINDS,\n} from \"../../documents/documentSummary\";\nimport { findLocalIdByDocumentId } from \"../../sqlite/documentPersistence\";\nimport { settleQueuedDocumentUpdatesInTransaction } from \"../../sqlite/documentPersistence/documentPendingUpdatePersistence\";\nimport {\n documentProjection,\n documentPurgeCheckpoints,\n documents,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, runSerializedSqlMutation } from \"../../sqlite/sqlSchema\";\nimport { applyContainerDocumentTombstonesWithExec } from \"./internal/containerDocumentTombstones\";\nimport { createStoredDocumentWithHistoryCheckpoint } from \"./internal/createDocumentWithHistoryCheckpoint\";\nimport { discardStoredDocumentToShell } from \"./internal/discardDocument\";\nimport { resolveDiscoveredDocumentPlacement } from \"./internal/discoveredDocumentPlacement\";\nimport {\n deleteStoredDocument,\n deleteStoredDocumentIfMatches,\n deleteStoredDocumentSideRowsIfAbsent,\n} from \"./internal/documentDeletionPersistence\";\nimport { loadStoredDocumentWithHistoryRestoreState } from \"./internal/documentHistoryStatePersistence\";\nimport {\n commitStoredDocumentMutation,\n settleStoredDocumentPendingUpdates,\n} from \"./internal/documentMutationPersistence\";\nimport {\n documentSummaryJoin,\n documentSummarySelection,\n getProjectionUpdatedAt,\n mapDocumentSummary,\n toDocumentSummary,\n} from \"./internal/documentProjectionRows\";\nimport { invalidateStoredDocumentPullContinuation } from \"./internal/documentPullContinuationPersistence\";\nimport {\n getDocumentScope,\n resolveDocumentSaveTimestamp,\n saveDocumentRows,\n} from \"./internal/documentRows\";\nimport {\n resolvePersistedAccessStateHash,\n resolvePersistedDocumentRuntimeState,\n} from \"./internal/documentRuntimeState\";\nimport { loadStoredDocumentStoreState } from \"./internal/documentStoreStatePersistence\";\nimport { listDocumentSummaries } from \"./internal/documentSummaryQueries\";\nimport { ensureDocumentsSchema } from \"./internal/ensureDocumentsSchema\";\nimport { saveHydratedAttachment } from \"./internal/hydratedAttachmentPersistence\";\nimport {\n acknowledgeDocumentOrphanBlobReclaim,\n deleteOrphanedDocumentSideRows,\n isDocumentBlobStorageKeyReferenced,\n listDocumentOrphanBlobReclaims,\n} from \"./internal/orphanSideRows\";\nimport {\n loadPendingCreateSummary,\n mapPendingCreateLocalIds,\n} from \"./internal/pendingCreateAdoption\";\nimport { documentRowQueryPersistence } from \"./internal/rowQueryPersistence\";\nimport { documentSyncQueuePersistence } from \"./internal/syncQueuePersistence\";\nimport type {\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nexport { DOCUMENTS_APP_KIND } from \"../../documents/documentConstants\";\nexport type {\n AttachmentRemovalRows,\n AttachmentStagingRows,\n ContainerDocumentTombstoneInput,\n DiscardDocumentToShellResult,\n DocumentsPersistence,\n LocalAttachmentRecord,\n PendingAttachmentRecord,\n PendingAttachmentUploadIdentity,\n PendingUpdateInsert,\n PendingUpdateRecord,\n RelinkPersistedDocumentInput,\n StoredDocumentRecord,\n} from \"./types\";\n\nconst DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE = \"Syncing document...\";\n\nasync function upsertDiscoveredDocumentWithExec(\n execSql: ExecSql,\n input: DiscoveredDocumentInput,\n pendingCreates: ReadonlyMap<string, string>,\n tx: ClientSQLiteTransactionScope,\n): Promise<DocumentSummary> {\n const [purgeCheckpoint] = await tx\n .select({ documentId: documentPurgeCheckpoints.documentId })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, input.documentId))\n .limit(1);\n if (purgeCheckpoint) {\n throw new KeyingVerificationError(\n \"rollback\",\n \"Document discovery targets a permanently purged document\",\n );\n }\n const existingLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n input.documentId,\n );\n const localId = existingLocalId ?? input.documentId;\n const pendingLocalId = pendingCreates.get(input.documentId);\n if (!existingLocalId && pendingLocalId) {\n const pending = await loadPendingCreateSummary(execSql, pendingLocalId);\n if (!pending) throw new Error(\"Pending create projection is unavailable\");\n return pending;\n }\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n localId,\n );\n const placement = await resolveDiscoveredDocumentPlacement(\n tx,\n existingDocument,\n input,\n );\n\n const nextDocument: StoredDocumentRecord = {\n id: localId,\n documentId: input.documentId,\n documentKind: existingDocument?.documentKind ?? DEFAULT_DOCUMENT_KIND,\n text: existingDocument?.text ?? \"\",\n title: existingDocument?.title ?? DISCOVERED_DOCUMENT_PLACEHOLDER_TITLE,\n snapshotEndVersion: existingDocument?.snapshotEndVersion ?? \"\",\n recoveryGeneration: existingDocument?.recoveryGeneration ?? 0,\n ...placement,\n effectiveAccessLevel:\n input.effectiveAccessLevel ??\n existingDocument?.effectiveAccessLevel ??\n null,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: placement.accessEpoch,\n documentId: input.documentId,\n }),\n };\n\n const saveOptions =\n existingDocument === null || existingDocument === undefined\n ? { updatedAt: input.createdAt }\n : undefined;\n const updatedAt = await resolveDocumentSaveTimestamp({\n document: nextDocument,\n options: saveOptions,\n tx,\n });\n if (!(await saveDocumentRows({ document: nextDocument, tx, updatedAt }))) {\n throw new Error(\"Document recovery generation changed during discovery\");\n }\n\n return toDocumentSummary(nextDocument, updatedAt);\n}\n\nasync function relinkPersistedDocumentWithExec(\n execSql: ExecSql,\n input: RelinkPersistedDocumentInput,\n): Promise<DocumentSummary | null> {\n const existingDocument = await sqlDocumentsPersistence.loadDocument(\n execSql,\n input.localId,\n );\n if (!existingDocument) {\n return null;\n }\n\n const nextAccessEpoch = Math.max(\n existingDocument.accessEpoch,\n input.accessEpoch,\n );\n const nextDocument: StoredDocumentRecord = {\n ...existingDocument,\n accessEpoch: nextAccessEpoch,\n accessStateHash: resolvePersistedAccessStateHash(existingDocument, {\n accessEpoch: nextAccessEpoch,\n accessStateHash: input.accessStateHash,\n documentId: input.documentId,\n }),\n containerId: input.containerId,\n documentId: input.documentId,\n ...resolvePersistedDocumentRuntimeState(existingDocument, {\n accessEpoch: nextAccessEpoch,\n documentId: input.documentId,\n }),\n };\n\n await sqlDocumentsPersistence.saveDocument(execSql, nextDocument);\n\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const updatedAtRows = await db\n .select({ updatedAt: documentProjection.updatedAt })\n .from(documentProjection)\n .where(eq(documentProjection.localId, input.localId))\n .limit(1);\n\n return toDocumentSummary(\n nextDocument,\n getProjectionUpdatedAt(updatedAtRows[0]),\n );\n}\n\nexport async function upsertDiscoveredDocuments(\n execSql: ExecSql,\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const pendingCreates = await mapPendingCreateLocalIds(lockedExecSql);\n const nextSummaries: DocumentSummary[] = [];\n\n for (const input of inputs) {\n nextSummaries.push(\n await upsertDiscoveredDocumentWithExec(\n lockedExecSql,\n input,\n pendingCreates,\n tx,\n ),\n );\n }\n\n return nextSummaries;\n },\n { behavior: \"immediate\" },\n );\n });\n}\n\nexport async function applyContainerDocumentTombstones(\n execSql: ExecSql,\n tombstones: ReadonlyArray<ContainerDocumentTombstoneInput>,\n): Promise<DocumentSummary[]> {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return applyContainerDocumentTombstonesWithExec(lockedExecSql, tombstones);\n });\n}\n\nexport async function listDocumentsByContainerIdsOrDocumentIds(\n execSql: ExecSql,\n input: {\n containerIds: ReadonlyArray<string>;\n documentIds: ReadonlyArray<string>;\n },\n): Promise<DocumentSummary[]> {\n const uniqueContainerIds = Array.from(new Set(input.containerIds));\n const uniqueDocumentIds = Array.from(new Set(input.documentIds));\n if (uniqueContainerIds.length === 0 && uniqueDocumentIds.length === 0) {\n return [];\n }\n\n const filters: SQL[] = [];\n if (uniqueContainerIds.length > 0) {\n filters.push(inArray(documentProjection.containerId, uniqueContainerIds));\n }\n\n if (uniqueDocumentIds.length > 0) {\n filters.push(inArray(documentProjection.documentId, uniqueDocumentIds));\n }\n\n const whereCondition = filters.length === 1 ? filters[0] : or(...filters);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(documentSummarySelection)\n .from(documentProjection)\n .leftJoin(documents, documentSummaryJoin)\n .where(\n and(\n whereCondition,\n notInArray(documentProjection.documentKind, [\n ...HIDDEN_DOCUMENT_SUMMARY_KINDS,\n ]),\n ),\n )\n .orderBy(\n desc(documentProjection.updatedAt),\n desc(documentProjection.localId),\n );\n\n return rows.map(mapDocumentSummary);\n}\n\nexport const sqlDocumentsPersistence: DocumentsPersistence = {\n orphanBlobs: {\n acknowledge: acknowledgeDocumentOrphanBlobReclaim,\n isReferenced: isDocumentBlobStorageKeyReferenced,\n list: listDocumentOrphanBlobReclaims,\n sweep: deleteOrphanedDocumentSideRows,\n },\n ...documentRowQueryPersistence,\n ...documentSyncQueuePersistence,\n supportsAtomicRecoveryHistoryPruning: true,\n saveHydratedAttachment,\n createDocumentWithHistoryCheckpoint:\n createStoredDocumentWithHistoryCheckpoint,\n commitDocumentMutation: (execSql, input, saveClientProjection) =>\n commitStoredDocumentMutation(\n execSql,\n input,\n saveClientProjection,\n sqlDocumentsPersistence.loadDocument,\n ),\n settleAcceptedPendingUpdates: (execSql, input) =>\n settleStoredDocumentPendingUpdates(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n ),\n ensureSchema: ensureDocumentsSchema,\n listDocumentSummaries,\n listDocumentsByContainerIdsOrDocumentIds,\n invalidatePullContinuation: (execSql, input) =>\n invalidateStoredDocumentPullContinuation(\n execSql,\n input,\n sqlDocumentsPersistence.loadDocument,\n sqlDocumentsPersistence.loadHistoryRestoreState,\n ),\n loadDocumentWithHistoryRestoreState: (execSql, localId) =>\n loadStoredDocumentWithHistoryRestoreState(\n execSql,\n localId,\n sqlDocumentsPersistence,\n ),\n loadDocumentStoreState: (execSql, localId) =>\n loadStoredDocumentStoreState(execSql, localId, sqlDocumentsPersistence),\n async saveDocument(execSql, document, options) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n async saveDocumentAndDeletePendingUpdates(\n execSql,\n document,\n pendingUpdateIds,\n options,\n ) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) =>\n getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const updatedAt = await resolveDocumentSaveTimestamp({\n document,\n options,\n tx,\n });\n const saved = await saveDocumentRows({\n document,\n tx,\n updatedAt,\n });\n if (!saved) return updatedAt;\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n getDocumentScope(document.id),\n pendingUpdateIds,\n );\n return updatedAt;\n },\n { behavior: \"immediate\" },\n ),\n );\n },\n deleteDocument: deleteStoredDocument,\n deleteDocumentIfMatches: deleteStoredDocumentIfMatches,\n deleteDocumentSideRowsIfAbsent: deleteStoredDocumentSideRowsIfAbsent,\n async discardDocumentToShell(\n execSql,\n localId,\n expectedDocumentId,\n documentProjectors,\n ): Promise<DiscardDocumentToShellResult> {\n return discardStoredDocumentToShell({\n documentProjectors,\n execSql,\n expectedDocumentId,\n localId,\n persistence: sqlDocumentsPersistence,\n });\n },\n async upsertDiscoveredDocument(execSql, input) {\n const [nextSummary] = await upsertDiscoveredDocuments(execSql, [input]);\n if (!nextSummary) {\n throw new Error(\"Failed to upsert discovered document\");\n }\n\n return nextSummary;\n },\n async relinkPersistedDocument(execSql, input) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n () => relinkPersistedDocumentWithExec(lockedExecSql, input),\n { behavior: \"immediate\" },\n );\n });\n },\n};\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { and, asc, desc, eq, inArray, notInArray } from "drizzle-orm";
|
|
2
|
+
import { DOCUMENTS_APP_KIND } from "../../../documents/documentConstants.js";
|
|
2
3
|
import { documentContainerProjection, documentProjection, documents, } from "../../../sqlite/schema/index.js";
|
|
3
4
|
import { getClientSQLitePersistenceRuntime, } from "../../../sqlite/sqlitePersistenceRuntime.js";
|
|
4
5
|
import { filterWritableDocumentPlacements } from "../../container-contents/documentPlacement.js";
|
|
5
6
|
import { getLatestTimestamp } from "../../latestTimestamp.js";
|
|
6
|
-
import { DOCUMENTS_APP_KIND } from "./constants.js";
|
|
7
7
|
import { deleteContainerDocumentTombstoneHoldRows } from "./containerDocumentTombstoneHolds.js";
|
|
8
8
|
import { documentSummaryJoin, documentSummarySelection, mapDocumentSummary, } from "./documentProjectionRows.js";
|
|
9
9
|
function dedupeContainerDocumentTombstones(tombstones) {
|