import { Annotation, ChangeSet } from '@codemirror/state' import type { NodeIndexResult } from '../automerge-markdown' import type { Heads } from './heads' import type { DocumentManager } from '../services/document-manager' import { diffTextChanges } from './text-diff' export type SaveStatus = | { state: 'idle' } | { state: 'saving' } | { state: 'saved' } | { state: 'error'; message: string } export type DocumentId = Parameters[0] export type LoadPhase = 'loading' | 'ready' | 'error' | 'disposed' export type SubscriptionPhase = 'detached' | 'resolving' | 'attached' export type SavePhase = 'idle' | 'pending-plain' | 'saving-plain' | 'queued-semantic' | 'saving-semantic' | 'saved' | 'error' export interface SyncTextState { documentId: DocumentId heads: Heads content: string beforeContent?: string afterContent?: string } export interface DocumentSyncSnapshot { sessionId: number docUrl: DocumentId loadPhase: LoadPhase loadError: string | undefined content: string | undefined saveStatus: SaveStatus savePhase: SavePhase isConcurrentTabOpen: boolean localGeneration: number persistedGeneration: number boundViewGeneration: number subscriptionPhase: SubscriptionPhase saveAttemptCount: number lastSaveOutcome: 'accepted' | 'rejected' | null lastSaveOutcomeGeneration: number | null markdownNodeIndex: NodeIndexResult | null settledEditorText: string | undefined persistedMarkdown: string | undefined checkpoint: SyncTextState | null durableHeads: Heads materializedHeads: Heads } export const REMOTE_CHANGE_ANNOTATION: ReturnType> = Annotation.define() export function projectionChange(oldText: string, newText: string): ChangeSet { return ChangeSet.of(diffTextChanges(oldText, newText), oldText.length) }