@lobehub/editor 1.5.2 → 1.5.4
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 +74 -23
- package/es/editor-kernel/kernel.d.ts +1 -0
- package/es/editor-kernel/kernel.js +57 -16
- package/es/editor-kernel/react/useDecorators.js +14 -4
- package/es/index.d.ts +1 -0
- package/es/index.js +11 -4
- package/es/plugins/common/node/cursor.js +5 -3
- package/es/plugins/file/command/index.js +3 -1
- package/es/plugins/file/plugin/index.js +3 -1
- package/es/plugins/image/command/index.js +3 -1
- package/es/plugins/image/plugin/index.js +1 -1
- package/es/plugins/markdown/service/shortcut.d.ts +1 -0
- package/es/plugins/markdown/service/shortcut.js +3 -1
- package/es/plugins/math/plugin/index.js +3 -1
- package/es/plugins/math/react/component/MathInline.js +3 -1
- package/es/plugins/math/react/index.js +1 -1
- package/es/plugins/mention/react/ReactMentionPlugin.js +1 -1
- package/es/plugins/slash/plugin/index.js +1 -1
- package/es/plugins/slash/service/i-slash-service.d.ts +1 -0
- package/es/plugins/slash/service/i-slash-service.js +4 -1
- package/es/plugins/upload/plugin/index.js +5 -3
- package/es/react/Editor/Editor.js +2 -1
- package/es/utils/debug.d.ts +429 -0
- package/es/utils/debug.js +348 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
A modern, extensible rich text editor built on Meta's Lexical framework with dual-architecture design, featuring both a powerful kernel and React integration. Optimized for AI applications and chat interfaces.
|
|
10
10
|
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
19
|
-
[
|
|
20
|
-
|
|
21
|
-
[Changelog](./CHANGELOG.md) · [Report Bug][github-issues-link] · [Request Feature][github-issues-link]
|
|
11
|
+
\[!\[]\[npm-release-shield]]\[npm-release-link]
|
|
12
|
+
\[!\[]\[github-releasedate-shield]]\[github-releasedate-link]
|
|
13
|
+
\[!\[]\[github-action-test-shield]]\[github-action-test-link]
|
|
14
|
+
\[!\[]\[github-action-release-shield]]\[github-action-release-link]<br/>
|
|
15
|
+
\[!\[]\[github-contributors-shield]]\[github-contributors-link]
|
|
16
|
+
\[!\[]\[github-forks-shield]]\[github-forks-link]
|
|
17
|
+
\[!\[]\[github-stars-shield]]\[github-stars-link]
|
|
18
|
+
\[!\[]\[github-issues-shield]]\[github-issues-link]
|
|
19
|
+
\[!\[]\[github-license-shield]]\[github-license-link]
|
|
20
|
+
|
|
21
|
+
[Changelog](./CHANGELOG.md) · \[Report Bug]\[github-issues-link] · \[Request Feature]\[github-issues-link]
|
|
22
22
|
|
|
23
23
|

|
|
24
24
|
|
|
@@ -47,12 +47,7 @@ A modern, extensible rich text editor built on Meta's Lexical framework with dua
|
|
|
47
47
|
- [🛠️ Development](#️-development)
|
|
48
48
|
- [Setup](#setup)
|
|
49
49
|
- [Available Scripts](#available-scripts)
|
|
50
|
-
- [
|
|
51
|
-
- [🤝 Contributing](#-contributing)
|
|
52
|
-
- [🔗 Links](#-links)
|
|
53
|
-
- [More Products](#more-products)
|
|
54
|
-
- [Design Resources](#design-resources)
|
|
55
|
-
- [Development Resources](#development-resources)
|
|
50
|
+
- [Debug Environment Variables](#debug-environment-variables)
|
|
56
51
|
|
|
57
52
|
####
|
|
58
53
|
|
|
@@ -75,7 +70,7 @@ A modern, extensible rich text editor built on Meta's Lexical framework with dua
|
|
|
75
70
|
|
|
76
71
|
To install `@lobehub/editor`, run the following command:
|
|
77
72
|
|
|
78
|
-
[
|
|
73
|
+
\[!\[]\[bun-shield]]\[bun-link]
|
|
79
74
|
|
|
80
75
|
```bash
|
|
81
76
|
$ bun add @lobehub/editor
|
|
@@ -87,7 +82,7 @@ $ pnpm add @lobehub/editor
|
|
|
87
82
|
|
|
88
83
|
<div align="right">
|
|
89
84
|
|
|
90
|
-
[
|
|
85
|
+
[!\[\]\[back-to-top\]](#readme-top)
|
|
91
86
|
|
|
92
87
|
</div>
|
|
93
88
|
|
|
@@ -236,7 +231,7 @@ editor.dispatchCommand(INSERT_HEADING_COMMAND, { tag: 'h2' });
|
|
|
236
231
|
|
|
237
232
|
<div align="right">
|
|
238
233
|
|
|
239
|
-
[
|
|
234
|
+
[!\[\]\[back-to-top\]](#readme-top)
|
|
240
235
|
|
|
241
236
|
</div>
|
|
242
237
|
|
|
@@ -395,7 +390,7 @@ CLEAR_FORMAT_COMMAND;
|
|
|
395
390
|
|
|
396
391
|
<div align="right">
|
|
397
392
|
|
|
398
|
-
[
|
|
393
|
+
[!\[\]\[back-to-top\]](#readme-top)
|
|
399
394
|
|
|
400
395
|
</div>
|
|
401
396
|
|
|
@@ -405,11 +400,11 @@ CLEAR_FORMAT_COMMAND;
|
|
|
405
400
|
|
|
406
401
|
You can use Github Codespaces for online development:
|
|
407
402
|
|
|
408
|
-
[
|
|
403
|
+
\[!\[]\[github-codespace-shield]]\[github-codespace-link]
|
|
409
404
|
|
|
410
405
|
Or clone it for local development:
|
|
411
406
|
|
|
412
|
-
[
|
|
407
|
+
\[!\[]\[bun-shield]]\[bun-link]
|
|
413
408
|
|
|
414
409
|
```bash
|
|
415
410
|
$ git clone https://github.com/lobehub/lobe-editor.git
|
|
@@ -434,6 +429,61 @@ This will start the Dumi documentation server with live playground at `http://lo
|
|
|
434
429
|
| `pnpm docs:build` | Build documentation for production |
|
|
435
430
|
| `pnpm release` | Publish new version with semantic-release |
|
|
436
431
|
|
|
432
|
+
### Debug Environment Variables
|
|
433
|
+
|
|
434
|
+
LobeHub Editor includes comprehensive debug logging that can be controlled via environment variables:
|
|
435
|
+
|
|
436
|
+
#### Basic Debug Configuration
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
# Enable all LobeHub Editor debug output
|
|
440
|
+
DEBUG=lobe-editor:*
|
|
441
|
+
|
|
442
|
+
# Enable only important logs (recommended for development)
|
|
443
|
+
DEBUG=lobe-editor:*:info,lobe-editor:*:warn,lobe-editor:*:error
|
|
444
|
+
|
|
445
|
+
# Enable specific components
|
|
446
|
+
DEBUG=lobe-editor:kernel,lobe-editor:plugin:*
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
#### Available Debug Categories
|
|
450
|
+
|
|
451
|
+
| Category | Description | Example |
|
|
452
|
+
| ------------------ | ------------------------- | ------------------------------------ |
|
|
453
|
+
| `kernel` | Core editor functionality | `DEBUG=lobe-editor:kernel` |
|
|
454
|
+
| `plugin:*` | All plugins | `DEBUG=lobe-editor:plugin:*` |
|
|
455
|
+
| `plugin:slash` | Slash commands | `DEBUG=lobe-editor:plugin:slash` |
|
|
456
|
+
| `plugin:mention` | Mention system | `DEBUG=lobe-editor:plugin:mention` |
|
|
457
|
+
| `plugin:image` | Image handling | `DEBUG=lobe-editor:plugin:image` |
|
|
458
|
+
| `plugin:file` | File operations | `DEBUG=lobe-editor:plugin:file` |
|
|
459
|
+
| `service:*` | All services | `DEBUG=lobe-editor:service:*` |
|
|
460
|
+
| `service:upload` | Upload service | `DEBUG=lobe-editor:service:upload` |
|
|
461
|
+
| `service:markdown` | Markdown processing | `DEBUG=lobe-editor:service:markdown` |
|
|
462
|
+
|
|
463
|
+
#### Debug Levels
|
|
464
|
+
|
|
465
|
+
| Level | Browser Display | Usage | Environment Variable |
|
|
466
|
+
| ------- | --------------------- | ------------------- | --------------------------- |
|
|
467
|
+
| `debug` | Console.log (gray) | Detailed tracing | `DEBUG=lobe-editor:*:debug` |
|
|
468
|
+
| `info` | Console.log (blue) | General information | `DEBUG=lobe-editor:*:info` |
|
|
469
|
+
| `warn` | Console.warn (yellow) | Warnings | `DEBUG=lobe-editor:*:warn` |
|
|
470
|
+
| `error` | Console.error (red) | Errors | `DEBUG=lobe-editor:*:error` |
|
|
471
|
+
|
|
472
|
+
#### Development Usage
|
|
473
|
+
|
|
474
|
+
````bash
|
|
475
|
+
# Full debug during development
|
|
476
|
+
DEBUG=lobe-editor:*
|
|
477
|
+
|
|
478
|
+
# Only critical logs
|
|
479
|
+
DEBUG=lobe-editor:*:error,lobe-editor:*:warn
|
|
480
|
+
# Plugin debugging
|
|
481
|
+
DEBUG=lobe-editor:plugin:*
|
|
482
|
+
# Service debugging
|
|
483
|
+
DEBUG=lobe-editor:service:*
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
|
|
437
487
|
### Project Architecture
|
|
438
488
|
|
|
439
489
|
```
|
|
@@ -635,3 +685,4 @@ This project is [MIT](./LICENSE) licensed.
|
|
|
635
685
|
[pr-welcome-link]: https://github.com/lobehub/lobe-editor/pulls
|
|
636
686
|
[pr-welcome-shield]: https://img.shields.io/badge/%F0%9F%A4%AF%20PR%20WELCOME-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge
|
|
637
687
|
[profile-link]: https://github.com/lobehub
|
|
688
|
+
````
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
1
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
2
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
3
|
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
5
4
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
5
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
6
6
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
7
7
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
8
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
@@ -24,6 +24,7 @@ import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, createEdit
|
|
|
24
24
|
import { get, merge, template, templateSettings } from 'lodash-es';
|
|
25
25
|
import defaultLocale from "../locale";
|
|
26
26
|
import { $isRootTextContentEmpty } from "../plugins/common/utils";
|
|
27
|
+
import { createDebugLogger } from "../utils/debug";
|
|
27
28
|
import { registerEvent } from "./event";
|
|
28
29
|
import { KernelPlugin } from "./plugin";
|
|
29
30
|
import { createEmptyEditorState } from "./utils";
|
|
@@ -45,12 +46,14 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
45
46
|
_defineProperty(_assertThisInitialized(_this), "serviceMap", new Map());
|
|
46
47
|
_defineProperty(_assertThisInitialized(_this), "localeMap", defaultLocale);
|
|
47
48
|
_defineProperty(_assertThisInitialized(_this), "hotReloadMode", false);
|
|
49
|
+
_defineProperty(_assertThisInitialized(_this), "logger", createDebugLogger('kernel'));
|
|
48
50
|
_defineProperty(_assertThisInitialized(_this), "editor", void 0);
|
|
49
51
|
_defineProperty(_assertThisInitialized(_this), "_commands", new Map());
|
|
50
52
|
_defineProperty(_assertThisInitialized(_this), "_commandsClean", new Map());
|
|
51
53
|
_this.dataTypeMap = new Map();
|
|
52
54
|
// Enable hot reload mode in development
|
|
53
55
|
_this.hotReloadMode = _this.detectDevelopmentMode();
|
|
56
|
+
_this.logger.info("\uD83D\uDE80 Kernel initialized (hot reload: ".concat(_this.hotReloadMode, ")"));
|
|
54
57
|
return _this;
|
|
55
58
|
}
|
|
56
59
|
_createClass(Kernel, [{
|
|
@@ -109,6 +112,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
109
112
|
key: "destroy",
|
|
110
113
|
value: function destroy() {
|
|
111
114
|
var _this$editor;
|
|
115
|
+
this.logger.info("\uD83D\uDDD1\uFE0F Destroying editor with ".concat(this.pluginsInstances.length, " plugins"));
|
|
112
116
|
(_this$editor = this.editor) === null || _this$editor === void 0 || _this$editor.setEditorState(createEmptyEditorState());
|
|
113
117
|
this.dataTypeMap.clear();
|
|
114
118
|
this.pluginsInstances.forEach(function (plugin) {
|
|
@@ -121,7 +125,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
121
125
|
this.serviceMap.clear();
|
|
122
126
|
// Clear decorators to prevent memory leaks
|
|
123
127
|
this.decorators = {};
|
|
124
|
-
|
|
128
|
+
this.logger.info('✅ Editor destroyed');
|
|
125
129
|
}
|
|
126
130
|
}, {
|
|
127
131
|
key: "getRootElement",
|
|
@@ -135,13 +139,14 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
135
139
|
var _this2 = this;
|
|
136
140
|
// Check if editor is already initialized to prevent re-initialization
|
|
137
141
|
if (this.editor) {
|
|
138
|
-
|
|
142
|
+
this.logger.warn('[Editor] Editor is already initialized, updating root element only');
|
|
139
143
|
this.editor.setRootElement(dom);
|
|
140
144
|
return this.editor;
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
// Initialize plugins if not already done
|
|
144
148
|
if (this.pluginsInstances.length === 0) {
|
|
149
|
+
this.logger.info("\uD83D\uDD0C Initializing ".concat(this.plugins.length, " plugins"));
|
|
145
150
|
var _iterator = _createForOfIteratorHelper(this.plugins),
|
|
146
151
|
_step;
|
|
147
152
|
try {
|
|
@@ -156,12 +161,14 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
156
161
|
_iterator.f();
|
|
157
162
|
}
|
|
158
163
|
}
|
|
164
|
+
this.logger.info("\uD83D\uDCDD Creating editor with ".concat(this.nodes.length, " nodes"));
|
|
159
165
|
var editor = this.editor = createEditor({
|
|
160
166
|
// @ts-expect-error Inject into lexical editor instance
|
|
161
167
|
__kernel: this,
|
|
162
168
|
namespace: 'lobehub',
|
|
163
169
|
nodes: this.nodes,
|
|
164
170
|
onError: function onError(error) {
|
|
171
|
+
_this2.logger.error('❌ Lexical editor error:', error);
|
|
165
172
|
_this2.emit('error', error);
|
|
166
173
|
},
|
|
167
174
|
theme: this.themes
|
|
@@ -172,6 +179,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
172
179
|
var _plugin$onInit;
|
|
173
180
|
(_plugin$onInit = plugin.onInit) === null || _plugin$onInit === void 0 || _plugin$onInit.call(plugin, editor);
|
|
174
181
|
});
|
|
182
|
+
this.logger.info("\u2705 Editor ready with ".concat(this.pluginsInstances.length, " plugins"));
|
|
175
183
|
this.emit('initialized', editor);
|
|
176
184
|
return this.editor;
|
|
177
185
|
}
|
|
@@ -180,12 +188,15 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
180
188
|
value: function setDocument(type, content) {
|
|
181
189
|
var datasource = this.dataTypeMap.get(type);
|
|
182
190
|
if (!datasource) {
|
|
191
|
+
this.logger.error("\u274C DataSource for type \"".concat(type, "\" not found"));
|
|
183
192
|
throw new Error("DataSource for type \"".concat(type, "\" is not registered."));
|
|
184
193
|
}
|
|
185
194
|
if (!this.editor) {
|
|
195
|
+
this.logger.error('❌ Editor not initialized');
|
|
186
196
|
throw new Error("Editor is not initialized.");
|
|
187
197
|
}
|
|
188
198
|
datasource.read(this.editor, content);
|
|
199
|
+
this.logger.debug("\uD83D\uDCE5 Set ".concat(type, " document"));
|
|
189
200
|
}
|
|
190
201
|
}, {
|
|
191
202
|
key: "focus",
|
|
@@ -204,12 +215,15 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
204
215
|
value: function getDocument(type) {
|
|
205
216
|
var datasource = this.dataTypeMap.get(type);
|
|
206
217
|
if (!datasource) {
|
|
218
|
+
this.logger.error("\u274C DataSource for type \"".concat(type, "\" not found"));
|
|
207
219
|
throw new Error("DataSource for type \"".concat(type, "\" is not registered."));
|
|
208
220
|
}
|
|
209
221
|
if (!this.editor) {
|
|
222
|
+
this.logger.error('❌ Editor not initialized');
|
|
210
223
|
throw new Error("Editor is not initialized.");
|
|
211
224
|
}
|
|
212
|
-
|
|
225
|
+
var result = datasource.write(this.editor);
|
|
226
|
+
return result;
|
|
213
227
|
}
|
|
214
228
|
}, {
|
|
215
229
|
key: "getSelectionDocument",
|
|
@@ -231,7 +245,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
231
245
|
if (this.decorators[name]) {
|
|
232
246
|
if (this.hotReloadMode) {
|
|
233
247
|
// In hot reload mode, allow decorator override with warning
|
|
234
|
-
|
|
248
|
+
this.logger.warn("\uD83D\uDD04 Hot reload: decorator \"".concat(name, "\""));
|
|
235
249
|
this.decorators[name] = decorator;
|
|
236
250
|
return this;
|
|
237
251
|
} else {
|
|
@@ -239,17 +253,17 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
239
253
|
var existingDecorator = this.decorators[name];
|
|
240
254
|
if (existingDecorator === decorator) {
|
|
241
255
|
// Same decorator function, no need to re-register
|
|
242
|
-
|
|
256
|
+
this.logger.warn("[Editor] Decorator \"".concat(name, "\" is already registered with the same function"));
|
|
243
257
|
return this;
|
|
244
258
|
}
|
|
245
259
|
|
|
246
260
|
// Different decorator function in production mode
|
|
247
|
-
|
|
261
|
+
this.logger.error("[Editor] Attempting to register duplicate decorator \"".concat(name, "\". Enable hot reload mode if this is intended."));
|
|
248
262
|
throw new Error("Decorator with name \"".concat(name, "\" is already registered."));
|
|
249
263
|
}
|
|
250
264
|
}
|
|
251
265
|
this.decorators[name] = decorator;
|
|
252
|
-
|
|
266
|
+
this.logger.debug("\uD83C\uDFAD Decorator: ".concat(name));
|
|
253
267
|
return this;
|
|
254
268
|
}
|
|
255
269
|
}, {
|
|
@@ -267,10 +281,10 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
267
281
|
value: function unregisterDecorator(name) {
|
|
268
282
|
if (this.decorators[name]) {
|
|
269
283
|
delete this.decorators[name];
|
|
270
|
-
|
|
284
|
+
this.logger.debug("\uD83D\uDDD1\uFE0F Removed decorator: ".concat(name));
|
|
271
285
|
return true;
|
|
272
286
|
}
|
|
273
|
-
|
|
287
|
+
this.logger.warn("\u26A0\uFE0F Decorator \"".concat(name, "\" not found"));
|
|
274
288
|
return false;
|
|
275
289
|
}
|
|
276
290
|
|
|
@@ -291,6 +305,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
291
305
|
key: "registerDataSource",
|
|
292
306
|
value: function registerDataSource(dataSource) {
|
|
293
307
|
this.dataTypeMap.set(dataSource.type, dataSource);
|
|
308
|
+
this.logger.debug("\uD83D\uDCC4 Data source: ".concat(dataSource.type));
|
|
294
309
|
}
|
|
295
310
|
}, {
|
|
296
311
|
key: "registerThemes",
|
|
@@ -307,7 +322,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
307
322
|
// Error if same name but different plugin
|
|
308
323
|
if (findPlugin !== plugin) {
|
|
309
324
|
if (this.hotReloadMode) {
|
|
310
|
-
|
|
325
|
+
this.logger.warn("\uD83D\uDD04 Hot reload: plugin \"".concat(plugin.pluginName, "\""));
|
|
311
326
|
// Remove old plugin
|
|
312
327
|
var index = this.plugins.findIndex(function (p) {
|
|
313
328
|
return p.pluginName === plugin.pluginName;
|
|
@@ -329,7 +344,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
329
344
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
330
345
|
var decoratorName = _step2.value;
|
|
331
346
|
this.unregisterDecorator(decoratorName);
|
|
332
|
-
|
|
347
|
+
this.logger.debug("\uD83E\uDDE8 Cleanup: decorator \"".concat(decoratorName, "\""));
|
|
333
348
|
}
|
|
334
349
|
} catch (err) {
|
|
335
350
|
_iterator2.e(err);
|
|
@@ -359,6 +374,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
359
374
|
plugin.__config = config || {};
|
|
360
375
|
// @ts-expect-error not error
|
|
361
376
|
this.plugins.push(plugin);
|
|
377
|
+
this.logger.debug("\uD83D\uDD0C Plugin: ".concat(plugin.pluginName));
|
|
362
378
|
return this;
|
|
363
379
|
}
|
|
364
380
|
}, {
|
|
@@ -380,13 +396,30 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
380
396
|
} finally {
|
|
381
397
|
_iterator3.f();
|
|
382
398
|
}
|
|
399
|
+
this.logger.debug("\uD83D\uDD0C Registered ".concat(plugins.length, " plugins"));
|
|
383
400
|
return this;
|
|
384
401
|
}
|
|
385
402
|
}, {
|
|
386
403
|
key: "registerNodes",
|
|
387
404
|
value: function registerNodes(nodes) {
|
|
388
405
|
var _this$nodes;
|
|
406
|
+
var nodeTypes = nodes.map(function (node) {
|
|
407
|
+
// Handle both node classes and node replacements
|
|
408
|
+
if (typeof node === 'function' && node.getType) {
|
|
409
|
+
return node.getType();
|
|
410
|
+
} else if (_typeof(node) === 'object' && node.replace && typeof node.replace === 'function' && node.replace.getType) {
|
|
411
|
+
return node.replace.getType();
|
|
412
|
+
}
|
|
413
|
+
return 'unknown';
|
|
414
|
+
}).filter(function (type) {
|
|
415
|
+
return type !== 'unknown';
|
|
416
|
+
});
|
|
389
417
|
(_this$nodes = this.nodes).push.apply(_this$nodes, _toConsumableArray(nodes));
|
|
418
|
+
if (nodeTypes.length > 3) {
|
|
419
|
+
this.logger.debug("\uD83E\uDDE9 Nodes: ".concat(nodeTypes.length, " types"));
|
|
420
|
+
} else {
|
|
421
|
+
this.logger.debug("\uD83E\uDDE9 Nodes: ".concat(nodeTypes.join(', ')));
|
|
422
|
+
}
|
|
390
423
|
}
|
|
391
424
|
}, {
|
|
392
425
|
key: "registerService",
|
|
@@ -395,7 +428,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
395
428
|
if (this.serviceMap.has(serviceIdString)) {
|
|
396
429
|
if (this.hotReloadMode) {
|
|
397
430
|
// In hot reload mode, allow service override with warning
|
|
398
|
-
|
|
431
|
+
this.logger.warn("\uD83D\uDD04 Hot reload: service \"".concat(serviceIdString, "\""));
|
|
399
432
|
this.serviceMap.set(serviceIdString, service);
|
|
400
433
|
return;
|
|
401
434
|
} else {
|
|
@@ -403,17 +436,17 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
403
436
|
var existingService = this.serviceMap.get(serviceIdString);
|
|
404
437
|
if (existingService === service) {
|
|
405
438
|
// Same service instance, no need to re-register
|
|
406
|
-
|
|
439
|
+
this.logger.warn("[Editor] Service \"".concat(serviceIdString, "\" is already registered with the same instance"));
|
|
407
440
|
return;
|
|
408
441
|
}
|
|
409
442
|
|
|
410
443
|
// Different service instance in production mode
|
|
411
|
-
|
|
444
|
+
this.logger.error("[Editor] Attempting to register duplicate service \"".concat(serviceIdString, "\". Enable hot reload mode if this is intended."));
|
|
412
445
|
throw new Error("Service with ID \"".concat(serviceIdString, "\" is already registered."));
|
|
413
446
|
}
|
|
414
447
|
}
|
|
415
448
|
this.serviceMap.set(serviceIdString, service);
|
|
416
|
-
|
|
449
|
+
this.logger.debug("\uD83D\uDD27 Service: ".concat(serviceIdString));
|
|
417
450
|
}
|
|
418
451
|
|
|
419
452
|
/**
|
|
@@ -425,6 +458,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
425
458
|
key: "registerServiceHotReload",
|
|
426
459
|
value: function registerServiceHotReload(serviceId, service) {
|
|
427
460
|
this.serviceMap.set(serviceId.__serviceId, service);
|
|
461
|
+
this.logger.debug("\uD83D\uDD04 Hot-reload service: ".concat(serviceId.__serviceId));
|
|
428
462
|
}
|
|
429
463
|
|
|
430
464
|
/**
|
|
@@ -480,7 +514,9 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
480
514
|
}, {
|
|
481
515
|
key: "registerLocale",
|
|
482
516
|
value: function registerLocale(locale) {
|
|
517
|
+
var localeKeys = Object.keys(locale);
|
|
483
518
|
this.localeMap = merge(this.localeMap, locale);
|
|
519
|
+
this.logger.debug("\uD83C\uDF10 Locale: ".concat(localeKeys.length, " keys"));
|
|
484
520
|
}
|
|
485
521
|
}, {
|
|
486
522
|
key: "t",
|
|
@@ -532,6 +568,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
532
568
|
}
|
|
533
569
|
var commandsMap = this._commands;
|
|
534
570
|
if (!commandsMap.has(command)) {
|
|
571
|
+
var _command$type;
|
|
535
572
|
commandsMap.set(command, [new Set(), new Set(), new Set(), new Set(), new Set()]);
|
|
536
573
|
this._commandsClean.set(command, lexicalEditor.registerCommand(command, function (payload) {
|
|
537
574
|
for (var i = 4; i >= 0; i--) {
|
|
@@ -556,6 +593,10 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
556
593
|
}
|
|
557
594
|
return false;
|
|
558
595
|
}, COMMAND_PRIORITY_CRITICAL));
|
|
596
|
+
// Only log non-keyboard commands to reduce noise
|
|
597
|
+
if (!((_command$type = command.type) !== null && _command$type !== void 0 && _command$type.includes('KEY'))) {
|
|
598
|
+
this.logger.debug("\u26A1 Command: ".concat(command.type || 'unknown'));
|
|
599
|
+
}
|
|
559
600
|
}
|
|
560
601
|
var listenersInPriorityOrder = commandsMap.get(command);
|
|
561
602
|
if (listenersInPriorityOrder === undefined) {
|
|
@@ -25,16 +25,26 @@ export function useDecorators(editor, ErrorBoundary) {
|
|
|
25
25
|
useLayoutEffectImpl(function () {
|
|
26
26
|
var clears = [];
|
|
27
27
|
var handleInit = function handleInit(editor) {
|
|
28
|
+
// Get initial decorators
|
|
29
|
+
var initialDecorators = editor.getDecorators();
|
|
30
|
+
setDecorators(initialDecorators);
|
|
28
31
|
clears.push(editor.registerDecoratorListener(function (nextDecorators) {
|
|
29
32
|
flushSync(function () {
|
|
30
33
|
setDecorators(nextDecorators);
|
|
31
34
|
});
|
|
32
35
|
}));
|
|
33
36
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
// Check if editor is already initialized
|
|
39
|
+
var lexicalEditor = editor.getLexicalEditor();
|
|
40
|
+
if (lexicalEditor) {
|
|
41
|
+
handleInit(lexicalEditor);
|
|
42
|
+
} else {
|
|
43
|
+
editor.on('initialized', handleInit);
|
|
44
|
+
clears.push(function () {
|
|
45
|
+
editor.off('initialized', handleInit);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
38
48
|
return function () {
|
|
39
49
|
clears.forEach(function (clear) {
|
|
40
50
|
return clear();
|
package/es/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './plugins/slash';
|
|
|
14
14
|
export * from './plugins/table';
|
|
15
15
|
export * from './plugins/upload';
|
|
16
16
|
export type { IEditor } from './types';
|
|
17
|
+
export { browserDebug, createDebugLogger, debugLogger, debugLoggers, devConsole, prodSafeLogger, } from './utils/debug';
|
|
17
18
|
export { Kernel } from './editor-kernel/kernel';
|
|
18
19
|
/**
|
|
19
20
|
* Enable hot reload mode globally for all editor instances
|
package/es/index.js
CHANGED
|
@@ -13,6 +13,9 @@ export * from "./plugins/mention";
|
|
|
13
13
|
export * from "./plugins/slash";
|
|
14
14
|
export * from "./plugins/table";
|
|
15
15
|
export * from "./plugins/upload";
|
|
16
|
+
// Debug utilities
|
|
17
|
+
export { browserDebug, createDebugLogger, debugLogger, debugLoggers, devConsole, prodSafeLogger } from "./utils/debug";
|
|
18
|
+
|
|
16
19
|
// Hot reload utilities
|
|
17
20
|
export { Kernel } from "./editor-kernel/kernel";
|
|
18
21
|
|
|
@@ -24,8 +27,10 @@ export function enableHotReload() {
|
|
|
24
27
|
if (typeof window !== 'undefined') {
|
|
25
28
|
var _require = require("./editor-kernel/kernel"),
|
|
26
29
|
Kernel = _require.Kernel;
|
|
30
|
+
var _require2 = require("./utils/debug"),
|
|
31
|
+
debugLoggers = _require2.debugLoggers;
|
|
27
32
|
Kernel.setGlobalHotReloadMode(true);
|
|
28
|
-
|
|
33
|
+
debugLoggers.kernel.info('[LobeHub Editor] Hot reload mode enabled globally');
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
36
|
|
|
@@ -34,9 +39,11 @@ export function enableHotReload() {
|
|
|
34
39
|
*/
|
|
35
40
|
export function disableHotReload() {
|
|
36
41
|
if (typeof window !== 'undefined') {
|
|
37
|
-
var
|
|
38
|
-
Kernel =
|
|
42
|
+
var _require3 = require("./editor-kernel/kernel"),
|
|
43
|
+
Kernel = _require3.Kernel;
|
|
44
|
+
var _require4 = require("./utils/debug"),
|
|
45
|
+
debugLoggers = _require4.debugLoggers;
|
|
39
46
|
Kernel.setGlobalHotReloadMode(false);
|
|
40
|
-
|
|
47
|
+
debugLoggers.kernel.info('[LobeHub Editor] Hot reload mode disabled globally');
|
|
41
48
|
}
|
|
42
49
|
}
|
|
@@ -20,6 +20,8 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
|
|
|
20
20
|
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
21
21
|
import { mergeRegister } from '@lexical/utils';
|
|
22
22
|
import { $createTextNode, $getNodeByKey, $getSelection, $isDecoratorNode, $isRangeSelection, $setSelection, COMMAND_PRIORITY_HIGH, DecoratorNode, ElementNode, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_BACKSPACE_COMMAND, TextNode } from 'lexical';
|
|
23
|
+
import { createDebugLogger } from "../../../utils/debug";
|
|
24
|
+
var logger = createDebugLogger('common', 'cursor');
|
|
23
25
|
export var CardLikeElementNode = /*#__PURE__*/function (_ElementNode) {
|
|
24
26
|
_inherits(CardLikeElementNode, _ElementNode);
|
|
25
27
|
var _super = _createSuper(CardLikeElementNode);
|
|
@@ -87,7 +89,7 @@ export function registerCursorNode(editor) {
|
|
|
87
89
|
key = _step2$value[0],
|
|
88
90
|
mutation = _step2$value[1];
|
|
89
91
|
var node = $getNodeByKey(key);
|
|
90
|
-
|
|
92
|
+
logger.debug('🎭 DecoratorNode mutated:', node === null || node === void 0 ? void 0 : node.getType(), mutation, node);
|
|
91
93
|
if (mutation === 'created' && node !== null && node !== void 0 && node.isInline() && node.getNextSibling() === null) {
|
|
92
94
|
needAddCursor.push(node);
|
|
93
95
|
}
|
|
@@ -237,7 +239,7 @@ export function registerCursorNode(editor) {
|
|
|
237
239
|
$setSelection(sel);
|
|
238
240
|
return true;
|
|
239
241
|
} catch (error) {
|
|
240
|
-
|
|
242
|
+
logger.error('❌ Cursor selection error:', error);
|
|
241
243
|
}
|
|
242
244
|
} else if ($isCursorNode(focusNode)) {
|
|
243
245
|
try {
|
|
@@ -255,7 +257,7 @@ export function registerCursorNode(editor) {
|
|
|
255
257
|
$setSelection(_sel);
|
|
256
258
|
return true;
|
|
257
259
|
} catch (error) {
|
|
258
|
-
|
|
260
|
+
logger.error('❌ Cursor navigation error:', error);
|
|
259
261
|
}
|
|
260
262
|
}
|
|
261
263
|
return false;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { $wrapNodeInElement } from '@lexical/utils';
|
|
2
2
|
import { $createParagraphNode, $insertNodes, $isRootOrShadowRoot, COMMAND_PRIORITY_HIGH, createCommand } from 'lexical';
|
|
3
|
+
import { createDebugLogger } from "../../../utils/debug";
|
|
3
4
|
import { $createFileNode } from "../node/FileNode";
|
|
5
|
+
var logger = createDebugLogger('plugin', 'file');
|
|
4
6
|
export var INSERT_FILE_COMMAND = createCommand('INSERT_FILE_COMMAND');
|
|
5
7
|
export function registerFileCommand(editor, handleUpload) {
|
|
6
8
|
return editor.registerCommand(INSERT_FILE_COMMAND, function (payload) {
|
|
@@ -16,7 +18,7 @@ export function registerFileCommand(editor, handleUpload) {
|
|
|
16
18
|
fileNode.setUploaded(url.url);
|
|
17
19
|
});
|
|
18
20
|
}).catch(function (error) {
|
|
19
|
-
|
|
21
|
+
logger.error('❌ File upload failed:', error);
|
|
20
22
|
editor.update(function () {
|
|
21
23
|
fileNode.setError('File upload failed : ' + error.message);
|
|
22
24
|
});
|
|
@@ -21,6 +21,7 @@ import { $createParagraphNode, $createRangeSelection, $insertNodes, $isRootOrSha
|
|
|
21
21
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
22
22
|
import { IMarkdownShortCutService } from "../../markdown";
|
|
23
23
|
import { IUploadService } from "../../upload";
|
|
24
|
+
import { createDebugLogger } from "../../../utils/debug";
|
|
24
25
|
import { registerFileCommand } from "../command";
|
|
25
26
|
import { $createFileNode, $isFileNode, FileNode } from "../node/FileNode";
|
|
26
27
|
import { registerFileNodeSelectionObserver } from "../utils";
|
|
@@ -36,6 +37,7 @@ export var FilePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
36
37
|
_classCallCheck(this, FilePlugin);
|
|
37
38
|
_this = _super.call(this);
|
|
38
39
|
// Register the file node
|
|
40
|
+
_defineProperty(_assertThisInitialized(_this), "logger", createDebugLogger('plugin', 'file'));
|
|
39
41
|
_this.kernel = kernel;
|
|
40
42
|
_this.config = config;
|
|
41
43
|
kernel.registerNodes([FileNode]);
|
|
@@ -91,7 +93,7 @@ export var FilePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
91
93
|
fileNode.setUploaded(url.url);
|
|
92
94
|
});
|
|
93
95
|
}).catch(function (error) {
|
|
94
|
-
|
|
96
|
+
_this2.logger.error('File upload failed:', error);
|
|
95
97
|
editor.update(function () {
|
|
96
98
|
fileNode.setError('File upload failed : ' + error.message);
|
|
97
99
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { $wrapNodeInElement } from '@lexical/utils';
|
|
2
2
|
import { $createParagraphNode, $createRangeSelection, $insertNodes, $isRootOrShadowRoot, $setSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
|
|
3
|
+
import { createDebugLogger } from "../../../utils/debug";
|
|
3
4
|
import { $createImageNode } from "../node/image-node";
|
|
5
|
+
var logger = createDebugLogger('plugin', 'image');
|
|
4
6
|
export var INSERT_IMAGE_COMMAND = createCommand('INSERT_IMAGE_COMMAND');
|
|
5
7
|
function isImageFile(file) {
|
|
6
8
|
return file.type.startsWith('image/');
|
|
@@ -34,7 +36,7 @@ export function registerImageCommand(editor, handleUpload) {
|
|
|
34
36
|
imageNode.setUploaded(res.url);
|
|
35
37
|
});
|
|
36
38
|
}).catch(function (error) {
|
|
37
|
-
|
|
39
|
+
logger.error('❌ Image upload failed:', error);
|
|
38
40
|
editor.update(function () {
|
|
39
41
|
imageNode.setError('Image upload failed : ' + error.message);
|
|
40
42
|
});
|
|
@@ -71,4 +71,4 @@ export var ImagePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
71
71
|
}
|
|
72
72
|
}]);
|
|
73
73
|
return ImagePlugin;
|
|
74
|
-
}(KernelPlugin), _defineProperty(_class, "pluginName", '
|
|
74
|
+
}(KernelPlugin), _defineProperty(_class, "pluginName", 'ImagePlugin'), _class);
|
|
@@ -90,6 +90,7 @@ export declare class MarkdownShortCutService implements IMarkdownShortCutService
|
|
|
90
90
|
private elementTransformers;
|
|
91
91
|
private textFormatTransformers;
|
|
92
92
|
private textMatchTransformers;
|
|
93
|
+
private logger;
|
|
93
94
|
private _markdownWriters;
|
|
94
95
|
constructor(kernel?: import("../../../types/kernel").IEditorKernel | undefined);
|
|
95
96
|
get markdownWriters(): Record<string, (ctx: IMarkdownWriterContext, node: LexicalNode) => boolean | void>;
|