@malva-ui/editor 0.1.13 → 0.1.14
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/README.md +5 -5
- package/fesm2022/malva-ui-editor-ai.mjs +17 -0
- package/fesm2022/malva-ui-editor-ai.mjs.map +1 -0
- package/fesm2022/malva-ui-editor.mjs +10227 -0
- package/fesm2022/malva-ui-editor.mjs.map +1 -0
- package/package.json +35 -26
- package/types/malva-ui-editor-ai.d.ts +1 -0
- package/types/malva-ui-editor.d.ts +2995 -0
- package/ai/index.d.ts +0 -12
- package/ai/malva-ui-editor-ai.d.ts +0 -5
- package/esm2022/ai/index.js +0 -12
- package/esm2022/ai/index.js.map +0 -1
- package/esm2022/ai/malva-ui-editor-ai.js +0 -5
- package/esm2022/ai/malva-ui-editor-ai.js.map +0 -1
- package/esm2022/index.js +0 -37
- package/esm2022/index.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-actions.js +0 -69
- package/esm2022/lib/ai/editor-ai-actions.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-context.js +0 -612
- package/esm2022/lib/ai/editor-ai-context.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-menu.js +0 -288
- package/esm2022/lib/ai/editor-ai-menu.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-review-bar.js +0 -223
- package/esm2022/lib/ai/editor-ai-review-bar.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-stream.js +0 -677
- package/esm2022/lib/ai/editor-ai-stream.js.map +0 -1
- package/esm2022/lib/ai/editor-ai-suggestions.js +0 -751
- package/esm2022/lib/ai/editor-ai-suggestions.js.map +0 -1
- package/esm2022/lib/ai/editor-ai.tokens.js +0 -10
- package/esm2022/lib/ai/editor-ai.tokens.js.map +0 -1
- package/esm2022/lib/ai/editor-ai.types.js +0 -1
- package/esm2022/lib/ai/editor-ai.types.js.map +0 -1
- package/esm2022/lib/editor/editor.js +0 -985
- package/esm2022/lib/editor/editor.js.map +0 -1
- package/esm2022/lib/editor-extension-preflight.js +0 -83
- package/esm2022/lib/editor-extension-preflight.js.map +0 -1
- package/esm2022/lib/editor-serialization.js +0 -152
- package/esm2022/lib/editor-serialization.js.map +0 -1
- package/esm2022/lib/editor-toolbar-context.js +0 -259
- package/esm2022/lib/editor-toolbar-context.js.map +0 -1
- package/esm2022/lib/editor.tokens.js +0 -10
- package/esm2022/lib/editor.tokens.js.map +0 -1
- package/esm2022/lib/editor.types.js +0 -48
- package/esm2022/lib/editor.types.js.map +0 -1
- package/esm2022/lib/extensions/editor-block-handle.js +0 -760
- package/esm2022/lib/extensions/editor-block-handle.js.map +0 -1
- package/esm2022/lib/extensions/editor-extensions.js +0 -321
- package/esm2022/lib/extensions/editor-extensions.js.map +0 -1
- package/esm2022/lib/extensions/editor-markdown-compatibility.js +0 -162
- package/esm2022/lib/extensions/editor-markdown-compatibility.js.map +0 -1
- package/esm2022/lib/extensions/editor-upload-placeholder.js +0 -156
- package/esm2022/lib/extensions/editor-upload-placeholder.js.map +0 -1
- package/esm2022/lib/status/editor-status.js +0 -64
- package/esm2022/lib/status/editor-status.js.map +0 -1
- package/esm2022/lib/toolbar/editor-alignment.js +0 -203
- package/esm2022/lib/toolbar/editor-alignment.js.map +0 -1
- package/esm2022/lib/toolbar/editor-block-insert.js +0 -101
- package/esm2022/lib/toolbar/editor-block-insert.js.map +0 -1
- package/esm2022/lib/toolbar/editor-color-control.js +0 -71
- package/esm2022/lib/toolbar/editor-color-control.js.map +0 -1
- package/esm2022/lib/toolbar/editor-command-button.js +0 -115
- package/esm2022/lib/toolbar/editor-command-button.js.map +0 -1
- package/esm2022/lib/toolbar/editor-heading.js +0 -266
- package/esm2022/lib/toolbar/editor-heading.js.map +0 -1
- package/esm2022/lib/toolbar/editor-highlight.js +0 -84
- package/esm2022/lib/toolbar/editor-highlight.js.map +0 -1
- package/esm2022/lib/toolbar/editor-image-upload-dialog.js +0 -289
- package/esm2022/lib/toolbar/editor-image-upload-dialog.js.map +0 -1
- package/esm2022/lib/toolbar/editor-image-upload.js +0 -315
- package/esm2022/lib/toolbar/editor-image-upload.js.map +0 -1
- package/esm2022/lib/toolbar/editor-inline-marks.js +0 -124
- package/esm2022/lib/toolbar/editor-inline-marks.js.map +0 -1
- package/esm2022/lib/toolbar/editor-link.js +0 -265
- package/esm2022/lib/toolbar/editor-link.js.map +0 -1
- package/esm2022/lib/toolbar/editor-list.js +0 -249
- package/esm2022/lib/toolbar/editor-list.js.map +0 -1
- package/esm2022/lib/toolbar/editor-table.js +0 -292
- package/esm2022/lib/toolbar/editor-table.js.map +0 -1
- package/esm2022/lib/toolbar/editor-text-color.js +0 -82
- package/esm2022/lib/toolbar/editor-text-color.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar-widget.js +0 -41
- package/esm2022/lib/toolbar/editor-toolbar-widget.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar.defs.js +0 -60
- package/esm2022/lib/toolbar/editor-toolbar.defs.js.map +0 -1
- package/esm2022/lib/toolbar/editor-toolbar.js +0 -826
- package/esm2022/lib/toolbar/editor-toolbar.js.map +0 -1
- package/esm2022/lib/toolbar/editor-undo-redo.js +0 -72
- package/esm2022/lib/toolbar/editor-undo-redo.js.map +0 -1
- package/esm2022/lib/toolbar/editor-zoom.js +0 -330
- package/esm2022/lib/toolbar/editor-zoom.js.map +0 -1
- package/esm2022/lib/upload/editor-image-upload-coordinator.js +0 -480
- package/esm2022/lib/upload/editor-image-upload-coordinator.js.map +0 -1
- package/esm2022/malva-ui-editor.js +0 -5
- package/esm2022/malva-ui-editor.js.map +0 -1
- package/index.d.ts +0 -35
- package/lib/ai/editor-ai-actions.d.ts +0 -27
- package/lib/ai/editor-ai-context.d.ts +0 -307
- package/lib/ai/editor-ai-menu.d.ts +0 -142
- package/lib/ai/editor-ai-review-bar.d.ts +0 -116
- package/lib/ai/editor-ai-stream.d.ts +0 -207
- package/lib/ai/editor-ai-suggestions.d.ts +0 -219
- package/lib/ai/editor-ai.tokens.d.ts +0 -10
- package/lib/ai/editor-ai.types.d.ts +0 -176
- package/lib/editor/editor.d.ts +0 -243
- package/lib/editor-extension-preflight.d.ts +0 -23
- package/lib/editor-serialization.d.ts +0 -74
- package/lib/editor-toolbar-context.d.ts +0 -116
- package/lib/editor.tokens.d.ts +0 -6
- package/lib/editor.types.d.ts +0 -194
- package/lib/extensions/editor-block-handle.d.ts +0 -59
- package/lib/extensions/editor-extensions.d.ts +0 -165
- package/lib/extensions/editor-markdown-compatibility.d.ts +0 -11
- package/lib/extensions/editor-upload-placeholder.d.ts +0 -75
- package/lib/status/editor-status.d.ts +0 -24
- package/lib/toolbar/editor-alignment.d.ts +0 -61
- package/lib/toolbar/editor-block-insert.d.ts +0 -26
- package/lib/toolbar/editor-color-control.d.ts +0 -32
- package/lib/toolbar/editor-command-button.d.ts +0 -29
- package/lib/toolbar/editor-heading.d.ts +0 -68
- package/lib/toolbar/editor-highlight.d.ts +0 -21
- package/lib/toolbar/editor-image-upload-dialog.d.ts +0 -96
- package/lib/toolbar/editor-image-upload.d.ts +0 -71
- package/lib/toolbar/editor-inline-marks.d.ts +0 -30
- package/lib/toolbar/editor-link.d.ts +0 -78
- package/lib/toolbar/editor-list.d.ts +0 -67
- package/lib/toolbar/editor-table.d.ts +0 -133
- package/lib/toolbar/editor-text-color.d.ts +0 -21
- package/lib/toolbar/editor-toolbar-widget.d.ts +0 -19
- package/lib/toolbar/editor-toolbar.d.ts +0 -157
- package/lib/toolbar/editor-toolbar.defs.d.ts +0 -35
- package/lib/toolbar/editor-undo-redo.d.ts +0 -26
- package/lib/toolbar/editor-zoom.d.ts +0 -108
- package/lib/upload/editor-image-upload-coordinator.d.ts +0 -55
- package/malva-ui-editor.d.ts +0 -5
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor-ai-stream.js","sourceRoot":"","sources":["../../../../../../libs/editor/src/lib/ai/editor-ai-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Editor, EditorEvents, JSONContent } from '@tiptap/core';\n// Type-only: augments `Editor` with the optional `markdown` manager the final\n// commit parses through. Erased at compile time, so the engine stays free of\n// any runtime dependency on the Markdown extension.\nimport type {} from '@tiptap/markdown';\nimport { closeHistory } from '@tiptap/pm/history';\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model';\nimport type { EditorState, Transaction } from '@tiptap/pm/state';\nimport { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport type { MlvEditorErrorCode } from '../editor.types';\nimport type { MlvEditorAiOutputMode } from './editor-ai.types';\n\n/**\n * CSS class of the inline decoration marking the active streaming region.\n *\n * The class is applied through a ProseMirror decoration held in plugin state,\n * never through document content, so it can appear in no HTML, Markdown, or\n * JSON serialization.\n */\nexport const MLV_EDITOR_AI_STREAMING_CLASS = 'mlv-editor__ai-streaming';\n\n/**\n * CSS class of the one-shot inline decoration over each flush's newly\n * revealed slice of the streaming region.\n *\n * Created exactly once per revealed delta and only mapped afterwards — never\n * rebuilt for old ranges — so a one-shot CSS entrance animation runs once per\n * chunk and earlier text never re-animates. Removed with the region\n * decoration on commit, cancel, and abandonment, and excluded from every\n * serialization the same way.\n */\nexport const MLV_EDITOR_AI_STREAMING_CHUNK_CLASS =\n 'mlv-editor__ai-streaming-chunk';\n\n/**\n * CSS class of the `aria-hidden` widget decoration the streaming engine\n * keeps at the current insertion tip while a writing session is active.\n *\n * View-layer only: it exists in no HTML, Markdown, or JSON serialization and\n * is removed when the session settles (commit, cancel, abandonment, failure).\n * Collect-only `'review'` sessions never render it — they never write.\n */\nexport const MLV_EDITOR_AI_CARET_CLASS = 'mlv-editor__ai-caret';\n\n/**\n * Output modes a streaming session supports.\n *\n * `'replace-selection'` and `'insert-below'` write into the document while\n * streaming. `'review'` is collect-only: the session runs the full lifecycle\n * — Escape cancellation, external-transaction abandonment, transport/result\n * error detection — but never writes; the caller routes the accumulated text\n * through the suggestion engine after commit.\n */\nexport type MlvEditorAiStreamOutputMode = MlvEditorAiOutputMode;\n\n/**\n * Error categories a streaming session can report.\n *\n * `'ai-transport'` — the chunk iterable threw or rejected mid-stream.\n * `'ai-result'` — the completed stream produced no usable content (empty or\n * whitespace-only total output), or the target region rejected the write.\n * Both are narrowed from {@link MlvEditorErrorCode} so hosts can forward them\n * to `editorError` unchanged.\n */\nexport type MlvEditorAiStreamErrorCode = Extract<\n MlvEditorErrorCode,\n 'ai-transport' | 'ai-result'\n>;\n\n/**\n * Terminal state of one streaming session.\n *\n * `'committed'` — the stream completed and the final content landed as exactly\n * one history-visible step. `'cancelled'` — {@link MlvEditorAiStreamHandle.cancel}\n * aborted the session and the checkpoint was restored silently. `'abandoned'`\n * — an external document change ended the session without any restore.\n * `'failed'` — the session ended with an {@link MlvEditorAiStreamErrorCode}\n * and the checkpoint was restored.\n */\nexport type MlvEditorAiStreamStatus =\n | 'committed'\n | 'cancelled'\n | 'abandoned'\n | 'failed';\n\n/**\n * Schedules one buffered-chunk flush for the next animation frame.\n *\n * Receives the flush callback and returns a cancel function. The default\n * implementation uses `requestAnimationFrame` and falls back to a short\n * `setTimeout` where no frame API exists (server rendering, test DOMs).\n * Tests inject a manual scheduler to control flush timing deterministically.\n */\nexport type MlvEditorAiFrameScheduler = (flush: () => void) => () => void;\n\n/** Options accepted by {@link runMlvEditorAiStream}. */\nexport interface MlvEditorAiStreamOptions {\n /**\n * Markdown/text chunks in document order, typically produced by an\n * `MlvEditorAiProvider`. A non-streaming source may yield a single chunk.\n */\n readonly chunks: AsyncIterable<string>;\n\n /**\n * Where the streamed content lands: `'replace-selection'` replaces the\n * selection captured when the session started, `'insert-below'` streams\n * into a new paragraph after the selection's top-level block, and\n * `'review'` collects the complete stream without touching the document —\n * the result is read from {@link MlvEditorAiStreamResult.text}.\n */\n readonly output: MlvEditorAiStreamOutputMode;\n\n /** Frame scheduler override; defaults to `requestAnimationFrame`. */\n readonly scheduler?: MlvEditorAiFrameScheduler;\n\n /**\n * Maximum characters one frame flush reveals into the document. Buffered\n * text beyond the cap carries over: the session keeps scheduling follow-up\n * frames until the buffer drains, so bursty provider chunks render at an\n * even typing cadence instead of appearing in per-chunk lumps. Defaults to\n * 4; `Infinity` restores the uncapped write-everything-per-frame behavior.\n * Non-finite values other than `Infinity` and values below 1 fall back to\n * the default; fractions are floored. The cap never delays settlement —\n * commit, cancellation, and abandonment still apply the complete\n * accumulated text immediately. Collect-only `'review'` sessions ignore it\n * entirely (they never flush).\n */\n readonly revealCharsPerFrame?: number;\n}\n\n/** Terminal result every streaming session resolves with; it never rejects. */\nexport interface MlvEditorAiStreamResult {\n /** Terminal state of the session. */\n readonly status: MlvEditorAiStreamStatus;\n\n /** Error category for `'failed'` sessions, `null` for every other status. */\n readonly error: MlvEditorAiStreamErrorCode | null;\n\n /**\n * Whether the session was stopped before completing: `true` for\n * `'cancelled'` and `'abandoned'`, `false` for `'committed'` and\n * `'failed'`. Cancellation and abandonment are silent — neither carries an\n * error code.\n */\n readonly aborted: boolean;\n\n /** Complete text accumulated from the stream, including unwritten chunks. */\n readonly text: string;\n}\n\n/** Handle controlling one in-flight or finished streaming session. */\nexport interface MlvEditorAiStreamHandle {\n /** Resolves with the terminal {@link MlvEditorAiStreamResult}; never rejects. */\n readonly done: Promise<MlvEditorAiStreamResult>;\n\n /**\n * Aborts an in-flight session: stops consuming chunks, restores the\n * checkpoint through a history-invisible step, and resolves {@link done}\n * with `'cancelled'` and no error. A no-op once the session has settled.\n */\n cancel(): void;\n\n /**\n * Restores the checkpoint captured when the session started.\n *\n * While the session is running this behaves exactly like {@link cancel}.\n * After the session has settled it replaces the whole document with the\n * checkpoint in one history-visible step — so a post-commit restore is\n * itself undoable. Returns whether the document changed; `false` when the\n * document already matches the checkpoint or the editor was destroyed.\n * After an `'abandoned'` session this overwrites the external edit too —\n * callers own that decision.\n */\n restoreCheckpoint(): boolean;\n}\n\n/** @internal Streaming target region tracked by the session plugin. */\ninterface MlvEditorAiStreamRegion {\n /** Document position where the streamed content begins. */\n readonly from: number;\n\n /** Document position where the streamed content ends. */\n readonly to: number;\n}\n\n/**\n * @internal State the session plugin holds: the tracked region plus the\n * decoration set carrying one entrance decoration per revealed chunk and the\n * caret widget at the insertion tip. Chunk decorations are created once per\n * flush and only mapped afterwards, so their DOM never rebuilds and the\n * one-shot CSS entrance cannot re-run over earlier text.\n */\ninterface MlvEditorAiStreamPluginState {\n /** Streaming target region, `null` before the first write. */\n readonly region: MlvEditorAiStreamRegion | null;\n\n /** Region tint, per-chunk entrance decorations, and the caret widget. */\n readonly decorations: DecorationSet;\n}\n\n/** @internal Transaction metadata updating or clearing the tracked region. */\ntype MlvEditorAiStreamMetadata =\n | {\n readonly type: 'set';\n readonly from: number;\n readonly to: number;\n /** Start of the slice this flush revealed (post-transaction position). */\n readonly chunkFrom: number;\n /** End of the slice this flush revealed (post-transaction position). */\n readonly chunkTo: number;\n }\n | { readonly type: 'clear' };\n\n/**\n * @internal Key identifying the per-session streaming plugin. Every\n * transaction the session dispatches carries metadata under this key, which\n * is also how the external-transaction listener tells session writes apart\n * from foreign document changes.\n */\nconst MLV_EDITOR_AI_STREAM_KEY =\n new PluginKey<MlvEditorAiStreamPluginState | null>('mlvEditorAiStream');\n\n/** @internal Metadata clearing the region on restore and commit transactions. */\nconst MLV_EDITOR_AI_CLEAR_METADATA: MlvEditorAiStreamMetadata = {\n type: 'clear',\n};\n\n/** @internal Empty plugin state shared by init and every clear. */\nconst MLV_EDITOR_AI_EMPTY_PLUGIN_STATE: MlvEditorAiStreamPluginState = {\n region: null,\n decorations: DecorationSet.empty,\n};\n\n/**\n * @internal Default {@link MlvEditorAiStreamOptions.revealCharsPerFrame}:\n * about four characters per frame reads as fast, steady typing at 60 fps\n * without the per-chunk lurch of uncapped writes.\n */\nconst MLV_EDITOR_AI_DEFAULT_REVEAL_CAP = 4;\n\n/**\n * @internal Spec marker identifying the caret widget inside the decoration\n * set, so each flush can remove the previous caret before re-anchoring it at\n * the new insertion tip.\n */\nconst MLV_EDITOR_AI_CARET_SPEC = 'mlvEditorAiCaret';\n\n/**\n * @internal Spec marker identifying the whole-region tint decoration, which\n * is rebuilt on every flush because its range grows — unlike the per-chunk\n * decorations, which are created once and only mapped.\n */\nconst MLV_EDITOR_AI_REGION_SPEC = 'mlvEditorAiRegion';\n\n/**\n * @internal Normalizes the reveal cap: `Infinity` is honoured as \"uncapped\",\n * unusable values fall back to the default, fractions floor.\n */\nconst normalizeRevealCap = (value: number | undefined): number => {\n if (value === Number.POSITIVE_INFINITY) return value;\n if (value === undefined || !Number.isFinite(value) || value < 1) {\n return MLV_EDITOR_AI_DEFAULT_REVEAL_CAP;\n }\n return Math.floor(value);\n};\n\n/**\n * @internal Builds the caret widget decoration at the given insertion tip.\n * The element is created lazily by the view (browser-only, so module scope\n * stays SSR-safe) and is `aria-hidden`: the caret is a purely visual pulse,\n * not content. `side: 1` keeps it after the text already revealed. The `key`\n * lets ProseMirror treat consecutive carets at one position as identical.\n */\nconst createCaretDecoration = (tip: number): Decoration =>\n Decoration.widget(\n tip,\n () => {\n const caret = document.createElement('span');\n caret.className = MLV_EDITOR_AI_CARET_CLASS;\n caret.setAttribute('aria-hidden', 'true');\n return caret;\n },\n {\n key: MLV_EDITOR_AI_CARET_SPEC,\n side: 1,\n ignoreSelection: true,\n [MLV_EDITOR_AI_CARET_SPEC]: true,\n },\n );\n\n/**\n * @internal One active session per editor. Starting a new session cancels the\n * previous one first, so the shared plugin key can never be registered twice.\n */\nconst activeSessions = new WeakMap<Editor, () => void>();\n\n/**\n * @internal Default frame scheduler: `requestAnimationFrame` where available,\n * otherwise a short timeout so streaming still progresses under server\n * rendering or a test DOM without a frame API. Feature-detected at call time —\n * module scope stays SSR-safe.\n */\nconst defaultScheduler: MlvEditorAiFrameScheduler = (flush) => {\n if (\n typeof requestAnimationFrame === 'function' &&\n typeof cancelAnimationFrame === 'function'\n ) {\n const handle = requestAnimationFrame(() => flush());\n return () => cancelAnimationFrame(handle);\n }\n const handle = setTimeout(flush, 16);\n return () => clearTimeout(handle);\n};\n\n/**\n * @internal Creates the per-session ProseMirror plugin holding the streaming\n * region and rendering it as an inline decoration. Decorations are view-layer\n * state, so the region reaches no HTML, Markdown, or JSON serialization —\n * the upload-placeholder precedent.\n *\n * The plugin also claims Escape while it is registered — which is exactly the\n * session's lifetime — so a keyboard user whose focus is in the content\n * region can cancel a running transform without reaching for the toolbar\n * stop button.\n *\n * @param onEscape Invoked when Escape is pressed inside the content region.\n */\nfunction createStreamPlugin(\n onEscape: () => void,\n): Plugin<MlvEditorAiStreamPluginState> {\n return new Plugin<MlvEditorAiStreamPluginState>({\n key: MLV_EDITOR_AI_STREAM_KEY,\n state: {\n init: () => MLV_EDITOR_AI_EMPTY_PLUGIN_STATE,\n apply: (transaction, value) => {\n const metadata = transaction.getMeta(MLV_EDITOR_AI_STREAM_KEY) as\n | MlvEditorAiStreamMetadata\n | undefined;\n if (metadata?.type === 'clear') return MLV_EDITOR_AI_EMPTY_PLUGIN_STATE;\n // Existing chunk decorations are only ever mapped — never rebuilt —\n // so their DOM survives later flushes and the one-shot entrance\n // animation cannot re-run over earlier text.\n let decorations = transaction.docChanged\n ? value.decorations.map(transaction.mapping, transaction.doc)\n : value.decorations;\n if (metadata?.type === 'set') {\n // The region tint (its range grew) and the caret (it moved to the\n // new tip) are replaced; the newly revealed slice gets its own\n // freshly created one-shot chunk decoration.\n decorations = decorations.remove(\n decorations.find(\n undefined,\n undefined,\n (spec: Record<string, unknown>) =>\n spec[MLV_EDITOR_AI_CARET_SPEC] === true ||\n spec[MLV_EDITOR_AI_REGION_SPEC] === true,\n ),\n );\n const added: Decoration[] = [];\n if (metadata.from < metadata.to) {\n added.push(\n Decoration.inline(\n metadata.from,\n metadata.to,\n { class: MLV_EDITOR_AI_STREAMING_CLASS },\n { [MLV_EDITOR_AI_REGION_SPEC]: true },\n ),\n );\n }\n if (metadata.chunkFrom < metadata.chunkTo) {\n added.push(\n Decoration.inline(metadata.chunkFrom, metadata.chunkTo, {\n class: MLV_EDITOR_AI_STREAMING_CHUNK_CLASS,\n }),\n );\n }\n added.push(createCaretDecoration(metadata.to));\n return {\n region: { from: metadata.from, to: metadata.to },\n decorations: decorations.add(transaction.doc, added),\n };\n }\n if (!value.region || !transaction.docChanged) {\n return decorations === value.decorations\n ? value\n : { region: value.region, decorations };\n }\n // Appended transactions from other plugins move the region too; the\n // session re-reads this mapped state after every dispatch.\n return {\n region: {\n from: transaction.mapping.map(value.region.from, -1),\n to: transaction.mapping.map(value.region.to, 1),\n },\n decorations,\n };\n },\n },\n props: {\n decorations: (state: EditorState) =>\n MLV_EDITOR_AI_STREAM_KEY.getState(state)?.decorations ?? null,\n handleKeyDown: (_view, event) => {\n if (event.key !== 'Escape') return false;\n onEscape();\n return true;\n },\n },\n });\n}\n\n/**\n * Runs one AI streaming session against a live Tiptap editor.\n *\n * Framework-free: the runner needs only the editor instance and an async\n * iterable of Markdown/text chunks — no Angular, no provider token, no\n * network. Interim writes render the chunks as plain text inside the target\n * region; the final commit parses the accumulated Markdown through the\n * editor's Markdown manager, so the committed document carries real\n * structure rather than literal Markdown syntax. An editor without a\n * Markdown manager commits plain text — the same fallback the Angular\n * context uses for request serialization. The `'review'` output mode is\n * collect-only: no interim write, no decoration, and no final commit ever\n * touches the document — a `'committed'` result just carries the complete\n * text for the caller to route through the suggestion engine. Every other\n * lifecycle rule below (Escape, cancellation, abandonment, transport and\n * result errors) applies to it unchanged.\n *\n * Lifecycle:\n *\n * - A checkpoint (document JSON) and the target coordinates are captured when\n * the session starts, before the first mutating step.\n * - Chunks are buffered and written at most once per animation frame, and\n * each flush reveals at most {@link MlvEditorAiStreamOptions.revealCharsPerFrame}\n * characters — the remainder carries over to self-scheduled follow-up\n * frames, smoothing bursty providers into a steady typing cadence. Every\n * interim write dispatches with `addToHistory: false`, so no partial state\n * ever becomes an undo step.\n * - Each flush's newly revealed slice carries a one-shot\n * {@link MLV_EDITOR_AI_STREAMING_CHUNK_CLASS} entrance decoration (created\n * once, then only mapped), and an `aria-hidden`\n * {@link MLV_EDITOR_AI_CARET_CLASS} widget marks the insertion tip while\n * the session writes. Both are view-layer decorations: removed when the\n * session settles and excluded from every serialization, exactly like the\n * region tint.\n * - On successful completion the session silently reverts to the checkpoint\n * and commits the complete content as exactly one history-visible step\n * (closed against the previous history group): one undo restores the\n * pre-session document.\n * - {@link MlvEditorAiStreamHandle.cancel} restores the checkpoint and\n * resolves with `'cancelled'` — silently, with no error code. Pressing\n * Escape inside the content region triggers the same cancellation through\n * the session plugin's key handler.\n * - A thrown or rejected chunk iteration restores the checkpoint and resolves\n * `'failed'` with `'ai-transport'`. Empty or whitespace-only total output\n * restores the checkpoint and resolves `'failed'` with `'ai-result'`.\n * - **Abandonment**: any external transaction — one whose root carries no\n * session metadata but changes the document (directly or through appended\n * transactions) — ends the session immediately following the drag-lifecycle\n * precedent. The session stops consuming and writing, removes its\n * decoration, and resolves `'abandoned'` with `error: null` and\n * `aborted: true`. **Nothing is restored**: inverting the checkpoint\n * through foreign steps is unsafe, so the document is left exactly as the\n * external edit made it, including any interim session writes (which were\n * history-invisible and therefore cannot be undone individually).\n * - Destroying the editor mid-session settles it as `'abandoned'` without\n * touching the DOM.\n *\n * The session never throws and {@link MlvEditorAiStreamHandle.done} never\n * rejects. Starting a new session on an editor cancels the session already\n * running there.\n *\n * @param editor Live Tiptap editor the session writes into.\n * @param options Chunk source, output mode, and optional frame scheduler.\n * @returns Handle exposing completion, cancellation, and checkpoint restore.\n */\nexport function runMlvEditorAiStream(\n editor: Editor,\n options: MlvEditorAiStreamOptions,\n): MlvEditorAiStreamHandle {\n const scheduler = options.scheduler ?? defaultScheduler;\n const output = options.output;\n const revealCap = normalizeRevealCap(options.revealCharsPerFrame);\n const iterator = options.chunks[Symbol.asyncIterator]();\n\n let resolveDone!: (result: MlvEditorAiStreamResult) => void;\n const done = new Promise<MlvEditorAiStreamResult>((resolve) => {\n resolveDone = resolve;\n });\n\n /** Resolves the consumption loop's race when the session settles early. */\n let notifyInterrupt: () => void = () => undefined;\n const interrupted = new Promise<'interrupted'>((resolve) => {\n notifyInterrupt = () => resolve('interrupted');\n });\n\n let settled = false;\n let hostDestroyed = false;\n let registered = false;\n let mutated = false;\n let accumulated = '';\n /** Characters of `accumulated` already written into the document. */\n let written = 0;\n /**\n * Characters the first (region-bootstrapping) flush wrote. Marks the exact\n * document point where prosemirror-history's deferred mapping pins the\n * `to` positions of earlier undo items (ReplaceStep maps `to` with assoc\n * -1, so later appends never move them past it); the precise revert must\n * split its steps at this point rather than replace across it.\n */\n let firstWritten = 0;\n let region: MlvEditorAiStreamRegion | null = null;\n let scheduled = false;\n let cancelScheduled: (() => void) | null = null;\n\n /** Politely closes the chunk producer; its cleanup must not break settlement. */\n const closeIterator = () => {\n try {\n const closing = iterator.return?.();\n if (closing) void Promise.resolve(closing).catch(() => undefined);\n } catch {\n // A producer throwing from return() has no bearing on the session result.\n }\n };\n\n if (editor.isDestroyed) {\n settled = true;\n closeIterator();\n resolveDone({ status: 'abandoned', error: null, aborted: true, text: '' });\n return {\n done,\n cancel: () => undefined,\n restoreCheckpoint: () => false,\n };\n }\n\n // One session per editor: the shared plugin key must never register twice,\n // and two writers over one region cannot both be correct.\n activeSessions.get(editor)?.();\n\n // Captured before the first mutating step. External document changes abandon\n // the session, and only session writes mutate otherwise, so these stay valid\n // until the session itself writes.\n const checkpoint: unknown = editor.state.doc.toJSON();\n const selectionFrom = editor.state.selection.from;\n const selectionTo = editor.state.selection.to;\n const $to = editor.state.selection.$to;\n /** Gap after the selection's top-level block, where `'insert-below'` writes. */\n const insertAt = $to.depth === 0 ? $to.pos : $to.after(1);\n\n /** @internal Parses the checkpoint back into a document node. */\n const checkpointDoc = (): ProseMirrorNode =>\n ProseMirrorNode.fromJSON(editor.schema, checkpoint);\n\n /**\n * @internal Tries to revert only the session-written region back to the\n * checkpoint content. Preferred over replacing the whole document because\n * a whole-document replace map collapses every position inside it, which\n * would corrupt the deferred mapping prosemirror-history applies to undo\n * items recorded before the session. Returns whether the built steps are\n * usable; the caller still verifies the result equals the checkpoint.\n */\n const buildPreciseRevert = (\n tr: Transaction,\n target: ProseMirrorNode,\n ): boolean => {\n if (!region) return false;\n try {\n if (output === 'replace-selection') {\n // Earlier undo items' `to` positions sit pinned at the end of the\n // first interim write (see `firstWritten`). Splitting the revert\n // there keeps every step boundary exactly on that point, so the\n // deferred mapping prosemirror-history applies to pre-session undo\n // items never crosses the interior of a replaced range — which would\n // silently corrupt those items.\n const firstEnd = Math.min(region.from + firstWritten, region.to);\n if (firstEnd < region.to) tr.delete(firstEnd, region.to);\n tr.replace(\n region.from,\n firstEnd,\n target.slice(selectionFrom, selectionTo),\n );\n } else {\n // The streamed paragraph wraps the region by exactly one position on\n // each side; deleting it removes everything the session inserted.\n tr.delete(\n Math.max(0, region.from - 1),\n Math.min(tr.doc.content.size, region.to + 1),\n );\n }\n return true;\n } catch {\n return false;\n }\n };\n\n /**\n * @internal Restores the checkpoint: precisely when the region-local revert\n * verifiably reproduces it, otherwise by replacing the whole document.\n * History-visible restores close the current history group so they undo on\n * their own; invisible restores also hide from history entirely.\n */\n const restoreDoc = (historyVisible: boolean) => {\n const target = checkpointDoc();\n let tr = editor.state.tr;\n if (!buildPreciseRevert(tr, target) || !tr.doc.eq(target)) {\n tr = editor.state.tr;\n tr.replaceWith(0, tr.doc.content.size, target.content);\n }\n tr.setSelection(\n TextSelection.near(\n tr.doc.resolve(Math.min(selectionFrom, tr.doc.content.size)),\n ),\n );\n tr.setMeta(MLV_EDITOR_AI_STREAM_KEY, MLV_EDITOR_AI_CLEAR_METADATA);\n if (historyVisible) closeHistory(tr);\n else tr.setMeta('addToHistory', false);\n editor.view.dispatch(tr);\n };\n\n /**\n * @internal Commits the streamed Markdown as parsed rich content through\n * the editor's Markdown manager, as one history-visible step against the\n * checkpoint document. A single plain paragraph replaces the selection\n * inline, so a one-line result never splits the surrounding block; every\n * other result lands as the block structure the Markdown describes.\n * Returns `false` — without dispatching a content change — when no manager\n * is registered, parsing fails or yields nothing, or the insertion is\n * refused; the caller then commits plain text instead.\n */\n const commitParsedMarkdown = (text: string): boolean => {\n const manager = editor.markdown;\n if (!manager) return false;\n let blocks: JSONContent[];\n try {\n const parsed = manager.parse(text);\n if (!Array.isArray(parsed.content) || parsed.content.length === 0) {\n return false;\n }\n blocks = parsed.content;\n } catch {\n return false;\n }\n const inline =\n output === 'replace-selection' &&\n blocks.length === 1 &&\n blocks[0].type === 'paragraph'\n ? (blocks[0].content ?? [])\n : null;\n const content = inline ?? blocks;\n if (content.length === 0) return false;\n try {\n return editor\n .chain()\n .command(({ tr }) => {\n tr.setMeta(MLV_EDITOR_AI_STREAM_KEY, MLV_EDITOR_AI_CLEAR_METADATA);\n closeHistory(tr);\n return true;\n })\n .insertContentAt(\n output === 'replace-selection'\n ? { from: selectionFrom, to: selectionTo }\n : insertAt,\n content,\n )\n .run();\n } catch {\n return false;\n }\n };\n\n /**\n * @internal Commits the complete streamed text as one history-visible step\n * against the checkpoint document. `closeHistory` prevents the step from\n * merging into a directly preceding user edit's undo group. Markdown\n * structure is committed through {@link commitParsedMarkdown}; the inline\n * path below is the plain-text fallback for editors without a Markdown\n * manager.\n */\n const commitFinal = (text: string) => {\n if (commitParsedMarkdown(text)) return;\n const tr = editor.state.tr;\n let end: number;\n if (output === 'replace-selection') {\n tr.insertText(text, selectionFrom, selectionTo);\n end = tr.mapping.map(selectionTo, 1);\n } else {\n const paragraph = editor.schema.nodes['paragraph'];\n if (paragraph) {\n tr.insert(insertAt, paragraph.create(null, editor.schema.text(text)));\n end = insertAt + 1 + text.length;\n } else {\n tr.insertText(text, insertAt, insertAt);\n end = tr.mapping.map(insertAt, 1);\n }\n }\n tr.setSelection(\n TextSelection.near(tr.doc.resolve(Math.min(end, tr.doc.content.size))),\n );\n tr.setMeta(MLV_EDITOR_AI_STREAM_KEY, MLV_EDITOR_AI_CLEAR_METADATA);\n closeHistory(tr);\n editor.view.dispatch(tr);\n };\n\n /**\n * @internal Settles the session exactly once: detaches every listener,\n * cancels pending frames, closes the producer, performs the requested\n * restore/commit, unregisters the plugin, and resolves `done`. Wrapped so a\n * failing dispatch can never surface as a thrown error — the session's\n * contract is that it never throws.\n */\n const settle = (\n status: MlvEditorAiStreamStatus,\n error: MlvEditorAiStreamErrorCode | null,\n behavior: { readonly restore: boolean; readonly commit: boolean },\n ) => {\n if (settled) return;\n settled = true;\n editor.off('transaction', onTransaction);\n editor.off('destroy', onDestroy);\n cancelScheduled?.();\n cancelScheduled = null;\n scheduled = false;\n closeIterator();\n try {\n if (!hostDestroyed && !editor.isDestroyed) {\n if (behavior.restore && mutated) restoreDoc(false);\n if (behavior.commit) commitFinal(accumulated);\n if (registered) editor.unregisterPlugin(MLV_EDITOR_AI_STREAM_KEY);\n }\n } catch {\n // Settlement must complete even when a final dispatch fails; the result\n // below still reports the session outcome.\n }\n if (activeSessions.get(editor) === cancel) activeSessions.delete(editor);\n notifyInterrupt();\n resolveDone({\n status,\n error,\n aborted: status === 'cancelled' || status === 'abandoned',\n text: accumulated,\n });\n };\n\n /**\n * @internal Abandons on any external document change: the root transaction\n * carries no session metadata and the document changed, either directly or\n * through transactions other plugins appended to that root. Session-rooted\n * events are skipped wholesale — reactions other plugins append to a\n * session write (for example a trailing paragraph) belong to the session.\n */\n const onTransaction = ({\n transaction,\n appendedTransactions,\n }: EditorEvents['transaction']) => {\n if (settled) return;\n if (transaction.getMeta(MLV_EDITOR_AI_STREAM_KEY) !== undefined) return;\n const docChanged =\n transaction.docChanged ||\n appendedTransactions.some((appended) => appended.docChanged);\n if (docChanged)\n settle('abandoned', null, { restore: false, commit: false });\n };\n\n /** @internal A destroyed editor leaves nothing to restore or unregister. */\n const onDestroy = () => {\n hostDestroyed = true;\n settle('abandoned', null, { restore: false, commit: false });\n };\n\n /**\n * @internal Writes the next paced slice of the accumulated text into the\n * target region. The first write bootstraps the region from the captured\n * target; later writes append at the region's end — appends only, so the\n * per-chunk entrance decorations over earlier text keep their positions and\n * DOM. Each flush reveals at most `revealCap` characters; a remaining\n * buffer schedules its own follow-up frame (carry-over), which is what\n * turns bursty chunks into a steady cadence. Region boundaries are mapped\n * through the transaction and then re-read from plugin state, so appended\n * transactions cannot desynchronize them.\n */\n const flush = () => {\n if (settled || hostDestroyed || editor.isDestroyed) return;\n const pending = accumulated.length - written;\n if (pending <= 0) return;\n const count = Math.min(pending, revealCap);\n const delta = accumulated.slice(written, written + count);\n try {\n const tr = editor.state.tr;\n let next: MlvEditorAiStreamRegion;\n let chunkFrom: number;\n if (region) {\n tr.insertText(delta, region.to, region.to);\n chunkFrom = tr.mapping.map(region.to, -1);\n next = {\n from: tr.mapping.map(region.from, -1),\n to: tr.mapping.map(region.to, 1),\n };\n } else if (output === 'replace-selection') {\n tr.insertText(delta, selectionFrom, selectionTo);\n next = {\n from: tr.mapping.map(selectionFrom, -1),\n to: tr.mapping.map(selectionTo, 1),\n };\n chunkFrom = next.from;\n } else {\n const paragraph = editor.schema.nodes['paragraph'];\n if (paragraph) {\n tr.insert(\n insertAt,\n paragraph.create(null, editor.schema.text(delta)),\n );\n next = { from: insertAt + 1, to: insertAt + 1 + delta.length };\n } else {\n tr.insertText(delta, insertAt, insertAt);\n next = {\n from: tr.mapping.map(insertAt, -1),\n to: tr.mapping.map(insertAt, 1),\n };\n }\n chunkFrom = next.from;\n }\n tr.setMeta('addToHistory', false);\n tr.setMeta(MLV_EDITOR_AI_STREAM_KEY, {\n type: 'set',\n from: next.from,\n to: next.to,\n chunkFrom,\n chunkTo: next.to,\n } satisfies MlvEditorAiStreamMetadata);\n editor.view.dispatch(tr);\n mutated = true;\n if (written === 0) firstWritten = count;\n written += count;\n region = MLV_EDITOR_AI_STREAM_KEY.getState(editor.state)?.region ?? next;\n // Carry-over: reveal the rest of the buffer on later frames.\n if (written < accumulated.length) scheduleFlush();\n } catch {\n // The target region rejected the write; the output is unusable here.\n settle('failed', 'ai-result', { restore: true, commit: false });\n }\n };\n\n /** @internal Schedules at most one flush per frame while chunks arrive. */\n const scheduleFlush = () => {\n if (settled || scheduled) return;\n scheduled = true;\n const cancelFrame = scheduler(() => {\n scheduled = false;\n cancelScheduled = null;\n flush();\n });\n // A synchronously invoked scheduler has already flushed by now.\n cancelScheduled = scheduled ? cancelFrame : null;\n };\n\n const cancel = () =>\n settle('cancelled', null, { restore: true, commit: false });\n\n const restoreCheckpoint = (): boolean => {\n if (hostDestroyed || editor.isDestroyed) return false;\n const changed = !editor.state.doc.eq(checkpointDoc());\n if (!settled) {\n cancel();\n return changed;\n }\n if (!changed) return false;\n try {\n restoreDoc(true);\n } catch {\n return false;\n }\n return true;\n };\n\n editor.registerPlugin(createStreamPlugin(() => cancel()));\n registered = true;\n editor.on('transaction', onTransaction);\n editor.on('destroy', onDestroy);\n activeSessions.set(editor, cancel);\n\n void (async () => {\n for (;;) {\n if (settled) return;\n const step = await Promise.race([\n interrupted,\n iterator.next().then(\n (result) => result,\n () => 'thrown' as const,\n ),\n ]);\n if (settled || step === 'interrupted') return;\n if (step === 'thrown') {\n settle('failed', 'ai-transport', { restore: true, commit: false });\n return;\n }\n if (step.done) {\n if (accumulated.trim().length === 0) {\n settle('failed', 'ai-result', { restore: true, commit: false });\n } else {\n // Collect-only review sessions never wrote, so there is nothing to\n // restore (`mutated` stayed false) and nothing to commit.\n settle('committed', null, {\n restore: true,\n commit: output !== 'review',\n });\n }\n return;\n }\n accumulated += step.value;\n // Review sessions only accumulate; a flush would write the document.\n if (output !== 'review') scheduleFlush();\n }\n })();\n\n return { done, cancel, restoreCheckpoint };\n}\n"]}
|