@tearleads/client-sdk 0.1.86 → 0.1.88
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/Tearleads.js +1 -1
- package/Tearleads.js.map +1 -1
- package/client/containerContents/documentDiscovery.js +16 -2
- package/client/containerContents/documentDiscovery.js.map +1 -1
- package/client/containerContents/index.d.ts +1 -1
- package/client/containerContents/index.js +1 -0
- package/client/containerContents/index.js.map +1 -1
- package/client/index.d.ts +1 -1
- package/client/index.js.map +1 -1
- package/client/organizations/index.d.ts +4 -2
- package/client/organizations/index.js +6 -3
- package/client/organizations/index.js.map +1 -1
- package/client/organizations/organizationMemberships.d.ts +30 -0
- package/client/organizations/organizationMemberships.js +132 -0
- package/client/organizations/organizationMemberships.js.map +1 -0
- package/client/organizations/organizationsTypes.d.ts +3 -0
- package/client/organizations/organizationsTypes.js.map +1 -1
- package/data/persistence/container-contents/containerStructuralRepair.js +19 -14
- package/data/persistence/container-contents/containerStructuralRepair.js.map +1 -1
- package/data/persistence/container-contents/exclusiveDocumentPlacements.js +60 -0
- package/data/persistence/container-contents/exclusiveDocumentPlacements.js.map +1 -0
- package/data/sqlite/schema/index.d.ts +71 -0
- package/data/sqlite/schema/index.js +3 -0
- package/data/sqlite/schema/index.js.map +1 -1
- package/data/sqlite/schema/organizationSyncPauseSchema.js +32 -0
- package/data/sqlite/schema/organizationSyncPauseSchema.js.map +1 -0
- package/data/sync/organizationSyncPauses.d.ts +59 -0
- package/data/sync/organizationSyncPauses.js +149 -0
- package/data/sync/organizationSyncPauses.js.map +1 -0
- package/index.d.ts +2 -2
- package/index.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +11 -2
- package/internal/api-client/ApiClient.js +9 -1
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/routes/organizations/memberships.js +17 -0
- package/internal/api-client/routes/organizations/memberships.js.map +1 -0
- package/internal/validators/operation/index.d.ts +1 -0
- package/internal/validators/operation/index.js +1 -0
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/organizationMemberships.d.ts +240 -0
- package/internal/validators/operation/organizationMemberships.js +51 -0
- package/internal/validators/operation/organizationMemberships.js.map +1 -0
- package/internal/validators/operation/registry.d.ts +3 -0
- package/internal/validators/operation/registry.js +3 -0
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/realtime/index.js +1 -1
- package/internal/validators/realtime/index.js.map +1 -1
- package/internal/validators/realtime/wsInvalidationHints.js +8 -0
- package/internal/validators/realtime/wsInvalidationHints.js.map +1 -1
- package/internal/validators/request/index.d.ts +1 -1
- package/internal/validators/request/index.js +1 -1
- package/internal/validators/request/index.js.map +1 -1
- package/internal/validators/request/organization.d.ts +6 -0
- package/internal/validators/request/organization.js +7 -0
- package/internal/validators/request/organization.js.map +1 -1
- package/internal/validators/response/index.d.ts +1 -0
- package/internal/validators/response/index.js +1 -0
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationMembership.d.ts +56 -0
- package/internal/validators/response/organizationMembership.js +26 -0
- package/internal/validators/response/organizationMembership.js.map +1 -0
- package/package.json +1 -1
- package/stores/container-contents/containerContentsStore.d.ts +1 -1
- package/stores/container-contents/containerContentsStore.js +2 -0
- package/stores/container-contents/containerContentsStore.js.map +1 -1
- package/stores/container-contents/operations/forgetOrganizationContentOperation.js +76 -0
- package/stores/container-contents/operations/forgetOrganizationContentOperation.js.map +1 -0
- package/stores/container-contents/types.d.ts +6 -0
- package/stores/container-contents/types.js.map +1 -1
- package/stores/documents/documentStore/attachments/attachmentRemoval.js +3 -4
- package/stores/documents/documentStore/attachments/attachmentRemoval.js.map +1 -1
- package/stores/documents/documentStore/attachments/index.js +5 -7
- package/stores/documents/documentStore/attachments/index.js.map +1 -1
- package/stores/documents/documentStore/index.js +16 -12
- package/stores/documents/documentStore/index.js.map +1 -1
- package/stores/documents/documentStore/initialization/index.js +9 -0
- package/stores/documents/documentStore/initialization/index.js.map +1 -1
- package/stores/documents/documentStore/mutations.js +5 -7
- package/stores/documents/documentStore/mutations.js.map +1 -1
- package/stores/documents/documentStore/rotation/index.js +2 -1
- package/stores/documents/documentStore/rotation/index.js.map +1 -1
- package/stores/documents/documentStore/rows/index.js +3 -4
- package/stores/documents/documentStore/rows/index.js.map +1 -1
- package/stores/documents/documentStore/state.js +18 -0
- package/stores/documents/documentStore/state.js.map +1 -1
- package/stores/documents/documentStore/sync/index.js +5 -2
- package/stores/documents/documentStore/sync/index.js.map +1 -1
- package/stores/documents/registry.d.ts +32 -0
- package/stores/documents/registry.js +79 -4
- package/stores/documents/registry.js.map +1 -1
- package/stores/documents/removedDocumentStore.js +38 -0
- package/stores/documents/removedDocumentStore.js.map +1 -0
- package/stores/documents/types.d.ts +2 -0
- package/stores/documents/types.js.map +1 -1
- package/sync/reconciliation/service.js +2 -2
- package/sync/reconciliation/service.js.map +1 -1
- package/sync/reconciliation/serviceTypes.d.ts +8 -1
- package/sync/reconciliation/serviceTypes.js.map +1 -1
- package/workflows/container-contents/pendingWrites/index.d.ts +5 -0
- package/workflows/container-contents/pendingWrites/index.js +7 -0
- package/workflows/container-contents/pendingWrites/index.js.map +1 -1
- package/workflows/container-contents/remoteHydration/index.js +7 -1
- package/workflows/container-contents/remoteHydration/index.js.map +1 -1
- package/workflows/container-contents/remoteHydration/remoteContainers/organizationSyncPauseFilter.js +13 -0
- package/workflows/container-contents/remoteHydration/remoteContainers/organizationSyncPauseFilter.js.map +1 -0
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js +13 -2
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js.map +1 -1
- package/workflows/container-contents/syncPause/discoveryGuard.js +31 -0
- package/workflows/container-contents/syncPause/discoveryGuard.js.map +1 -0
- package/workflows/container-contents/syncPause/documentRemoval.js +154 -0
- package/workflows/container-contents/syncPause/documentRemoval.js.map +1 -0
- package/workflows/organizations/index.d.ts +1 -0
- package/workflows/organizations/index.js +1 -0
- package/workflows/organizations/index.js.map +1 -1
- package/workflows/organizations/memberships/organizationMemberships.d.ts +84 -0
- package/workflows/organizations/memberships/organizationMemberships.js +95 -0
- package/workflows/organizations/memberships/organizationMemberships.js.map +1 -0
- package/workflows/organizations/readModel/listLocalOrganizations.d.ts +14 -7
- package/workflows/organizations/readModel/listLocalOrganizations.js +58 -38
- package/workflows/organizations/readModel/listLocalOrganizations.js.map +1 -1
- package/workflows/sync/index.d.ts +1 -0
- package/workflows/sync/index.js +1 -0
- package/workflows/sync/index.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport {\n emptyVersionVector,\n encodeVersionVector,\n exportAllUpdates,\n exportFullHistorySnapshot,\n mergeVersionVectors,\n} from \"@tearleads/loro\";\nimport {\n DEFAULT_DOCUMENT_ACCESS_EPOCH,\n DEFAULT_DOCUMENT_KIND,\n} from \"../../../../data/documents/documentConstants\";\nimport {\n initializeStoredDocumentKind,\n readStoredDocumentState,\n} from \"../../../../data/documents/documentKinds\";\nimport type { DocumentSummary } from \"../../../../data/documents/documentSummary\";\nimport { createPendingUpdateFields } from \"../../../../data/documents/documentSync\";\nimport {\n type DocumentRecord,\n isDatabaseUnavailableError,\n loadPersistedDocumentStoreState,\n} from \"../../../../workflows/documents\";\nimport type { DocumentStoreRelinkInput } from \"../../types\";\nimport { chainIdentityWrite } from \"../identityWriteChain\";\nimport type { DocumentRelinkCommitSideEffect } from \"../internalRelink\";\nimport { runDocumentOrphanMaintenance } from \"../orphanMaintenance\";\nimport {\n advancePendingBaseVersion,\n documentSummaryFromRecord,\n persistDocument,\n saveDocumentRecord,\n} from \"../persistence\";\nimport {\n type DocumentState,\n type DocumentStoreState,\n setReadySnapshot,\n} from \"../state\";\nimport { createStoredDocument } from \"../storedDocument\";\nimport { logRevalidationScheduled } from \"../sync/remoteRevalidationTelemetry\";\nimport {\n allowDocumentStoreRemoteSync,\n captureDocumentStoreSyncGeneration,\n invalidateDocumentStoreRemoteSync,\n isDocumentStoreSyncGenerationCurrent,\n markDocumentStoreRemoteSyncPending,\n} from \"../sync/syncGeneration\";\nimport { writeInitialDocumentContent } from \"./initialContent\";\nimport {\n installPersistedAttachments,\n type LoadedDocumentStoreState,\n} from \"./initializationAttachments\";\nimport {\n type RestoredHistoryState,\n restoredRemoteTailCoverage,\n restorePersistedDocumentContent,\n} from \"./initializationHistory\";\nimport {\n healLocalAttachmentDetachState,\n recoverDroppedAttachmentSlots,\n} from \"./initializationRecovery\";\n\nasync function createInitialDocumentRecord(\n state: DocumentStoreState,\n nextDoc: DocumentState,\n): ReturnType<typeof saveDocumentRecord> {\n initializeStoredDocumentKind(\n nextDoc,\n state.initialDocumentKind,\n state.runtime.infra.documentProjectors,\n );\n if (state.initialText.length > 0) {\n nextDoc.getText(\"text\").update(state.initialText);\n }\n const wroteInitialContent = writeInitialDocumentContent(state, nextDoc);\n const initialDocumentState = readStoredDocumentState(\n nextDoc,\n state.runtime.infra.documentProjectors,\n );\n const hasInitialContent =\n wroteInitialContent ||\n state.initialText.length > 0 ||\n state.initialDocumentKind !== DEFAULT_DOCUMENT_KIND;\n const initialUpdate = hasInitialContent\n ? createPendingUpdateFields(exportAllUpdates(nextDoc))\n : null;\n // A deferred birth still commits its checkpoint, but leaves the marker at the\n // empty version with nothing queued: the promised attach exports every op\n // since that marker, so one update carries the birth and the attachment.\n const birthDurability = !initialUpdate\n ? {}\n : state.deferInitialUpdate\n ? { pendingBaseVersionOverride: emptyVersionVector() }\n : { pendingUpdate: initialUpdate };\n\n const created: DocumentRecord = {\n id: state.localId,\n containerId: state.runtime.state.containerId ?? null,\n documentId: state.initialDocumentId,\n documentKind: initialDocumentState.documentKind,\n text: initialDocumentState.text,\n title: initialDocumentState.title,\n snapshotEndVersion: encodeVersionVector(nextDoc),\n accessEpoch: DEFAULT_DOCUMENT_ACCESS_EPOCH,\n accessStateHash: null,\n effectiveAccessLevel: \"admin\",\n lastCommitLsn: null,\n contentKeyBundle: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n };\n // The create-only persistence primitive commits the canonical row and birth\n // checkpoint together. A concurrent initializer either wins both or adopts\n // both, so it cannot replace another pane's history or keying state.\n const persisted = await saveDocumentRecord(\n state,\n nextDoc,\n {\n ...created,\n snapshotEndVersion: encodeVersionVector(nextDoc),\n },\n {\n historyCheckpoint: {\n coveredTailIds: [],\n endVersionVector: encodeVersionVector(nextDoc),\n pruneCoveredLocalState: false,\n snapshot: bytesToBase64(exportFullHistorySnapshot(nextDoc)),\n },\n ...birthDurability,\n },\n );\n return persisted;\n}\n\nfunction installPersistedDocumentRecord(\n state: DocumentStoreState,\n record: NonNullable<DocumentStoreState[\"record\"]>,\n): void {\n state.record = record;\n state.pullContinuation = record.pullContinuation ?? null;\n}\n\ninterface RestoredInitialDocumentState {\n activePersistedState: LoadedDocumentStoreState;\n activeRecord: NonNullable<DocumentStoreState[\"record\"]>;\n doc: DocumentState;\n history: RestoredHistoryState | null;\n}\n\nasync function restoreLoadedInitialDocument(input: {\n initializeGeneration: number;\n nextDoc: DocumentState;\n persistedState: LoadedDocumentStoreState;\n state: DocumentStoreState;\n}): Promise<RestoredInitialDocumentState | null> {\n const { initializeGeneration, persistedState, state } = input;\n const record = persistedState.document;\n if (!record) return null;\n const history = await restorePersistedDocumentContent(\n input.nextDoc,\n persistedState.historyRestoreState,\n );\n if (state.localWriteGeneration !== initializeGeneration) return null;\n installPersistedDocumentRecord(state, record);\n return {\n activePersistedState: persistedState,\n activeRecord: record,\n doc: input.nextDoc,\n history,\n };\n}\n\nasync function restoreOrCreateInitialDocument(input: {\n initializeGeneration: number;\n nextDoc: DocumentState;\n persistedState: LoadedDocumentStoreState;\n state: DocumentStoreState;\n}): Promise<RestoredInitialDocumentState | null> {\n const { initializeGeneration, persistedState, state } = input;\n if (persistedState.document) {\n return restoreLoadedInitialDocument(input);\n }\n\n const created = await createInitialDocumentRecord(state, input.nextDoc);\n if (!created || state.localWriteGeneration !== initializeGeneration) {\n return null;\n }\n const activePersistedState = await loadPersistedDocumentStoreState({\n execSql: state.runtime.infra.execSql,\n localId: state.localId,\n persistence: state.persistence,\n });\n if (state.localWriteGeneration !== initializeGeneration) {\n return null;\n }\n if (!activePersistedState.document) {\n throw new Error(\"Document creation completed without a durable record\");\n }\n const replacementDoc = await createStoredDocument(state);\n return restoreLoadedInitialDocument({\n initializeGeneration,\n nextDoc: replacementDoc,\n persistedState: activePersistedState,\n state,\n });\n}\n\nfunction restorePendingBaseVersion(input: {\n activeRecord: NonNullable<DocumentStoreState[\"record\"]>;\n doc: DocumentState;\n history: RestoredHistoryState | null;\n state: DocumentStoreState;\n}): void {\n const { activeRecord, doc, history, state } = input;\n const markerBase =\n activeRecord.pendingBaseVersion ??\n (activeRecord.snapshotEndVersion.length > 0\n ? activeRecord.snapshotEndVersion\n : null);\n if (markerBase === null) {\n advancePendingBaseVersion(state, doc);\n return;\n }\n\n const remoteCoverage = restoredRemoteTailCoverage(history);\n state.pendingBaseVersion =\n remoteCoverage.length > 0\n ? mergeVersionVectors([markerBase, ...remoteCoverage])\n : markerBase;\n}\n\nasync function initializeDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n) {\n if (state.runtime.infra.dbStatus !== \"ready\") {\n return;\n }\n\n // A store reset while this fire-and-forget initialization is loading (a\n // runtime swap, or a local-edits discard that re-seeds the persisted rows)\n // must win: assigning the state loaded BEFORE the reset would bring the\n // replaced record and doc back to life. Every reset bumps the local write\n // generation, so a stale capture here aborts before each assignment batch.\n const initializeGeneration = state.localWriteGeneration;\n\n const nextDoc = await createStoredDocument(state);\n const persistedState = await loadPersistedDocumentStoreState({\n execSql: state.runtime.infra.execSql,\n localId: state.localId,\n persistence: state.persistence,\n });\n if (state.localWriteGeneration !== initializeGeneration) {\n return;\n }\n const restored = await restoreOrCreateInitialDocument({\n initializeGeneration,\n nextDoc,\n persistedState,\n state,\n });\n if (!restored) {\n return;\n }\n const activePersistedState = restored.activePersistedState;\n installPersistedAttachments(state, activePersistedState);\n\n state.doc = restored.doc;\n // Restore the durable outgoing-delta marker. Re-seeding it to the restored\n // document's version would move it PAST any device-first `deferRemoteSync`\n // op (persisted into the durable history but deliberately left un-enqueued\n // and behind the marker), permanently dropping that op from sync across a\n // restart. When a marker was persisted, restore it so the next edit still\n // re-derives the deferred delta. Only seed for rows that never persisted\n // one, from the RECORD's persisted frontier rather than the restored\n // document: a crash between the tail append and the queue/marker writes can\n // resurrect ops the outgoing queue never durably received, and seeding from\n // the restored document would classify those as covered and orphan them\n // from sync forever.\n restorePendingBaseVersion({\n activeRecord: restored.activeRecord,\n doc: restored.doc,\n history: restored.history,\n state,\n });\n // Heal attachment slots lost to an interrupted attach write before marking\n // ready, so the recovered slots are in the snapshot the editor first renders\n // and are queued for sync. recoverDroppedAttachmentSlots advances the marker\n // again for whatever it re-derives. Both helpers gate every durable write\n // on this generation (validated inside the writes' serialized mutations),\n // so a reset mid-helper cannot repopulate discarded state.\n const writeGeneration = captureDocumentStoreSyncGeneration(\n state,\n restored.doc,\n );\n if (!writeGeneration) {\n return;\n }\n await recoverDroppedAttachmentSlots(state, restored.doc, writeGeneration);\n if (state.localWriteGeneration !== initializeGeneration) {\n return;\n }\n await healLocalAttachmentDetachState(\n state,\n restored.doc,\n activePersistedState,\n writeGeneration,\n );\n if (state.localWriteGeneration !== initializeGeneration) {\n return;\n }\n state.initialized = true;\n state.initializePromise = null;\n setReadySnapshot(state, restored.doc, false);\n\n if (restored.activeRecord.documentId && state.scheduleStartupRemoteSync) {\n // Websocket invalidations are intentionally session-local. A process can\n // stop before receiving a peer device's update event, and no event survives\n // the restart to distinguish a clean local snapshot from a stale one. Probe\n // each opened remote document once after loading it; unopened documents stay\n // lazy, while body and attachment state for a restored window converges.\n allowDocumentStoreRemoteSync(state);\n markDocumentStoreRemoteSyncPending(state, \"independent\");\n logRevalidationScheduled(state.runtime, \"startup\");\n }\n scheduleSync();\n void runDocumentOrphanMaintenance(state);\n}\n\nexport function ensureDocumentStoreInitialized(\n state: DocumentStoreState,\n scheduleSync: () => void,\n) {\n if (\n state.initialized ||\n state.initializePromise ||\n state.runtime.infra.dbStatus !== \"ready\"\n ) {\n return;\n }\n\n const initializePromise = initializeDocumentStore(state, scheduleSync).catch(\n (error: unknown) => {\n state.initializePromise = null;\n // A caller that deferred the birth for its attach may give up once\n // opening fails; never leave its durable birth holding sync. No attach\n // has reached a live doc yet, so lifting the hold ships nothing unsafe.\n state.deferInitialUpdate = false;\n\n if (isDatabaseUnavailableError(error)) {\n return;\n }\n\n throw error;\n },\n );\n state.initializePromise = initializePromise;\n void initializePromise.catch(() => undefined);\n}\n\nexport async function awaitInitializationForSync(state: DocumentStoreState) {\n if (!state.initializePromise) {\n return true;\n }\n\n try {\n await state.initializePromise;\n return true;\n } catch (error) {\n if (isDatabaseUnavailableError(error)) {\n return false;\n }\n\n throw error;\n }\n}\n\nexport async function ensureDocumentStoreReady(\n state: DocumentStoreState,\n scheduleSync: () => void,\n): Promise<boolean> {\n ensureDocumentStoreInitialized(state, scheduleSync);\n\n if (state.initialized) {\n return true;\n }\n\n if (!state.initializePromise) {\n return false;\n }\n\n return awaitInitializationForSync(state);\n}\n\nexport async function relinkDocumentStore(\n state: DocumentStoreState,\n input: DocumentStoreRelinkInput,\n scheduleSync: () => void,\n commitSideEffect?: DocumentRelinkCommitSideEffect,\n): Promise<DocumentSummary | null> {\n if (\n input.stillCurrent?.() === false ||\n !(await ensureDocumentStoreReady(state, scheduleSync)) ||\n input.stillCurrent?.() === false ||\n !state.doc\n ) {\n return null;\n }\n const currentDoc = state.doc;\n const generation = captureDocumentStoreSyncGeneration(state, currentDoc);\n if (!generation) return null;\n // Read the record and persist on the identity-write chain so an in-flight\n // eager create cannot interleave: a create that captured a null identity\n // before its network round trip would otherwise write the derived documentId\n // over the one this relink assigns.\n const persisted = await chainIdentityWrite(state, async () => {\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) return null;\n const currentDocumentId = state.record?.documentId ?? null;\n const currentAccessEpoch =\n state.record?.accessEpoch ?? DEFAULT_DOCUMENT_ACCESS_EPOCH;\n const patch: Partial<DocumentRecord> = {\n accessEpoch: Math.max(currentAccessEpoch, input.accessEpoch),\n accessStateHash:\n input.accessStateHash === undefined\n ? (state.record?.accessStateHash ?? null)\n : input.accessStateHash,\n containerId: input.containerId,\n documentId: input.documentId,\n };\n if (input.contentKeyBundle !== undefined) {\n patch.contentKeyBundle = input.contentKeyBundle;\n }\n if (input.documentKekTargets !== undefined) {\n patch.documentKekTargets = input.documentKekTargets;\n }\n if (input.documentManifestBundle !== undefined) {\n patch.documentManifestBundle = input.documentManifestBundle;\n }\n\n // Relink rewrites access/identity metadata, not content. If it lands while\n // the user is mid-edit, re-deriving text/structured fields from the\n // (possibly lagging) doc would republish a stale read over the live\n // optimistic snapshot and drop in-flight keystrokes; preserve the snapshot\n // like the keystroke and sync persists do.\n // A prior chained write may have cleared this store (resurrect-guard\n // refusal): persisting the captured doc against a null record would\n // resurrect the document as a create. The identity check runs inside\n // the chain, after every earlier write settled.\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n return null;\n }\n const result = await persistDocument(\n state,\n currentDoc,\n patch,\n {\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n stillCurrent: input.stillCurrent,\n },\n generation,\n commitSideEffect,\n );\n if (result && currentDocumentId !== input.documentId) {\n state.writerProjection = null;\n invalidateDocumentStoreRemoteSync(state);\n }\n return result;\n });\n // A refused persist means the durable row vanished mid-relink (resurrect\n // guard); there is no summary to report.\n if (!persisted) {\n return null;\n }\n if (persisted.updatedAt === undefined) {\n return null;\n }\n return documentSummaryFromRecord(\n persisted.record,\n persisted.updatedAt,\n state.runtime.infra.documentProjectors,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport {\n emptyVersionVector,\n encodeVersionVector,\n exportAllUpdates,\n exportFullHistorySnapshot,\n mergeVersionVectors,\n} from \"@tearleads/loro\";\nimport {\n DEFAULT_DOCUMENT_ACCESS_EPOCH,\n DEFAULT_DOCUMENT_KIND,\n} from \"../../../../data/documents/documentConstants\";\nimport {\n initializeStoredDocumentKind,\n readStoredDocumentState,\n} from \"../../../../data/documents/documentKinds\";\nimport type { DocumentSummary } from \"../../../../data/documents/documentSummary\";\nimport { createPendingUpdateFields } from \"../../../../data/documents/documentSync\";\nimport {\n type DocumentRecord,\n isDatabaseUnavailableError,\n loadPersistedDocumentStoreState,\n} from \"../../../../workflows/documents\";\nimport { isPauseRemovedDocument } from \"../../../../workflows/sync\";\nimport type { DocumentStoreRelinkInput } from \"../../types\";\nimport { chainIdentityWrite } from \"../identityWriteChain\";\nimport type { DocumentRelinkCommitSideEffect } from \"../internalRelink\";\nimport { runDocumentOrphanMaintenance } from \"../orphanMaintenance\";\nimport {\n advancePendingBaseVersion,\n documentSummaryFromRecord,\n persistDocument,\n saveDocumentRecord,\n} from \"../persistence\";\nimport {\n type DocumentState,\n type DocumentStoreState,\n setReadySnapshot,\n} from \"../state\";\nimport { createStoredDocument } from \"../storedDocument\";\nimport { logRevalidationScheduled } from \"../sync/remoteRevalidationTelemetry\";\nimport {\n allowDocumentStoreRemoteSync,\n captureDocumentStoreSyncGeneration,\n invalidateDocumentStoreRemoteSync,\n isDocumentStoreSyncGenerationCurrent,\n markDocumentStoreRemoteSyncPending,\n} from \"../sync/syncGeneration\";\nimport { writeInitialDocumentContent } from \"./initialContent\";\nimport {\n installPersistedAttachments,\n type LoadedDocumentStoreState,\n} from \"./initializationAttachments\";\nimport {\n type RestoredHistoryState,\n restoredRemoteTailCoverage,\n restorePersistedDocumentContent,\n} from \"./initializationHistory\";\nimport {\n healLocalAttachmentDetachState,\n recoverDroppedAttachmentSlots,\n} from \"./initializationRecovery\";\n\nasync function createInitialDocumentRecord(\n state: DocumentStoreState,\n nextDoc: DocumentState,\n): ReturnType<typeof saveDocumentRecord> {\n initializeStoredDocumentKind(\n nextDoc,\n state.initialDocumentKind,\n state.runtime.infra.documentProjectors,\n );\n if (state.initialText.length > 0) {\n nextDoc.getText(\"text\").update(state.initialText);\n }\n const wroteInitialContent = writeInitialDocumentContent(state, nextDoc);\n const initialDocumentState = readStoredDocumentState(\n nextDoc,\n state.runtime.infra.documentProjectors,\n );\n const hasInitialContent =\n wroteInitialContent ||\n state.initialText.length > 0 ||\n state.initialDocumentKind !== DEFAULT_DOCUMENT_KIND;\n const initialUpdate = hasInitialContent\n ? createPendingUpdateFields(exportAllUpdates(nextDoc))\n : null;\n // A deferred birth still commits its checkpoint, but leaves the marker at the\n // empty version with nothing queued: the promised attach exports every op\n // since that marker, so one update carries the birth and the attachment.\n const birthDurability = !initialUpdate\n ? {}\n : state.deferInitialUpdate\n ? { pendingBaseVersionOverride: emptyVersionVector() }\n : { pendingUpdate: initialUpdate };\n\n const created: DocumentRecord = {\n id: state.localId,\n containerId: state.runtime.state.containerId ?? null,\n documentId: state.initialDocumentId,\n documentKind: initialDocumentState.documentKind,\n text: initialDocumentState.text,\n title: initialDocumentState.title,\n snapshotEndVersion: encodeVersionVector(nextDoc),\n accessEpoch: DEFAULT_DOCUMENT_ACCESS_EPOCH,\n accessStateHash: null,\n effectiveAccessLevel: \"admin\",\n lastCommitLsn: null,\n contentKeyBundle: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n };\n // The create-only persistence primitive commits the canonical row and birth\n // checkpoint together. A concurrent initializer either wins both or adopts\n // both, so it cannot replace another pane's history or keying state.\n const persisted = await saveDocumentRecord(\n state,\n nextDoc,\n {\n ...created,\n snapshotEndVersion: encodeVersionVector(nextDoc),\n },\n {\n historyCheckpoint: {\n coveredTailIds: [],\n endVersionVector: encodeVersionVector(nextDoc),\n pruneCoveredLocalState: false,\n snapshot: bytesToBase64(exportFullHistorySnapshot(nextDoc)),\n },\n ...birthDurability,\n },\n );\n return persisted;\n}\n\nfunction installPersistedDocumentRecord(\n state: DocumentStoreState,\n record: NonNullable<DocumentStoreState[\"record\"]>,\n): void {\n state.record = record;\n state.pullContinuation = record.pullContinuation ?? null;\n}\n\ninterface RestoredInitialDocumentState {\n activePersistedState: LoadedDocumentStoreState;\n activeRecord: NonNullable<DocumentStoreState[\"record\"]>;\n doc: DocumentState;\n history: RestoredHistoryState | null;\n}\n\nasync function restoreLoadedInitialDocument(input: {\n initializeGeneration: number;\n nextDoc: DocumentState;\n persistedState: LoadedDocumentStoreState;\n state: DocumentStoreState;\n}): Promise<RestoredInitialDocumentState | null> {\n const { initializeGeneration, persistedState, state } = input;\n const record = persistedState.document;\n if (!record) return null;\n const history = await restorePersistedDocumentContent(\n input.nextDoc,\n persistedState.historyRestoreState,\n );\n if (state.localWriteGeneration !== initializeGeneration) return null;\n installPersistedDocumentRecord(state, record);\n return {\n activePersistedState: persistedState,\n activeRecord: record,\n doc: input.nextDoc,\n history,\n };\n}\n\nasync function restoreOrCreateInitialDocument(input: {\n initializeGeneration: number;\n nextDoc: DocumentState;\n persistedState: LoadedDocumentStoreState;\n state: DocumentStoreState;\n}): Promise<RestoredInitialDocumentState | null> {\n const { initializeGeneration, persistedState, state } = input;\n if (persistedState.document) {\n return restoreLoadedInitialDocument(input);\n }\n const created = await createInitialDocumentRecord(state, input.nextDoc);\n if (!created || state.localWriteGeneration !== initializeGeneration) {\n return null;\n }\n const activePersistedState = await loadPersistedDocumentStoreState({\n execSql: state.runtime.infra.execSql,\n localId: state.localId,\n persistence: state.persistence,\n });\n if (state.localWriteGeneration !== initializeGeneration) {\n return null;\n }\n if (!activePersistedState.document) {\n throw new Error(\"Document creation completed without a durable record\");\n }\n const replacementDoc = await createStoredDocument(state);\n return restoreLoadedInitialDocument({\n initializeGeneration,\n nextDoc: replacementDoc,\n persistedState: activePersistedState,\n state,\n });\n}\n\nfunction restorePendingBaseVersion(input: {\n activeRecord: NonNullable<DocumentStoreState[\"record\"]>;\n doc: DocumentState;\n history: RestoredHistoryState | null;\n state: DocumentStoreState;\n}): void {\n const { activeRecord, doc, history, state } = input;\n const markerBase =\n activeRecord.pendingBaseVersion ??\n (activeRecord.snapshotEndVersion.length > 0\n ? activeRecord.snapshotEndVersion\n : null);\n if (markerBase === null) {\n advancePendingBaseVersion(state, doc);\n return;\n }\n\n const remoteCoverage = restoredRemoteTailCoverage(history);\n state.pendingBaseVersion =\n remoteCoverage.length > 0\n ? mergeVersionVectors([markerBase, ...remoteCoverage])\n : markerBase;\n}\n\nasync function initializeDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n) {\n if (state.runtime.infra.dbStatus !== \"ready\") {\n return;\n }\n\n // A store reset while this fire-and-forget initialization is loading (a\n // runtime swap, or a local-edits discard that re-seeds the persisted rows)\n // must win: assigning the state loaded BEFORE the reset would bring the\n // replaced record and doc back to life. Every reset bumps the local write\n // generation, so a stale capture here aborts before each assignment batch.\n const initializeGeneration = state.localWriteGeneration;\n\n const nextDoc = await createStoredDocument(state);\n const persistedState = await loadPersistedDocumentStoreState({\n execSql: state.runtime.infra.execSql,\n localId: state.localId,\n persistence: state.persistence,\n });\n if (state.localWriteGeneration !== initializeGeneration) {\n return;\n }\n // A paused organization's cleanup removed it; creating it again would\n // download the organization's content while the pause lasts. A later open\n // retries, so it loads once the organization resumes.\n if (\n !persistedState.document &&\n (await isPauseRemovedDocument(state.runtime.infra.execSql, state.localId))\n ) {\n state.initializePromise = null;\n return;\n }\n const restored = await restoreOrCreateInitialDocument({\n initializeGeneration,\n nextDoc,\n persistedState,\n state,\n });\n if (!restored) {\n return;\n }\n const activePersistedState = restored.activePersistedState;\n installPersistedAttachments(state, activePersistedState);\n\n state.doc = restored.doc;\n // Restore the durable outgoing-delta marker. Re-seeding it to the restored\n // document's version would move it PAST any device-first `deferRemoteSync`\n // op (persisted into the durable history but deliberately left un-enqueued\n // and behind the marker), permanently dropping that op from sync across a\n // restart. When a marker was persisted, restore it so the next edit still\n // re-derives the deferred delta. Only seed for rows that never persisted\n // one, from the RECORD's persisted frontier rather than the restored\n // document: a crash between the tail append and the queue/marker writes can\n // resurrect ops the outgoing queue never durably received, and seeding from\n // the restored document would classify those as covered and orphan them\n // from sync forever.\n restorePendingBaseVersion({\n activeRecord: restored.activeRecord,\n doc: restored.doc,\n history: restored.history,\n state,\n });\n // Heal attachment slots lost to an interrupted attach write before marking\n // ready, so the recovered slots are in the snapshot the editor first renders\n // and are queued for sync. recoverDroppedAttachmentSlots advances the marker\n // again for whatever it re-derives. Both helpers gate every durable write\n // on this generation (validated inside the writes' serialized mutations),\n // so a reset mid-helper cannot repopulate discarded state.\n const writeGeneration = captureDocumentStoreSyncGeneration(\n state,\n restored.doc,\n );\n if (!writeGeneration) {\n return;\n }\n await recoverDroppedAttachmentSlots(state, restored.doc, writeGeneration);\n if (state.localWriteGeneration !== initializeGeneration) {\n return;\n }\n await healLocalAttachmentDetachState(\n state,\n restored.doc,\n activePersistedState,\n writeGeneration,\n );\n if (state.localWriteGeneration !== initializeGeneration) {\n return;\n }\n state.initialized = true;\n state.initializePromise = null;\n setReadySnapshot(state, restored.doc, false);\n\n if (restored.activeRecord.documentId && state.scheduleStartupRemoteSync) {\n // Websocket invalidations are intentionally session-local. A process can\n // stop before receiving a peer device's update event, and no event survives\n // the restart to distinguish a clean local snapshot from a stale one. Probe\n // each opened remote document once after loading it; unopened documents stay\n // lazy, while body and attachment state for a restored window converges.\n allowDocumentStoreRemoteSync(state);\n markDocumentStoreRemoteSyncPending(state, \"independent\");\n logRevalidationScheduled(state.runtime, \"startup\");\n }\n scheduleSync();\n void runDocumentOrphanMaintenance(state);\n}\n\nexport function ensureDocumentStoreInitialized(\n state: DocumentStoreState,\n scheduleSync: () => void,\n) {\n if (\n state.initialized ||\n state.initializePromise ||\n state.runtime.infra.dbStatus !== \"ready\"\n ) {\n return;\n }\n\n const initializePromise = initializeDocumentStore(state, scheduleSync).catch(\n (error: unknown) => {\n state.initializePromise = null;\n // A caller that deferred the birth for its attach may give up once\n // opening fails; never leave its durable birth holding sync. No attach\n // has reached a live doc yet, so lifting the hold ships nothing unsafe.\n state.deferInitialUpdate = false;\n\n if (isDatabaseUnavailableError(error)) {\n return;\n }\n\n throw error;\n },\n );\n state.initializePromise = initializePromise;\n void initializePromise.catch(() => undefined);\n}\n\nexport async function awaitInitializationForSync(state: DocumentStoreState) {\n if (!state.initializePromise) {\n return true;\n }\n\n try {\n await state.initializePromise;\n return true;\n } catch (error) {\n if (isDatabaseUnavailableError(error)) {\n return false;\n }\n\n throw error;\n }\n}\n\nexport async function ensureDocumentStoreReady(\n state: DocumentStoreState,\n scheduleSync: () => void,\n): Promise<boolean> {\n ensureDocumentStoreInitialized(state, scheduleSync);\n\n if (state.initialized) {\n return true;\n }\n\n if (!state.initializePromise) {\n return false;\n }\n\n return awaitInitializationForSync(state);\n}\n\nexport async function relinkDocumentStore(\n state: DocumentStoreState,\n input: DocumentStoreRelinkInput,\n scheduleSync: () => void,\n commitSideEffect?: DocumentRelinkCommitSideEffect,\n): Promise<DocumentSummary | null> {\n if (\n input.stillCurrent?.() === false ||\n !(await ensureDocumentStoreReady(state, scheduleSync)) ||\n input.stillCurrent?.() === false ||\n !state.doc\n ) {\n return null;\n }\n const currentDoc = state.doc;\n const generation = captureDocumentStoreSyncGeneration(state, currentDoc);\n if (!generation) return null;\n // Read the record and persist on the identity-write chain so an in-flight\n // eager create cannot interleave: a create that captured a null identity\n // before its network round trip would otherwise write the derived documentId\n // over the one this relink assigns.\n const persisted = await chainIdentityWrite(state, async () => {\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) return null;\n const currentDocumentId = state.record?.documentId ?? null;\n const currentAccessEpoch =\n state.record?.accessEpoch ?? DEFAULT_DOCUMENT_ACCESS_EPOCH;\n const patch: Partial<DocumentRecord> = {\n accessEpoch: Math.max(currentAccessEpoch, input.accessEpoch),\n accessStateHash:\n input.accessStateHash === undefined\n ? (state.record?.accessStateHash ?? null)\n : input.accessStateHash,\n containerId: input.containerId,\n documentId: input.documentId,\n };\n if (input.contentKeyBundle !== undefined) {\n patch.contentKeyBundle = input.contentKeyBundle;\n }\n if (input.documentKekTargets !== undefined) {\n patch.documentKekTargets = input.documentKekTargets;\n }\n if (input.documentManifestBundle !== undefined) {\n patch.documentManifestBundle = input.documentManifestBundle;\n }\n\n // Relink rewrites access/identity metadata, not content. If it lands while\n // the user is mid-edit, re-deriving text/structured fields from the\n // (possibly lagging) doc would republish a stale read over the live\n // optimistic snapshot and drop in-flight keystrokes; preserve the snapshot\n // like the keystroke and sync persists do.\n // A prior chained write may have cleared this store (resurrect-guard\n // refusal): persisting the captured doc against a null record would\n // resurrect the document as a create. The identity check runs inside\n // the chain, after every earlier write settled.\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n return null;\n }\n const result = await persistDocument(\n state,\n currentDoc,\n patch,\n {\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n stillCurrent: input.stillCurrent,\n },\n generation,\n commitSideEffect,\n );\n if (result && currentDocumentId !== input.documentId) {\n state.writerProjection = null;\n invalidateDocumentStoreRemoteSync(state);\n }\n return result;\n });\n // A refused persist means the durable row vanished mid-relink (resurrect\n // guard); there is no summary to report.\n if (!persisted) {\n return null;\n }\n if (persisted.updatedAt === undefined) {\n return null;\n }\n return documentSummaryFromRecord(\n persisted.record,\n persisted.updatedAt,\n state.runtime.infra.documentProjectors,\n );\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import { ensureDocumentStoreInitialized, ensureDocumentStoreReady, } from "./ini
|
|
|
7
7
|
import { revalidateDocumentMutationIdentity } from "./mutationIdentityRevalidation.js";
|
|
8
8
|
import { advancePendingBaseVersion, pendingDeltaSinceBase, persistDocument, } from "./persistence.js";
|
|
9
9
|
import { reportDocumentStoreWriteFailure } from "./reportWriteFailure.js";
|
|
10
|
-
import { canWriteDocument, setDocumentSnapshot, setReadySnapshot, } from "./state.js";
|
|
10
|
+
import { canWriteDocument, chainQueuedWrite, setDocumentSnapshot, setReadySnapshot, } from "./state.js";
|
|
11
11
|
import { captureDocumentStoreSyncGeneration } from "./sync/syncGeneration.js";
|
|
12
12
|
// Fixed literals: a reported message must never carry document text or ids.
|
|
13
13
|
const TEXT_FAILURE_MESSAGE = "Documents: local text persist failed";
|
|
@@ -61,7 +61,7 @@ function queueDocumentTextWrite(state, value) {
|
|
|
61
61
|
// pass that runs during this burst sees pendingLocalWrites > 0 and preserves
|
|
62
62
|
// the optimistic snapshot instead of regressing it to a stale doc read.
|
|
63
63
|
state.pendingLocalWrites += 1;
|
|
64
|
-
state
|
|
64
|
+
return chainQueuedWrite(state, state.writeChain
|
|
65
65
|
.catch(() => undefined)
|
|
66
66
|
.then(async () => {
|
|
67
67
|
if (state.localWriteGeneration !== writeGeneration ||
|
|
@@ -110,8 +110,7 @@ function queueDocumentTextWrite(state, value) {
|
|
|
110
110
|
// keeps a reset write from decrementing a replacement generation.
|
|
111
111
|
.finally(() => {
|
|
112
112
|
settleDocumentLocalWrite(state, writeGeneration);
|
|
113
|
-
});
|
|
114
|
-
return state.writeChain;
|
|
113
|
+
}));
|
|
115
114
|
}
|
|
116
115
|
function publishDocumentStructuredFieldSnapshot(state, kind, patch) {
|
|
117
116
|
const nextStructuredFields = {
|
|
@@ -150,7 +149,7 @@ function queueDocumentStructuredFieldWrite(state, kind, patch, options = {}) {
|
|
|
150
149
|
// See queueDocumentTextWrite: gate sync-lane text/field republish on the same
|
|
151
150
|
// in-flight-write counter so structured edits get the identical protection.
|
|
152
151
|
state.pendingLocalWrites += 1;
|
|
153
|
-
state
|
|
152
|
+
return chainQueuedWrite(state, state.writeChain
|
|
154
153
|
.catch(() => undefined)
|
|
155
154
|
.then(async () => {
|
|
156
155
|
if (state.localWriteGeneration !== writeGeneration ||
|
|
@@ -214,8 +213,7 @@ function queueDocumentStructuredFieldWrite(state, kind, patch, options = {}) {
|
|
|
214
213
|
// republishes any remote content that was held during the optimistic burst.
|
|
215
214
|
.finally(() => {
|
|
216
215
|
settleDocumentLocalWrite(state, writeGeneration);
|
|
217
|
-
});
|
|
218
|
-
return state.writeChain;
|
|
216
|
+
}));
|
|
219
217
|
}
|
|
220
218
|
export function setDocumentText(state, scheduleSync, value) {
|
|
221
219
|
ensureDocumentStoreInitialized(state, scheduleSync);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutations.js","sourceRoot":"","sources":["mutations.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { encodeVersionVector, getTextValue } from \"@tearleads/loro\";\nimport {\n projectStoredDocumentState,\n type StoredDocumentKind,\n writeStoredDocumentFields,\n} from \"../../../data/documents/documentKinds\";\nimport { createPendingUpdateFields } from \"../../../data/documents/documentSync\";\nimport { requestDocumentStoreSync } from \"../registry\";\nimport type {\n DocumentMutationOptions,\n DocumentStructuredFieldPatch,\n} from \"../types\";\nimport {\n ensureDocumentStoreInitialized,\n ensureDocumentStoreReady,\n} from \"./initialization\";\nimport { revalidateDocumentMutationIdentity } from \"./mutationIdentityRevalidation\";\nimport {\n advancePendingBaseVersion,\n pendingDeltaSinceBase,\n persistDocument,\n} from \"./persistence\";\nimport { reportDocumentStoreWriteFailure } from \"./reportWriteFailure\";\nimport {\n canWriteDocument,\n type DocumentState,\n type DocumentStoreState,\n type SaveDocumentRecordOptions,\n setDocumentSnapshot,\n setReadySnapshot,\n} from \"./state\";\nimport { captureDocumentStoreSyncGeneration } from \"./sync/syncGeneration\";\n\n// Fixed literals: a reported message must never carry document text or ids.\nconst TEXT_FAILURE_MESSAGE = \"Documents: local text persist failed\";\nconst FIELD_FAILURE_MESSAGE = \"Documents: local field persist failed\";\n\nfunction structuredMutationDurabilityOptions(\n options: DocumentMutationOptions,\n update: Uint8Array,\n): Pick<SaveDocumentRecordOptions, \"historyUpdates\" | \"pendingUpdate\"> | null {\n if (options.deferRemoteSync) {\n return { historyUpdates: [bytesToBase64(update)] };\n }\n const pendingUpdate = createPendingUpdateFields(update);\n return pendingUpdate ? { pendingUpdate } : null;\n}\n\nfunction isDocumentLocalWriteCurrent(\n state: DocumentStoreState,\n writeGeneration: number,\n writeDoc: DocumentState,\n): boolean {\n return (\n state.localWriteGeneration === writeGeneration && state.doc === writeDoc\n );\n}\n\nfunction settleDocumentLocalWrite(\n state: DocumentStoreState,\n writeGeneration: number,\n): void {\n // Reset/reinitialization owns the new generation's counter. A write queued\n // against the prior document must touch neither it nor the replacement doc.\n if (state.localWriteGeneration !== writeGeneration) {\n return;\n }\n\n state.pendingLocalWrites = Math.max(0, state.pendingLocalWrites - 1);\n if (state.pendingLocalWrites !== 0 || !state.doc) {\n return;\n }\n\n // A sync pass or rotation may merge remote content while preserving the\n // controlled editor value. Publish the authoritative doc once typing drains;\n // setReadySnapshot is a no-op when the optimistic projection already matches.\n setReadySnapshot(state, state.doc, state.snapshot.syncing);\n}\n\nfunction publishDocumentTextSnapshot(\n state: DocumentStoreState,\n value: string,\n): void {\n setDocumentSnapshot(state, {\n ...state.snapshot,\n text: value,\n title: projectStoredDocumentState(\n {\n documentKind: state.snapshot.documentKind,\n structuredFields: state.snapshot.structuredFields,\n text: value,\n rows: state.snapshot.rows.map((row) => ({\n id: row.id,\n fields: row.fields,\n })),\n },\n state.runtime.infra.documentProjectors,\n ).title,\n });\n}\n\nfunction queueDocumentTextWrite(\n state: DocumentStoreState,\n value: string,\n): Promise<void> {\n if (!state.doc) {\n return Promise.resolve();\n }\n const writeGeneration = state.localWriteGeneration;\n\n // Mark a local edit as in flight SYNCHRONOUSLY, before chaining, so a sync\n // pass that runs during this burst sees pendingLocalWrites > 0 and preserves\n // the optimistic snapshot instead of regressing it to a stale doc read.\n state.pendingLocalWrites += 1;\n state.writeChain = state.writeChain\n .catch(() => undefined)\n .then(async () => {\n if (\n state.localWriteGeneration !== writeGeneration ||\n !state.doc ||\n !canWriteDocument(state)\n ) {\n return;\n }\n const writeDoc = state.doc;\n const syncGeneration = captureDocumentStoreSyncGeneration(\n state,\n writeDoc,\n );\n if (!syncGeneration) {\n return;\n }\n\n if (getTextValue(writeDoc) === value) {\n await revalidateDocumentMutationIdentity({\n currentDoc: writeDoc,\n generation: syncGeneration,\n state,\n });\n return;\n }\n\n writeDoc.getText(\"text\").update(value);\n const update = pendingDeltaSinceBase(state, writeDoc);\n // Captured at delta time: the enqueued row proves durable coverage up\n // to exactly this version, so this is the frontier the persist may\n // publish (a raced later edit publishes its own on its own persist).\n const coveredVersion = encodeVersionVector(writeDoc);\n const pendingUpdate = createPendingUpdateFields(update);\n if (!pendingUpdate) {\n return;\n }\n const persisted = await persistDocument(\n state,\n writeDoc,\n { snapshotEndVersion: coveredVersion },\n { pendingUpdate, preserveSnapshotText: true },\n syncGeneration,\n );\n if (\n !persisted ||\n !isDocumentLocalWriteCurrent(state, writeGeneration, writeDoc)\n ) {\n return;\n }\n advancePendingBaseVersion(state, writeDoc);\n requestDocumentStoreSync(state);\n })\n // The user is already looking at this text: publishDocumentTextSnapshot ran\n // before the chain, and nothing downstream surfaces a failed persist.\n .catch((error: unknown) => {\n reportDocumentStoreWriteFailure(state, TEXT_FAILURE_MESSAGE, error);\n })\n // Always settle, even on the value-equality short-circuit or a throw, so the\n // current document's counter cannot stick non-zero. The generation guard\n // keeps a reset write from decrementing a replacement generation.\n .finally(() => {\n settleDocumentLocalWrite(state, writeGeneration);\n });\n return state.writeChain;\n}\n\nfunction publishDocumentStructuredFieldSnapshot(\n state: DocumentStoreState,\n kind: Exclude<StoredDocumentKind, \"note\">,\n patch: DocumentStructuredFieldPatch,\n): void {\n const nextStructuredFields: Record<string, unknown> = {\n ...state.snapshot.structuredFields,\n };\n for (const [field, value] of Object.entries(patch)) {\n if (value === undefined) {\n delete nextStructuredFields[field];\n } else {\n nextStructuredFields[field] = value;\n }\n }\n const projectedState = projectStoredDocumentState(\n {\n documentKind: kind,\n structuredFields: nextStructuredFields,\n text: state.snapshot.text,\n rows: state.snapshot.rows.map((row) => ({\n id: row.id,\n fields: row.fields,\n })),\n },\n state.runtime.infra.documentProjectors,\n );\n\n setDocumentSnapshot(state, {\n ...state.snapshot,\n documentKind: projectedState.documentKind,\n fieldValidationIssues: projectedState.fieldValidationIssues,\n structuredFields: projectedState.structuredFields,\n title: projectedState.title,\n });\n}\n\nfunction queueDocumentStructuredFieldWrite(\n state: DocumentStoreState,\n kind: Exclude<StoredDocumentKind, \"note\">,\n patch: DocumentStructuredFieldPatch,\n options: DocumentMutationOptions = {},\n): Promise<void> {\n if (!state.doc) {\n return Promise.resolve();\n }\n const writeGeneration = state.localWriteGeneration;\n\n // See queueDocumentTextWrite: gate sync-lane text/field republish on the same\n // in-flight-write counter so structured edits get the identical protection.\n state.pendingLocalWrites += 1;\n state.writeChain = state.writeChain\n .catch(() => undefined)\n .then(async () => {\n if (\n state.localWriteGeneration !== writeGeneration ||\n !state.doc ||\n !canWriteDocument(state)\n ) {\n return;\n }\n const writeDoc = state.doc;\n const syncGeneration = captureDocumentStoreSyncGeneration(\n state,\n writeDoc,\n );\n if (!syncGeneration) {\n return;\n }\n\n writeStoredDocumentFields(\n writeDoc,\n kind,\n patch,\n state.runtime.infra.documentProjectors,\n );\n const update = pendingDeltaSinceBase(state, writeDoc);\n if (update.byteLength === 0) {\n await revalidateDocumentMutationIdentity({\n currentDoc: writeDoc,\n generation: syncGeneration,\n state,\n });\n return;\n }\n // Captured at delta time: the durable row written below (queue\n // dual-write or in-mutation tail append) proves coverage up to exactly\n // this version, so it is the frontier this persist may publish.\n const coveredVersion = encodeVersionVector(writeDoc);\n const durabilityOptions = structuredMutationDurabilityOptions(\n options,\n update,\n );\n if (!durabilityOptions) {\n await revalidateDocumentMutationIdentity({\n currentDoc: writeDoc,\n generation: syncGeneration,\n state,\n });\n return;\n }\n // A deferred write advances the record's content frontier AHEAD of the\n // outgoing queue (the op is re-derived by the next edit). Its delta\n // rides in the persist's own claimed mutation as a durable-history tail\n // row written before the record — the tail is the only content store,\n // so the record frontier must never durably lead the tail row that\n // holds its content. Passed as an option (no pre-persist await) so this\n // write adds no extra hop that would change cross-store interleaving.\n const persisted = await persistDocument(\n state,\n writeDoc,\n { snapshotEndVersion: coveredVersion },\n {\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n ...durabilityOptions,\n },\n syncGeneration,\n );\n if (\n !persisted ||\n !isDocumentLocalWriteCurrent(state, writeGeneration, writeDoc)\n ) {\n return;\n }\n if (!options.deferRemoteSync) {\n advancePendingBaseVersion(state, writeDoc);\n requestDocumentStoreSync(state);\n }\n })\n .catch((error: unknown) => {\n reportDocumentStoreWriteFailure(state, FIELD_FAILURE_MESSAGE, error);\n })\n // See queueDocumentTextWrite: the final current-generation write also\n // republishes any remote content that was held during the optimistic burst.\n .finally(() => {\n settleDocumentLocalWrite(state, writeGeneration);\n });\n return state.writeChain;\n}\n\nexport function setDocumentText(\n state: DocumentStoreState,\n scheduleSync: () => void,\n value: string,\n): Promise<void> {\n ensureDocumentStoreInitialized(state, scheduleSync);\n\n if (!state.initialized || !state.doc) {\n return ensureDocumentStoreReady(state, scheduleSync).then((ready) => {\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n publishDocumentTextSnapshot(state, value);\n return queueDocumentTextWrite(state, value);\n });\n }\n\n if (!canWriteDocument(state)) {\n return Promise.resolve();\n }\n\n publishDocumentTextSnapshot(state, value);\n return queueDocumentTextWrite(state, value);\n}\n\nexport function setDocumentStructuredFields(\n state: DocumentStoreState,\n scheduleSync: () => void,\n kind: Exclude<StoredDocumentKind, \"note\">,\n patch: DocumentStructuredFieldPatch,\n options: DocumentMutationOptions = {},\n): Promise<void> {\n ensureDocumentStoreInitialized(state, scheduleSync);\n\n if (!state.initialized || !state.doc) {\n return ensureDocumentStoreReady(state, scheduleSync).then((ready) => {\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n publishDocumentStructuredFieldSnapshot(state, kind, patch);\n return queueDocumentStructuredFieldWrite(state, kind, patch, options);\n });\n }\n\n if (!canWriteDocument(state)) {\n return Promise.resolve();\n }\n\n publishDocumentStructuredFieldSnapshot(state, kind, patch);\n return queueDocumentStructuredFieldWrite(state, kind, patch, options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mutations.js","sourceRoot":"","sources":["mutations.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { encodeVersionVector, getTextValue } from \"@tearleads/loro\";\nimport {\n projectStoredDocumentState,\n type StoredDocumentKind,\n writeStoredDocumentFields,\n} from \"../../../data/documents/documentKinds\";\nimport { createPendingUpdateFields } from \"../../../data/documents/documentSync\";\nimport { requestDocumentStoreSync } from \"../registry\";\nimport type {\n DocumentMutationOptions,\n DocumentStructuredFieldPatch,\n} from \"../types\";\nimport {\n ensureDocumentStoreInitialized,\n ensureDocumentStoreReady,\n} from \"./initialization\";\nimport { revalidateDocumentMutationIdentity } from \"./mutationIdentityRevalidation\";\nimport {\n advancePendingBaseVersion,\n pendingDeltaSinceBase,\n persistDocument,\n} from \"./persistence\";\nimport { reportDocumentStoreWriteFailure } from \"./reportWriteFailure\";\nimport {\n canWriteDocument,\n chainQueuedWrite,\n type DocumentState,\n type DocumentStoreState,\n type SaveDocumentRecordOptions,\n setDocumentSnapshot,\n setReadySnapshot,\n} from \"./state\";\nimport { captureDocumentStoreSyncGeneration } from \"./sync/syncGeneration\";\n\n// Fixed literals: a reported message must never carry document text or ids.\nconst TEXT_FAILURE_MESSAGE = \"Documents: local text persist failed\";\nconst FIELD_FAILURE_MESSAGE = \"Documents: local field persist failed\";\n\nfunction structuredMutationDurabilityOptions(\n options: DocumentMutationOptions,\n update: Uint8Array,\n): Pick<SaveDocumentRecordOptions, \"historyUpdates\" | \"pendingUpdate\"> | null {\n if (options.deferRemoteSync) {\n return { historyUpdates: [bytesToBase64(update)] };\n }\n const pendingUpdate = createPendingUpdateFields(update);\n return pendingUpdate ? { pendingUpdate } : null;\n}\n\nfunction isDocumentLocalWriteCurrent(\n state: DocumentStoreState,\n writeGeneration: number,\n writeDoc: DocumentState,\n): boolean {\n return (\n state.localWriteGeneration === writeGeneration && state.doc === writeDoc\n );\n}\n\nfunction settleDocumentLocalWrite(\n state: DocumentStoreState,\n writeGeneration: number,\n): void {\n // Reset/reinitialization owns the new generation's counter. A write queued\n // against the prior document must touch neither it nor the replacement doc.\n if (state.localWriteGeneration !== writeGeneration) {\n return;\n }\n\n state.pendingLocalWrites = Math.max(0, state.pendingLocalWrites - 1);\n if (state.pendingLocalWrites !== 0 || !state.doc) {\n return;\n }\n\n // A sync pass or rotation may merge remote content while preserving the\n // controlled editor value. Publish the authoritative doc once typing drains;\n // setReadySnapshot is a no-op when the optimistic projection already matches.\n setReadySnapshot(state, state.doc, state.snapshot.syncing);\n}\n\nfunction publishDocumentTextSnapshot(\n state: DocumentStoreState,\n value: string,\n): void {\n setDocumentSnapshot(state, {\n ...state.snapshot,\n text: value,\n title: projectStoredDocumentState(\n {\n documentKind: state.snapshot.documentKind,\n structuredFields: state.snapshot.structuredFields,\n text: value,\n rows: state.snapshot.rows.map((row) => ({\n id: row.id,\n fields: row.fields,\n })),\n },\n state.runtime.infra.documentProjectors,\n ).title,\n });\n}\n\nfunction queueDocumentTextWrite(\n state: DocumentStoreState,\n value: string,\n): Promise<void> {\n if (!state.doc) {\n return Promise.resolve();\n }\n const writeGeneration = state.localWriteGeneration;\n\n // Mark a local edit as in flight SYNCHRONOUSLY, before chaining, so a sync\n // pass that runs during this burst sees pendingLocalWrites > 0 and preserves\n // the optimistic snapshot instead of regressing it to a stale doc read.\n state.pendingLocalWrites += 1;\n return chainQueuedWrite(\n state,\n state.writeChain\n .catch(() => undefined)\n .then(async () => {\n if (\n state.localWriteGeneration !== writeGeneration ||\n !state.doc ||\n !canWriteDocument(state)\n ) {\n return;\n }\n const writeDoc = state.doc;\n const syncGeneration = captureDocumentStoreSyncGeneration(\n state,\n writeDoc,\n );\n if (!syncGeneration) {\n return;\n }\n\n if (getTextValue(writeDoc) === value) {\n await revalidateDocumentMutationIdentity({\n currentDoc: writeDoc,\n generation: syncGeneration,\n state,\n });\n return;\n }\n\n writeDoc.getText(\"text\").update(value);\n const update = pendingDeltaSinceBase(state, writeDoc);\n // Captured at delta time: the enqueued row proves durable coverage up\n // to exactly this version, so this is the frontier the persist may\n // publish (a raced later edit publishes its own on its own persist).\n const coveredVersion = encodeVersionVector(writeDoc);\n const pendingUpdate = createPendingUpdateFields(update);\n if (!pendingUpdate) {\n return;\n }\n const persisted = await persistDocument(\n state,\n writeDoc,\n { snapshotEndVersion: coveredVersion },\n { pendingUpdate, preserveSnapshotText: true },\n syncGeneration,\n );\n if (\n !persisted ||\n !isDocumentLocalWriteCurrent(state, writeGeneration, writeDoc)\n ) {\n return;\n }\n advancePendingBaseVersion(state, writeDoc);\n requestDocumentStoreSync(state);\n })\n // The user is already looking at this text: publishDocumentTextSnapshot ran\n // before the chain, and nothing downstream surfaces a failed persist.\n .catch((error: unknown) => {\n reportDocumentStoreWriteFailure(state, TEXT_FAILURE_MESSAGE, error);\n })\n // Always settle, even on the value-equality short-circuit or a throw, so the\n // current document's counter cannot stick non-zero. The generation guard\n // keeps a reset write from decrementing a replacement generation.\n .finally(() => {\n settleDocumentLocalWrite(state, writeGeneration);\n }),\n );\n}\n\nfunction publishDocumentStructuredFieldSnapshot(\n state: DocumentStoreState,\n kind: Exclude<StoredDocumentKind, \"note\">,\n patch: DocumentStructuredFieldPatch,\n): void {\n const nextStructuredFields: Record<string, unknown> = {\n ...state.snapshot.structuredFields,\n };\n for (const [field, value] of Object.entries(patch)) {\n if (value === undefined) {\n delete nextStructuredFields[field];\n } else {\n nextStructuredFields[field] = value;\n }\n }\n const projectedState = projectStoredDocumentState(\n {\n documentKind: kind,\n structuredFields: nextStructuredFields,\n text: state.snapshot.text,\n rows: state.snapshot.rows.map((row) => ({\n id: row.id,\n fields: row.fields,\n })),\n },\n state.runtime.infra.documentProjectors,\n );\n\n setDocumentSnapshot(state, {\n ...state.snapshot,\n documentKind: projectedState.documentKind,\n fieldValidationIssues: projectedState.fieldValidationIssues,\n structuredFields: projectedState.structuredFields,\n title: projectedState.title,\n });\n}\n\nfunction queueDocumentStructuredFieldWrite(\n state: DocumentStoreState,\n kind: Exclude<StoredDocumentKind, \"note\">,\n patch: DocumentStructuredFieldPatch,\n options: DocumentMutationOptions = {},\n): Promise<void> {\n if (!state.doc) {\n return Promise.resolve();\n }\n const writeGeneration = state.localWriteGeneration;\n\n // See queueDocumentTextWrite: gate sync-lane text/field republish on the same\n // in-flight-write counter so structured edits get the identical protection.\n state.pendingLocalWrites += 1;\n return chainQueuedWrite(\n state,\n state.writeChain\n .catch(() => undefined)\n .then(async () => {\n if (\n state.localWriteGeneration !== writeGeneration ||\n !state.doc ||\n !canWriteDocument(state)\n ) {\n return;\n }\n const writeDoc = state.doc;\n const syncGeneration = captureDocumentStoreSyncGeneration(\n state,\n writeDoc,\n );\n if (!syncGeneration) {\n return;\n }\n\n writeStoredDocumentFields(\n writeDoc,\n kind,\n patch,\n state.runtime.infra.documentProjectors,\n );\n const update = pendingDeltaSinceBase(state, writeDoc);\n if (update.byteLength === 0) {\n await revalidateDocumentMutationIdentity({\n currentDoc: writeDoc,\n generation: syncGeneration,\n state,\n });\n return;\n }\n // Captured at delta time: the durable row written below (queue\n // dual-write or in-mutation tail append) proves coverage up to exactly\n // this version, so it is the frontier this persist may publish.\n const coveredVersion = encodeVersionVector(writeDoc);\n const durabilityOptions = structuredMutationDurabilityOptions(\n options,\n update,\n );\n if (!durabilityOptions) {\n await revalidateDocumentMutationIdentity({\n currentDoc: writeDoc,\n generation: syncGeneration,\n state,\n });\n return;\n }\n // A deferred write advances the record's content frontier AHEAD of the\n // outgoing queue (the op is re-derived by the next edit). Its delta\n // rides in the persist's own claimed mutation as a durable-history tail\n // row written before the record — the tail is the only content store,\n // so the record frontier must never durably lead the tail row that\n // holds its content. Passed as an option (no pre-persist await) so this\n // write adds no extra hop that would change cross-store interleaving.\n const persisted = await persistDocument(\n state,\n writeDoc,\n { snapshotEndVersion: coveredVersion },\n {\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n ...durabilityOptions,\n },\n syncGeneration,\n );\n if (\n !persisted ||\n !isDocumentLocalWriteCurrent(state, writeGeneration, writeDoc)\n ) {\n return;\n }\n if (!options.deferRemoteSync) {\n advancePendingBaseVersion(state, writeDoc);\n requestDocumentStoreSync(state);\n }\n })\n .catch((error: unknown) => {\n reportDocumentStoreWriteFailure(state, FIELD_FAILURE_MESSAGE, error);\n })\n // See queueDocumentTextWrite: the final current-generation write also\n // republishes any remote content that was held during the optimistic burst.\n .finally(() => {\n settleDocumentLocalWrite(state, writeGeneration);\n }),\n );\n}\n\nexport function setDocumentText(\n state: DocumentStoreState,\n scheduleSync: () => void,\n value: string,\n): Promise<void> {\n ensureDocumentStoreInitialized(state, scheduleSync);\n\n if (!state.initialized || !state.doc) {\n return ensureDocumentStoreReady(state, scheduleSync).then((ready) => {\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n publishDocumentTextSnapshot(state, value);\n return queueDocumentTextWrite(state, value);\n });\n }\n\n if (!canWriteDocument(state)) {\n return Promise.resolve();\n }\n\n publishDocumentTextSnapshot(state, value);\n return queueDocumentTextWrite(state, value);\n}\n\nexport function setDocumentStructuredFields(\n state: DocumentStoreState,\n scheduleSync: () => void,\n kind: Exclude<StoredDocumentKind, \"note\">,\n patch: DocumentStructuredFieldPatch,\n options: DocumentMutationOptions = {},\n): Promise<void> {\n ensureDocumentStoreInitialized(state, scheduleSync);\n\n if (!state.initialized || !state.doc) {\n return ensureDocumentStoreReady(state, scheduleSync).then((ready) => {\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n publishDocumentStructuredFieldSnapshot(state, kind, patch);\n return queueDocumentStructuredFieldWrite(state, kind, patch, options);\n });\n }\n\n if (!canWriteDocument(state)) {\n return Promise.resolve();\n }\n\n publishDocumentStructuredFieldSnapshot(state, kind, patch);\n return queueDocumentStructuredFieldWrite(state, kind, patch, options);\n}\n"]}
|
|
@@ -5,6 +5,7 @@ import { requestDocumentStoreSync } from "../../registry.js";
|
|
|
5
5
|
import { installRebuiltDocument } from "../history/historyRebuild.js";
|
|
6
6
|
import { chainIdentityWrite } from "../identityWriteChain.js";
|
|
7
7
|
import { listPendingUpdates } from "../persistence.js";
|
|
8
|
+
import { chainQueuedWrite, } from "../state.js";
|
|
8
9
|
import { createStoredDocument } from "../storedDocument.js";
|
|
9
10
|
import { runDocumentRemoteWork } from "../sync/remoteWork.js";
|
|
10
11
|
import { captureDocumentStoreAttachmentSyncGeneration, captureDocumentStoreSyncLaneGeneration, isDocumentStoreSyncGenerationCurrent, } from "../sync/syncGeneration.js";
|
|
@@ -182,7 +183,7 @@ function installRotationRecovery(input) {
|
|
|
182
183
|
}));
|
|
183
184
|
// Only the checked local install occupies the write queue. Network recovery
|
|
184
185
|
// uses the remote queue, so an outage cannot hold new edits hostage.
|
|
185
|
-
state
|
|
186
|
+
void chainQueuedWrite(state, installation.then(() => undefined, () => undefined));
|
|
186
187
|
return installation;
|
|
187
188
|
}
|
|
188
189
|
async function recoverFullHistoryForRotation(state, laneGeneration) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeVersionVector, versionVectorsEqual } from \"@tearleads/loro\";\nimport {\n createDocumentWriterPublicKeyResolver,\n type DocumentSyncPullContinuation,\n readPullContinuation,\n resolveDocumentCreateAuthor,\n syncRemoteDocument,\n validateDocumentSyncUpdateImports,\n} from \"../../../../workflows/documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../../workflows/principals/runtimePolicyWarmer\";\nimport { requestDocumentStoreSync } from \"../../registry\";\nimport { installRebuiltDocument } from \"../history/historyRebuild\";\nimport { chainIdentityWrite } from \"../identityWriteChain\";\nimport { listPendingUpdates } from \"../persistence\";\nimport type { DocumentState, DocumentStoreState } from \"../state\";\nimport { createStoredDocument } from \"../storedDocument\";\nimport { runDocumentRemoteWork } from \"../sync/remoteWork\";\nimport {\n captureDocumentStoreAttachmentSyncGeneration,\n captureDocumentStoreSyncLaneGeneration,\n type DocumentStoreSyncGeneration,\n type DocumentStoreSyncLaneGeneration,\n isDocumentStoreSyncGenerationCurrent,\n} from \"../sync/syncGeneration\";\nimport { deleteUpstreamDeletedDocument } from \"../sync/syncRequest\";\nimport { documentIncomingUpdateIsolationFailureHandler } from \"../sync/syncShared\";\nimport { importSyncedDocumentUpdates } from \"../sync/syncUpdateImport\";\nimport {\n assertExactDocumentHistory,\n importProvenOrdinaryPendingHistory,\n} from \"./rotationProvenance\";\nimport {\n invalidatePullContinuationBeforeRotation,\n RotationPendingUpdatesChangedError,\n settleOrdinaryDocumentUpdatesBeforeRotation,\n} from \"./rotationSettlement\";\n\nfunction ordinaryRawHistoryUpdates<T extends { checkpointKind?: string }>(\n updates: readonly T[],\n): T[] {\n return updates.filter((update) => update.checkpointKind === undefined);\n}\n\nfunction assertRotationRecoveryPrerequisites(state: DocumentStoreState) {\n if (state.persistence.supportsAtomicRecoveryHistoryPruning !== true) {\n throw new Error(\n \"Rotation raw-history recovery requires an adapter with atomic local-history pruning\",\n );\n }\n const author = resolveDocumentCreateAuthor(state.runtime);\n const encapsulationKeyPair = state.runtime.crypto.encapsulationKeyPair;\n const documentId = state.record?.documentId;\n if (\n !author ||\n !encapsulationKeyPair ||\n !documentId ||\n !state.runtime.auth.isAuthenticated ||\n !state.runtime.state.online\n ) {\n throw new Error(\n \"Rotation requires verified full-history recovery, but remote sync prerequisites are unavailable\",\n );\n }\n return { author, documentId, encapsulationKeyPair };\n}\n\nfunction assertRotationRecoveryGeneration(input: {\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}): void {\n if (!isDocumentStoreSyncGenerationCurrent(input.state, input.generation)) {\n throw new Error(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n }\n}\n\nfunction rotationIncomingUpdateIsolation(input: {\n currentDocument: DocumentState;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}) {\n return {\n onIncomingUpdateIsolationFailure:\n documentIncomingUpdateIsolationFailureHandler(\n input.state,\n input.generation,\n ),\n validateIncomingUpdates: async (\n result: Pick<\n NonNullable<Awaited<ReturnType<typeof syncRemoteDocument>>>,\n \"decryptedUpdates\" | \"response\"\n >,\n ) => {\n await validateDocumentSyncUpdateImports({\n currentDocument: input.currentDocument,\n decryptedUpdates: result.decryptedUpdates,\n responseUpdates: result.response.updates,\n });\n const decryptedUpdates = ordinaryRawHistoryUpdates(\n result.decryptedUpdates,\n );\n const ordinaryUpdateIds = new Set(\n decryptedUpdates.map((update) => update.id),\n );\n await validateDocumentSyncUpdateImports({\n currentDocument: input.currentDocument,\n decryptedUpdates,\n responseUpdates: result.response.updates.filter((update) =>\n ordinaryUpdateIds.has(update.id),\n ),\n });\n },\n };\n}\n\nasync function pullVerifiedRawHistoryForRotation(input: {\n currentRecord: NonNullable<DocumentStoreState[\"record\"]>;\n generation: DocumentStoreSyncGeneration;\n rebuiltDocument: DocumentState;\n state: DocumentStoreState;\n}) {\n const { author, documentId, encapsulationKeyPair } =\n assertRotationRecoveryPrerequisites(input.state);\n let pullContinuation: DocumentSyncPullContinuation | undefined;\n const seenPullCursors = new Set<string>();\n let planningRecord = input.currentRecord;\n let writerProjection =\n input.state.writerProjection?.documentId === documentId\n ? input.state.writerProjection\n : undefined;\n\n while (true) {\n let abandonReason: string | null = null;\n const synced = await syncRemoteDocument({\n apiClient: input.state.runtime.apiClient,\n author,\n documentId,\n execSql: input.state.runtime.infra.execSql,\n historyMode: \"raw\",\n isRemoteSyncBlocked: input.state.runtime.util.isRemoteSyncBlocked,\n localVersionVector: null,\n minLsn: input.currentRecord.lastCommitLsn ?? undefined,\n onRemoteDocumentDeleted: ({ commitPurgeProof, documentId }) =>\n deleteUpstreamDeletedDocument(\n input.state,\n input.generation,\n input.currentRecord,\n documentId,\n commitPurgeProof,\n ),\n // Recorded, never parked: this pass submits no writes, so it plans no\n // ancestor repair and cannot abandon as `inaccessible`.\n onSyncAbandoned: (reason) => {\n abandonReason = reason;\n },\n ...rotationIncomingUpdateIsolation({\n currentDocument: input.rebuiltDocument,\n generation: input.generation,\n state: input.state,\n }),\n onSyncTrace: (line) => input.state.runtime.util.log(`Documents: ${line}`),\n pendingUpdates: [],\n persistedState: planningRecord,\n pullContinuation,\n resolveProjectionUserKey: input.state.resolveProjectionUserKey,\n resolveWriterPublicKey: createDocumentWriterPublicKeyResolver({\n logPrefix: \"Documents\",\n runtime: input.state.runtime,\n writerKeyLabel: \"writer key\",\n }),\n targetSecretKey: encapsulationKeyPair.secretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.state.runtime,\n ),\n writerProjection,\n });\n if (!synced) {\n throw new Error(\n `Rotation raw-history recovery could not complete (${abandonReason ?? \"sync did not finish\"}); key rotation was not started`,\n );\n }\n\n assertRotationRecoveryGeneration(input);\n\n importSyncedDocumentUpdates(\n input.rebuiltDocument,\n ordinaryRawHistoryUpdates(synced.decryptedUpdates),\n );\n if (!synced.hasIncompletePull) return synced;\n\n const nextContinuation = readPullContinuation(synced.response);\n if (!nextContinuation) {\n throw new Error(\n \"Rotation raw-history recovery ended before the retained history was complete\",\n );\n }\n if (seenPullCursors.has(nextContinuation.cursor)) {\n throw new Error(\n \"Rotation raw-history recovery encountered a repeated pull cursor\",\n );\n }\n seenPullCursors.add(nextContinuation.cursor);\n pullContinuation = nextContinuation;\n planningRecord = { ...planningRecord, ...synced.persistedState };\n writerProjection = synced.writerProjection;\n }\n}\n\nasync function collectVerifiedRawHistoryForRotation(input: {\n currentRecord: NonNullable<DocumentStoreState[\"record\"]>;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}) {\n const consumedPullContinuation = input.state.pullContinuation;\n const writerProjectionGeneration = input.state.writerProjectionGeneration;\n const rebuiltDocument = await createStoredDocument(input.state);\n try {\n const synced = await pullVerifiedRawHistoryForRotation({\n ...input,\n rebuiltDocument,\n });\n return {\n consumedPullContinuation,\n currentRecord: input.currentRecord,\n rebuiltDocument,\n synced,\n writerProjectionGeneration,\n };\n } catch (error) {\n rebuiltDocument.free();\n throw error;\n }\n}\n\nclass RotationDocumentChangedError extends Error {}\n\nfunction assertCapturedDocumentCurrent(input: {\n capturedVersion: string;\n currentDocument: DocumentState;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}): void {\n assertRotationRecoveryGeneration(input);\n if (\n !versionVectorsEqual(\n encodeVersionVector(input.currentDocument),\n input.capturedVersion,\n )\n ) {\n throw new RotationDocumentChangedError(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n }\n}\n\nfunction currentRotationRecoveryRecord(\n state: DocumentStoreState,\n): NonNullable<DocumentStoreState[\"record\"]> {\n if (state.record) return state.record;\n throw new Error(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n}\n\nfunction installRotationRecovery(input: {\n capturedVersion: string;\n collection: Awaited<ReturnType<typeof collectVerifiedRawHistoryForRotation>>;\n currentDoc: DocumentState;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}) {\n const { capturedVersion, collection, currentDoc, generation, state } = input;\n const installation = state.writeChain\n .catch(() => undefined)\n .then(() =>\n chainIdentityWrite(state, async () => {\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n assertExactDocumentHistory({\n currentDocument: currentDoc,\n rebuiltDocument: collection.rebuiltDocument,\n });\n return installRebuiltDocument({\n consumedPullContinuation: collection.consumedPullContinuation,\n currentRecord: collection.currentRecord,\n generation,\n rebuiltDoc: collection.rebuiltDocument,\n state,\n synced: collection.synced,\n writerProjectionGeneration: collection.writerProjectionGeneration,\n });\n }),\n );\n // Only the checked local install occupies the write queue. Network recovery\n // uses the remote queue, so an outage cannot hold new edits hostage.\n state.writeChain = installation.then(\n () => undefined,\n () => undefined,\n );\n return installation;\n}\n\nasync function recoverFullHistoryForRotation(\n state: DocumentStoreState,\n laneGeneration: DocumentStoreSyncLaneGeneration,\n): Promise<Uint8Array> {\n assertRotationRecoveryPrerequisites(state);\n await invalidatePullContinuationBeforeRotation(state);\n const currentDoc = state.doc;\n const currentRecord = state.record;\n if (!currentDoc || !currentRecord) {\n throw new Error(\n \"Document must finish loading before its content key can rotate\",\n );\n }\n // The teardown guard for the recovery's terminal-failure handler: captured\n // before the pull so a discard (row 21) racing this preflight invalidates\n // it, and the stale handler cannot resurrect a deleted failure row.\n const generation = captureDocumentStoreAttachmentSyncGeneration(\n state,\n currentDoc,\n laneGeneration,\n );\n if (!generation) {\n throw new Error(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n }\n\n const capturedVersion = encodeVersionVector(currentDoc);\n let settlementRequiresRetry = false;\n\n // A raw recovery starts from an empty scratch document, bypasses untrusted\n // rotation-baseline redirects, drains every retained page in memory, and\n // publishes nothing until all response updates have validated. Checkpoints\n // are authenticated and decrypted but are not reconstruction inputs: the\n // original ordinary update stream is the source of truth in this mode.\n let collection = await collectVerifiedRawHistoryForRotation({\n currentRecord,\n generation,\n state,\n });\n\n try {\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n const pendingUpdates = await listPendingUpdates(state);\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n const verifiedOrdinaryVersion = importProvenOrdinaryPendingHistory({\n currentDocument: currentDoc,\n pendingUpdates,\n rebuiltDocument: collection.rebuiltDocument,\n });\n if (pendingUpdates.some((update) => update.sourceVersionVector == null)) {\n // The first raw pass proves the exact ordinary frontier before any local\n // row can be published. Pull raw history again after settlement so the\n // installed snapshot also includes remote work that raced that submit.\n await settleOrdinaryDocumentUpdatesBeforeRotation(\n state,\n verifiedOrdinaryVersion,\n pendingUpdates,\n generation,\n );\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n const definitiveCollection = await collectVerifiedRawHistoryForRotation({\n currentRecord: currentRotationRecoveryRecord(state),\n generation,\n state,\n });\n collection.rebuiltDocument.free();\n collection = definitiveCollection;\n }\n const installed = await installRotationRecovery({\n capturedVersion,\n collection,\n currentDoc,\n generation,\n state,\n });\n settlementRequiresRetry = installed.settlementRequiresRetry;\n if (settlementRequiresRetry) {\n throw new Error(\n \"Rotation raw-history recovery was superseded during its atomic install; retry key rotation\",\n );\n }\n return installed.fullHistorySnapshot;\n } finally {\n if (state.doc !== collection.rebuiltDocument) {\n collection.rebuiltDocument.free();\n }\n if (settlementRequiresRetry) {\n requestDocumentStoreSync(state);\n }\n }\n}\n\n/**\n * Wait for prior local writes and serialize with other remote work. Edits can\n * continue during the pull; the checked install rejects a changed document so\n * a stale recovery cannot replace them. This preflight can then be retried.\n */\nexport function assertDocumentStoreCanRotateContentKey(\n state: DocumentStoreState,\n): Promise<Uint8Array> {\n const laneGeneration = captureDocumentStoreSyncLaneGeneration(state);\n const generation = captureDocumentStoreAttachmentSyncGeneration(\n state,\n state.doc,\n laneGeneration,\n );\n return runDocumentRemoteWork(state, async () => {\n await state.writeChain.catch(() => undefined);\n if (\n !generation ||\n !isDocumentStoreSyncGenerationCurrent(state, generation)\n ) {\n throw new Error(\n \"Document changed before rotation recovery; retry key rotation\",\n );\n }\n for (let attempt = 0; ; attempt += 1) {\n try {\n return await recoverFullHistoryForRotation(state, laneGeneration);\n } catch (error) {\n // Autosaves and conflict re-keying can invalidate the proven frontier.\n // Repeat the complete proof without blocking new local edits; repeated\n // changes remain bounded and leave the durable queue retryable.\n if (\n !(\n error instanceof RotationPendingUpdatesChangedError ||\n error instanceof RotationDocumentChangedError\n ) ||\n attempt >= 2 ||\n !isDocumentStoreSyncGenerationCurrent(state, generation)\n ) {\n throw error;\n }\n }\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeVersionVector, versionVectorsEqual } from \"@tearleads/loro\";\nimport {\n createDocumentWriterPublicKeyResolver,\n type DocumentSyncPullContinuation,\n readPullContinuation,\n resolveDocumentCreateAuthor,\n syncRemoteDocument,\n validateDocumentSyncUpdateImports,\n} from \"../../../../workflows/documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../../workflows/principals/runtimePolicyWarmer\";\nimport { requestDocumentStoreSync } from \"../../registry\";\nimport { installRebuiltDocument } from \"../history/historyRebuild\";\nimport { chainIdentityWrite } from \"../identityWriteChain\";\nimport { listPendingUpdates } from \"../persistence\";\nimport {\n chainQueuedWrite,\n type DocumentState,\n type DocumentStoreState,\n} from \"../state\";\nimport { createStoredDocument } from \"../storedDocument\";\nimport { runDocumentRemoteWork } from \"../sync/remoteWork\";\nimport {\n captureDocumentStoreAttachmentSyncGeneration,\n captureDocumentStoreSyncLaneGeneration,\n type DocumentStoreSyncGeneration,\n type DocumentStoreSyncLaneGeneration,\n isDocumentStoreSyncGenerationCurrent,\n} from \"../sync/syncGeneration\";\nimport { deleteUpstreamDeletedDocument } from \"../sync/syncRequest\";\nimport { documentIncomingUpdateIsolationFailureHandler } from \"../sync/syncShared\";\nimport { importSyncedDocumentUpdates } from \"../sync/syncUpdateImport\";\nimport {\n assertExactDocumentHistory,\n importProvenOrdinaryPendingHistory,\n} from \"./rotationProvenance\";\nimport {\n invalidatePullContinuationBeforeRotation,\n RotationPendingUpdatesChangedError,\n settleOrdinaryDocumentUpdatesBeforeRotation,\n} from \"./rotationSettlement\";\n\nfunction ordinaryRawHistoryUpdates<T extends { checkpointKind?: string }>(\n updates: readonly T[],\n): T[] {\n return updates.filter((update) => update.checkpointKind === undefined);\n}\n\nfunction assertRotationRecoveryPrerequisites(state: DocumentStoreState) {\n if (state.persistence.supportsAtomicRecoveryHistoryPruning !== true) {\n throw new Error(\n \"Rotation raw-history recovery requires an adapter with atomic local-history pruning\",\n );\n }\n const author = resolveDocumentCreateAuthor(state.runtime);\n const encapsulationKeyPair = state.runtime.crypto.encapsulationKeyPair;\n const documentId = state.record?.documentId;\n if (\n !author ||\n !encapsulationKeyPair ||\n !documentId ||\n !state.runtime.auth.isAuthenticated ||\n !state.runtime.state.online\n ) {\n throw new Error(\n \"Rotation requires verified full-history recovery, but remote sync prerequisites are unavailable\",\n );\n }\n return { author, documentId, encapsulationKeyPair };\n}\n\nfunction assertRotationRecoveryGeneration(input: {\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}): void {\n if (!isDocumentStoreSyncGenerationCurrent(input.state, input.generation)) {\n throw new Error(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n }\n}\n\nfunction rotationIncomingUpdateIsolation(input: {\n currentDocument: DocumentState;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}) {\n return {\n onIncomingUpdateIsolationFailure:\n documentIncomingUpdateIsolationFailureHandler(\n input.state,\n input.generation,\n ),\n validateIncomingUpdates: async (\n result: Pick<\n NonNullable<Awaited<ReturnType<typeof syncRemoteDocument>>>,\n \"decryptedUpdates\" | \"response\"\n >,\n ) => {\n await validateDocumentSyncUpdateImports({\n currentDocument: input.currentDocument,\n decryptedUpdates: result.decryptedUpdates,\n responseUpdates: result.response.updates,\n });\n const decryptedUpdates = ordinaryRawHistoryUpdates(\n result.decryptedUpdates,\n );\n const ordinaryUpdateIds = new Set(\n decryptedUpdates.map((update) => update.id),\n );\n await validateDocumentSyncUpdateImports({\n currentDocument: input.currentDocument,\n decryptedUpdates,\n responseUpdates: result.response.updates.filter((update) =>\n ordinaryUpdateIds.has(update.id),\n ),\n });\n },\n };\n}\n\nasync function pullVerifiedRawHistoryForRotation(input: {\n currentRecord: NonNullable<DocumentStoreState[\"record\"]>;\n generation: DocumentStoreSyncGeneration;\n rebuiltDocument: DocumentState;\n state: DocumentStoreState;\n}) {\n const { author, documentId, encapsulationKeyPair } =\n assertRotationRecoveryPrerequisites(input.state);\n let pullContinuation: DocumentSyncPullContinuation | undefined;\n const seenPullCursors = new Set<string>();\n let planningRecord = input.currentRecord;\n let writerProjection =\n input.state.writerProjection?.documentId === documentId\n ? input.state.writerProjection\n : undefined;\n\n while (true) {\n let abandonReason: string | null = null;\n const synced = await syncRemoteDocument({\n apiClient: input.state.runtime.apiClient,\n author,\n documentId,\n execSql: input.state.runtime.infra.execSql,\n historyMode: \"raw\",\n isRemoteSyncBlocked: input.state.runtime.util.isRemoteSyncBlocked,\n localVersionVector: null,\n minLsn: input.currentRecord.lastCommitLsn ?? undefined,\n onRemoteDocumentDeleted: ({ commitPurgeProof, documentId }) =>\n deleteUpstreamDeletedDocument(\n input.state,\n input.generation,\n input.currentRecord,\n documentId,\n commitPurgeProof,\n ),\n // Recorded, never parked: this pass submits no writes, so it plans no\n // ancestor repair and cannot abandon as `inaccessible`.\n onSyncAbandoned: (reason) => {\n abandonReason = reason;\n },\n ...rotationIncomingUpdateIsolation({\n currentDocument: input.rebuiltDocument,\n generation: input.generation,\n state: input.state,\n }),\n onSyncTrace: (line) => input.state.runtime.util.log(`Documents: ${line}`),\n pendingUpdates: [],\n persistedState: planningRecord,\n pullContinuation,\n resolveProjectionUserKey: input.state.resolveProjectionUserKey,\n resolveWriterPublicKey: createDocumentWriterPublicKeyResolver({\n logPrefix: \"Documents\",\n runtime: input.state.runtime,\n writerKeyLabel: \"writer key\",\n }),\n targetSecretKey: encapsulationKeyPair.secretKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.state.runtime,\n ),\n writerProjection,\n });\n if (!synced) {\n throw new Error(\n `Rotation raw-history recovery could not complete (${abandonReason ?? \"sync did not finish\"}); key rotation was not started`,\n );\n }\n\n assertRotationRecoveryGeneration(input);\n\n importSyncedDocumentUpdates(\n input.rebuiltDocument,\n ordinaryRawHistoryUpdates(synced.decryptedUpdates),\n );\n if (!synced.hasIncompletePull) return synced;\n\n const nextContinuation = readPullContinuation(synced.response);\n if (!nextContinuation) {\n throw new Error(\n \"Rotation raw-history recovery ended before the retained history was complete\",\n );\n }\n if (seenPullCursors.has(nextContinuation.cursor)) {\n throw new Error(\n \"Rotation raw-history recovery encountered a repeated pull cursor\",\n );\n }\n seenPullCursors.add(nextContinuation.cursor);\n pullContinuation = nextContinuation;\n planningRecord = { ...planningRecord, ...synced.persistedState };\n writerProjection = synced.writerProjection;\n }\n}\n\nasync function collectVerifiedRawHistoryForRotation(input: {\n currentRecord: NonNullable<DocumentStoreState[\"record\"]>;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}) {\n const consumedPullContinuation = input.state.pullContinuation;\n const writerProjectionGeneration = input.state.writerProjectionGeneration;\n const rebuiltDocument = await createStoredDocument(input.state);\n try {\n const synced = await pullVerifiedRawHistoryForRotation({\n ...input,\n rebuiltDocument,\n });\n return {\n consumedPullContinuation,\n currentRecord: input.currentRecord,\n rebuiltDocument,\n synced,\n writerProjectionGeneration,\n };\n } catch (error) {\n rebuiltDocument.free();\n throw error;\n }\n}\n\nclass RotationDocumentChangedError extends Error {}\n\nfunction assertCapturedDocumentCurrent(input: {\n capturedVersion: string;\n currentDocument: DocumentState;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}): void {\n assertRotationRecoveryGeneration(input);\n if (\n !versionVectorsEqual(\n encodeVersionVector(input.currentDocument),\n input.capturedVersion,\n )\n ) {\n throw new RotationDocumentChangedError(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n }\n}\n\nfunction currentRotationRecoveryRecord(\n state: DocumentStoreState,\n): NonNullable<DocumentStoreState[\"record\"]> {\n if (state.record) return state.record;\n throw new Error(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n}\n\nfunction installRotationRecovery(input: {\n capturedVersion: string;\n collection: Awaited<ReturnType<typeof collectVerifiedRawHistoryForRotation>>;\n currentDoc: DocumentState;\n generation: DocumentStoreSyncGeneration;\n state: DocumentStoreState;\n}) {\n const { capturedVersion, collection, currentDoc, generation, state } = input;\n const installation = state.writeChain\n .catch(() => undefined)\n .then(() =>\n chainIdentityWrite(state, async () => {\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n assertExactDocumentHistory({\n currentDocument: currentDoc,\n rebuiltDocument: collection.rebuiltDocument,\n });\n return installRebuiltDocument({\n consumedPullContinuation: collection.consumedPullContinuation,\n currentRecord: collection.currentRecord,\n generation,\n rebuiltDoc: collection.rebuiltDocument,\n state,\n synced: collection.synced,\n writerProjectionGeneration: collection.writerProjectionGeneration,\n });\n }),\n );\n // Only the checked local install occupies the write queue. Network recovery\n // uses the remote queue, so an outage cannot hold new edits hostage.\n void chainQueuedWrite(\n state,\n installation.then(\n () => undefined,\n () => undefined,\n ),\n );\n return installation;\n}\n\nasync function recoverFullHistoryForRotation(\n state: DocumentStoreState,\n laneGeneration: DocumentStoreSyncLaneGeneration,\n): Promise<Uint8Array> {\n assertRotationRecoveryPrerequisites(state);\n await invalidatePullContinuationBeforeRotation(state);\n const currentDoc = state.doc;\n const currentRecord = state.record;\n if (!currentDoc || !currentRecord) {\n throw new Error(\n \"Document must finish loading before its content key can rotate\",\n );\n }\n // The teardown guard for the recovery's terminal-failure handler: captured\n // before the pull so a discard (row 21) racing this preflight invalidates\n // it, and the stale handler cannot resurrect a deleted failure row.\n const generation = captureDocumentStoreAttachmentSyncGeneration(\n state,\n currentDoc,\n laneGeneration,\n );\n if (!generation) {\n throw new Error(\n \"Document changed during rotation recovery; retry key rotation\",\n );\n }\n\n const capturedVersion = encodeVersionVector(currentDoc);\n let settlementRequiresRetry = false;\n\n // A raw recovery starts from an empty scratch document, bypasses untrusted\n // rotation-baseline redirects, drains every retained page in memory, and\n // publishes nothing until all response updates have validated. Checkpoints\n // are authenticated and decrypted but are not reconstruction inputs: the\n // original ordinary update stream is the source of truth in this mode.\n let collection = await collectVerifiedRawHistoryForRotation({\n currentRecord,\n generation,\n state,\n });\n\n try {\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n const pendingUpdates = await listPendingUpdates(state);\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n const verifiedOrdinaryVersion = importProvenOrdinaryPendingHistory({\n currentDocument: currentDoc,\n pendingUpdates,\n rebuiltDocument: collection.rebuiltDocument,\n });\n if (pendingUpdates.some((update) => update.sourceVersionVector == null)) {\n // The first raw pass proves the exact ordinary frontier before any local\n // row can be published. Pull raw history again after settlement so the\n // installed snapshot also includes remote work that raced that submit.\n await settleOrdinaryDocumentUpdatesBeforeRotation(\n state,\n verifiedOrdinaryVersion,\n pendingUpdates,\n generation,\n );\n assertCapturedDocumentCurrent({\n capturedVersion,\n currentDocument: currentDoc,\n generation,\n state,\n });\n const definitiveCollection = await collectVerifiedRawHistoryForRotation({\n currentRecord: currentRotationRecoveryRecord(state),\n generation,\n state,\n });\n collection.rebuiltDocument.free();\n collection = definitiveCollection;\n }\n const installed = await installRotationRecovery({\n capturedVersion,\n collection,\n currentDoc,\n generation,\n state,\n });\n settlementRequiresRetry = installed.settlementRequiresRetry;\n if (settlementRequiresRetry) {\n throw new Error(\n \"Rotation raw-history recovery was superseded during its atomic install; retry key rotation\",\n );\n }\n return installed.fullHistorySnapshot;\n } finally {\n if (state.doc !== collection.rebuiltDocument) {\n collection.rebuiltDocument.free();\n }\n if (settlementRequiresRetry) {\n requestDocumentStoreSync(state);\n }\n }\n}\n\n/**\n * Wait for prior local writes and serialize with other remote work. Edits can\n * continue during the pull; the checked install rejects a changed document so\n * a stale recovery cannot replace them. This preflight can then be retried.\n */\nexport function assertDocumentStoreCanRotateContentKey(\n state: DocumentStoreState,\n): Promise<Uint8Array> {\n const laneGeneration = captureDocumentStoreSyncLaneGeneration(state);\n const generation = captureDocumentStoreAttachmentSyncGeneration(\n state,\n state.doc,\n laneGeneration,\n );\n return runDocumentRemoteWork(state, async () => {\n await state.writeChain.catch(() => undefined);\n if (\n !generation ||\n !isDocumentStoreSyncGenerationCurrent(state, generation)\n ) {\n throw new Error(\n \"Document changed before rotation recovery; retry key rotation\",\n );\n }\n for (let attempt = 0; ; attempt += 1) {\n try {\n return await recoverFullHistoryForRotation(state, laneGeneration);\n } catch (error) {\n // Autosaves and conflict re-keying can invalidate the proven frontier.\n // Repeat the complete proof without blocking new local edits; repeated\n // changes remain bounded and leave the durable queue retryable.\n if (\n !(\n error instanceof RotationPendingUpdatesChangedError ||\n error instanceof RotationDocumentChangedError\n ) ||\n attempt >= 2 ||\n !isDocumentStoreSyncGenerationCurrent(state, generation)\n ) {\n throw error;\n }\n }\n }\n });\n}\n"]}
|
|
@@ -6,7 +6,7 @@ import { ensureDocumentStoreReady } from "../initialization/index.js";
|
|
|
6
6
|
import { revalidateDocumentMutationIdentity } from "../mutationIdentityRevalidation.js";
|
|
7
7
|
import { advancePendingBaseVersion, pendingDeltaSinceBase, persistDocument, } from "../persistence.js";
|
|
8
8
|
import { reportDocumentStoreWriteFailure } from "../reportWriteFailure.js";
|
|
9
|
-
import { canWriteDocument, } from "../state.js";
|
|
9
|
+
import { canWriteDocument, chainQueuedWrite, } from "../state.js";
|
|
10
10
|
import { captureDocumentStoreSyncGeneration, isDocumentStoreSyncGenerationCurrent, } from "../sync/syncGeneration.js";
|
|
11
11
|
import { resolveRowAttribution } from "./rowAttribution.js";
|
|
12
12
|
// Fixed literal: a reported message must never carry row ids or field values.
|
|
@@ -66,13 +66,12 @@ function queueRowMutation(state, mutate) {
|
|
|
66
66
|
// `setReadySnapshot` always re-derives them from the doc — so there is no
|
|
67
67
|
// optimistic snapshot for a concurrent sync pass to clobber. Input smoothness
|
|
68
68
|
// during rapid edits is handled in the app layer (useDocumentRowEditing).
|
|
69
|
-
state
|
|
69
|
+
return chainQueuedWrite(state, state.writeChain
|
|
70
70
|
.catch(() => undefined)
|
|
71
71
|
.then(async () => persistRowMutation(state, writeGeneration, mutate))
|
|
72
72
|
.catch((error) => {
|
|
73
73
|
reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);
|
|
74
|
-
});
|
|
75
|
-
return state.writeChain;
|
|
74
|
+
}));
|
|
76
75
|
}
|
|
77
76
|
export async function addRowToDocumentStore(state, scheduleSync, fields) {
|
|
78
77
|
const id = createDocumentRowId();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeVersionVector } from \"@tearleads/loro\";\nimport {\n addDocumentRow,\n createDocumentRowId,\n removeDocumentRow,\n setDocumentRowFields,\n} from \"../../../../data/documents/documentRowList\";\nimport { createPendingUpdateFields } from \"../../../../data/documents/documentSync\";\nimport { requestDocumentStoreSync } from \"../../registry\";\nimport { ensureDocumentStoreReady } from \"../initialization\";\nimport { revalidateDocumentMutationIdentity } from \"../mutationIdentityRevalidation\";\nimport {\n advancePendingBaseVersion,\n pendingDeltaSinceBase,\n persistDocument,\n} from \"../persistence\";\nimport { reportDocumentStoreWriteFailure } from \"../reportWriteFailure\";\nimport {\n canWriteDocument,\n type DocumentState,\n type DocumentStoreState,\n} from \"../state\";\nimport {\n captureDocumentStoreSyncGeneration,\n isDocumentStoreSyncGenerationCurrent,\n} from \"../sync/syncGeneration\";\nimport { resolveRowAttribution } from \"./rowAttribution\";\n\n// Fixed literal: a reported message must never carry row ids or field values.\nconst ROW_FAILURE_MESSAGE = \"Documents: row mutation failed\";\n\nasync function persistRowMutation(\n state: DocumentStoreState,\n expectedLocalWriteGeneration: number,\n mutate: (doc: DocumentState) => boolean,\n): Promise<void> {\n if (state.localWriteGeneration !== expectedLocalWriteGeneration) {\n return;\n }\n const currentDoc = state.doc;\n if (!currentDoc || !canWriteDocument(state)) {\n return;\n }\n const generation = captureDocumentStoreSyncGeneration(state, currentDoc);\n if (!generation) {\n return;\n }\n\n if (!mutate(currentDoc)) {\n await revalidateDocumentMutationIdentity({ currentDoc, generation, state });\n return;\n }\n\n const update = pendingDeltaSinceBase(state, currentDoc);\n if (update.byteLength === 0) {\n await revalidateDocumentMutationIdentity({ currentDoc, generation, state });\n return;\n }\n // Captured at delta time: the enqueued row proves coverage up to exactly\n // this version, so it is the frontier the persist below may publish.\n const coveredVersion = encodeVersionVector(currentDoc);\n\n const pendingUpdate = createPendingUpdateFields(update);\n if (!pendingUpdate) {\n await revalidateDocumentMutationIdentity({ currentDoc, generation, state });\n return;\n }\n // Row writes change neither prose nor structured fields; setReadySnapshot\n // always re-derives rows from the doc, so preserve the text/structured fields\n // in case this write overlaps an in-flight keystroke elsewhere.\n const persisted = await persistDocument(\n state,\n currentDoc,\n { snapshotEndVersion: coveredVersion },\n {\n pendingUpdate,\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n },\n generation,\n );\n if (\n !persisted ||\n persisted.pullContinuationSuperseded ||\n persisted.syncIdentitySuperseded ||\n !isDocumentStoreSyncGenerationCurrent(state, generation)\n ) {\n // Refused: the document was deleted while this persist was queued\n // and the store is cleared — no state advance, no sync request.\n return;\n }\n advancePendingBaseVersion(state, currentDoc);\n requestDocumentStoreSync(state);\n}\n\nfunction queueRowMutation(\n state: DocumentStoreState,\n mutate: (doc: DocumentState) => boolean,\n): Promise<void> {\n const writeGeneration = state.localWriteGeneration;\n // Unlike text/structured-field writes, row writes intentionally do NOT bump\n // `state.pendingLocalWrites`: rows are never in the optimistic-preserve set —\n // `setReadySnapshot` always re-derives them from the doc — so there is no\n // optimistic snapshot for a concurrent sync pass to clobber. Input smoothness\n // during rapid edits is handled in the app layer (useDocumentRowEditing).\n state.writeChain = state.writeChain\n .catch(() => undefined)\n .then(async () => persistRowMutation(state, writeGeneration, mutate))\n .catch((error: unknown) => {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n });\n return state.writeChain;\n}\n\nexport async function addRowToDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n fields: Readonly<Record<string, string>>,\n): Promise<string> {\n const id = createDocumentRowId();\n let ready: boolean;\n try {\n ready = await ensureDocumentStoreReady(state, scheduleSync);\n } catch (error) {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n return id;\n }\n\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return id;\n }\n\n await queueRowMutation(state, (doc) => {\n addDocumentRow(doc, id, fields, resolveRowAttribution(state));\n return true;\n });\n return id;\n}\n\nexport async function updateRowInDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n id: string,\n patch: Readonly<Record<string, string>>,\n): Promise<void> {\n let ready: boolean;\n try {\n ready = await ensureDocumentStoreReady(state, scheduleSync);\n } catch (error) {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n return;\n }\n\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n await queueRowMutation(state, (doc) =>\n setDocumentRowFields(doc, id, patch, resolveRowAttribution(state)),\n );\n}\n\nexport async function removeRowFromDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n id: string,\n): Promise<void> {\n let ready: boolean;\n try {\n ready = await ensureDocumentStoreReady(state, scheduleSync);\n } catch (error) {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n return;\n }\n\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n await queueRowMutation(state, (doc) => removeDocumentRow(doc, id));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeVersionVector } from \"@tearleads/loro\";\nimport {\n addDocumentRow,\n createDocumentRowId,\n removeDocumentRow,\n setDocumentRowFields,\n} from \"../../../../data/documents/documentRowList\";\nimport { createPendingUpdateFields } from \"../../../../data/documents/documentSync\";\nimport { requestDocumentStoreSync } from \"../../registry\";\nimport { ensureDocumentStoreReady } from \"../initialization\";\nimport { revalidateDocumentMutationIdentity } from \"../mutationIdentityRevalidation\";\nimport {\n advancePendingBaseVersion,\n pendingDeltaSinceBase,\n persistDocument,\n} from \"../persistence\";\nimport { reportDocumentStoreWriteFailure } from \"../reportWriteFailure\";\nimport {\n canWriteDocument,\n chainQueuedWrite,\n type DocumentState,\n type DocumentStoreState,\n} from \"../state\";\nimport {\n captureDocumentStoreSyncGeneration,\n isDocumentStoreSyncGenerationCurrent,\n} from \"../sync/syncGeneration\";\nimport { resolveRowAttribution } from \"./rowAttribution\";\n\n// Fixed literal: a reported message must never carry row ids or field values.\nconst ROW_FAILURE_MESSAGE = \"Documents: row mutation failed\";\n\nasync function persistRowMutation(\n state: DocumentStoreState,\n expectedLocalWriteGeneration: number,\n mutate: (doc: DocumentState) => boolean,\n): Promise<void> {\n if (state.localWriteGeneration !== expectedLocalWriteGeneration) {\n return;\n }\n const currentDoc = state.doc;\n if (!currentDoc || !canWriteDocument(state)) {\n return;\n }\n const generation = captureDocumentStoreSyncGeneration(state, currentDoc);\n if (!generation) {\n return;\n }\n\n if (!mutate(currentDoc)) {\n await revalidateDocumentMutationIdentity({ currentDoc, generation, state });\n return;\n }\n\n const update = pendingDeltaSinceBase(state, currentDoc);\n if (update.byteLength === 0) {\n await revalidateDocumentMutationIdentity({ currentDoc, generation, state });\n return;\n }\n // Captured at delta time: the enqueued row proves coverage up to exactly\n // this version, so it is the frontier the persist below may publish.\n const coveredVersion = encodeVersionVector(currentDoc);\n\n const pendingUpdate = createPendingUpdateFields(update);\n if (!pendingUpdate) {\n await revalidateDocumentMutationIdentity({ currentDoc, generation, state });\n return;\n }\n // Row writes change neither prose nor structured fields; setReadySnapshot\n // always re-derives rows from the doc, so preserve the text/structured fields\n // in case this write overlaps an in-flight keystroke elsewhere.\n const persisted = await persistDocument(\n state,\n currentDoc,\n { snapshotEndVersion: coveredVersion },\n {\n pendingUpdate,\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n },\n generation,\n );\n if (\n !persisted ||\n persisted.pullContinuationSuperseded ||\n persisted.syncIdentitySuperseded ||\n !isDocumentStoreSyncGenerationCurrent(state, generation)\n ) {\n // Refused: the document was deleted while this persist was queued\n // and the store is cleared — no state advance, no sync request.\n return;\n }\n advancePendingBaseVersion(state, currentDoc);\n requestDocumentStoreSync(state);\n}\n\nfunction queueRowMutation(\n state: DocumentStoreState,\n mutate: (doc: DocumentState) => boolean,\n): Promise<void> {\n const writeGeneration = state.localWriteGeneration;\n // Unlike text/structured-field writes, row writes intentionally do NOT bump\n // `state.pendingLocalWrites`: rows are never in the optimistic-preserve set —\n // `setReadySnapshot` always re-derives them from the doc — so there is no\n // optimistic snapshot for a concurrent sync pass to clobber. Input smoothness\n // during rapid edits is handled in the app layer (useDocumentRowEditing).\n return chainQueuedWrite(\n state,\n state.writeChain\n .catch(() => undefined)\n .then(async () => persistRowMutation(state, writeGeneration, mutate))\n .catch((error: unknown) => {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n }),\n );\n}\n\nexport async function addRowToDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n fields: Readonly<Record<string, string>>,\n): Promise<string> {\n const id = createDocumentRowId();\n let ready: boolean;\n try {\n ready = await ensureDocumentStoreReady(state, scheduleSync);\n } catch (error) {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n return id;\n }\n\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return id;\n }\n\n await queueRowMutation(state, (doc) => {\n addDocumentRow(doc, id, fields, resolveRowAttribution(state));\n return true;\n });\n return id;\n}\n\nexport async function updateRowInDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n id: string,\n patch: Readonly<Record<string, string>>,\n): Promise<void> {\n let ready: boolean;\n try {\n ready = await ensureDocumentStoreReady(state, scheduleSync);\n } catch (error) {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n return;\n }\n\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n await queueRowMutation(state, (doc) =>\n setDocumentRowFields(doc, id, patch, resolveRowAttribution(state)),\n );\n}\n\nexport async function removeRowFromDocumentStore(\n state: DocumentStoreState,\n scheduleSync: () => void,\n id: string,\n): Promise<void> {\n let ready: boolean;\n try {\n ready = await ensureDocumentStoreReady(state, scheduleSync);\n } catch (error) {\n reportDocumentStoreWriteFailure(state, ROW_FAILURE_MESSAGE, error);\n return;\n }\n\n if (!ready || !state.doc || !canWriteDocument(state)) {\n return;\n }\n\n await queueRowMutation(state, (doc) => removeDocumentRow(doc, id));\n}\n"]}
|
|
@@ -45,6 +45,7 @@ export function createDocumentStoreState(localId, initialRuntime, persistence, e
|
|
|
45
45
|
pendingBaseVersion: null,
|
|
46
46
|
pendingLocalWrites: 0,
|
|
47
47
|
persistence,
|
|
48
|
+
queuedWrites: 0,
|
|
48
49
|
pullContinuation: null,
|
|
49
50
|
record: null,
|
|
50
51
|
rejectedServedAttachmentBindings: new Set(),
|
|
@@ -194,4 +195,21 @@ export function subscribeToDocumentStore(state, listener) {
|
|
|
194
195
|
state.listeners.add(listener);
|
|
195
196
|
return () => void state.listeners.delete(listener);
|
|
196
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Counts `write` in `queuedWrites` until it settles. Counted synchronously, so
|
|
200
|
+
* a write started while a removal runs is visible to its commit guard.
|
|
201
|
+
*/
|
|
202
|
+
export function countQueuedWrite(state, write) {
|
|
203
|
+
state.queuedWrites += 1;
|
|
204
|
+
const settle = () => {
|
|
205
|
+
state.queuedWrites -= 1;
|
|
206
|
+
};
|
|
207
|
+
void write.then(settle, settle);
|
|
208
|
+
return write;
|
|
209
|
+
}
|
|
210
|
+
/** Installs `link` as the store's write chain, counted until it settles. */
|
|
211
|
+
export function chainQueuedWrite(state, link) {
|
|
212
|
+
state.writeChain = countQueuedWrite(state, link);
|
|
213
|
+
return state.writeChain;
|
|
214
|
+
}
|
|
197
215
|
//# sourceMappingURL=state.js.map
|