/** * Keeps one editor's suggestion marks and Velt in step. * * - Follows Velt's suggestion mode and signed-in user (→ plugin state). * - Commits the current user's pending clusters (idle / blur / block change / page hidden): * registers a getter, calls `commitSuggestion`, then gives the cluster its target id. A cluster is * frozen while it is committed, so new keystrokes start a new one. * - Applies accept / reject / stale from Velt's events, and reconciles the document with Velt's * suggestion list (a suggestion resolved while this editor was closed is applied on load). * * Talks to Velt only through the `SuggestionVeltPort` it is given. */ import type { Editor } from '@tiptap/core'; import type { SuggestionSummaryInput, TiptapVeltSuggestionsOptions } from './types'; interface Subscribable { subscribe: (next: (value: T) => void) => { unsubscribe: () => void; }; } /** The Velt surface the sync needs (implemented over `window.Velt` by the adapter). */ export interface SuggestionVeltPort { registerTarget: (config: { targetId: string; getter: () => unknown; }) => void; unregisterTarget: (targetId: string) => void; commitSuggestion: (config: { targetId: string; newValue: unknown; summary?: string; metadata?: Record; }) => Promise; enableSuggestionMode: () => void; disableSuggestionMode: () => void; isSuggestionModeEnabled$: () => Subscribable; getSuggestions$: () => Subscribable | null | undefined>; on: (event: 'suggestionApproved' | 'suggestionRejected' | 'suggestionStale') => Subscribable<{ suggestion?: { targetId?: string; }; } | null | undefined>; currentUser$: () => Subscribable<{ userId?: string; } | null | undefined> | null; } /** A stable colour per user id. */ export declare const colorForUser: (userId: string) => string; /** The default one-line summary (the first comment of the suggestion). */ export declare const defaultSummary: ({ kind, oldText, newText, markName }: SuggestionSummaryInput) => string; export declare class SuggestionSync { private readonly editor; private readonly options; private readonly port; private subscriptions; private debounce; private lastBlock; /** pendingId → the target id it is committed under (fixed across retries). */ private targetIds; /** Target ids with a registered getter. */ private registered; private inFlight; /** Resolutions that arrived while their commit was still in flight (targetId → outcome). */ private earlyResolutions; /** Velt's latest suggestion list: content loaded later is reconciled against it. */ private lastList; private attached; private destroyed; constructor(editor: Editor, options: TiptapVeltSuggestionsOptions, port: SuggestionVeltPort); /** Starts following Velt. Call once Velt is loaded. */ attach(): void; destroy(): void; /** Commits every pending cluster of the current user. Resolves when the commits settle. */ flush(exceptPendingId?: string | null): Promise; /** Turns suggesting on, or flushes pending edits and then turns it off. */ setSuggesting(enabled: boolean): Promise; /** * Commits pending edits until none is left that was not tried yet — including edits typed while an * earlier commit was in flight. Each cluster is tried once, so a failing one cannot loop. */ private drain; private pluginState; private setPluginState; private freeze; private readonly onTransaction; private readonly onSelectionUpdate; private readonly onBlur; private readonly onVisibilityChange; /** The getter Velt reads for a target's current value (the text the suggestion replaces). */ private getter; private commit; /** Applies a resolution from Velt to this document (no-op when it has no such suggestion). */ private resolve; /** Velt's list → resolve committed marks whose suggestion is no longer pending; register getters for the rest. */ private reconcile; /** Every committed suggestion in the document has a getter; removed ones lose theirs. */ private syncGetters; private unregister; private reportError; } export {};