@tearleads/client-sdk 0.1.69 → 0.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/shared/userTiming.js +42 -0
- package/data/shared/userTiming.js.map +1 -0
- package/data/sqlite/sqlExec.js +27 -3
- package/data/sqlite/sqlExec.js.map +1 -1
- package/data/sync/coordinatorLaneRun.js +29 -6
- package/data/sync/coordinatorLaneRun.js.map +1 -1
- package/data/sync/coordinatorState.d.ts +3 -1
- package/data/sync/coordinatorState.js +1 -0
- package/data/sync/coordinatorState.js.map +1 -1
- package/data/sync/syncTelemetry.d.ts +15 -0
- package/data/sync/syncTelemetry.js +10 -0
- package/data/sync/syncTelemetry.js.map +1 -1
- package/data/sync/uploadLane.js +20 -3
- package/data/sync/uploadLane.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +73 -3
- package/internal/api-client/apiRequestMetrics.d.ts +18 -4
- package/internal/api-client/apiRequestMetrics.js +55 -5
- package/internal/api-client/apiRequestMetrics.js.map +1 -1
- package/internal/api-client/durationSampleWindow.d.ts +26 -0
- package/internal/api-client/durationSampleWindow.js +42 -0
- package/internal/api-client/durationSampleWindow.js.map +1 -0
- package/internal/api-client/measureApiRequest.js +9 -4
- package/internal/api-client/measureApiRequest.js.map +1 -1
- package/internal/api-client/serverTiming.d.ts +12 -0
- package/internal/api-client/serverTiming.js +49 -0
- package/internal/api-client/serverTiming.js.map +1 -0
- package/internal/validators/documentCreateSeedRefinements.js +9 -0
- package/internal/validators/documentCreateSeedRefinements.js.map +1 -0
- package/internal/validators/operation/auth.d.ts +120 -0
- package/internal/validators/operation/containerMutations.d.ts +355 -0
- package/internal/validators/operation/containerMutations.js +7 -1
- package/internal/validators/operation/containerMutations.js.map +1 -1
- package/internal/validators/operation/documentMutations.d.ts +356 -0
- package/internal/validators/operation/documentMutations.js +6 -1
- package/internal/validators/operation/documentMutations.js.map +1 -1
- package/internal/validators/operation/documentSync.d.ts +9 -9
- package/internal/validators/operation/organizations.d.ts +120 -0
- package/internal/validators/request/containerMetadata.d.ts +313 -0
- package/internal/validators/request/containerMetadata.js +20 -3
- package/internal/validators/request/containerMetadata.js.map +1 -1
- package/internal/validators/request/document.d.ts +571 -0
- package/internal/validators/request/document.js +19 -1
- package/internal/validators/request/document.js.map +1 -1
- package/internal/validators/request/documentCreateSeed.js +35 -0
- package/internal/validators/request/documentCreateSeed.js.map +1 -0
- package/internal/validators/request/organizationProvisioning.js +9 -22
- package/internal/validators/request/organizationProvisioning.js.map +1 -1
- package/internal/validators/response/containerMetadata.d.ts +20 -0
- package/internal/validators/response/documentMutation.d.ts +43 -0
- package/internal/validators/response/documentMutation.js +12 -1
- package/internal/validators/response/documentMutation.js.map +1 -1
- package/internal/validators/response/documentSyncSchema.d.ts +13 -9
- package/internal/validators/response/documentSyncSchema.js +23 -18
- package/internal/validators/response/documentSyncSchema.js.map +1 -1
- package/internal/validators/response/index.d.ts +1 -1
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationProvisioning.d.ts +350 -0
- package/internal/validators/response/registration.d.ts +120 -0
- package/package.json +1 -1
- package/stores/container-contents/containerState/containerStatePersistence.js +2 -0
- package/stores/container-contents/containerState/containerStatePersistence.js.map +1 -1
- package/stores/container-contents/remoteEvents/remoteEventSync.js +1 -1
- package/stores/container-contents/remoteEvents/remoteEventSync.js.map +1 -1
- package/stores/container-contents/state.js +2 -0
- package/stores/container-contents/state.js.map +1 -1
- package/stores/container-contents/syncAgent/syncAgentTypes.d.ts +5 -0
- package/stores/container-contents/syncAgent/syncAgentTypes.js.map +1 -1
- package/stores/documents/documentStore/sync/createdDocumentPersistence.js +71 -0
- package/stores/documents/documentStore/sync/createdDocumentPersistence.js.map +1 -0
- package/stores/documents/documentStore/sync/index.js +13 -2
- package/stores/documents/documentStore/sync/index.js.map +1 -1
- package/stores/documents/documentStore/sync/syncRemoteSignals.js +21 -3
- package/stores/documents/documentStore/sync/syncRemoteSignals.js.map +1 -1
- package/stores/documents/documentStore/sync/syncSeededCreate.js +50 -0
- package/stores/documents/documentStore/sync/syncSeededCreate.js.map +1 -0
- package/stores/documents/documentStore/sync/syncShared.js +16 -8
- package/stores/documents/documentStore/sync/syncShared.js.map +1 -1
- package/workflows/container-contents/container-state/create/createIntentSeed.js +60 -0
- package/workflows/container-contents/container-state/create/createIntentSeed.js.map +1 -0
- package/workflows/container-contents/container-state/create/createIntentSync.js +18 -19
- package/workflows/container-contents/container-state/create/createIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/create/createWithMetadata.js +43 -6
- package/workflows/container-contents/container-state/create/createWithMetadata.js.map +1 -1
- package/workflows/container-contents/container-state/create/createWithMetadataPlan.js +5 -1
- package/workflows/container-contents/container-state/create/createWithMetadataPlan.js.map +1 -1
- package/workflows/container-contents/container-state/remote.js +15 -0
- package/workflows/container-contents/container-state/remote.js.map +1 -1
- package/workflows/container-contents/container-state/types.js.map +1 -1
- package/workflows/container-contents/metadata/metadataEvents.d.ts +7 -1
- package/workflows/container-contents/metadata/metadataEvents.js +8 -2
- package/workflows/container-contents/metadata/metadataEvents.js.map +1 -1
- package/workflows/container-contents/remoteHydration/types.d.ts +3 -0
- package/workflows/container-contents/remoteHydration/types.js.map +1 -1
- package/workflows/documents/create/index.d.ts +7 -0
- package/workflows/documents/create/index.js +40 -2
- package/workflows/documents/create/index.js.map +1 -1
- package/workflows/documents/index.d.ts +1 -0
- package/workflows/documents/index.js +1 -0
- package/workflows/documents/index.js.map +1 -1
- package/workflows/documents/sync/initialSync.d.ts +39 -0
- package/workflows/documents/sync/initialSync.js +39 -6
- package/workflows/documents/sync/initialSync.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createIntentSync.js","sourceRoot":"","sources":["createIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../../data/keyingProjectionVerification/error\";\nimport { ContainerCreateIntentSupersededError } from \"../../../../data/persistence/container-contents/containerIntentPersistence\";\nimport { errorMessage } from \"../../../../data/shared/errorMessage\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../../metadata/metadataStateIsolation\";\nimport type { ContainerState } from \"../../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../../remoteHydration/reconciliation\";\nimport { createRemoteContainer, deleteRemoteContainer } from \"../remote\";\nimport type {\n ContainerCreateIntentSyncHost,\n ContainerCreateIntentSyncInput,\n ContainerCreateIntentSyncState,\n CreatedRemoteContainerState,\n} from \"../types\";\nimport { syncListedContainerCreate } from \"./createAdoption\";\nimport {\n deferTooDeepCreate,\n recordRefusedTooDeepCreate,\n} from \"./createIntentDepth\";\nimport { CONTAINER_ALREADY_COMMITTED } from \"./createWithMetadata\";\n\nclass IncompleteContainerCreateSettlementError extends Error {}\n\ntype CreateIntentSyncResult = \"abandoned\" | \"blocked\" | \"created\" | \"failed\";\n\nfunction currentCreateResult<\n Result extends Exclude<CreateIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function reportContainerCreateIntegrityFailure(input: {\n readonly containerId: string;\n readonly error: unknown;\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n await reportAndRethrowKeyingVerificationError(\n input.error,\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: input.containerId,\n objectKind: \"container\",\n operation: \"container.create.replay\",\n organizationId: input.organizationId,\n },\n );\n}\n\nasync function recordContainerCreateFailure(input: {\n readonly error: unknown;\n readonly isCurrent: () => boolean;\n readonly intent: ContainerCreateIntentSyncInput[\"intent\"];\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<\"abandoned\" | \"failed\"> {\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await reportContainerCreateIntegrityFailure({\n containerId: input.intent.containerId,\n error: input.error,\n organizationId: input.organizationId,\n state: input.state,\n });\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await input.state.persistence.recordCreateIntentRevisionError(\n input.state.runtime.infra.execSql,\n {\n containerId: input.intent.containerId,\n expectedIntentId: input.intent.id,\n expectedUpdatedAt: input.intent.updatedAt,\n message: `${input.error instanceof IncompleteContainerCreateSettlementError ? \"Container create persistence failed\" : \"Remote container create failed\"}: ${errorMessage(input.error)}`,\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n}\n\nasync function persistCreatedRemoteContainerStateFromIntent(input: {\n containerState: ContainerState;\n created: CreatedRemoteContainerState;\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerCreateIntentSyncInput[\"intent\"];\n state: ContainerCreateIntentSyncState;\n}): Promise<\n | \"abandoned\"\n | \"identity-superseded\"\n | \"intent-superseded\"\n | \"missing\"\n | \"persisted\"\n> {\n const { containerState, created, host, intent, state } = input;\n if (!input.isCurrent()) return \"abandoned\";\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) return \"abandoned\";\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: created.createdAt,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n updatedAt: created.updatedAt,\n };\n\n let persistenceResult: Awaited<\n ReturnType<ContainerCreateIntentSyncHost[\"persistContainerState\"]>\n >;\n try {\n persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: 1,\n accessStateHash: created.accessManifestHash,\n lastCommitLsn: null,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: created.parentId,\n ...created.persistedMetadataState,\n },\n false,\n {\n serverTimestamps: {\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n },\n },\n {\n createIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n remoteContainerId: created.containerId,\n remoteMetadataAccessStateHash: created.accessManifestHash,\n remoteMetadataDocumentId: created.metadataDocumentId,\n supersededMovePreviousParentId: created.parentId,\n },\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n preserveDurableStructureWhenPending: true,\n },\n );\n } catch (error) {\n if (error instanceof ContainerCreateIntentSupersededError) {\n return \"intent-superseded\";\n }\n throw error;\n }\n if (!input.isCurrent() || persistenceResult.status === \"stale-generation\") {\n return \"abandoned\";\n }\n if (persistenceResult.status !== \"persisted\") return persistenceResult.status;\n if (persistenceResult.createIntentSettled !== true) {\n throw new IncompleteContainerCreateSettlementError(\n \"Container create persistence must settle the intent atomically\",\n );\n }\n const { record: nextRecord } = persistenceResult;\n if (!input.isCurrent()) return \"abandoned\";\n const currentContainerState = state.containersById.get(intent.containerId);\n if (!currentContainerState) return \"missing\";\n if (currentContainerState !== containerState) return \"identity-superseded\";\n\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: persistenceCandidate.container.parentId,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n };\n return \"persisted\";\n}\n\nasync function discardOrphanedRemoteContainer(input: {\n created: CreatedRemoteContainerState;\n isCurrent: () => boolean;\n state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n if (!input.isCurrent()) {\n return;\n }\n const discardFailure = await deleteRemoteContainer({\n containerId: input.created.containerId,\n organizationId: input.created.organizationId,\n runtime: input.state.runtime,\n }).then(\n (deleted) => (deleted ? null : \"the server rejected the delete\"),\n (error: unknown) => errorMessage(error),\n );\n if (input.isCurrent() && discardFailure !== null) {\n input.state.runtime.util.log(\n `Container contents: failed to discard orphaned remote container ${input.created.containerId} after local delete: ${discardFailure}`,\n );\n }\n}\n\nasync function settleRemoteContainerCreate(input: {\n containerState: ContainerState;\n created: Awaited<ReturnType<typeof createRemoteContainer>>;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, created, syncInput } = input;\n const { host, intent, state } = syncInput;\n if (created === CONTAINER_ALREADY_COMMITTED) {\n // A lost create response leaves the intent pending until hydration installs\n // the committed remote metadata state.\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; container already committed remotely, awaiting hydration.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (!created) {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Remote container create was rejected or unavailable\",\n stillCurrent: syncInput.isCurrent,\n },\n );\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (!state.containersById.has(intent.containerId)) {\n // A same-generation local delete wins; discard the remote orphan instead\n // of resurrecting the deleted local container.\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n\n const persistenceStatus = await persistCreatedRemoteContainerStateFromIntent({\n containerState,\n created,\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n state,\n });\n if (persistenceStatus === \"abandoned\") {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n if (persistenceStatus === \"missing\") {\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (persistenceStatus === \"identity-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; another writer persisted its remote identity.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (persistenceStatus === \"intent-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; a newer local intent superseded this pass.`,\n );\n return \"blocked\";\n }\n state.runtime.util.log(\n `Container contents: synced local container create ${containerState.container.id}`,\n );\n return \"created\";\n}\n\nasync function createPendingRemoteContainer(input: {\n containerState: ContainerState;\n parentState: ContainerState;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, parentState, syncInput } = input;\n const { intent, state } = syncInput;\n let created: Awaited<ReturnType<typeof createRemoteContainer>>;\n try {\n created = await createRemoteContainer({\n systemSlot: containerState.container.systemSlot,\n containerId: containerState.container.id,\n parentContainerId: parentState.container.id,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n } catch (error) {\n if (error instanceof ContainerPathTooDeepError)\n return recordRefusedTooDeepCreate(syncInput);\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n try {\n return await settleRemoteContainerCreate({\n containerState,\n created,\n syncInput,\n });\n } catch (error) {\n if (!(error instanceof IncompleteContainerCreateSettlementError))\n throw error;\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n}\n\nasync function trySyncPendingContainerContentsContainerCreateIntent(\n input: ContainerCreateIntentSyncInput,\n): Promise<CreateIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState || !parentState) {\n const execSql = state.runtime.infra.execSql;\n await state.persistence.recordCreateIntentRevisionError(execSql, {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create intent references a missing local container\",\n stillCurrent: input.isCurrent,\n });\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (typeof state.persistence.markCreateIntentRevisionSynced !== \"function\") {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create replay requires revision-CAS persistence\",\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (input.isRemoteSyncBlocked(parentState.container.organizationId)) {\n return \"blocked\";\n }\n\n if (hasRemoteContainerMetadataState(containerState)) {\n return syncListedContainerCreate({\n containerState,\n parentState,\n syncInput: input,\n });\n }\n\n // A parent whose own create has not settled may carry a listed identity\n // adoption has not verified, or has refused; nothing is created under it.\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(parentState.container.id)\n ) {\n return \"blocked\";\n }\n\n if (await deferTooDeepCreate(input)) {\n return currentCreateResult(input.isCurrent, \"blocked\");\n }\n\n return createPendingRemoteContainer({\n containerState,\n parentState,\n syncInput: input,\n });\n}\n\nexport async function syncPendingContainerCreateIntents(input: {\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listPendingCreateIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n const remainingContainerIds = new Set(\n pendingIntents.map((intent) => intent.containerId),\n );\n // Only a create that settles in this pass leaves the pending set; a failed\n // or parked one stays pending even though this pass stops retrying it.\n const unsettledContainerIds = new Set(remainingContainerIds);\n let createdCount = 0;\n let progressed = true;\n\n while (progressed && input.isCurrent()) {\n progressed = false;\n\n for (const intent of pendingIntents) {\n if (!remainingContainerIds.has(intent.containerId)) {\n continue;\n }\n\n const result = await trySyncPendingContainerContentsContainerCreateIntent(\n {\n host,\n isCreatePending: (containerId) =>\n unsettledContainerIds.has(containerId),\n isCurrent: input.isCurrent,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n },\n );\n if (result === \"abandoned\") {\n return createdCount;\n }\n\n if (result === \"blocked\") {\n continue;\n }\n\n remainingContainerIds.delete(intent.containerId);\n progressed = result === \"created\" || progressed;\n if (result === \"created\") {\n createdCount += 1;\n unsettledContainerIds.delete(intent.containerId);\n }\n }\n }\n\n return createdCount;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createIntentSync.js","sourceRoot":"","sources":["createIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../../data/keyingProjectionVerification/error\";\nimport { ContainerCreateIntentSupersededError } from \"../../../../data/persistence/container-contents/containerIntentPersistence\";\nimport { errorMessage } from \"../../../../data/shared/errorMessage\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../../metadata/metadataStateIsolation\";\nimport type { ContainerState } from \"../../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../../remoteHydration/reconciliation\";\nimport {\n createRemoteContainer,\n discardOrphanedRemoteContainer,\n} from \"../remote\";\nimport type {\n ContainerCreateIntentSyncHost,\n ContainerCreateIntentSyncInput,\n ContainerCreateIntentSyncState,\n CreatedRemoteContainerState,\n} from \"../types\";\nimport { syncListedContainerCreate } from \"./createAdoption\";\nimport {\n deferTooDeepCreate,\n recordRefusedTooDeepCreate,\n} from \"./createIntentDepth\";\nimport {\n loadMetadataSeedUpdate,\n withPlannedMetadataDocumentId,\n withRegisteredMetadataSeed,\n} from \"./createIntentSeed\";\nimport { CONTAINER_ALREADY_COMMITTED } from \"./createWithMetadata\";\n\nclass IncompleteContainerCreateSettlementError extends Error {}\n\ntype CreateIntentSyncResult = \"abandoned\" | \"blocked\" | \"created\" | \"failed\";\n\nfunction currentCreateResult<\n Result extends Exclude<CreateIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function reportContainerCreateIntegrityFailure(input: {\n readonly containerId: string;\n readonly error: unknown;\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n await reportAndRethrowKeyingVerificationError(\n input.error,\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: input.containerId,\n objectKind: \"container\",\n operation: \"container.create.replay\",\n organizationId: input.organizationId,\n },\n );\n}\n\nasync function recordContainerCreateFailure(input: {\n readonly error: unknown;\n readonly isCurrent: () => boolean;\n readonly intent: ContainerCreateIntentSyncInput[\"intent\"];\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<\"abandoned\" | \"failed\"> {\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await reportContainerCreateIntegrityFailure({\n containerId: input.intent.containerId,\n error: input.error,\n organizationId: input.organizationId,\n state: input.state,\n });\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await input.state.persistence.recordCreateIntentRevisionError(\n input.state.runtime.infra.execSql,\n {\n containerId: input.intent.containerId,\n expectedIntentId: input.intent.id,\n expectedUpdatedAt: input.intent.updatedAt,\n message: `${input.error instanceof IncompleteContainerCreateSettlementError ? \"Container create persistence failed\" : \"Remote container create failed\"}: ${errorMessage(input.error)}`,\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n}\n\nasync function persistCreatedRemoteContainerStateFromIntent(input: {\n containerState: ContainerState;\n created: CreatedRemoteContainerState;\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerCreateIntentSyncInput[\"intent\"];\n state: ContainerCreateIntentSyncState;\n}): Promise<\n | \"abandoned\"\n | \"identity-superseded\"\n | \"intent-superseded\"\n | \"missing\"\n | \"persisted\"\n> {\n const { containerState, created, host, intent, state } = input;\n if (!input.isCurrent()) return \"abandoned\";\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) return \"abandoned\";\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: created.createdAt,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n updatedAt: created.updatedAt,\n };\n\n let persistenceResult: Awaited<\n ReturnType<ContainerCreateIntentSyncHost[\"persistContainerState\"]>\n >;\n try {\n persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: 1,\n accessStateHash: created.accessManifestHash,\n // A committed seed stands in for the first metadata sync.\n lastCommitLsn: created.metadataSeed?.commitLsn ?? null,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: created.parentId,\n ...created.persistedMetadataState,\n },\n false,\n {\n serverTimestamps: {\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n },\n },\n {\n ...(created.metadataSeed\n ? {\n acceptedPendingUpdateIds: [created.metadataSeed.updateId],\n clearSyncFailure: true,\n }\n : {}),\n createIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n remoteContainerId: created.containerId,\n remoteMetadataAccessStateHash: created.accessManifestHash,\n remoteMetadataDocumentId: created.metadataDocumentId,\n supersededMovePreviousParentId: created.parentId,\n },\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n preserveDurableStructureWhenPending: true,\n },\n );\n } catch (error) {\n if (error instanceof ContainerCreateIntentSupersededError) {\n return \"intent-superseded\";\n }\n throw error;\n }\n if (!input.isCurrent() || persistenceResult.status === \"stale-generation\") {\n return \"abandoned\";\n }\n if (persistenceResult.status !== \"persisted\") return persistenceResult.status;\n if (persistenceResult.createIntentSettled !== true) {\n throw new IncompleteContainerCreateSettlementError(\n \"Container create persistence must settle the intent atomically\",\n );\n }\n const { record: nextRecord } = persistenceResult;\n if (!input.isCurrent()) return \"abandoned\";\n const currentContainerState = state.containersById.get(intent.containerId);\n if (!currentContainerState) return \"missing\";\n if (currentContainerState !== containerState) return \"identity-superseded\";\n\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: persistenceCandidate.container.parentId,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n };\n return \"persisted\";\n}\n\nasync function settleRemoteContainerCreate(input: {\n containerState: ContainerState;\n created: Awaited<ReturnType<typeof createRemoteContainer>>;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, created, syncInput } = input;\n const { host, intent, state } = syncInput;\n if (created === CONTAINER_ALREADY_COMMITTED) {\n // A lost create response leaves the intent pending until hydration installs\n // the committed remote metadata state.\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; container already committed remotely, awaiting hydration.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (!created) {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Remote container create was rejected or unavailable\",\n stillCurrent: syncInput.isCurrent,\n },\n );\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (!state.containersById.has(intent.containerId)) {\n // A same-generation local delete wins; discard the remote orphan instead\n // of resurrecting the deleted local container.\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n\n const persistenceStatus = await persistCreatedRemoteContainerStateFromIntent({\n containerState,\n created,\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n state,\n });\n if (persistenceStatus === \"abandoned\") {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n if (persistenceStatus === \"missing\") {\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (persistenceStatus === \"identity-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; another writer persisted its remote identity.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (persistenceStatus === \"intent-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; a newer local intent superseded this pass.`,\n );\n return \"blocked\";\n }\n state.runtime.util.log(\n `Container contents: synced local container create ${containerState.container.id}`,\n );\n return \"created\";\n}\n\nasync function createPendingRemoteContainer(input: {\n containerState: ContainerState;\n parentState: ContainerState;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, parentState, syncInput } = input;\n const { intent, state } = syncInput;\n const metadataSeedUpdate = await loadMetadataSeedUpdate(\n syncInput.state,\n containerState,\n );\n if (!syncInput.isCurrent()) return \"abandoned\";\n let created: Awaited<ReturnType<typeof createRemoteContainer>>;\n try {\n created = await withRegisteredMetadataSeed(\n state.locallyAcceptedMetadataUpdateIds,\n metadataSeedUpdate,\n () =>\n createRemoteContainer({\n systemSlot: containerState.container.systemSlot,\n containerId: containerState.container.id,\n ...(metadataSeedUpdate ? { metadataSeedUpdate } : {}),\n parentContainerId: parentState.container.id,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n }),\n );\n } catch (error) {\n if (error instanceof ContainerPathTooDeepError)\n return recordRefusedTooDeepCreate(syncInput);\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n try {\n return await settleRemoteContainerCreate({\n containerState,\n created,\n syncInput,\n });\n } catch (error) {\n if (!(error instanceof IncompleteContainerCreateSettlementError))\n throw error;\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n}\n\nasync function trySyncPendingContainerContentsContainerCreateIntent(\n input: ContainerCreateIntentSyncInput,\n): Promise<CreateIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState || !parentState) {\n const execSql = state.runtime.infra.execSql;\n await state.persistence.recordCreateIntentRevisionError(execSql, {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create intent references a missing local container\",\n stillCurrent: input.isCurrent,\n });\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (typeof state.persistence.markCreateIntentRevisionSynced !== \"function\") {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create replay requires revision-CAS persistence\",\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (input.isRemoteSyncBlocked(parentState.container.organizationId)) {\n return \"blocked\";\n }\n\n if (hasRemoteContainerMetadataState(containerState)) {\n return syncListedContainerCreate({\n containerState,\n parentState,\n syncInput: input,\n });\n }\n\n // A parent whose own create has not settled may carry a listed identity\n // adoption has not verified, or has refused; nothing is created under it.\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(parentState.container.id)\n ) {\n return \"blocked\";\n }\n\n if (await deferTooDeepCreate(input)) {\n return currentCreateResult(input.isCurrent, \"blocked\");\n }\n\n return withPlannedMetadataDocumentId(\n state.plannedMetadataDocumentIds,\n containerState.container.id,\n () =>\n createPendingRemoteContainer({\n containerState,\n parentState,\n syncInput: input,\n }),\n );\n}\n\nexport async function syncPendingContainerCreateIntents(input: {\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listPendingCreateIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n const remainingContainerIds = new Set(\n pendingIntents.map((intent) => intent.containerId),\n );\n // Only a create that settles in this pass leaves the pending set; a failed\n // or parked one stays pending even though this pass stops retrying it.\n const unsettledContainerIds = new Set(remainingContainerIds);\n let createdCount = 0;\n let progressed = true;\n\n while (progressed && input.isCurrent()) {\n progressed = false;\n\n for (const intent of pendingIntents) {\n if (!remainingContainerIds.has(intent.containerId)) {\n continue;\n }\n\n const result = await trySyncPendingContainerContentsContainerCreateIntent(\n {\n host,\n isCreatePending: (containerId) =>\n unsettledContainerIds.has(containerId),\n isCurrent: input.isCurrent,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n },\n );\n if (result === \"abandoned\") {\n return createdCount;\n }\n\n if (result === \"blocked\") {\n continue;\n }\n\n remainingContainerIds.delete(intent.containerId);\n progressed = result === \"created\" || progressed;\n if (result === \"created\") {\n createdCount += 1;\n unsettledContainerIds.delete(intent.containerId);\n }\n }\n }\n\n return createdCount;\n}\n"]}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { isContainerSystemSlot, } from "../../../../internal/validators/containerSystemSlot.js";
|
|
2
2
|
import { locallyAcknowledgedContainerMutationHead } from "../../../../data/containers/shared/mutationAcknowledgement.js";
|
|
3
|
+
import { isContainerManifestAlreadyExistsConflict } from "../../../../data/containers/shared/mutationFailures.js";
|
|
3
4
|
import { assertDocumentWriterProjectionConsistent } from "../../../../data/documents/shared/projection/index.js";
|
|
4
5
|
import { advanceLocallyAcknowledgedAccessManifestHeadsAtomically, locallyAuthoredAccessManifestHead, } from "../../../../data/persistence/keyingCheckpoints/locallyAcknowledgedCheckpointPersistence.js";
|
|
5
6
|
import { readContainerMutationMetadataDocumentId, } from "../../../containers/index.js";
|
|
6
7
|
import { repairContainerCreateFailure } from "../../../containers/child/create/createSubmission.js";
|
|
7
8
|
import { documentWriterProjectionFromCreateResponse, persistedDocumentCreateStateFromResponse, resolveDocumentCreateAuthor, } from "../../../documents/index.js";
|
|
9
|
+
import { buildDocumentCreateSeedRequest, documentCreateSeedFits, } from "../../../documents/sync/initialSync.js";
|
|
8
10
|
import { PrincipalPolicyRepairBudget } from "../../../principals/policyRepairBudget.js";
|
|
9
11
|
import { createRuntimePrincipalPolicyWarmer } from "../../../principals/runtimePolicyWarmer.js";
|
|
10
12
|
import { settleTerminalCreateFailure } from "./createTerminalFailure.js";
|
|
@@ -106,6 +108,13 @@ function signedCreateSystemSlot(state) {
|
|
|
106
108
|
}
|
|
107
109
|
return state.systemSlot;
|
|
108
110
|
}
|
|
111
|
+
/** The seed the create committed, if the response accepted it. */
|
|
112
|
+
function committedMetadataSeed(response, seedUpdateId) {
|
|
113
|
+
const seed = response.metadataDocument.initialSync;
|
|
114
|
+
return seedUpdateId && seed?.acceptedOutgoingUpdateIds.includes(seedUpdateId)
|
|
115
|
+
? { commitLsn: seed.commitLsn, updateId: seedUpdateId }
|
|
116
|
+
: undefined;
|
|
117
|
+
}
|
|
109
118
|
async function settleContainerWithMetadataCreate(input) {
|
|
110
119
|
if (input.response.container.containerId !==
|
|
111
120
|
input.containerPlan.plan.containerId) {
|
|
@@ -147,10 +156,12 @@ async function settleContainerWithMetadataCreate(input) {
|
|
|
147
156
|
response: input.response,
|
|
148
157
|
runtime: input.runtime,
|
|
149
158
|
});
|
|
159
|
+
const metadataSeed = committedMetadataSeed(input.response, input.seedUpdateId);
|
|
150
160
|
return {
|
|
151
161
|
ok: true,
|
|
152
162
|
state: {
|
|
153
163
|
accessManifestHash: input.response.container.manifestHead.manifestHash,
|
|
164
|
+
...(metadataSeed ? { metadataSeed } : {}),
|
|
154
165
|
systemSlot: signedCreateSystemSlot(input.containerPlan.plan.state),
|
|
155
166
|
containerId: input.response.container.containerId,
|
|
156
167
|
createdAt: input.response.container.createdAt,
|
|
@@ -168,16 +179,40 @@ async function createRemoteContainerWithMetadataDocumentAttempt(input) {
|
|
|
168
179
|
if (!plans)
|
|
169
180
|
return null;
|
|
170
181
|
const { containerPlan, childProjection, metadataDocumentPlan } = plans;
|
|
171
|
-
const
|
|
182
|
+
const request = {
|
|
183
|
+
systemSlot: input.systemSlot ?? null,
|
|
184
|
+
container: containerPlan.plan.request,
|
|
185
|
+
metadataDocument: metadataDocumentPlan.plan.request,
|
|
186
|
+
};
|
|
187
|
+
const submitRequest = (body) => submitContainerWithMetadataDocument({
|
|
172
188
|
organizationId: containerPlan.plan.state.organizationId,
|
|
173
|
-
request:
|
|
174
|
-
systemSlot: input.systemSlot ?? null,
|
|
175
|
-
container: containerPlan.plan.request,
|
|
176
|
-
metadataDocument: metadataDocumentPlan.plan.request,
|
|
177
|
-
},
|
|
189
|
+
request: body,
|
|
178
190
|
runtime: input.runtime,
|
|
179
191
|
stillCurrent: input.stillCurrent,
|
|
180
192
|
});
|
|
193
|
+
const seed = input.metadataSeedUpdate
|
|
194
|
+
? await buildDocumentCreateSeedRequest({
|
|
195
|
+
author: input.author,
|
|
196
|
+
containerProjection: childProjection,
|
|
197
|
+
materializedDocument: metadataDocumentPlan,
|
|
198
|
+
pendingUpdate: input.metadataSeedUpdate,
|
|
199
|
+
})
|
|
200
|
+
: null;
|
|
201
|
+
let submitted = null;
|
|
202
|
+
if (seed && documentCreateSeedFits(seed)) {
|
|
203
|
+
submitted = await submitRequest({ ...request, initialMetadataSync: seed });
|
|
204
|
+
if (!submitted)
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
// A seed only saves the first metadata sync: a refused seeded create falls
|
|
208
|
+
// back to the plain create once, so the row syncs as before, and its failures
|
|
209
|
+
// take the ordinary repair path. A lost response is adopted directly, as a
|
|
210
|
+
// plain create's would be.
|
|
211
|
+
const seeded = submitted?.ok === true;
|
|
212
|
+
if (!submitted ||
|
|
213
|
+
(!submitted.ok && !isContainerManifestAlreadyExistsConflict(submitted))) {
|
|
214
|
+
submitted = await submitRequest(request);
|
|
215
|
+
}
|
|
181
216
|
if (!submitted?.ok) {
|
|
182
217
|
return submitted;
|
|
183
218
|
}
|
|
@@ -188,6 +223,7 @@ async function createRemoteContainerWithMetadataDocumentAttempt(input) {
|
|
|
188
223
|
metadataDocumentPlan,
|
|
189
224
|
response: submitted.response,
|
|
190
225
|
runtime: input.runtime,
|
|
226
|
+
seedUpdateId: seeded ? input.metadataSeedUpdate?.id : undefined,
|
|
191
227
|
stillCurrent: input.stillCurrent,
|
|
192
228
|
});
|
|
193
229
|
}
|
|
@@ -257,6 +293,7 @@ export async function createRemoteContainerWithMetadataDocument(input) {
|
|
|
257
293
|
containerSignedAt,
|
|
258
294
|
metadataContentKey,
|
|
259
295
|
metadataEventId,
|
|
296
|
+
metadataSeedUpdate: input.metadataSeedUpdate,
|
|
260
297
|
metadataSignedAt,
|
|
261
298
|
parentContainerId: input.parentContainerId,
|
|
262
299
|
parentProjection,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWithMetadata.js","sourceRoot":"","sources":["createWithMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerAccessManifestState } from \"@tearleads/crypto\";\nimport {\n type ContainerSystemSlot,\n isContainerSystemSlot,\n} from \"@tearleads/validators/containerSystemSlot\";\nimport type { ContainerCreateWithMetadataDocumentRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerCreateWithMetadataDocumentResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { locallyAcknowledgedContainerMutationHead } from \"../../../../data/containers/shared/mutationAcknowledgement\";\nimport type { ContainerMutationSubmitFailure } from \"../../../../data/containers/shared/types\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../../data/documents/shared/projection\";\nimport type { ProjectionUserKeyResolver } from \"../../../../data/keyingProjectionVerification\";\nimport {\n advanceLocallyAcknowledgedAccessManifestHeadsAtomically,\n locallyAuthoredAccessManifestHead,\n} from \"../../../../data/persistence/keyingCheckpoints/locallyAcknowledgedCheckpointPersistence\";\nimport type { ExecSql } from \"../../../../data/sqlite/sqlSchema\";\nimport {\n type buildMaterializedContainerCreatePlan,\n readContainerMutationMetadataDocumentId,\n} from \"../../../containers\";\nimport { repairContainerCreateFailure } from \"../../../containers/child/create/createSubmission\";\nimport {\n type buildMaterializedDocumentCreatePlan,\n documentWriterProjectionFromCreateResponse,\n persistedDocumentCreateStateFromResponse,\n resolveDocumentCreateAuthor,\n} from \"../../../documents\";\nimport { PrincipalPolicyRepairBudget } from \"../../../principals/policyRepairBudget\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../principals/runtimePolicyWarmer\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n} from \"../types\";\nimport { settleTerminalCreateFailure } from \"./createTerminalFailure\";\nimport {\n buildContainerWithMetadataPlans,\n type ContainerWithMetadataPlanInput,\n} from \"./createWithMetadataPlan\";\n\n/**\n * Sentinel for a lost-response retry whose manifest already exists remotely.\n * Callers avoid a duplicate; the next parent hydration settles local state.\n */\nexport const CONTAINER_ALREADY_COMMITTED = Symbol(\"containerAlreadyCommitted\");\nexport type ContainerAlreadyCommitted = typeof CONTAINER_ALREADY_COMMITTED;\n\nasync function submitContainerWithMetadataDocument(input: {\n readonly organizationId: string;\n readonly request: ContainerCreateWithMetadataDocumentRequest;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n | {\n readonly ok: true;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input.runtime;\n const result = await apiClient.createContainerWithMetadataDocumentResult(\n input.request,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n },\n );\n return result.ok ? { ok: true, response: result.data } : result;\n}\n\n/**\n * Seed the metadata document's writer projection from the create response so the\n * first read after the container is created (its own metadata sync, contents\n * hydration) resolves locally instead of a cold `GET writer-projection`. The\n * authorizing path is the child container projection the create was authored\n * against — locally built rather than server-fetched, so unlike the plain\n * document-create path this is gated on the projection's internal consistency;\n * on any mismatch the seed is skipped and the next read falls back to a fetch.\n */\nasync function seedMetadataDocumentWriterProjection(input: {\n readonly runtime: ContainerWorkflowRuntime;\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = documentWriterProjectionFromCreateResponse({\n containerProjection: input.childProjection,\n response: input.response.metadataDocument,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n stillCurrent: input.stillCurrent,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.runtime.apiClient.primeDocumentWriterProjection(\n input.response.metadataDocument.id,\n projection,\n );\n}\n\nasync function acknowledgeContainerWithMetadata(input: {\n containerPlan: Parameters<\n typeof locallyAcknowledgedContainerMutationHead\n >[0][\"plan\"];\n execSql: ExecSql;\n metadataDocumentPlan: Parameters<\n typeof persistedDocumentCreateStateFromResponse\n >[0];\n response: ContainerCreateWithMetadataDocumentResponse;\n stillCurrent?: (() => boolean) | undefined;\n}) {\n const persistedState = persistedDocumentCreateStateFromResponse(\n input.metadataDocumentPlan,\n input.response.metadataDocument,\n );\n const containerHead = await locallyAcknowledgedContainerMutationHead({\n plan: input.containerPlan,\n response: input.response.container,\n });\n await advanceLocallyAcknowledgedAccessManifestHeadsAtomically({\n execSql: input.execSql,\n heads: [\n containerHead,\n locallyAuthoredAccessManifestHead(input.metadataDocumentPlan),\n ],\n stillCurrent: input.stillCurrent,\n });\n return persistedState;\n}\n\n/**\n * Prime the new container's writer projection from the create plan the client\n * just authored, so the first write under it (a child folder, a document)\n * resolves locally instead of a cold `GET writer-projection`. Only primed when\n * the locally-built projection matches what the server created — the create\n * response echoes the container id and manifest head — so a mismatch skips the\n * seed and the next write falls back to a fetch (same fail-closed contract as\n * the metadata-document seed). Priming is safe for writes: the server still\n * validates every mutation, so a projection that later goes stale (rekey/share/\n * move evict it) just yields a rejected write that retries with a fresh fetch.\n */\nfunction seedChildContainerWriterProjection(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n}): void {\n const createdManifestHash =\n input.response.container.manifestHead.manifestHash;\n const projectedManifestHash = input.childProjection.path.at(-1)?.manifestHash;\n // Both hashes must be present and equal, or two undefined hashes would compare\n // equal and prime an empty/invalid projection.\n if (\n !createdManifestHash ||\n !projectedManifestHash ||\n input.childProjection.containerId !==\n input.response.container.containerId ||\n projectedManifestHash !== createdManifestHash\n ) {\n return;\n }\n\n input.runtime.apiClient.primeContainerWriterProjection(\n input.response.container.containerId,\n input.childProjection,\n );\n}\n\n/**\n * The persisted slot is the one this client signed into the manifest state.\n * The acknowledgement already refused a response that echoed anything else,\n * so the server's column never chooses which local record becomes Trash.\n */\nfunction signedCreateSystemSlot(\n state: ContainerAccessManifestState,\n): ContainerSystemSlot | null {\n if (state.systemSlot === null) return null;\n if (!isContainerSystemSlot(state.systemSlot)) {\n throw new Error(\"Container create plan signed an invalid system slot\");\n }\n return state.systemSlot;\n}\n\nasync function settleContainerWithMetadataCreate(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly containerPlan: Awaited<\n ReturnType<typeof buildMaterializedContainerCreatePlan>\n >;\n readonly execSql: ExecSql;\n readonly metadataDocumentPlan: Awaited<\n ReturnType<typeof buildMaterializedDocumentCreatePlan>\n >;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<{\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n} | null> {\n if (\n input.response.container.containerId !==\n input.containerPlan.plan.containerId\n ) {\n throw new Error(\"Container metadata create response container mismatch\");\n }\n // The acknowledgement echoed the signed parent, which a child always names.\n const parentId = input.containerPlan.plan.state.parentContainerId;\n if (parentId === null) {\n throw new Error(\"A container create must commit under a parent\");\n }\n const metadataDocumentId = readContainerMutationMetadataDocumentId({\n response: input.response.container,\n });\n if (\n metadataDocumentId !== input.containerPlan.plan.metadataDocumentId ||\n input.response.metadataDocument.id !==\n input.metadataDocumentPlan.plan.documentId\n ) {\n throw new Error(\"Container metadata create response document mismatch\");\n }\n const persistedMetadataState = await acknowledgeContainerWithMetadata({\n containerPlan: input.containerPlan.plan,\n execSql: input.execSql,\n metadataDocumentPlan: input.metadataDocumentPlan.plan,\n response: input.response,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n await seedMetadataDocumentWriterProjection({\n childProjection: input.childProjection,\n execSql: input.execSql,\n response: input.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n seedChildContainerWriterProjection({\n childProjection: input.childProjection,\n response: input.response,\n runtime: input.runtime,\n });\n return {\n ok: true,\n state: {\n accessManifestHash: input.response.container.manifestHead.manifestHash,\n systemSlot: signedCreateSystemSlot(input.containerPlan.plan.state),\n containerId: input.response.container.containerId,\n createdAt: input.response.container.createdAt,\n metadataDocumentId,\n organizationId: input.response.container.organizationId,\n parentId,\n persistedMetadataState,\n updatedAt: input.response.container.updatedAt,\n },\n };\n}\n\nasync function createRemoteContainerWithMetadataDocumentAttempt(\n input: ContainerWithMetadataPlanInput,\n): Promise<\n | {\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n const execSql = input.runtime.infra.execSql;\n const plans = await buildContainerWithMetadataPlans(input);\n if (!plans) return null;\n const { containerPlan, childProjection, metadataDocumentPlan } = plans;\n const submitted = await submitContainerWithMetadataDocument({\n organizationId: containerPlan.plan.state.organizationId,\n request: {\n systemSlot: input.systemSlot ?? null,\n container: containerPlan.plan.request,\n metadataDocument: metadataDocumentPlan.plan.request,\n },\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (!submitted?.ok) {\n return submitted;\n }\n return settleContainerWithMetadataCreate({\n childProjection,\n containerPlan,\n execSql,\n metadataDocumentPlan,\n response: submitted.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n}\n\nasync function createContainerWithMetadataWithRepairs(\n input: Parameters<\n typeof createRemoteContainerWithMetadataDocumentAttempt\n >[0] & {\n readonly parentContainerId: string;\n },\n): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const { apiClient } = input.runtime;\n let parentProjection = input.parentProjection;\n const repairState = {\n didRepairStaleParent: false,\n policyRepairs: new PrincipalPolicyRepairBudget(),\n };\n for (;;) {\n const submitted = await createRemoteContainerWithMetadataDocumentAttempt({\n ...input,\n parentProjection,\n });\n if (!submitted) {\n return null;\n }\n if (submitted.ok) {\n return submitted.state;\n }\n const repair = await repairContainerCreateFailure({\n apiClient,\n failure: submitted,\n parentContainerId: input.parentContainerId,\n parentProjection,\n state: repairState,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n stillCurrent: input.stillCurrent,\n });\n if (repair.kind === \"retry\") {\n parentProjection = repair.parentProjection;\n continue;\n }\n if (repair.kind === \"unavailable\") return null;\n return settleTerminalCreateFailure(submitted, input.stillCurrent) ===\n \"committed\"\n ? CONTAINER_ALREADY_COMMITTED\n : null;\n }\n}\n\nexport async function createRemoteContainerWithMetadataDocument(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const author = resolveDocumentCreateAuthor(input.runtime);\n const { apiClient } = input.runtime;\n const parentSecretKey = input.runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !parentSecretKey) {\n input.runtime.util.log(\n \"Container contents: skipped container create because the writer context is unavailable.\",\n );\n return null;\n }\n\n const parentProjection =\n input.parentProjection ??\n (await apiClient.getContainerWriterProjection(input.parentContainerId));\n if (!parentProjection) {\n return null;\n }\n\n const containerEventId = crypto.randomUUID();\n const containerKey = crypto.getRandomValues(new Uint8Array(32));\n const containerSignedAt = new Date().toISOString();\n const metadataContentKey = crypto.getRandomValues(new Uint8Array(32));\n const metadataEventId = crypto.randomUUID();\n const metadataSignedAt = new Date().toISOString();\n return createContainerWithMetadataWithRepairs({\n author,\n containerEventId,\n containerId: input.containerId,\n containerKey,\n containerSignedAt,\n metadataContentKey,\n metadataEventId,\n metadataSignedAt,\n parentContainerId: input.parentContainerId,\n parentProjection,\n parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n systemSlot: input.systemSlot,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createWithMetadata.js","sourceRoot":"","sources":["createWithMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerAccessManifestState } from \"@tearleads/crypto\";\nimport {\n type ContainerSystemSlot,\n isContainerSystemSlot,\n} from \"@tearleads/validators/containerSystemSlot\";\nimport type { ContainerCreateWithMetadataDocumentRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerCreateWithMetadataDocumentResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { locallyAcknowledgedContainerMutationHead } from \"../../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerManifestAlreadyExistsConflict } from \"../../../../data/containers/shared/mutationFailures\";\nimport type { ContainerMutationSubmitFailure } from \"../../../../data/containers/shared/types\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../../data/documents/shared/projection\";\nimport type { ProjectionUserKeyResolver } from \"../../../../data/keyingProjectionVerification\";\nimport {\n advanceLocallyAcknowledgedAccessManifestHeadsAtomically,\n locallyAuthoredAccessManifestHead,\n} from \"../../../../data/persistence/keyingCheckpoints/locallyAcknowledgedCheckpointPersistence\";\nimport type { ExecSql } from \"../../../../data/sqlite/sqlSchema\";\nimport {\n type buildMaterializedContainerCreatePlan,\n readContainerMutationMetadataDocumentId,\n} from \"../../../containers\";\nimport { repairContainerCreateFailure } from \"../../../containers/child/create/createSubmission\";\nimport {\n type buildMaterializedDocumentCreatePlan,\n documentWriterProjectionFromCreateResponse,\n persistedDocumentCreateStateFromResponse,\n resolveDocumentCreateAuthor,\n} from \"../../../documents\";\nimport {\n buildDocumentCreateSeedRequest,\n documentCreateSeedFits,\n} from \"../../../documents/sync/initialSync\";\nimport { PrincipalPolicyRepairBudget } from \"../../../principals/policyRepairBudget\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../principals/runtimePolicyWarmer\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n} from \"../types\";\nimport { settleTerminalCreateFailure } from \"./createTerminalFailure\";\nimport {\n buildContainerWithMetadataPlans,\n type ContainerWithMetadataPlanInput,\n} from \"./createWithMetadataPlan\";\n\n/**\n * Sentinel for a lost-response retry whose manifest already exists remotely.\n * Callers avoid a duplicate; the next parent hydration settles local state.\n */\nexport const CONTAINER_ALREADY_COMMITTED = Symbol(\"containerAlreadyCommitted\");\nexport type ContainerAlreadyCommitted = typeof CONTAINER_ALREADY_COMMITTED;\n\nasync function submitContainerWithMetadataDocument(input: {\n readonly organizationId: string;\n readonly request: ContainerCreateWithMetadataDocumentRequest;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n | {\n readonly ok: true;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input.runtime;\n const result = await apiClient.createContainerWithMetadataDocumentResult(\n input.request,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n },\n );\n return result.ok ? { ok: true, response: result.data } : result;\n}\n\n/**\n * Seed the metadata document's writer projection from the create response so the\n * first read after the container is created (its own metadata sync, contents\n * hydration) resolves locally instead of a cold `GET writer-projection`. The\n * authorizing path is the child container projection the create was authored\n * against — locally built rather than server-fetched, so unlike the plain\n * document-create path this is gated on the projection's internal consistency;\n * on any mismatch the seed is skipped and the next read falls back to a fetch.\n */\nasync function seedMetadataDocumentWriterProjection(input: {\n readonly runtime: ContainerWorkflowRuntime;\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = documentWriterProjectionFromCreateResponse({\n containerProjection: input.childProjection,\n response: input.response.metadataDocument,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n stillCurrent: input.stillCurrent,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.runtime.apiClient.primeDocumentWriterProjection(\n input.response.metadataDocument.id,\n projection,\n );\n}\n\nasync function acknowledgeContainerWithMetadata(input: {\n containerPlan: Parameters<\n typeof locallyAcknowledgedContainerMutationHead\n >[0][\"plan\"];\n execSql: ExecSql;\n metadataDocumentPlan: Parameters<\n typeof persistedDocumentCreateStateFromResponse\n >[0];\n response: ContainerCreateWithMetadataDocumentResponse;\n stillCurrent?: (() => boolean) | undefined;\n}) {\n const persistedState = persistedDocumentCreateStateFromResponse(\n input.metadataDocumentPlan,\n input.response.metadataDocument,\n );\n const containerHead = await locallyAcknowledgedContainerMutationHead({\n plan: input.containerPlan,\n response: input.response.container,\n });\n await advanceLocallyAcknowledgedAccessManifestHeadsAtomically({\n execSql: input.execSql,\n heads: [\n containerHead,\n locallyAuthoredAccessManifestHead(input.metadataDocumentPlan),\n ],\n stillCurrent: input.stillCurrent,\n });\n return persistedState;\n}\n\n/**\n * Prime the new container's writer projection from the create plan the client\n * just authored, so the first write under it (a child folder, a document)\n * resolves locally instead of a cold `GET writer-projection`. Only primed when\n * the locally-built projection matches what the server created — the create\n * response echoes the container id and manifest head — so a mismatch skips the\n * seed and the next write falls back to a fetch (same fail-closed contract as\n * the metadata-document seed). Priming is safe for writes: the server still\n * validates every mutation, so a projection that later goes stale (rekey/share/\n * move evict it) just yields a rejected write that retries with a fresh fetch.\n */\nfunction seedChildContainerWriterProjection(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n}): void {\n const createdManifestHash =\n input.response.container.manifestHead.manifestHash;\n const projectedManifestHash = input.childProjection.path.at(-1)?.manifestHash;\n // Both hashes must be present and equal, or two undefined hashes would compare\n // equal and prime an empty/invalid projection.\n if (\n !createdManifestHash ||\n !projectedManifestHash ||\n input.childProjection.containerId !==\n input.response.container.containerId ||\n projectedManifestHash !== createdManifestHash\n ) {\n return;\n }\n\n input.runtime.apiClient.primeContainerWriterProjection(\n input.response.container.containerId,\n input.childProjection,\n );\n}\n\n/**\n * The persisted slot is the one this client signed into the manifest state.\n * The acknowledgement already refused a response that echoed anything else,\n * so the server's column never chooses which local record becomes Trash.\n */\nfunction signedCreateSystemSlot(\n state: ContainerAccessManifestState,\n): ContainerSystemSlot | null {\n if (state.systemSlot === null) return null;\n if (!isContainerSystemSlot(state.systemSlot)) {\n throw new Error(\"Container create plan signed an invalid system slot\");\n }\n return state.systemSlot;\n}\n\n/** The seed the create committed, if the response accepted it. */\nfunction committedMetadataSeed(\n response: ContainerCreateWithMetadataDocumentResponse,\n seedUpdateId: string | undefined,\n): CreatedRemoteContainerState[\"metadataSeed\"] {\n const seed = response.metadataDocument.initialSync;\n return seedUpdateId && seed?.acceptedOutgoingUpdateIds.includes(seedUpdateId)\n ? { commitLsn: seed.commitLsn, updateId: seedUpdateId }\n : undefined;\n}\n\nasync function settleContainerWithMetadataCreate(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly containerPlan: Awaited<\n ReturnType<typeof buildMaterializedContainerCreatePlan>\n >;\n readonly execSql: ExecSql;\n readonly metadataDocumentPlan: Awaited<\n ReturnType<typeof buildMaterializedDocumentCreatePlan>\n >;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n readonly seedUpdateId?: string | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<{\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n} | null> {\n if (\n input.response.container.containerId !==\n input.containerPlan.plan.containerId\n ) {\n throw new Error(\"Container metadata create response container mismatch\");\n }\n // The acknowledgement echoed the signed parent, which a child always names.\n const parentId = input.containerPlan.plan.state.parentContainerId;\n if (parentId === null) {\n throw new Error(\"A container create must commit under a parent\");\n }\n const metadataDocumentId = readContainerMutationMetadataDocumentId({\n response: input.response.container,\n });\n if (\n metadataDocumentId !== input.containerPlan.plan.metadataDocumentId ||\n input.response.metadataDocument.id !==\n input.metadataDocumentPlan.plan.documentId\n ) {\n throw new Error(\"Container metadata create response document mismatch\");\n }\n const persistedMetadataState = await acknowledgeContainerWithMetadata({\n containerPlan: input.containerPlan.plan,\n execSql: input.execSql,\n metadataDocumentPlan: input.metadataDocumentPlan.plan,\n response: input.response,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n await seedMetadataDocumentWriterProjection({\n childProjection: input.childProjection,\n execSql: input.execSql,\n response: input.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n seedChildContainerWriterProjection({\n childProjection: input.childProjection,\n response: input.response,\n runtime: input.runtime,\n });\n const metadataSeed = committedMetadataSeed(\n input.response,\n input.seedUpdateId,\n );\n return {\n ok: true,\n state: {\n accessManifestHash: input.response.container.manifestHead.manifestHash,\n ...(metadataSeed ? { metadataSeed } : {}),\n systemSlot: signedCreateSystemSlot(input.containerPlan.plan.state),\n containerId: input.response.container.containerId,\n createdAt: input.response.container.createdAt,\n metadataDocumentId,\n organizationId: input.response.container.organizationId,\n parentId,\n persistedMetadataState,\n updatedAt: input.response.container.updatedAt,\n },\n };\n}\n\nasync function createRemoteContainerWithMetadataDocumentAttempt(\n input: ContainerWithMetadataPlanInput,\n): Promise<\n | {\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n const execSql = input.runtime.infra.execSql;\n const plans = await buildContainerWithMetadataPlans(input);\n if (!plans) return null;\n const { containerPlan, childProjection, metadataDocumentPlan } = plans;\n const request = {\n systemSlot: input.systemSlot ?? null,\n container: containerPlan.plan.request,\n metadataDocument: metadataDocumentPlan.plan.request,\n };\n const submitRequest = (body: ContainerCreateWithMetadataDocumentRequest) =>\n submitContainerWithMetadataDocument({\n organizationId: containerPlan.plan.state.organizationId,\n request: body,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n const seed = input.metadataSeedUpdate\n ? await buildDocumentCreateSeedRequest({\n author: input.author,\n containerProjection: childProjection,\n materializedDocument: metadataDocumentPlan,\n pendingUpdate: input.metadataSeedUpdate,\n })\n : null;\n let submitted: Awaited<ReturnType<typeof submitRequest>> = null;\n if (seed && documentCreateSeedFits(seed)) {\n submitted = await submitRequest({ ...request, initialMetadataSync: seed });\n if (!submitted) return null;\n }\n // A seed only saves the first metadata sync: a refused seeded create falls\n // back to the plain create once, so the row syncs as before, and its failures\n // take the ordinary repair path. A lost response is adopted directly, as a\n // plain create's would be.\n const seeded = submitted?.ok === true;\n if (\n !submitted ||\n (!submitted.ok && !isContainerManifestAlreadyExistsConflict(submitted))\n ) {\n submitted = await submitRequest(request);\n }\n if (!submitted?.ok) {\n return submitted;\n }\n return settleContainerWithMetadataCreate({\n childProjection,\n containerPlan,\n execSql,\n metadataDocumentPlan,\n response: submitted.response,\n runtime: input.runtime,\n seedUpdateId: seeded ? input.metadataSeedUpdate?.id : undefined,\n stillCurrent: input.stillCurrent,\n });\n}\n\nasync function createContainerWithMetadataWithRepairs(\n input: Parameters<\n typeof createRemoteContainerWithMetadataDocumentAttempt\n >[0] & {\n readonly parentContainerId: string;\n },\n): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const { apiClient } = input.runtime;\n let parentProjection = input.parentProjection;\n const repairState = {\n didRepairStaleParent: false,\n policyRepairs: new PrincipalPolicyRepairBudget(),\n };\n for (;;) {\n const submitted = await createRemoteContainerWithMetadataDocumentAttempt({\n ...input,\n parentProjection,\n });\n if (!submitted) {\n return null;\n }\n if (submitted.ok) {\n return submitted.state;\n }\n const repair = await repairContainerCreateFailure({\n apiClient,\n failure: submitted,\n parentContainerId: input.parentContainerId,\n parentProjection,\n state: repairState,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n stillCurrent: input.stillCurrent,\n });\n if (repair.kind === \"retry\") {\n parentProjection = repair.parentProjection;\n continue;\n }\n if (repair.kind === \"unavailable\") return null;\n return settleTerminalCreateFailure(submitted, input.stillCurrent) ===\n \"committed\"\n ? CONTAINER_ALREADY_COMMITTED\n : null;\n }\n}\n\nexport async function createRemoteContainerWithMetadataDocument(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n metadataSeedUpdate?: ContainerWithMetadataPlanInput[\"metadataSeedUpdate\"];\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const author = resolveDocumentCreateAuthor(input.runtime);\n const { apiClient } = input.runtime;\n const parentSecretKey = input.runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !parentSecretKey) {\n input.runtime.util.log(\n \"Container contents: skipped container create because the writer context is unavailable.\",\n );\n return null;\n }\n\n const parentProjection =\n input.parentProjection ??\n (await apiClient.getContainerWriterProjection(input.parentContainerId));\n if (!parentProjection) {\n return null;\n }\n\n const containerEventId = crypto.randomUUID();\n const containerKey = crypto.getRandomValues(new Uint8Array(32));\n const containerSignedAt = new Date().toISOString();\n const metadataContentKey = crypto.getRandomValues(new Uint8Array(32));\n const metadataEventId = crypto.randomUUID();\n const metadataSignedAt = new Date().toISOString();\n return createContainerWithMetadataWithRepairs({\n author,\n containerEventId,\n containerId: input.containerId,\n containerKey,\n containerSignedAt,\n metadataContentKey,\n metadataEventId,\n metadataSeedUpdate: input.metadataSeedUpdate,\n metadataSignedAt,\n parentContainerId: input.parentContainerId,\n parentProjection,\n parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n systemSlot: input.systemSlot,\n });\n}\n"]}
|
|
@@ -2,6 +2,10 @@ import { ProjectionDependencyUnavailableError } from "../../../../data/keyingPro
|
|
|
2
2
|
import { buildMaterializedContainerCreatePlan, childContainerWriterProjectionFromCreatePlan, } from "../../../containers/index.js";
|
|
3
3
|
import { buildMaterializedDocumentCreatePlan, } from "../../../documents/index.js";
|
|
4
4
|
import { createRuntimePrincipalPolicyWarmer } from "../../../principals/runtimePolicyWarmer.js";
|
|
5
|
+
/** A folder's metadata document takes the folder's id, known before the create. */
|
|
6
|
+
export function plannedContainerMetadataDocumentId(containerId) {
|
|
7
|
+
return containerId;
|
|
8
|
+
}
|
|
5
9
|
async function buildPlans(input) {
|
|
6
10
|
const execSql = input.runtime.infra.execSql;
|
|
7
11
|
// Rebuild parent- and policy-dependent hashes, signatures, and wraps on every
|
|
@@ -12,7 +16,7 @@ async function buildPlans(input) {
|
|
|
12
16
|
containerKey: input.containerKey,
|
|
13
17
|
execSql,
|
|
14
18
|
eventId: input.containerEventId,
|
|
15
|
-
metadataDocumentId: input.containerId,
|
|
19
|
+
metadataDocumentId: plannedContainerMetadataDocumentId(input.containerId),
|
|
16
20
|
systemSlot: input.systemSlot,
|
|
17
21
|
parentProjection: input.parentProjection,
|
|
18
22
|
parentSecretKey: input.parentSecretKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWithMetadataPlan.js","sourceRoot":"","sources":["createWithMetadataPlan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oCAAoC,EAAE,MAAM,qEAAqE,CAAC;
|
|
1
|
+
{"version":3,"file":"createWithMetadataPlan.js","sourceRoot":"","sources":["createWithMetadataPlan.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { ProjectionUserKeyResolver } from \"../../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport type { PendingUpdateRecord } from \"../../../../data/sqlite/documentPersistence\";\nimport {\n buildMaterializedContainerCreatePlan,\n childContainerWriterProjectionFromCreatePlan,\n} from \"../../../containers\";\nimport {\n buildMaterializedDocumentCreatePlan,\n type resolveDocumentCreateAuthor,\n} from \"../../../documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../principals/runtimePolicyWarmer\";\nimport type { ContainerWorkflowRuntime } from \"../types\";\n\nexport interface ContainerWithMetadataPlanInput {\n readonly author: NonNullable<ReturnType<typeof resolveDocumentCreateAuthor>>;\n readonly containerEventId: string;\n readonly containerId: string;\n readonly containerKey: Uint8Array;\n readonly containerSignedAt: string;\n readonly metadataContentKey: Uint8Array;\n readonly metadataEventId: string;\n /** The queued update holding the metadata document's whole content. */\n readonly metadataSeedUpdate?: PendingUpdateRecord | undefined;\n readonly metadataSignedAt: string;\n readonly parentProjection: ContainerWriterProjectionResponse;\n readonly parentSecretKey: Uint8Array;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly runtime: ContainerWorkflowRuntime;\n readonly systemSlot?: ContainerSystemSlot | null | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\n/** A folder's metadata document takes the folder's id, known before the create. */\nexport function plannedContainerMetadataDocumentId(\n containerId: string,\n): string {\n return containerId;\n}\n\nasync function buildPlans(input: ContainerWithMetadataPlanInput) {\n const execSql = input.runtime.infra.execSql;\n // Rebuild parent- and policy-dependent hashes, signatures, and wraps on every\n // attempt while retaining the logical mutation identities and key material.\n const containerPlan = await buildMaterializedContainerCreatePlan({\n author: input.author,\n containerId: input.containerId,\n containerKey: input.containerKey,\n execSql,\n eventId: input.containerEventId,\n metadataDocumentId: plannedContainerMetadataDocumentId(input.containerId),\n systemSlot: input.systemSlot,\n parentProjection: input.parentProjection,\n parentSecretKey: input.parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.containerSignedAt,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n const childProjection = childContainerWriterProjectionFromCreatePlan({\n materializedPlan: containerPlan,\n parentProjection: input.parentProjection,\n });\n const metadataDocumentPlan = await buildMaterializedDocumentCreatePlan({\n author: input.author,\n containerProjection: childProjection,\n contentKey: input.metadataContentKey,\n documentId: containerPlan.plan.metadataDocumentId,\n eventId: input.metadataEventId,\n execSql,\n knownContainerKeks: new Map([\n [containerPlan.plan.containerKeyEpochId, containerPlan.containerKey],\n ]),\n signedAt: input.metadataSignedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.parentSecretKey,\n trustedLocalProjection: true,\n });\n return { containerPlan, childProjection, metadataDocumentPlan };\n}\n\n/** Refresh stale history evidence once, strictly before submitting the write. */\nexport async function buildContainerWithMetadataPlans(\n input: ContainerWithMetadataPlanInput,\n) {\n try {\n return await buildPlans(input);\n } catch (error) {\n if (!(error instanceof ProjectionDependencyUnavailableError)) throw error;\n }\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input.runtime;\n const parentId = input.parentProjection.containerId;\n apiClient.evictContainerWriterProjection(parentId);\n const parentProjection =\n await apiClient.getContainerWriterProjection(parentId);\n if (!parentProjection || input.stillCurrent?.() === false) return null;\n if (\n parentProjection.containerId !== parentId ||\n parentProjection.organizationId !== input.parentProjection.organizationId\n ) {\n throw new Error(\n \"Refreshed parent projection belongs to another container or organization\",\n );\n }\n return buildPlans({ ...input, parentProjection });\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isContainerNotFoundFailure } from "../../../data/containers/shared/mutationFailures.js";
|
|
2
2
|
import { ProjectionDependencyUnavailableError } from "../../../data/keyingProjectionVerification/dependencyUnavailable.js";
|
|
3
|
+
import { errorMessage } from "../../../data/shared/errorMessage.js";
|
|
3
4
|
import { readContainerMutationMetadataDocumentId, referencedPrincipalHeadsFromContainerMutationResponse, replayRemoteContainerMove, shareRemoteContainer as shareRemoteContainerMutation, } from "../../containers/index.js";
|
|
4
5
|
import { createRuntimeCurrentGroupShare } from "../../containers/child/share/runtimeCurrentGroupShare.js";
|
|
5
6
|
import { resolveDocumentCreateAuthor } from "../../documents/index.js";
|
|
@@ -163,4 +164,18 @@ export async function deleteRemoteContainer(input) {
|
|
|
163
164
|
}
|
|
164
165
|
return { deletedAt: deleteResult.data.deletedAt };
|
|
165
166
|
}
|
|
167
|
+
/** Best-effort delete of a remote container whose local folder is gone. */
|
|
168
|
+
export async function discardOrphanedRemoteContainer(input) {
|
|
169
|
+
if (!input.isCurrent()) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const discardFailure = await deleteRemoteContainer({
|
|
173
|
+
containerId: input.created.containerId,
|
|
174
|
+
organizationId: input.created.organizationId,
|
|
175
|
+
runtime: input.state.runtime,
|
|
176
|
+
}).then((deleted) => (deleted ? null : "the server rejected the delete"), (error) => errorMessage(error));
|
|
177
|
+
if (input.isCurrent() && discardFailure !== null) {
|
|
178
|
+
input.state.runtime.util.log(`Container contents: failed to discard orphaned remote container ${input.created.containerId} after local delete: ${discardFailure}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
166
181
|
//# sourceMappingURL=remote.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote.js","sourceRoot":"","sources":["remote.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport {\n type AppliedContainerMove,\n readContainerMutationMetadataDocumentId,\n referencedPrincipalHeadsFromContainerMutationResponse,\n replayRemoteContainerMove,\n shareRemoteContainer as shareRemoteContainerMutation,\n} from \"../../containers\";\nimport { createRuntimeCurrentGroupShare } from \"../../containers/child/share/runtimeCurrentGroupShare\";\nimport { resolveDocumentCreateAuthor } from \"../../documents\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadata/groupMetadataRuntime\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n type ContainerAlreadyCommitted,\n createRemoteContainerWithMetadataDocument,\n} from \"./create/createWithMetadata\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n RemoteContainer,\n SharedRemoteContainerState,\n} from \"./types\";\n\n/**\n * Resolve the author, api client, executor, and encapsulation secret a remote\n * container mutation needs, logging a skip for the given operation when the\n * writer context is unavailable.\n */\nfunction resolveContainerWriterContext(\n runtime: ContainerWorkflowRuntime,\n operation:\n | \"container create\"\n | \"container group share\"\n | \"container move\"\n | \"container share\",\n) {\n const author = resolveDocumentCreateAuthor(runtime);\n const secretKey = runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !secretKey) {\n runtime.util.log(\n `Container contents: skipped ${operation} because the writer context is unavailable.`,\n );\n return null;\n }\n\n return {\n apiClient: runtime.apiClient,\n author,\n execSql: runtime.infra.execSql,\n secretKey,\n };\n}\n\nexport async function createRemoteContainer(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n return createRemoteContainerWithMetadataDocument(input);\n}\n\nfunction sharedRemoteContainerStateFromMutation(\n previousProjection: ContainerWriterProjectionResponse,\n response: ContainerMutationResponse,\n): SharedRemoteContainerState {\n if (\n response.containerId !== previousProjection.containerId ||\n response.organizationId !== previousProjection.organizationId\n )\n throw new Error(\"Container mutation response projection mismatch\");\n return {\n accessManifestHash: response.manifestHead.manifestHash,\n accessEpoch: response.manifestHead.epoch,\n createdAt: response.createdAt,\n metadataDocumentId: readContainerMutationMetadataDocumentId({ response }),\n referencedPrincipalHeads:\n referencedPrincipalHeadsFromContainerMutationResponse({ response }),\n updatedAt: response.updatedAt,\n // The next read obtains the post-commit proof. A failed read cannot undo\n // acknowledgement of this successful mutation.\n writerProjection: null,\n };\n}\n\nexport async function shareRemoteContainer(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n previousProjection: ContainerWriterProjectionResponse;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shared = await shareRemoteContainerMutation({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n previousProjection: input.previousProjection,\n recipientUserId: input.recipientUserId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\nexport async function shareRemoteContainerWithGroup(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n expectedGroupName?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection: ContainerWriterProjectionResponse;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container group share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shareWithGroup = createRuntimeCurrentGroupShare(input.runtime);\n if (!shareWithGroup)\n throw new ProjectionDependencyUnavailableError(\n \"Group sharing requires private paged recovery\",\n );\n const shared = await shareWithGroup({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n expectedGroupName: input.expectedGroupName ?? null,\n readEncryptedName: (bundle) =>\n createRuntimeGroupMetadataAccess(\n input.runtime,\n author.organizationId,\n input.stillCurrent,\n ).readName(bundle),\n knownContainerKeks: input.knownContainerKeks,\n previousProjection: input.previousProjection,\n recipientGroupId: input.recipientGroupId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n signingKeyPair: input.runtime.crypto.signingKeyPair,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\n/**\n * Replays a queued move. `applied` carries the verified head when the server\n * already holds the container under the destination, so nothing is posted.\n */\nexport async function moveRemoteContainer(input: {\n containerId: string;\n onAccepted?: (() => void) | undefined;\n parentContainerId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n { applied: AppliedContainerMove } | { moved: RemoteContainer } | null\n> {\n const writer = resolveContainerWriterContext(input.runtime, \"container move\");\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const replayed = await replayRemoteContainerMove({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n apiClient,\n author,\n containerId: input.containerId,\n destinationParentContainerId: input.parentContainerId,\n execSql,\n onAccepted: input.onAccepted,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!replayed || \"applied\" in replayed) {\n return replayed;\n }\n\n const { response } = replayed;\n return {\n moved: {\n createdAt: response.createdAt,\n effectiveAccessLevel: \"admin\",\n id: response.containerId,\n organizationId: response.organizationId,\n parentId: response.parentId,\n metadataDocumentId: readContainerMutationMetadataDocumentId({ response }),\n metadataAccessEpoch: response.manifestHead.epoch,\n metadataAccessStateHash: response.manifestHead.manifestHash,\n metadataReferencedPrincipals:\n referencedPrincipalHeadsFromContainerMutationResponse({ response }),\n updatedAt: response.updatedAt,\n },\n };\n}\n\nexport async function deleteRemoteContainer(input: {\n containerId: string;\n organizationId: string;\n requiredAncestorId?: string | undefined;\n runtime: ContainerWorkflowRuntime;\n}): Promise<{ deletedAt: string } | null> {\n const deleteResult = await input.runtime.apiClient.deleteContainerResult(\n input.containerId,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n requiredAncestorId: input.requiredAncestorId,\n },\n );\n if (!deleteResult.ok && !isContainerNotFoundFailure(deleteResult)) {\n deleteResult.report();\n return null;\n }\n\n if (!deleteResult.ok) {\n // A 404 proves this immutable id is permanently absent, but it does not\n // carry the server deletion time. A maximal fence prevents an older\n // in-flight listing page from resurrecting it.\n return { deletedAt: \"9999-12-31T23:59:59.999Z\" };\n }\n\n return { deletedAt: deleteResult.data.deletedAt };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["remote.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport {\n type AppliedContainerMove,\n readContainerMutationMetadataDocumentId,\n referencedPrincipalHeadsFromContainerMutationResponse,\n replayRemoteContainerMove,\n shareRemoteContainer as shareRemoteContainerMutation,\n} from \"../../containers\";\nimport { createRuntimeCurrentGroupShare } from \"../../containers/child/share/runtimeCurrentGroupShare\";\nimport { resolveDocumentCreateAuthor } from \"../../documents\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadata/groupMetadataRuntime\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n type ContainerAlreadyCommitted,\n createRemoteContainerWithMetadataDocument,\n} from \"./create/createWithMetadata\";\nimport type {\n ContainerCreateIntentSyncState,\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n RemoteContainer,\n SharedRemoteContainerState,\n} from \"./types\";\n\n/**\n * Resolve the author, api client, executor, and encapsulation secret a remote\n * container mutation needs, logging a skip for the given operation when the\n * writer context is unavailable.\n */\nfunction resolveContainerWriterContext(\n runtime: ContainerWorkflowRuntime,\n operation:\n | \"container create\"\n | \"container group share\"\n | \"container move\"\n | \"container share\",\n) {\n const author = resolveDocumentCreateAuthor(runtime);\n const secretKey = runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !secretKey) {\n runtime.util.log(\n `Container contents: skipped ${operation} because the writer context is unavailable.`,\n );\n return null;\n }\n\n return {\n apiClient: runtime.apiClient,\n author,\n execSql: runtime.infra.execSql,\n secretKey,\n };\n}\n\nexport async function createRemoteContainer(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n metadataSeedUpdate?: Parameters<\n typeof createRemoteContainerWithMetadataDocument\n >[0][\"metadataSeedUpdate\"];\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n return createRemoteContainerWithMetadataDocument(input);\n}\n\nfunction sharedRemoteContainerStateFromMutation(\n previousProjection: ContainerWriterProjectionResponse,\n response: ContainerMutationResponse,\n): SharedRemoteContainerState {\n if (\n response.containerId !== previousProjection.containerId ||\n response.organizationId !== previousProjection.organizationId\n )\n throw new Error(\"Container mutation response projection mismatch\");\n return {\n accessManifestHash: response.manifestHead.manifestHash,\n accessEpoch: response.manifestHead.epoch,\n createdAt: response.createdAt,\n metadataDocumentId: readContainerMutationMetadataDocumentId({ response }),\n referencedPrincipalHeads:\n referencedPrincipalHeadsFromContainerMutationResponse({ response }),\n updatedAt: response.updatedAt,\n // The next read obtains the post-commit proof. A failed read cannot undo\n // acknowledgement of this successful mutation.\n writerProjection: null,\n };\n}\n\nexport async function shareRemoteContainer(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n previousProjection: ContainerWriterProjectionResponse;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shared = await shareRemoteContainerMutation({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n previousProjection: input.previousProjection,\n recipientUserId: input.recipientUserId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\nexport async function shareRemoteContainerWithGroup(input: {\n accessLevel: \"read\" | \"write\" | \"admin\";\n containerId: string;\n expectedGroupName?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection: ContainerWriterProjectionResponse;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<SharedRemoteContainerState | null> {\n const writer = resolveContainerWriterContext(\n input.runtime,\n \"container group share\",\n );\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const shareWithGroup = createRuntimeCurrentGroupShare(input.runtime);\n if (!shareWithGroup)\n throw new ProjectionDependencyUnavailableError(\n \"Group sharing requires private paged recovery\",\n );\n const shared = await shareWithGroup({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n accessLevel: input.accessLevel,\n apiClient,\n author,\n containerId: input.containerId,\n execSql,\n expectedGroupName: input.expectedGroupName ?? null,\n readEncryptedName: (bundle) =>\n createRuntimeGroupMetadataAccess(\n input.runtime,\n author.organizationId,\n input.stillCurrent,\n ).readName(bundle),\n knownContainerKeks: input.knownContainerKeks,\n previousProjection: input.previousProjection,\n recipientGroupId: input.recipientGroupId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n signingKeyPair: input.runtime.crypto.signingKeyPair,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!shared) {\n return null;\n }\n\n return sharedRemoteContainerStateFromMutation(\n input.previousProjection,\n shared.response,\n );\n}\n\n/**\n * Replays a queued move. `applied` carries the verified head when the server\n * already holds the container under the destination, so nothing is posted.\n */\nexport async function moveRemoteContainer(input: {\n containerId: string;\n onAccepted?: (() => void) | undefined;\n parentContainerId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n { applied: AppliedContainerMove } | { moved: RemoteContainer } | null\n> {\n const writer = resolveContainerWriterContext(input.runtime, \"container move\");\n if (!writer) {\n return null;\n }\n const { apiClient, author, execSql, secretKey: targetSecretKey } = writer;\n\n const replayed = await replayRemoteContainerMove({\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n apiClient,\n author,\n containerId: input.containerId,\n destinationParentContainerId: input.parentContainerId,\n execSql,\n onAccepted: input.onAccepted,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n if (!replayed || \"applied\" in replayed) {\n return replayed;\n }\n\n const { response } = replayed;\n return {\n moved: {\n createdAt: response.createdAt,\n effectiveAccessLevel: \"admin\",\n id: response.containerId,\n organizationId: response.organizationId,\n parentId: response.parentId,\n metadataDocumentId: readContainerMutationMetadataDocumentId({ response }),\n metadataAccessEpoch: response.manifestHead.epoch,\n metadataAccessStateHash: response.manifestHead.manifestHash,\n metadataReferencedPrincipals:\n referencedPrincipalHeadsFromContainerMutationResponse({ response }),\n updatedAt: response.updatedAt,\n },\n };\n}\n\nexport async function deleteRemoteContainer(input: {\n containerId: string;\n organizationId: string;\n requiredAncestorId?: string | undefined;\n runtime: ContainerWorkflowRuntime;\n}): Promise<{ deletedAt: string } | null> {\n const deleteResult = await input.runtime.apiClient.deleteContainerResult(\n input.containerId,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n requiredAncestorId: input.requiredAncestorId,\n },\n );\n if (!deleteResult.ok && !isContainerNotFoundFailure(deleteResult)) {\n deleteResult.report();\n return null;\n }\n\n if (!deleteResult.ok) {\n // A 404 proves this immutable id is permanently absent, but it does not\n // carry the server deletion time. A maximal fence prevents an older\n // in-flight listing page from resurrecting it.\n return { deletedAt: \"9999-12-31T23:59:59.999Z\" };\n }\n\n return { deletedAt: deleteResult.data.deletedAt };\n}\n\n/** Best-effort delete of a remote container whose local folder is gone. */\nexport async function discardOrphanedRemoteContainer(input: {\n created: CreatedRemoteContainerState;\n isCurrent: () => boolean;\n state: Pick<ContainerCreateIntentSyncState, \"runtime\">;\n}): Promise<void> {\n if (!input.isCurrent()) {\n return;\n }\n const discardFailure = await deleteRemoteContainer({\n containerId: input.created.containerId,\n organizationId: input.created.organizationId,\n runtime: input.state.runtime,\n }).then(\n (deleted) => (deleted ? null : \"the server rejected the delete\"),\n (error: unknown) => errorMessage(error),\n );\n if (input.isCurrent() && discardFailure !== null) {\n input.state.runtime.util.log(\n `Container contents: failed to discard orphaned remote container ${input.created.containerId} after local delete: ${discardFailure}`,\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerDeleteResponse,\n ContainerWriterProjectionResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { createInitializedContainerMetadataDocument } from \"../../../data/containers/containerMetadataDocument\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport type { DocumentRecord } from \"../../../data/sqlite/documentPersistence\";\nimport type {\n createRemoteContainer,\n moveRemoteContainer,\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"../../containers\";\nimport type { createRemoteDocument } from \"../../documents\";\nimport type { CurrentPrincipalPolicyReader } from \"../../principals/currentPrincipalPolicyReader\";\nimport type { PrincipalPolicyHistoryReader } from \"../../principals/principalPolicyHistoryReader\";\nimport type {\n ContainerContentsPersistence,\n ContainerCreateIntentRecord,\n ContainerMoveIntentRecord,\n} from \"../containerPersistence\";\nimport type {\n ContainerState,\n RemoteContainer as HydratedRemoteContainer,\n RemoteContainerHydrationHost,\n} from \"../remoteHydration\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport type ContainerWorkflowApi = Parameters<\n typeof createRemoteContainer\n>[0][\"apiClient\"] &\n Parameters<typeof shareRemoteContainer>[0][\"apiClient\"] &\n Parameters<typeof shareRemoteContainerWithGroup>[0][\"apiClient\"] &\n Parameters<typeof moveRemoteContainer>[0][\"apiClient\"] &\n Parameters<typeof createRemoteDocument>[0][\"apiClient\"] &\n Partial<PrincipalPolicyHistoryReader> &\n CurrentPrincipalPolicyReader & {\n deleteContainerResult(\n containerId: string,\n options?: {\n expectedPaymentRequiredOrganizationId?: string;\n reportErrors?: boolean;\n requiredAncestorId?: string | undefined;\n },\n ): Promise<\n | { data: ContainerDeleteResponse; ok: true }\n | {\n ok: false;\n report: () => void;\n status: number | null;\n }\n >;\n primeContainerWriterProjection(\n containerId: string,\n projection: ContainerWriterProjectionResponse,\n ): void;\n };\n\nexport interface ContainerWorkflowRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n readonly apiClient: ContainerWorkflowApi;\n}\n\nexport interface CreatedRemoteContainerState {\n accessManifestHash: string;\n /** The slot this client signed into the create; never the server's echo. */\n systemSlot: ContainerSystemSlot | null;\n containerId: string;\n createdAt: string;\n metadataDocumentId: string;\n organizationId: string;\n /** A created container is a child; the acknowledgement echoed this parent. */\n parentId: string;\n persistedMetadataState: Pick<\n DocumentRecord,\n | \"documentId\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\"\n >;\n updatedAt: string;\n}\n\nexport interface SharedRemoteContainerState {\n accessEpoch: number;\n accessManifestHash: string;\n createdAt: string;\n metadataDocumentId: string;\n referencedPrincipalHeads: ReferencedPrincipalStateResponse[];\n updatedAt: string;\n writerProjection: ContainerWriterProjectionResponse | null;\n}\n\nexport interface SharedContainerState {\n container: ContainerState[\"container\"];\n record: ContainerState[\"record\"];\n}\n\nexport type SharedContainerStateResult =\n | { status: \"missing\" }\n | { status: \"confirmed\" }\n | (SharedContainerState & {\n status: \"identity-superseded\" | \"persisted\";\n });\n\nexport type RemoteContainer = HydratedRemoteContainer;\n\nexport type ContainerMetadataDocumentState = Awaited<\n ReturnType<typeof createInitializedContainerMetadataDocument>\n>[\"doc\"];\n\nexport interface CreatedChildContainerState {\n containerState: ContainerState;\n initialUpdate: Uint8Array;\n shouldRequestSync: boolean;\n}\n\nexport interface ContainerIntentSyncState {\n containersById: ReadonlyMap<string, ContainerState>;\n persistence: ContainerContentsPersistence;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n /**\n * Verifies that a listed container is this device's pending create before it\n * is adopted and returns where it sits; `assertContainerCreateAdoptable`\n * unless a test replaces it.\n */\n verifyCreateAdoption?: (input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n }) => Promise<AdoptedContainerPlacement>;\n}\n\n/** Where a verified listed create committed, and where its container is now. */\nexport interface AdoptedContainerPlacement {\n /** The parent its signed epoch-1 `container.create` named. */\n readonly createdParentId: string;\n /** The verified head's parent; another writer may have moved it since. */\n readonly currentParentId: string;\n}\n\nexport type ContainerCreateIntentSyncState = ContainerIntentSyncState;\n\nexport type ContainerCreateIntentSyncHost = Pick<\n RemoteContainerHydrationHost,\n \"persistContainerState\"\n>;\n\nexport interface ContainerCreateIntentSyncInput {\n host: ContainerCreateIntentSyncHost;\n /** A parent whose own create has not settled takes no child create. */\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n intent: ContainerCreateIntentRecord;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}\n\nexport type ContainerMoveIntentSyncState = ContainerIntentSyncState;\n\nexport type ContainerMoveIntentSyncHost = Pick<\n RemoteContainerHydrationHost,\n \"persistContainerState\" | \"updateSnapshot\"\n>;\n\n/** Later passes for moves the server accepted but no pass settled. */\nexport interface AcceptedMoveRetry {\n /** The server holds the move: schedule a replay to settle it. */\n arm: (intentId: string) => void;\n /** A replay failed; continue an accepted move's retries, if it has some. */\n resume: (intentId: string) => void;\n}\n\nexport interface ContainerMoveIntentSyncInput {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n /** A folder whose create has not settled takes no structural writes. */\n isCreatePending: (containerId: string) => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n intent: ContainerMoveIntentRecord;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n acceptedMoveRetry: AcceptedMoveRetry;\n state: ContainerMoveIntentSyncState;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerDeleteResponse,\n ContainerWriterProjectionResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { createInitializedContainerMetadataDocument } from \"../../../data/containers/containerMetadataDocument\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport type { DocumentRecord } from \"../../../data/sqlite/documentPersistence\";\nimport type {\n createRemoteContainer,\n moveRemoteContainer,\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"../../containers\";\nimport type { createRemoteDocument } from \"../../documents\";\nimport type { CurrentPrincipalPolicyReader } from \"../../principals/currentPrincipalPolicyReader\";\nimport type { PrincipalPolicyHistoryReader } from \"../../principals/principalPolicyHistoryReader\";\nimport type {\n ContainerContentsPersistence,\n ContainerCreateIntentRecord,\n ContainerMoveIntentRecord,\n} from \"../containerPersistence\";\nimport type {\n ContainerState,\n RemoteContainer as HydratedRemoteContainer,\n RemoteContainerHydrationHost,\n} from \"../remoteHydration\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport type ContainerWorkflowApi = Parameters<\n typeof createRemoteContainer\n>[0][\"apiClient\"] &\n Parameters<typeof shareRemoteContainer>[0][\"apiClient\"] &\n Parameters<typeof shareRemoteContainerWithGroup>[0][\"apiClient\"] &\n Parameters<typeof moveRemoteContainer>[0][\"apiClient\"] &\n Parameters<typeof createRemoteDocument>[0][\"apiClient\"] &\n Partial<PrincipalPolicyHistoryReader> &\n CurrentPrincipalPolicyReader & {\n deleteContainerResult(\n containerId: string,\n options?: {\n expectedPaymentRequiredOrganizationId?: string;\n reportErrors?: boolean;\n requiredAncestorId?: string | undefined;\n },\n ): Promise<\n | { data: ContainerDeleteResponse; ok: true }\n | {\n ok: false;\n report: () => void;\n status: number | null;\n }\n >;\n primeContainerWriterProjection(\n containerId: string,\n projection: ContainerWriterProjectionResponse,\n ): void;\n };\n\nexport interface ContainerWorkflowRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n readonly apiClient: ContainerWorkflowApi;\n}\n\nexport interface CreatedRemoteContainerState {\n accessManifestHash: string;\n /**\n * The metadata seed the create committed, settled by the caller instead of\n * a first metadata sync. Absent when the create carried no seed or fell back\n * to a plain create.\n */\n metadataSeed?:\n | { readonly commitLsn: string | null; readonly updateId: string }\n | undefined;\n /** The slot this client signed into the create; never the server's echo. */\n systemSlot: ContainerSystemSlot | null;\n containerId: string;\n createdAt: string;\n metadataDocumentId: string;\n organizationId: string;\n /** A created container is a child; the acknowledgement echoed this parent. */\n parentId: string;\n persistedMetadataState: Pick<\n DocumentRecord,\n | \"documentId\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\"\n >;\n updatedAt: string;\n}\n\nexport interface SharedRemoteContainerState {\n accessEpoch: number;\n accessManifestHash: string;\n createdAt: string;\n metadataDocumentId: string;\n referencedPrincipalHeads: ReferencedPrincipalStateResponse[];\n updatedAt: string;\n writerProjection: ContainerWriterProjectionResponse | null;\n}\n\nexport interface SharedContainerState {\n container: ContainerState[\"container\"];\n record: ContainerState[\"record\"];\n}\n\nexport type SharedContainerStateResult =\n | { status: \"missing\" }\n | { status: \"confirmed\" }\n | (SharedContainerState & {\n status: \"identity-superseded\" | \"persisted\";\n });\n\nexport type RemoteContainer = HydratedRemoteContainer;\n\nexport type ContainerMetadataDocumentState = Awaited<\n ReturnType<typeof createInitializedContainerMetadataDocument>\n>[\"doc\"];\n\nexport interface CreatedChildContainerState {\n containerState: ContainerState;\n initialUpdate: Uint8Array;\n shouldRequestSync: boolean;\n}\n\nexport interface ContainerIntentSyncState {\n containersById: ReadonlyMap<string, ContainerState>;\n /**\n * Metadata update ids this device sent, so their own update echoes are\n * classified as self-authored (shared with the metadata sync).\n */\n locallyAcceptedMetadataUpdateIds?: Set<string> | undefined;\n /** Metadata document ids of folder creates in flight (shared with hints). */\n plannedMetadataDocumentIds?: Set<string> | undefined;\n persistence: ContainerContentsPersistence;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n /**\n * Verifies that a listed container is this device's pending create before it\n * is adopted and returns where it sits; `assertContainerCreateAdoptable`\n * unless a test replaces it.\n */\n verifyCreateAdoption?: (input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n }) => Promise<AdoptedContainerPlacement>;\n}\n\n/** Where a verified listed create committed, and where its container is now. */\nexport interface AdoptedContainerPlacement {\n /** The parent its signed epoch-1 `container.create` named. */\n readonly createdParentId: string;\n /** The verified head's parent; another writer may have moved it since. */\n readonly currentParentId: string;\n}\n\nexport type ContainerCreateIntentSyncState = ContainerIntentSyncState;\n\nexport type ContainerCreateIntentSyncHost = Pick<\n RemoteContainerHydrationHost,\n \"persistContainerState\"\n>;\n\nexport interface ContainerCreateIntentSyncInput {\n host: ContainerCreateIntentSyncHost;\n /** A parent whose own create has not settled takes no child create. */\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n intent: ContainerCreateIntentRecord;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}\n\nexport type ContainerMoveIntentSyncState = ContainerIntentSyncState;\n\nexport type ContainerMoveIntentSyncHost = Pick<\n RemoteContainerHydrationHost,\n \"persistContainerState\" | \"updateSnapshot\"\n>;\n\n/** Later passes for moves the server accepted but no pass settled. */\nexport interface AcceptedMoveRetry {\n /** The server holds the move: schedule a replay to settle it. */\n arm: (intentId: string) => void;\n /** A replay failed; continue an accepted move's retries, if it has some. */\n resume: (intentId: string) => void;\n}\n\nexport interface ContainerMoveIntentSyncInput {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n /** A folder whose create has not settled takes no structural writes. */\n isCreatePending: (containerId: string) => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n intent: ContainerMoveIntentRecord;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n acceptedMoveRetry: AcceptedMoveRetry;\n state: ContainerMoveIntentSyncState;\n}\n"]}
|
|
@@ -2,6 +2,12 @@ import type { DocumentRecord } from "../../../data/sqlite/documentPersistence/in
|
|
|
2
2
|
export declare function hasContainerMetadataDocumentUpdateEvent(events: ReadonlyArray<unknown>, metadataStates: Iterable<{
|
|
3
3
|
record: Pick<DocumentRecord, "documentId">;
|
|
4
4
|
}>, locallyAcceptedUpdateIds?: Set<string>): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* `plannedDocumentIds` names the metadata documents of folders whose create is
|
|
7
|
+
* in flight. A peer can edit one after the create commits but before the
|
|
8
|
+
* response installs its id, and a committed seed stands in for the folder's
|
|
9
|
+
* first metadata sync, so that hint must still queue a read.
|
|
10
|
+
*/
|
|
5
11
|
export declare function listContainerMetadataDocumentUpdateIds(events: ReadonlyArray<unknown>, metadataStates: Iterable<{
|
|
6
12
|
record: Pick<DocumentRecord, "documentId">;
|
|
7
|
-
}>, locallyAcceptedUpdateIds?: Set<string>): string[];
|
|
13
|
+
}>, locallyAcceptedUpdateIds?: Set<string>, plannedDocumentIds?: Iterable<string>): string[];
|
|
@@ -22,8 +22,14 @@ function metadataEventHasRemoteUpdate(event, locallyAcceptedUpdateIds) {
|
|
|
22
22
|
}
|
|
23
23
|
return remoteUpdateFound;
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* `plannedDocumentIds` names the metadata documents of folders whose create is
|
|
27
|
+
* in flight. A peer can edit one after the create commits but before the
|
|
28
|
+
* response installs its id, and a committed seed stands in for the folder's
|
|
29
|
+
* first metadata sync, so that hint must still queue a read.
|
|
30
|
+
*/
|
|
31
|
+
export function listContainerMetadataDocumentUpdateIds(events, metadataStates, locallyAcceptedUpdateIds, plannedDocumentIds) {
|
|
32
|
+
const metadataDocumentIds = new Set(plannedDocumentIds);
|
|
27
33
|
for (const metadataState of metadataStates) {
|
|
28
34
|
if (typeof metadataState.record.documentId === "string") {
|
|
29
35
|
metadataDocumentIds.add(metadataState.record.documentId);
|