import { Plugin, PluginKey } from "prosemirror-state"; import { type Mark, type MarkType, type Node } from "prosemirror-model"; export type Author = string; export interface AuthorInfo { name: string; picture?: string; } export interface SuggestionReply { id: string; author: Author; content: string; timestamp: number; } export type SuggestionSubtype = "insert" | "delete" | "format" | "comment"; export interface SuggestionNodeMeta { type: SuggestionSubtype; id: string; } export interface SuggestionFormatNodeMeta extends SuggestionNodeMeta { type: "format"; oldAttrs: Record; } export declare function findSuggestionMark(marks: readonly Mark[], suggestionType: MarkType, subtype: SuggestionSubtype): Mark | undefined; export declare function getNodeSuggestions(node: Node): SuggestionNodeMeta[]; export declare function findNodeSuggestion(node: Node, subtype: SuggestionSubtype): SuggestionNodeMeta | undefined; export declare function withNodeSuggestion(node: Node, meta: SuggestionNodeMeta): SuggestionNodeMeta[]; export declare function withoutNodeSuggestion(node: Node, id: string): SuggestionNodeMeta[] | null; export declare function collectSuggestionIds(doc: Node, suggestionType: MarkType): Set; export type SuggestionMode = "editing" | "suggesting"; export interface SuggestionSourceEntry { author: Author; timestamp: number; comments: SuggestionReply[]; } export interface SuggestionSource { get: (ids: string[]) => Promise>; create: (id: string, type: SuggestionSubtype, author: Author, timestamp: number) => void; reply: (id: string, reply: SuggestionReply) => void; resolve?: (id: string, decision: "accept" | "reject" | "resolve") => void; editReply?: (id: string, replyId: string, content: string) => void; deleteReply?: (id: string, replyId: string) => void; } export type SuggestionEvent = { kind: "create"; id: string; type: SuggestionSubtype; author: Author; timestamp: number; } | { kind: "reply"; id: string; reply: SuggestionReply; } | { kind: "editReply"; id: string; replyId: string; content: string; } | { kind: "deleteReply"; id: string; replyId: string; } | { kind: "resolve"; id: string; decision: "accept" | "reject" | "resolve"; } | { kind: "loaded"; entries: Record; }; export interface SuggestionsPluginState { mode: SuggestionMode; author: Author; resolveAuthor: (author: Author) => AuthorInfo | Promise; source: SuggestionSource; disableCommenting: boolean; cache: Record; pendingEvents: SuggestionEvent[]; } export interface SuggestionsPluginConfig { author: Author; mode?: SuggestionMode; resolveAuthor: (author: Author) => AuthorInfo | Promise; source: SuggestionSource; disableCommenting?: boolean; } export declare const suggestionsPluginKey: PluginKey; export declare const SUGGESTIONS_SKIP_META = "suggestionsSkip"; export declare function generateSuggestionId(): string; /** * Provides suggestions & comments features. * * ## Suggestion Mode * When suggestion mode is on (config.mode === 'suggestion' for initial or later suggestions.setMode()), * all edits are rewritten into suggestion marks (insert/delete/format type). * * For nodes, suggestion mode is applied via suggestions attribute added to the node. * Supported by all nodes except doc and text. * * The document only saves a suggestion ID. It's the host app's responsibility to * save suggestions & replies in a persistent store. * * This plugin only produces "delete" type for nodes. insert or format for whole nodes * are only provided by the diff lib. * * ## Comments * Comments are built on top of suggestions. * They can be created using the node menu or the marks tooltip. */ export default function suggestionsPlugin(config: SuggestionsPluginConfig): Plugin;