@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.
Files changed (134) hide show
  1. package/README.md +5 -5
  2. package/fesm2022/malva-ui-editor-ai.mjs +17 -0
  3. package/fesm2022/malva-ui-editor-ai.mjs.map +1 -0
  4. package/fesm2022/malva-ui-editor.mjs +10227 -0
  5. package/fesm2022/malva-ui-editor.mjs.map +1 -0
  6. package/package.json +35 -26
  7. package/types/malva-ui-editor-ai.d.ts +1 -0
  8. package/types/malva-ui-editor.d.ts +2995 -0
  9. package/ai/index.d.ts +0 -12
  10. package/ai/malva-ui-editor-ai.d.ts +0 -5
  11. package/esm2022/ai/index.js +0 -12
  12. package/esm2022/ai/index.js.map +0 -1
  13. package/esm2022/ai/malva-ui-editor-ai.js +0 -5
  14. package/esm2022/ai/malva-ui-editor-ai.js.map +0 -1
  15. package/esm2022/index.js +0 -37
  16. package/esm2022/index.js.map +0 -1
  17. package/esm2022/lib/ai/editor-ai-actions.js +0 -69
  18. package/esm2022/lib/ai/editor-ai-actions.js.map +0 -1
  19. package/esm2022/lib/ai/editor-ai-context.js +0 -612
  20. package/esm2022/lib/ai/editor-ai-context.js.map +0 -1
  21. package/esm2022/lib/ai/editor-ai-menu.js +0 -288
  22. package/esm2022/lib/ai/editor-ai-menu.js.map +0 -1
  23. package/esm2022/lib/ai/editor-ai-review-bar.js +0 -223
  24. package/esm2022/lib/ai/editor-ai-review-bar.js.map +0 -1
  25. package/esm2022/lib/ai/editor-ai-stream.js +0 -677
  26. package/esm2022/lib/ai/editor-ai-stream.js.map +0 -1
  27. package/esm2022/lib/ai/editor-ai-suggestions.js +0 -751
  28. package/esm2022/lib/ai/editor-ai-suggestions.js.map +0 -1
  29. package/esm2022/lib/ai/editor-ai.tokens.js +0 -10
  30. package/esm2022/lib/ai/editor-ai.tokens.js.map +0 -1
  31. package/esm2022/lib/ai/editor-ai.types.js +0 -1
  32. package/esm2022/lib/ai/editor-ai.types.js.map +0 -1
  33. package/esm2022/lib/editor/editor.js +0 -985
  34. package/esm2022/lib/editor/editor.js.map +0 -1
  35. package/esm2022/lib/editor-extension-preflight.js +0 -83
  36. package/esm2022/lib/editor-extension-preflight.js.map +0 -1
  37. package/esm2022/lib/editor-serialization.js +0 -152
  38. package/esm2022/lib/editor-serialization.js.map +0 -1
  39. package/esm2022/lib/editor-toolbar-context.js +0 -259
  40. package/esm2022/lib/editor-toolbar-context.js.map +0 -1
  41. package/esm2022/lib/editor.tokens.js +0 -10
  42. package/esm2022/lib/editor.tokens.js.map +0 -1
  43. package/esm2022/lib/editor.types.js +0 -48
  44. package/esm2022/lib/editor.types.js.map +0 -1
  45. package/esm2022/lib/extensions/editor-block-handle.js +0 -760
  46. package/esm2022/lib/extensions/editor-block-handle.js.map +0 -1
  47. package/esm2022/lib/extensions/editor-extensions.js +0 -321
  48. package/esm2022/lib/extensions/editor-extensions.js.map +0 -1
  49. package/esm2022/lib/extensions/editor-markdown-compatibility.js +0 -162
  50. package/esm2022/lib/extensions/editor-markdown-compatibility.js.map +0 -1
  51. package/esm2022/lib/extensions/editor-upload-placeholder.js +0 -156
  52. package/esm2022/lib/extensions/editor-upload-placeholder.js.map +0 -1
  53. package/esm2022/lib/status/editor-status.js +0 -64
  54. package/esm2022/lib/status/editor-status.js.map +0 -1
  55. package/esm2022/lib/toolbar/editor-alignment.js +0 -203
  56. package/esm2022/lib/toolbar/editor-alignment.js.map +0 -1
  57. package/esm2022/lib/toolbar/editor-block-insert.js +0 -101
  58. package/esm2022/lib/toolbar/editor-block-insert.js.map +0 -1
  59. package/esm2022/lib/toolbar/editor-color-control.js +0 -71
  60. package/esm2022/lib/toolbar/editor-color-control.js.map +0 -1
  61. package/esm2022/lib/toolbar/editor-command-button.js +0 -115
  62. package/esm2022/lib/toolbar/editor-command-button.js.map +0 -1
  63. package/esm2022/lib/toolbar/editor-heading.js +0 -266
  64. package/esm2022/lib/toolbar/editor-heading.js.map +0 -1
  65. package/esm2022/lib/toolbar/editor-highlight.js +0 -84
  66. package/esm2022/lib/toolbar/editor-highlight.js.map +0 -1
  67. package/esm2022/lib/toolbar/editor-image-upload-dialog.js +0 -289
  68. package/esm2022/lib/toolbar/editor-image-upload-dialog.js.map +0 -1
  69. package/esm2022/lib/toolbar/editor-image-upload.js +0 -315
  70. package/esm2022/lib/toolbar/editor-image-upload.js.map +0 -1
  71. package/esm2022/lib/toolbar/editor-inline-marks.js +0 -124
  72. package/esm2022/lib/toolbar/editor-inline-marks.js.map +0 -1
  73. package/esm2022/lib/toolbar/editor-link.js +0 -265
  74. package/esm2022/lib/toolbar/editor-link.js.map +0 -1
  75. package/esm2022/lib/toolbar/editor-list.js +0 -249
  76. package/esm2022/lib/toolbar/editor-list.js.map +0 -1
  77. package/esm2022/lib/toolbar/editor-table.js +0 -292
  78. package/esm2022/lib/toolbar/editor-table.js.map +0 -1
  79. package/esm2022/lib/toolbar/editor-text-color.js +0 -82
  80. package/esm2022/lib/toolbar/editor-text-color.js.map +0 -1
  81. package/esm2022/lib/toolbar/editor-toolbar-widget.js +0 -41
  82. package/esm2022/lib/toolbar/editor-toolbar-widget.js.map +0 -1
  83. package/esm2022/lib/toolbar/editor-toolbar.defs.js +0 -60
  84. package/esm2022/lib/toolbar/editor-toolbar.defs.js.map +0 -1
  85. package/esm2022/lib/toolbar/editor-toolbar.js +0 -826
  86. package/esm2022/lib/toolbar/editor-toolbar.js.map +0 -1
  87. package/esm2022/lib/toolbar/editor-undo-redo.js +0 -72
  88. package/esm2022/lib/toolbar/editor-undo-redo.js.map +0 -1
  89. package/esm2022/lib/toolbar/editor-zoom.js +0 -330
  90. package/esm2022/lib/toolbar/editor-zoom.js.map +0 -1
  91. package/esm2022/lib/upload/editor-image-upload-coordinator.js +0 -480
  92. package/esm2022/lib/upload/editor-image-upload-coordinator.js.map +0 -1
  93. package/esm2022/malva-ui-editor.js +0 -5
  94. package/esm2022/malva-ui-editor.js.map +0 -1
  95. package/index.d.ts +0 -35
  96. package/lib/ai/editor-ai-actions.d.ts +0 -27
  97. package/lib/ai/editor-ai-context.d.ts +0 -307
  98. package/lib/ai/editor-ai-menu.d.ts +0 -142
  99. package/lib/ai/editor-ai-review-bar.d.ts +0 -116
  100. package/lib/ai/editor-ai-stream.d.ts +0 -207
  101. package/lib/ai/editor-ai-suggestions.d.ts +0 -219
  102. package/lib/ai/editor-ai.tokens.d.ts +0 -10
  103. package/lib/ai/editor-ai.types.d.ts +0 -176
  104. package/lib/editor/editor.d.ts +0 -243
  105. package/lib/editor-extension-preflight.d.ts +0 -23
  106. package/lib/editor-serialization.d.ts +0 -74
  107. package/lib/editor-toolbar-context.d.ts +0 -116
  108. package/lib/editor.tokens.d.ts +0 -6
  109. package/lib/editor.types.d.ts +0 -194
  110. package/lib/extensions/editor-block-handle.d.ts +0 -59
  111. package/lib/extensions/editor-extensions.d.ts +0 -165
  112. package/lib/extensions/editor-markdown-compatibility.d.ts +0 -11
  113. package/lib/extensions/editor-upload-placeholder.d.ts +0 -75
  114. package/lib/status/editor-status.d.ts +0 -24
  115. package/lib/toolbar/editor-alignment.d.ts +0 -61
  116. package/lib/toolbar/editor-block-insert.d.ts +0 -26
  117. package/lib/toolbar/editor-color-control.d.ts +0 -32
  118. package/lib/toolbar/editor-command-button.d.ts +0 -29
  119. package/lib/toolbar/editor-heading.d.ts +0 -68
  120. package/lib/toolbar/editor-highlight.d.ts +0 -21
  121. package/lib/toolbar/editor-image-upload-dialog.d.ts +0 -96
  122. package/lib/toolbar/editor-image-upload.d.ts +0 -71
  123. package/lib/toolbar/editor-inline-marks.d.ts +0 -30
  124. package/lib/toolbar/editor-link.d.ts +0 -78
  125. package/lib/toolbar/editor-list.d.ts +0 -67
  126. package/lib/toolbar/editor-table.d.ts +0 -133
  127. package/lib/toolbar/editor-text-color.d.ts +0 -21
  128. package/lib/toolbar/editor-toolbar-widget.d.ts +0 -19
  129. package/lib/toolbar/editor-toolbar.d.ts +0 -157
  130. package/lib/toolbar/editor-toolbar.defs.d.ts +0 -35
  131. package/lib/toolbar/editor-undo-redo.d.ts +0 -26
  132. package/lib/toolbar/editor-zoom.d.ts +0 -108
  133. package/lib/upload/editor-image-upload-coordinator.d.ts +0 -55
  134. package/malva-ui-editor.d.ts +0 -5
@@ -1,207 +0,0 @@
1
- import type { Editor } from '@tiptap/core';
2
- import type { MlvEditorErrorCode } from '../editor.types';
3
- import type { MlvEditorAiOutputMode } from './editor-ai.types';
4
- /**
5
- * CSS class of the inline decoration marking the active streaming region.
6
- *
7
- * The class is applied through a ProseMirror decoration held in plugin state,
8
- * never through document content, so it can appear in no HTML, Markdown, or
9
- * JSON serialization.
10
- */
11
- export declare const MLV_EDITOR_AI_STREAMING_CLASS = "mlv-editor__ai-streaming";
12
- /**
13
- * CSS class of the one-shot inline decoration over each flush's newly
14
- * revealed slice of the streaming region.
15
- *
16
- * Created exactly once per revealed delta and only mapped afterwards — never
17
- * rebuilt for old ranges — so a one-shot CSS entrance animation runs once per
18
- * chunk and earlier text never re-animates. Removed with the region
19
- * decoration on commit, cancel, and abandonment, and excluded from every
20
- * serialization the same way.
21
- */
22
- export declare const MLV_EDITOR_AI_STREAMING_CHUNK_CLASS = "mlv-editor__ai-streaming-chunk";
23
- /**
24
- * CSS class of the `aria-hidden` widget decoration the streaming engine
25
- * keeps at the current insertion tip while a writing session is active.
26
- *
27
- * View-layer only: it exists in no HTML, Markdown, or JSON serialization and
28
- * is removed when the session settles (commit, cancel, abandonment, failure).
29
- * Collect-only `'review'` sessions never render it — they never write.
30
- */
31
- export declare const MLV_EDITOR_AI_CARET_CLASS = "mlv-editor__ai-caret";
32
- /**
33
- * Output modes a streaming session supports.
34
- *
35
- * `'replace-selection'` and `'insert-below'` write into the document while
36
- * streaming. `'review'` is collect-only: the session runs the full lifecycle
37
- * — Escape cancellation, external-transaction abandonment, transport/result
38
- * error detection — but never writes; the caller routes the accumulated text
39
- * through the suggestion engine after commit.
40
- */
41
- export type MlvEditorAiStreamOutputMode = MlvEditorAiOutputMode;
42
- /**
43
- * Error categories a streaming session can report.
44
- *
45
- * `'ai-transport'` — the chunk iterable threw or rejected mid-stream.
46
- * `'ai-result'` — the completed stream produced no usable content (empty or
47
- * whitespace-only total output), or the target region rejected the write.
48
- * Both are narrowed from {@link MlvEditorErrorCode} so hosts can forward them
49
- * to `editorError` unchanged.
50
- */
51
- export type MlvEditorAiStreamErrorCode = Extract<MlvEditorErrorCode, 'ai-transport' | 'ai-result'>;
52
- /**
53
- * Terminal state of one streaming session.
54
- *
55
- * `'committed'` — the stream completed and the final content landed as exactly
56
- * one history-visible step. `'cancelled'` — {@link MlvEditorAiStreamHandle.cancel}
57
- * aborted the session and the checkpoint was restored silently. `'abandoned'`
58
- * — an external document change ended the session without any restore.
59
- * `'failed'` — the session ended with an {@link MlvEditorAiStreamErrorCode}
60
- * and the checkpoint was restored.
61
- */
62
- export type MlvEditorAiStreamStatus = 'committed' | 'cancelled' | 'abandoned' | 'failed';
63
- /**
64
- * Schedules one buffered-chunk flush for the next animation frame.
65
- *
66
- * Receives the flush callback and returns a cancel function. The default
67
- * implementation uses `requestAnimationFrame` and falls back to a short
68
- * `setTimeout` where no frame API exists (server rendering, test DOMs).
69
- * Tests inject a manual scheduler to control flush timing deterministically.
70
- */
71
- export type MlvEditorAiFrameScheduler = (flush: () => void) => () => void;
72
- /** Options accepted by {@link runMlvEditorAiStream}. */
73
- export interface MlvEditorAiStreamOptions {
74
- /**
75
- * Markdown/text chunks in document order, typically produced by an
76
- * `MlvEditorAiProvider`. A non-streaming source may yield a single chunk.
77
- */
78
- readonly chunks: AsyncIterable<string>;
79
- /**
80
- * Where the streamed content lands: `'replace-selection'` replaces the
81
- * selection captured when the session started, `'insert-below'` streams
82
- * into a new paragraph after the selection's top-level block, and
83
- * `'review'` collects the complete stream without touching the document —
84
- * the result is read from {@link MlvEditorAiStreamResult.text}.
85
- */
86
- readonly output: MlvEditorAiStreamOutputMode;
87
- /** Frame scheduler override; defaults to `requestAnimationFrame`. */
88
- readonly scheduler?: MlvEditorAiFrameScheduler;
89
- /**
90
- * Maximum characters one frame flush reveals into the document. Buffered
91
- * text beyond the cap carries over: the session keeps scheduling follow-up
92
- * frames until the buffer drains, so bursty provider chunks render at an
93
- * even typing cadence instead of appearing in per-chunk lumps. Defaults to
94
- * 4; `Infinity` restores the uncapped write-everything-per-frame behavior.
95
- * Non-finite values other than `Infinity` and values below 1 fall back to
96
- * the default; fractions are floored. The cap never delays settlement —
97
- * commit, cancellation, and abandonment still apply the complete
98
- * accumulated text immediately. Collect-only `'review'` sessions ignore it
99
- * entirely (they never flush).
100
- */
101
- readonly revealCharsPerFrame?: number;
102
- }
103
- /** Terminal result every streaming session resolves with; it never rejects. */
104
- export interface MlvEditorAiStreamResult {
105
- /** Terminal state of the session. */
106
- readonly status: MlvEditorAiStreamStatus;
107
- /** Error category for `'failed'` sessions, `null` for every other status. */
108
- readonly error: MlvEditorAiStreamErrorCode | null;
109
- /**
110
- * Whether the session was stopped before completing: `true` for
111
- * `'cancelled'` and `'abandoned'`, `false` for `'committed'` and
112
- * `'failed'`. Cancellation and abandonment are silent — neither carries an
113
- * error code.
114
- */
115
- readonly aborted: boolean;
116
- /** Complete text accumulated from the stream, including unwritten chunks. */
117
- readonly text: string;
118
- }
119
- /** Handle controlling one in-flight or finished streaming session. */
120
- export interface MlvEditorAiStreamHandle {
121
- /** Resolves with the terminal {@link MlvEditorAiStreamResult}; never rejects. */
122
- readonly done: Promise<MlvEditorAiStreamResult>;
123
- /**
124
- * Aborts an in-flight session: stops consuming chunks, restores the
125
- * checkpoint through a history-invisible step, and resolves {@link done}
126
- * with `'cancelled'` and no error. A no-op once the session has settled.
127
- */
128
- cancel(): void;
129
- /**
130
- * Restores the checkpoint captured when the session started.
131
- *
132
- * While the session is running this behaves exactly like {@link cancel}.
133
- * After the session has settled it replaces the whole document with the
134
- * checkpoint in one history-visible step — so a post-commit restore is
135
- * itself undoable. Returns whether the document changed; `false` when the
136
- * document already matches the checkpoint or the editor was destroyed.
137
- * After an `'abandoned'` session this overwrites the external edit too —
138
- * callers own that decision.
139
- */
140
- restoreCheckpoint(): boolean;
141
- }
142
- /**
143
- * Runs one AI streaming session against a live Tiptap editor.
144
- *
145
- * Framework-free: the runner needs only the editor instance and an async
146
- * iterable of Markdown/text chunks — no Angular, no provider token, no
147
- * network. Interim writes render the chunks as plain text inside the target
148
- * region; the final commit parses the accumulated Markdown through the
149
- * editor's Markdown manager, so the committed document carries real
150
- * structure rather than literal Markdown syntax. An editor without a
151
- * Markdown manager commits plain text — the same fallback the Angular
152
- * context uses for request serialization. The `'review'` output mode is
153
- * collect-only: no interim write, no decoration, and no final commit ever
154
- * touches the document — a `'committed'` result just carries the complete
155
- * text for the caller to route through the suggestion engine. Every other
156
- * lifecycle rule below (Escape, cancellation, abandonment, transport and
157
- * result errors) applies to it unchanged.
158
- *
159
- * Lifecycle:
160
- *
161
- * - A checkpoint (document JSON) and the target coordinates are captured when
162
- * the session starts, before the first mutating step.
163
- * - Chunks are buffered and written at most once per animation frame, and
164
- * each flush reveals at most {@link MlvEditorAiStreamOptions.revealCharsPerFrame}
165
- * characters — the remainder carries over to self-scheduled follow-up
166
- * frames, smoothing bursty providers into a steady typing cadence. Every
167
- * interim write dispatches with `addToHistory: false`, so no partial state
168
- * ever becomes an undo step.
169
- * - Each flush's newly revealed slice carries a one-shot
170
- * {@link MLV_EDITOR_AI_STREAMING_CHUNK_CLASS} entrance decoration (created
171
- * once, then only mapped), and an `aria-hidden`
172
- * {@link MLV_EDITOR_AI_CARET_CLASS} widget marks the insertion tip while
173
- * the session writes. Both are view-layer decorations: removed when the
174
- * session settles and excluded from every serialization, exactly like the
175
- * region tint.
176
- * - On successful completion the session silently reverts to the checkpoint
177
- * and commits the complete content as exactly one history-visible step
178
- * (closed against the previous history group): one undo restores the
179
- * pre-session document.
180
- * - {@link MlvEditorAiStreamHandle.cancel} restores the checkpoint and
181
- * resolves with `'cancelled'` — silently, with no error code. Pressing
182
- * Escape inside the content region triggers the same cancellation through
183
- * the session plugin's key handler.
184
- * - A thrown or rejected chunk iteration restores the checkpoint and resolves
185
- * `'failed'` with `'ai-transport'`. Empty or whitespace-only total output
186
- * restores the checkpoint and resolves `'failed'` with `'ai-result'`.
187
- * - **Abandonment**: any external transaction — one whose root carries no
188
- * session metadata but changes the document (directly or through appended
189
- * transactions) — ends the session immediately following the drag-lifecycle
190
- * precedent. The session stops consuming and writing, removes its
191
- * decoration, and resolves `'abandoned'` with `error: null` and
192
- * `aborted: true`. **Nothing is restored**: inverting the checkpoint
193
- * through foreign steps is unsafe, so the document is left exactly as the
194
- * external edit made it, including any interim session writes (which were
195
- * history-invisible and therefore cannot be undone individually).
196
- * - Destroying the editor mid-session settles it as `'abandoned'` without
197
- * touching the DOM.
198
- *
199
- * The session never throws and {@link MlvEditorAiStreamHandle.done} never
200
- * rejects. Starting a new session on an editor cancels the session already
201
- * running there.
202
- *
203
- * @param editor Live Tiptap editor the session writes into.
204
- * @param options Chunk source, output mode, and optional frame scheduler.
205
- * @returns Handle exposing completion, cancellation, and checkpoint restore.
206
- */
207
- export declare function runMlvEditorAiStream(editor: Editor, options: MlvEditorAiStreamOptions): MlvEditorAiStreamHandle;
@@ -1,219 +0,0 @@
1
- import type { Editor } from '@tiptap/core';
2
- /**
3
- * CSS class of the inline decoration highlighting text a pending suggestion
4
- * inserted into the document.
5
- *
6
- * The class is applied through a ProseMirror decoration held in plugin state,
7
- * never through document content, so it can appear in no HTML, Markdown, or
8
- * JSON serialization.
9
- */
10
- export declare const MLV_EDITOR_AI_SUGGESTION_INSERT_CLASS = "mlv-editor__ai-suggestion-insert";
11
- /**
12
- * CSS class of the widget decoration rendering text a pending suggestion
13
- * removed from the document.
14
- *
15
- * The removed text lives only inside the widget element — a strikethrough,
16
- * `aria-hidden` affordance — so it is absent from the document and from every
17
- * serialization the moment the suggestion is applied.
18
- */
19
- export declare const MLV_EDITOR_AI_SUGGESTION_DELETE_CLASS = "mlv-editor__ai-suggestion-delete";
20
- /**
21
- * CSS class added on top of the insert and delete decorations of the one
22
- * suggestion a review surface currently navigates
23
- * ({@link MlvEditorAiSuggestionsSession.setCurrent}).
24
- *
25
- * A decoration-only outline affordance: it never enters document content or
26
- * any serialization, and marking a suggestion current dispatches no document
27
- * step, so it can never create a history entry.
28
- */
29
- export declare const MLV_EDITOR_AI_SUGGESTION_CURRENT_CLASS = "mlv-editor__ai-suggestion-current";
30
- /**
31
- * Shape of one reviewable change.
32
- *
33
- * `'insert'` — new text was added; reject removes it. `'delete'` — text was
34
- * removed; reject restores it. `'replace'` — text was swapped; reject
35
- * restores the original.
36
- */
37
- export type MlvEditorAiSuggestionKind = 'insert' | 'delete' | 'replace';
38
- /** Document range a suggestion currently occupies. */
39
- export interface MlvEditorAiSuggestionRange {
40
- /** Start position of the suggestion's inserted content. */
41
- readonly from: number;
42
- /**
43
- * End position of the suggestion's inserted content. Equals {@link from}
44
- * for `'delete'` suggestions, whose removed text exists only in the widget
45
- * decoration anchored at this collapsed position.
46
- */
47
- readonly to: number;
48
- }
49
- /** One pending, reviewable AI change. */
50
- export interface MlvEditorAiSuggestion {
51
- /** Stable identifier, unique across sessions within this runtime. */
52
- readonly id: string;
53
- /** Shape of the change. */
54
- readonly kind: MlvEditorAiSuggestionKind;
55
- /**
56
- * Current document range of the inserted content, remapped through every
57
- * concurrent transaction. Collapsed for `'delete'` suggestions.
58
- */
59
- readonly range: MlvEditorAiSuggestionRange;
60
- /** Plain text the change removed; empty for `'insert'`. */
61
- readonly oldText: string;
62
- /** Plain text the change added; empty for `'delete'`. */
63
- readonly newText: string;
64
- }
65
- /** Options accepted by {@link applyMlvEditorAiSuggestions}. */
66
- export interface MlvEditorAiSuggestionsOptions {
67
- /** Start of the document region the replacement rewrites. */
68
- readonly from: number;
69
- /** End of the document region the replacement rewrites. */
70
- readonly to: number;
71
- /**
72
- * AI-produced replacement for the region, as Markdown. Parsed through the
73
- * editor's Markdown manager when one is registered; treated as plain text
74
- * otherwise — the same fallback the streaming engine uses for its commit.
75
- */
76
- readonly replacementMarkdown: string;
77
- }
78
- /**
79
- * Handle over one review session created by {@link applyMlvEditorAiSuggestions}.
80
- *
81
- * Undo semantics — a deliberate refinement of the spec sentence "each
82
- * accept/reject = one undo step": in the applied-edits storage model the
83
- * document already carries every change, so **accepting changes no document
84
- * content**. Accept operations (including {@link acceptAll}) are pure
85
- * plugin-state updates that drop decorations and entries without dispatching
86
- * a single step, and therefore create **no** history entry — an "accept undo
87
- * step" would necessarily be an empty one. Rejects mutate the document:
88
- * {@link reject} is exactly one history-visible step per call, and
89
- * {@link rejectAll} is exactly one step total.
90
- *
91
- * Every method returns `false` once the session has ended — all suggestions
92
- * resolved, the application undone, a newer session started, or the editor
93
- * destroyed.
94
- */
95
- export interface MlvEditorAiSuggestionsSession {
96
- /**
97
- * Current pending suggestions in document order, with ranges remapped
98
- * through every transaction dispatched since application. Empty once the
99
- * session has ended.
100
- */
101
- suggestions(): readonly MlvEditorAiSuggestion[];
102
- /**
103
- * Accepts one suggestion: the applied change stays in the document and its
104
- * decorations are dropped. A pure plugin-state update — no document step,
105
- * no history entry. Returns whether the suggestion existed.
106
- */
107
- accept(id: string): boolean;
108
- /**
109
- * Rejects one suggestion: the original content is restored over the
110
- * suggestion's current range in exactly one history-visible step, and the
111
- * suggestion's decorations are dropped. Returns whether the suggestion
112
- * existed and the restore succeeded.
113
- *
114
- * Restored is the reviewed region, not the editor's own schema-maintenance
115
- * reactions to the suggested state: for example, the default preset's
116
- * `trailingNode` paragraph appended while a structural suggestion was the
117
- * last block stays behind — the same residue an ordinary user edit leaves.
118
- */
119
- reject(id: string): boolean;
120
- /**
121
- * Accepts every pending suggestion in one plugin-state update. Like
122
- * {@link accept}, dispatches no document step and creates no history
123
- * entry. Returns whether any suggestion was pending.
124
- */
125
- acceptAll(): boolean;
126
- /**
127
- * Rejects every pending suggestion in exactly one history-visible step,
128
- * restoring the original content of the whole reviewed region. Returns
129
- * whether any suggestion was pending and the restore succeeded.
130
- */
131
- rejectAll(): boolean;
132
- /**
133
- * Marks one suggestion as the current one under review: its decorations
134
- * gain {@link MLV_EDITOR_AI_SUGGESTION_CURRENT_CLASS} and the previous
135
- * current suggestion loses it. `null` clears the marker. Like
136
- * {@link accept}, a pure plugin-state update — no document step, no
137
- * history entry. The marker clears itself when its suggestion resolves or
138
- * is dropped by a concurrent edit. Returns `false` once the session has
139
- * ended or for an unknown id.
140
- */
141
- setCurrent(id: string | null): boolean;
142
- }
143
- /** One contiguous change between two texts, produced by {@link mlvEditorAiWordDiff}. */
144
- export interface MlvEditorAiWordDiffRun {
145
- /** Shape of the change at this position. */
146
- readonly kind: MlvEditorAiSuggestionKind;
147
- /** Inclusive character offset in the old text where the run starts. */
148
- readonly oldFrom: number;
149
- /**
150
- * Exclusive character offset in the old text where the run ends. Equals
151
- * {@link oldFrom} for `'insert'` runs.
152
- */
153
- readonly oldTo: number;
154
- /** Old text covered by the run; empty for `'insert'`. */
155
- readonly oldText: string;
156
- /** New text the run introduces; empty for `'delete'`. */
157
- readonly newText: string;
158
- }
159
- /**
160
- * Token-level word diff between two plain texts, computed over a
161
- * longest-common-subsequence of tokens. Tokens are maximal whitespace or
162
- * non-whitespace runs, so whitespace changes are diffed like words.
163
- * Consecutive non-equal tokens merge into one run; a run that both removes
164
- * and adds text is a `'replace'`.
165
- *
166
- * Pure and framework-free. Returns an empty array for identical inputs.
167
- *
168
- * @param oldText Text currently in the document.
169
- * @param newText Replacement text.
170
- * @returns Change runs in ascending old-text offset order.
171
- */
172
- export declare function mlvEditorAiWordDiff(oldText: string, newText: string): readonly MlvEditorAiWordDiffRun[];
173
- /**
174
- * Applies an AI replacement for `[from, to]` as reviewable tracked changes —
175
- * the Phase 2 suggestion engine (storage option B of the design spec).
176
- *
177
- * Framework-free: only the editor instance and the replacement Markdown are
178
- * needed — no Angular, no provider token, no network.
179
- *
180
- * Diff granularity (pragmatic, documented rule): when the original region is
181
- * a single textblock of plain, unmarked text **and** the parsed replacement
182
- * is a single paragraph of plain text, the two are diffed token-by-token
183
- * (tokens are whitespace or word runs) over a longest common subsequence,
184
- * producing individual insert/delete/replace suggestions. Any structural or
185
- * formatted content on either side falls back to **one** whole-region
186
- * replace suggestion.
187
- *
188
- * Representation: inserted text enters the document immediately and is
189
- * highlighted by an inline decoration
190
- * ({@link MLV_EDITOR_AI_SUGGESTION_INSERT_CLASS}); deleted text is removed
191
- * from the document and re-rendered at its position by a strikethrough
192
- * `aria-hidden` widget decoration
193
- * ({@link MLV_EDITOR_AI_SUGGESTION_DELETE_CLASS}). Because both are
194
- * decorations, `getHTML`/`getMarkdown`/`getJSON` during review serialize the
195
- * document as-is — inserted text present, removed text absent — the spec's
196
- * accepted-by-default rule. Hosts gate saves on pending suggestions.
197
- *
198
- * The whole application is exactly **one** history-visible transaction:
199
- * one undo removes every suggested change at once — and, because the undo
200
- * intersects every suggestion range, it also drops the whole session.
201
- *
202
- * Concurrent edits: user transactions remap all suggestion ranges through
203
- * their step maps; an edit that intersects a suggestion's range drops that
204
- * one suggestion (decorations removed, the current document text stands,
205
- * nothing is restored). The session ends when every suggestion is resolved
206
- * or dropped, and editor destruction cleans up listeners and plugin state.
207
- * Starting a new session on an editor first ends the previous one, leaving
208
- * its remaining suggestions applied (accepted-by-default).
209
- *
210
- * Undo-step semantics of the returned session are documented on
211
- * {@link MlvEditorAiSuggestionsSession}.
212
- *
213
- * @param editor Live Tiptap editor the suggestions are applied to.
214
- * @param options Region to rewrite and the replacement Markdown.
215
- * @returns The review session, or `null` when nothing reviewable results —
216
- * destroyed editor, out-of-range positions, unusable replacement, or a
217
- * replacement identical to the region.
218
- */
219
- export declare function applyMlvEditorAiSuggestions(editor: Editor, options: MlvEditorAiSuggestionsOptions): MlvEditorAiSuggestionsSession | null;
@@ -1,10 +0,0 @@
1
- import { InjectionToken } from '@angular/core';
2
- import { type MlvEditorAiProvider } from './editor-ai.types';
3
- /**
4
- * Optional dependency-injection token for a host-provided AI transport.
5
- *
6
- * The per-editor `aiProvider` input wins over this token, mirroring
7
- * `MLV_EDITOR_IMAGE_UPLOADER` precedence. Without either, AI UI modules hide
8
- * and AI commands are unavailable.
9
- */
10
- export declare const MLV_EDITOR_AI_PROVIDER: InjectionToken<MlvEditorAiProvider>;
@@ -1,176 +0,0 @@
1
- import type { MlvEditorAiContext } from './editor-ai-context';
2
- import type { MlvEditorAiSuggestionKind } from './editor-ai-suggestions';
3
- /**
4
- * The transform kinds the library itself ships menu entries and i18n copy for.
5
- *
6
- * `'improve'`, `'fix-grammar'`, `'shorten'`, `'extend'`, and `'summarize'`
7
- * rewrite the selection without further arguments. `'tone'` and `'translate'`
8
- * carry their target tone or language in
9
- * {@link MlvEditorAiRequest.instruction}. `'custom'` carries a free-form host
10
- * or user prompt in the same field.
11
- */
12
- export type MlvEditorAiBuiltInTransformKind = 'improve' | 'fix-grammar' | 'shorten' | 'extend' | 'summarize' | 'tone' | 'translate' | 'custom';
13
- /**
14
- * Selection transform requested from an AI provider: one of the
15
- * {@link MlvEditorAiBuiltInTransformKind} values, or any host-authored string.
16
- *
17
- * The provider owns prompting, so a kind is a name the *provider* understands
18
- * and is fully opaque to the editor: nothing in the library branches on it,
19
- * and it is forwarded verbatim on {@link MlvEditorAiRequest.kind}. A host that
20
- * supplies its own {@link MlvEditorAiAction} list can therefore name kinds the
21
- * library has never heard of (`'legal-review'`, `'to-bullets'`, …) and answer
22
- * them in its own provider.
23
- *
24
- * The union with `string` deliberately keeps the built-in literals in
25
- * autocomplete — `(string & {})` is not reduced to `string` by the compiler,
26
- * so editors still suggest `'improve'` while any other string remains
27
- * assignable. The corollary for providers: `request.kind` is not exhaustively
28
- * checkable, so a `switch` over it needs a `default` branch that tolerates
29
- * kinds it does not know.
30
- */
31
- export type MlvEditorAiTransformKind = MlvEditorAiBuiltInTransformKind | (string & {});
32
- /**
33
- * One entry of the AI menu's action list.
34
- *
35
- * Hosts pass an array of these to `MlvEditorAiMenu.actions` to replace the
36
- * built-in list literally — see `mlvEditorAiDefaultActions()` to start from
37
- * the built-ins instead of retyping them.
38
- */
39
- export interface MlvEditorAiAction {
40
- /**
41
- * Transform kind forwarded verbatim to the provider through
42
- * {@link MlvEditorAiContext.runTransform}. Any string is valid; see
43
- * {@link MlvEditorAiTransformKind}. Ignored when {@link run} is present.
44
- *
45
- * Kinds are not required to be unique within one list: two entries may run
46
- * the same kind with different instructions.
47
- */
48
- readonly kind: MlvEditorAiTransformKind;
49
- /**
50
- * Display text of the menu item, already resolved. The menu renders it as
51
- * given and never translates it — a localized list is built by resolving
52
- * the copy before constructing the actions.
53
- */
54
- readonly label: string;
55
- /**
56
- * Free-form transform argument passed through as
57
- * {@link MlvEditorAiRequest.instruction}: a fixed tone for `'tone'`, a fixed
58
- * target language for `'translate'`, or a canned prompt for `'custom'`.
59
- * Omitted from the request when absent. Ignored when {@link run} is present.
60
- */
61
- readonly instruction?: string;
62
- /**
63
- * Where the result lands; defaults to `'replace-selection'`. Ignored when
64
- * {@link run} is present.
65
- */
66
- readonly output?: MlvEditorAiOutputMode;
67
- /**
68
- * Escape hatch replacing the menu's own behaviour for this entry.
69
- *
70
- * When present the menu calls this instead of `runTransform` and reads
71
- * neither {@link kind}, {@link instruction}, nor {@link output} — they stay
72
- * available to the callback itself, which owns the whole action. The
73
- * argument is the live per-editor {@link MlvEditorAiContext}, so the
74
- * callback can call `runTransform` with anything (including options this
75
- * shape cannot express), chain several calls, inspect `status()` /
76
- * `hasProvider()` / the review surface, or do something else entirely and
77
- * never touch the AI context at all.
78
- *
79
- * It runs only when the item is enabled, so the readonly, disabled, and
80
- * already-running guards still hold.
81
- *
82
- * @param context The AI context of the editor this menu belongs to.
83
- */
84
- readonly run?: (context: MlvEditorAiContext) => void;
85
- }
86
- /**
87
- * Where the streamed result of a transform lands in the document.
88
- *
89
- * `'replace-selection'` overwrites the selected fragment in place.
90
- * `'insert-below'` keeps the selection and streams the result into a new
91
- * block after it. `'review'` collects the complete result without touching
92
- * the document, then lands it as reviewable tracked suggestions the user
93
- * accepts or rejects through the context's suggestion surface.
94
- */
95
- export type MlvEditorAiOutputMode = 'replace-selection' | 'insert-below' | 'review';
96
- /**
97
- * One pending AI change as the Angular context exposes it to review UIs.
98
- *
99
- * A projection of the engine-level `MlvEditorAiSuggestion`: the live document
100
- * range stays internal to the context — positions remap on every transaction
101
- * and would be stale the moment a template read them. Review surfaces render
102
- * identity, shape, and the two texts; accept/reject go back through the
103
- * context by `id`.
104
- */
105
- export interface MlvEditorAiReviewSuggestion {
106
- /** Stable identifier, unique across sessions within this runtime. */
107
- readonly id: string;
108
- /**
109
- * Shape of the change: `'insert'` added text, `'delete'` removed text,
110
- * `'replace'` swapped text.
111
- */
112
- readonly kind: MlvEditorAiSuggestionKind;
113
- /** Plain text the change removed; empty for `'insert'`. */
114
- readonly oldText: string;
115
- /** Plain text the change added; empty for `'delete'`. */
116
- readonly newText: string;
117
- }
118
- /**
119
- * One structured request handed to an {@link MlvEditorAiProvider}.
120
- *
121
- * The editor never builds a prompt: the provider receives the transform kind,
122
- * the optional instruction, and Markdown context, and owns prompting, model
123
- * choice, and server-side policy itself.
124
- */
125
- export interface MlvEditorAiRequest {
126
- /**
127
- * Requested capability. Either a selection transform or `'autocomplete'`
128
- * for ghost-text completion at the caret.
129
- *
130
- * Not a closed union: a host-supplied action list can name any kind, so a
131
- * provider that branches on this field must tolerate kinds it does not
132
- * recognize rather than assume exhaustiveness.
133
- */
134
- readonly kind: MlvEditorAiTransformKind | 'autocomplete';
135
- /**
136
- * Free-form argument for the transform: the custom prompt for `'custom'`,
137
- * the target tone for `'tone'`, or the target language for `'translate'`.
138
- * Absent for transforms that need no argument.
139
- */
140
- readonly instruction?: string;
141
- /** Markdown context captured from the editor when the request started. */
142
- readonly context: {
143
- /** Selected fragment as Markdown, or `null` when nothing is selected. */
144
- readonly selection: string | null;
145
- /** Optional surrounding document window as Markdown, or `null`. */
146
- readonly document: string | null;
147
- };
148
- /**
149
- * Aborted when the user cancels, presses Escape, or edits the document
150
- * mid-stream. Providers should stop producing chunks once aborted.
151
- */
152
- readonly signal: AbortSignal;
153
- /** Host-defined passthrough metadata; the editor never reads it. */
154
- readonly meta?: Record<string, unknown>;
155
- }
156
- /**
157
- * Host-supplied transport for AI transforms.
158
- *
159
- * The library performs no network requests itself. Hosts provide an
160
- * implementation through the `aiProvider` input on `mlv-editor` or the
161
- * `MLV_EDITOR_AI_PROVIDER` injection token; the input wins, mirroring the
162
- * image-uploader precedence rule.
163
- */
164
- export interface MlvEditorAiProvider {
165
- /**
166
- * Streams the result of one request as plain Markdown/text chunks.
167
- *
168
- * Non-streaming transports may return a single-chunk iterable. A thrown
169
- * error or rejected iteration surfaces as a recoverable `'ai-transport'`
170
- * editor error; unusable output surfaces as `'ai-result'`.
171
- *
172
- * @param request Structured transform or autocomplete request.
173
- * @returns Async iterable of Markdown/text chunks in document order.
174
- */
175
- stream(request: MlvEditorAiRequest): AsyncIterable<string>;
176
- }