@ckeditor/ckeditor5-watchdog 46.0.3 → 46.1.0-alpha.0
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/dist/index.js +645 -18
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/actionsrecorder.d.ts +259 -0
- package/src/actionsrecorder.js +627 -0
- package/src/actionsrecorderconfig.d.ts +204 -0
- package/src/actionsrecorderconfig.js +5 -0
- package/src/augmentation.d.ts +5 -0
- package/src/editorwatchdog.js +21 -14
- package/src/index.d.ts +2 -0
- package/src/index.js +1 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module watchdog/actionsrecorderconfig
|
|
7
|
+
*/
|
|
8
|
+
import type { ActionsRecorder } from './actionsrecorder.js';
|
|
9
|
+
/**
|
|
10
|
+
* The configuration of the ActionsRecorder plugin.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* ClassicEditor
|
|
14
|
+
* .create( editorElement, {
|
|
15
|
+
* actionsRecorder: ... // ActionsRecorder feature options.
|
|
16
|
+
* } )
|
|
17
|
+
* .then( ... )
|
|
18
|
+
* .catch( ... );
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}.
|
|
22
|
+
*/
|
|
23
|
+
export interface ActionsRecorderConfig {
|
|
24
|
+
/**
|
|
25
|
+
* The maximum number of action entries to keep in memory.
|
|
26
|
+
* When this limit is reached, older entries will be removed.
|
|
27
|
+
*
|
|
28
|
+
* This behavior can be modified by providing {@link #onMaxEntries `onMaxEntries`} callback.
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* ClassicEditor
|
|
32
|
+
* .create( editorElement, {
|
|
33
|
+
* plugins: [ ActionsRecorder, ... ],
|
|
34
|
+
* actionsRecorder: {
|
|
35
|
+
* maxEntries: 1000
|
|
36
|
+
* }
|
|
37
|
+
* } )
|
|
38
|
+
* .then( ... )
|
|
39
|
+
* .catch( ... );
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @default 1000
|
|
43
|
+
*/
|
|
44
|
+
maxEntries?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Filter function that determines whether a record should be added to the list.
|
|
47
|
+
* This is called before the action executes and before the entry is stored.
|
|
48
|
+
* It allows to reduce memory usage by filtering out unnecessary records.
|
|
49
|
+
*
|
|
50
|
+
* If this function returns `false`, the record will not be stored in the entries array.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* ClassicEditor
|
|
54
|
+
* .create( editorElement, {
|
|
55
|
+
* plugins: [ ActionsRecorder, ... ],
|
|
56
|
+
* actionsRecorder: {
|
|
57
|
+
* onFilter( entry, prevEntries ) {
|
|
58
|
+
* // Only record command executions.
|
|
59
|
+
* return entry.action.startsWith( 'commands.' );
|
|
60
|
+
* }
|
|
61
|
+
* }
|
|
62
|
+
* } )
|
|
63
|
+
* .then( ... )
|
|
64
|
+
* .catch( ... );
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
onFilter?: ActionsRecorderFilterCallback;
|
|
68
|
+
/**
|
|
69
|
+
* Callback function called on caught error.
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* ClassicEditor
|
|
73
|
+
* .create( editorElement, {
|
|
74
|
+
* plugins: [ ActionsRecorder, ... ],
|
|
75
|
+
* actionsRecorder: {
|
|
76
|
+
* onError( error, entries ) {
|
|
77
|
+
* console.error( 'ActionsRecorder - Error detected:', error );
|
|
78
|
+
* console.warn( 'Actions recorded before error:', entries );
|
|
79
|
+
*
|
|
80
|
+
* this.flushEntries();
|
|
81
|
+
* }
|
|
82
|
+
* }
|
|
83
|
+
* } )
|
|
84
|
+
* .then( ... )
|
|
85
|
+
* .catch( ... );
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
onError?: ActionsRecorderErrorCallback;
|
|
89
|
+
/**
|
|
90
|
+
* Callback function called when recorded entries count reaches {@link #maxEntries `maxEntries`}.
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* ClassicEditor
|
|
94
|
+
* .create( editorElement, {
|
|
95
|
+
* plugins: [ ActionsRecorder, ... ],
|
|
96
|
+
* actionsRecorder: {
|
|
97
|
+
* onMaxEntries() {
|
|
98
|
+
* const entries = this.getEntries();
|
|
99
|
+
*
|
|
100
|
+
* this.flushEntries();
|
|
101
|
+
*
|
|
102
|
+
* console.log( 'ActionsRecorder - Batch of entries:', entries );
|
|
103
|
+
* }
|
|
104
|
+
* }
|
|
105
|
+
* } )
|
|
106
|
+
* .then( ... )
|
|
107
|
+
* .catch( ... );
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* By default, when this callback is not provided, the list of entries is shifted so it does not include more than
|
|
111
|
+
* {@link #maxEntries `maxEntries`}.
|
|
112
|
+
*/
|
|
113
|
+
onMaxEntries?: ActionsRecorderMaxEntriesCallback;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Callback function type for the {@link ~ActionsRecorderConfig#onFilter `onFilter`} option.
|
|
117
|
+
* Called before the action executes to determine if it should be recorded.
|
|
118
|
+
*
|
|
119
|
+
* @param entry The action entry to be filtered.
|
|
120
|
+
* @param prevEntries The array of previous action entries.
|
|
121
|
+
*/
|
|
122
|
+
export type ActionsRecorderFilterCallback = (this: ActionsRecorder, entry: ActionsRecorderEntry, prevEntries: Array<ActionsRecorderEntry>) => boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Callback function type for the {@link ~ActionsRecorderConfig#onError `onError`} option.
|
|
125
|
+
*
|
|
126
|
+
* @param error The error that occurred.
|
|
127
|
+
* @param entries The log of actions before the error was encountered.
|
|
128
|
+
*/
|
|
129
|
+
export type ActionsRecorderErrorCallback = (this: ActionsRecorder, error: any, entries: Array<ActionsRecorderEntry>) => void;
|
|
130
|
+
/**
|
|
131
|
+
* Callback function type for the {@link ~ActionsRecorderConfig#onMaxEntries `onMaxEntries`} option.
|
|
132
|
+
*/
|
|
133
|
+
export type ActionsRecorderMaxEntriesCallback = (this: ActionsRecorder) => void;
|
|
134
|
+
/**
|
|
135
|
+
* Represents the state snapshot of the editor at a specific point in time.
|
|
136
|
+
*/
|
|
137
|
+
export interface ActionsRecorderEntryEditorSnapshot {
|
|
138
|
+
/**
|
|
139
|
+
* The document version. See {@link module:engine/model/document~ModelDocument#version}.
|
|
140
|
+
*/
|
|
141
|
+
documentVersion: number;
|
|
142
|
+
/**
|
|
143
|
+
* Whether the editor is in the read-only mode. See {@link module:core/editor/editor~Editor#isReadOnly}.
|
|
144
|
+
*/
|
|
145
|
+
editorReadOnly: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* True if document is focused. See {@link module:engine/view/document~ViewDocument#isFocused}.
|
|
148
|
+
*/
|
|
149
|
+
editorFocused: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* The current model selection. See {@link module:engine/model/document~ModelDocument#selection}.
|
|
152
|
+
*/
|
|
153
|
+
modelSelection: any;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Represents a recorded action entry with context and state information.
|
|
157
|
+
*/
|
|
158
|
+
export interface ActionsRecorderEntry {
|
|
159
|
+
/**
|
|
160
|
+
* Entry timestamp in ISO date time format.
|
|
161
|
+
*/
|
|
162
|
+
timeStamp: string;
|
|
163
|
+
/**
|
|
164
|
+
* For nested actions this is a reference to parent action (nesting of try-catch blocks).
|
|
165
|
+
*
|
|
166
|
+
* For example when user clicks a button in a toolbar it could generate such nested tree:
|
|
167
|
+
* * `component.bold:execute`
|
|
168
|
+
* * `commands.bold:execute`
|
|
169
|
+
* * `model.applyOperation`
|
|
170
|
+
*/
|
|
171
|
+
parentEntry?: ActionsRecorderEntry;
|
|
172
|
+
/**
|
|
173
|
+
* The name of the action.
|
|
174
|
+
*
|
|
175
|
+
* For example:
|
|
176
|
+
* * `component.bold:execute` Main action for toolbar button `bold` was executed.
|
|
177
|
+
* * `commands.bold:execute` The `bold` command was executed.
|
|
178
|
+
* * `model.applyOperation` The low-level operation was applied to the model.
|
|
179
|
+
* * `observers:paste` The `paste` DOM event was dispatched in the editing root.
|
|
180
|
+
* * `model.insertContent` The `model#insertContent()` was called.
|
|
181
|
+
* * `model-selection:change:range` The model selection range was changed.
|
|
182
|
+
*/
|
|
183
|
+
action: string;
|
|
184
|
+
/**
|
|
185
|
+
* The editor state before the action was executed.
|
|
186
|
+
*/
|
|
187
|
+
before: ActionsRecorderEntryEditorSnapshot;
|
|
188
|
+
/**
|
|
189
|
+
* The editor state after the action was executed.
|
|
190
|
+
*/
|
|
191
|
+
after?: ActionsRecorderEntryEditorSnapshot;
|
|
192
|
+
/**
|
|
193
|
+
* Params provided for the executed action. They depend on the actual action.
|
|
194
|
+
*/
|
|
195
|
+
params?: Array<any>;
|
|
196
|
+
/**
|
|
197
|
+
* The result returned by the executed action. It depends on the actual action.
|
|
198
|
+
*/
|
|
199
|
+
result?: any;
|
|
200
|
+
/**
|
|
201
|
+
* The error if the action throws one.
|
|
202
|
+
*/
|
|
203
|
+
error?: any;
|
|
204
|
+
}
|
package/src/augmentation.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
5
|
import type { EditorData } from './editorwatchdog.js';
|
|
6
|
+
import type { ActionsRecorderConfig } from './actionsrecorderconfig.js';
|
|
6
7
|
declare module '@ckeditor/ckeditor5-core' {
|
|
7
8
|
interface EditorConfig {
|
|
8
9
|
/**
|
|
@@ -11,5 +12,9 @@ declare module '@ckeditor/ckeditor5-core' {
|
|
|
11
12
|
* @internal
|
|
12
13
|
*/
|
|
13
14
|
_watchdogInitialData?: EditorData;
|
|
15
|
+
/**
|
|
16
|
+
* The configuration for the actions recorder plugin.
|
|
17
|
+
*/
|
|
18
|
+
actionsRecorder?: ActionsRecorderConfig;
|
|
14
19
|
}
|
|
15
20
|
}
|
package/src/editorwatchdog.js
CHANGED
|
@@ -440,24 +440,31 @@ class EditorWatchdogInitPlugin {
|
|
|
440
440
|
// `as any` to avoid linking from external private repo.
|
|
441
441
|
const parsedCommentThreads = JSON.parse(this._data.commentThreads);
|
|
442
442
|
const parsedSuggestions = JSON.parse(this._data.suggestions);
|
|
443
|
-
|
|
444
|
-
const channelId = this.editor.config.get('collaboration.channelId');
|
|
443
|
+
if (this.editor.plugins.has('CommentsRepository')) {
|
|
445
444
|
const commentsRepository = this.editor.plugins.get('CommentsRepository');
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
445
|
+
// First, remove the existing comments that were created by integration plugins during initialization.
|
|
446
|
+
// These comments may be outdated, and new instances will be created in the next step based on the saved data.
|
|
447
|
+
for (const commentThread of commentsRepository.getCommentThreads()) {
|
|
448
|
+
// Use the internal API since it removes the comment thread directly and does not trigger events
|
|
449
|
+
// that could cause side effects, such as removing markers.
|
|
450
|
+
commentsRepository._removeCommentThread({ threadId: commentThread.id });
|
|
449
451
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
452
|
+
parsedCommentThreads.forEach(commentThreadData => {
|
|
453
|
+
const channelId = this.editor.config.get('collaboration.channelId');
|
|
454
|
+
const commentsRepository = this.editor.plugins.get('CommentsRepository');
|
|
455
|
+
commentsRepository.addCommentThread({ channelId, ...commentThreadData });
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
if (this.editor.plugins.has('TrackChangesEditing')) {
|
|
453
459
|
const trackChangesEditing = this.editor.plugins.get('TrackChangesEditing');
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
460
|
+
// First, remove the existing suggestions that were created by integration plugins during initialization.
|
|
461
|
+
// These suggestions may be outdated, and new instances will be created in the next step based on the saved data.
|
|
462
|
+
for (const suggestion of trackChangesEditing.getSuggestions()) {
|
|
463
|
+
trackChangesEditing._removeSuggestion(suggestion);
|
|
457
464
|
}
|
|
458
|
-
|
|
465
|
+
parsedSuggestions.forEach(suggestionData => {
|
|
459
466
|
trackChangesEditing.addSuggestionData(suggestionData);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
462
469
|
}
|
|
463
470
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -8,5 +8,7 @@
|
|
|
8
8
|
export { ContextWatchdog, type ContextWatchdogRestartEvent, type ContextWatchdogItemErrorEvent, type ContextWatchdogItemErrorEventData, type ContextWatchdogItemRestartEvent, type ContextWatchdogItemRestartEventData, type ContextWatchdogItemConfiguration } from './contextwatchdog.js';
|
|
9
9
|
export { EditorWatchdog, type EditorWatchdogCreatorFunction, type EditorWatchdogRestartEvent } from './editorwatchdog.js';
|
|
10
10
|
export { Watchdog, type WatchdogConfig } from './watchdog.js';
|
|
11
|
+
export { ActionsRecorder } from './actionsrecorder.js';
|
|
12
|
+
export type { ActionsRecorderConfig, ActionsRecorderEntry, ActionsRecorderEntryEditorSnapshot, ActionsRecorderErrorCallback, ActionsRecorderFilterCallback, ActionsRecorderMaxEntriesCallback } from './actionsrecorderconfig.js';
|
|
11
13
|
export type { WatchdogEventMap, WatchdogEventArgs, WatchdogEventCallback, WatchdogErrorEvent, WatchdogErrorEventData, WatchdogStateChangeEvent, WatchdogState } from './watchdog.js';
|
|
12
14
|
import './augmentation.js';
|
package/src/index.js
CHANGED