@lobehub/editor 4.29.0 → 4.29.2
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 +86 -0
- package/es/editor-kernel/index.d.ts +2 -2
- package/es/editor-kernel/index.js +2 -2
- package/es/headless/index.d.ts +5 -2
- package/es/headless/index.js +20 -22
- package/es/headless.d.ts +6 -507
- package/es/headless.js +906 -411
- package/es/i-node-identity-service-BBC_bg97.d.ts +522 -0
- package/es/index.d.ts +4 -2
- package/es/index.js +5 -2
- package/es/plugins/block/react/ReactBlockPlugin.js +0 -3
- package/es/plugins/common/data-source/json-data-source.js +33 -25
- package/es/plugins/common/data-source/text-data-source.js +6 -1
- package/es/plugins/common/index.d.ts +3 -1
- package/es/plugins/common/node/node-id.d.ts +7 -0
- package/es/plugins/common/node/node-id.js +484 -0
- package/es/plugins/common/node/node-identity-policy.d.ts +26 -0
- package/es/plugins/common/node/node-identity-policy.js +68 -0
- package/es/plugins/common/plugin/index.js +28 -2
- package/es/plugins/common/service/i-node-identity-service.d.ts +19 -0
- package/es/plugins/common/service/i-node-identity-service.js +4 -0
- package/es/plugins/common/service/node-identity-service.js +87 -0
- package/es/plugins/common/utils/index.js +3 -1
- package/es/plugins/list/plugin/index.js +7 -1
- package/es/plugins/litexml/command/index.d.ts +2 -2
- package/es/plugins/litexml/command/index.js +464 -292
- package/es/plugins/litexml/command/symbols.d.ts +18 -7
- package/es/plugins/litexml/command/symbols.js +2 -1
- package/es/plugins/litexml/data-source/litexml-data-source.js +35 -32
- package/es/plugins/litexml/diff-validation.js +68 -14
- package/es/plugins/litexml/index.d.ts +2 -2
- package/es/plugins/litexml/node/identity-policy.js +91 -0
- package/es/plugins/litexml/plugin/index.js +6 -0
- package/es/plugins/litexml/table-cell-diff.js +4 -0
- package/es/plugins/litexml/table-row-diff.js +4 -0
- package/es/plugins/litexml/utils/index.js +10 -23
- package/es/plugins/markdown/command/index.js +77 -4
- package/es/plugins/markdown/data-source/markdown-data-source.js +6 -1
- package/es/plugins/math/plugin/index.js +2 -2
- package/es/plugins/slash/service/i-slash-service.d.ts +2 -2
- package/es/plugins/yjs/plugin/index.js +5 -3
- package/es/plugins/yjs/plugin/utils/editor-state.js +8 -1
- package/es/plugins/yjs/plugin/utils/node-identity.js +106 -0
- package/es/plugins/yjs/service/index.js +38 -4
- package/es/{symbols-Do7jD4Tt.d.ts → symbols-Dyr9yyS0.d.ts} +18 -7
- package/package.json +4 -4
- package/scripts/postinstall-lexical-patch.cjs +0 -21
- package/patches/lexical@0.42.0.patch +0 -82
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { $getEditor, $isRootNode } from "lexical";
|
|
3
|
+
//#region src/plugins/common/node/node-identity-policy.ts
|
|
4
|
+
function subscribeNodeIdentityPolicy(editor, listener) {
|
|
5
|
+
const listeners = policyListeners.get(editor) || /* @__PURE__ */ new Set();
|
|
6
|
+
listeners.add(listener);
|
|
7
|
+
policyListeners.set(editor, listeners);
|
|
8
|
+
let active = true;
|
|
9
|
+
return () => {
|
|
10
|
+
if (!active) return;
|
|
11
|
+
active = false;
|
|
12
|
+
listeners.delete(listener);
|
|
13
|
+
if (listeners.size === 0 && policyListeners.get(editor) === listeners) policyListeners.delete(editor);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function getNodeIdentityPolicyRevision(editor) {
|
|
17
|
+
return policyRevisions.get(editor) || 0;
|
|
18
|
+
}
|
|
19
|
+
function bumpPolicyRevision(editor) {
|
|
20
|
+
policyRevisions.set(editor, getNodeIdentityPolicyRevision(editor) + 1);
|
|
21
|
+
const listeners = Array.from(policyListeners.get(editor) || []);
|
|
22
|
+
for (const listener of listeners) listener();
|
|
23
|
+
}
|
|
24
|
+
/** Register a document-format policy for one editor, with order-independent disposal. */
|
|
25
|
+
function registerNodeIdentityPolicy(editor, policy) {
|
|
26
|
+
const entry = { policy };
|
|
27
|
+
const registrations = editorPolicies.get(editor) || [];
|
|
28
|
+
registrations.push(entry);
|
|
29
|
+
editorPolicies.set(editor, registrations);
|
|
30
|
+
bumpPolicyRevision(editor);
|
|
31
|
+
return () => {
|
|
32
|
+
const current = editorPolicies.get(editor);
|
|
33
|
+
if (!current) return;
|
|
34
|
+
const index = current.indexOf(entry);
|
|
35
|
+
if (index >= 0) {
|
|
36
|
+
current.splice(index, 1);
|
|
37
|
+
bumpPolicyRevision(editor);
|
|
38
|
+
}
|
|
39
|
+
if (current.length === 0) editorPolicies.delete(editor);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Requires an editor-bound Lexical context. For an EditorState snapshot, pass
|
|
44
|
+
* `{ editor }` to `state.read` so its document policy is unambiguous.
|
|
45
|
+
*/
|
|
46
|
+
function $getNodeIdentityPolicy() {
|
|
47
|
+
let editor;
|
|
48
|
+
try {
|
|
49
|
+
editor = $getEditor();
|
|
50
|
+
} catch {
|
|
51
|
+
throw new Error("Node ID access requires editor.read/update or state.read(callback, { editor }).");
|
|
52
|
+
}
|
|
53
|
+
return editorPolicies.get(editor)?.at(-1)?.policy || defaultPolicy;
|
|
54
|
+
}
|
|
55
|
+
var defaultPolicy, editorPolicies, policyRevisions, policyListeners;
|
|
56
|
+
var init_node_identity_policy = __esmMin((() => {
|
|
57
|
+
defaultPolicy = {
|
|
58
|
+
canShareId: () => false,
|
|
59
|
+
isIdentityNode: (node) => !$isRootNode(node),
|
|
60
|
+
project: (node) => $isRootNode(node) ? "container" : "content"
|
|
61
|
+
};
|
|
62
|
+
editorPolicies = /* @__PURE__ */ new WeakMap();
|
|
63
|
+
policyRevisions = /* @__PURE__ */ new WeakMap();
|
|
64
|
+
policyListeners = /* @__PURE__ */ new WeakMap();
|
|
65
|
+
}));
|
|
66
|
+
//#endregion
|
|
67
|
+
init_node_identity_policy();
|
|
68
|
+
export { $getNodeIdentityPolicy, getNodeIdentityPolicyRevision, init_node_identity_policy, registerNodeIdentityPolicy, subscribeNodeIdentityPolicy };
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { INodeHelper, init_helper } from "../../../editor-kernel/inode/helper.js";
|
|
2
|
+
import { $clearNodeId, $normalizeNodeIds, init_node_id } from "../node/node-id.js";
|
|
2
3
|
import { $isCursorInQuote, $isCursorInTable, createBlockNode, init_utils, sampleReader } from "../utils/index.js";
|
|
3
4
|
import { KernelPlugin, init_plugin } from "../../../editor-kernel/plugin.js";
|
|
4
5
|
import { registerCommands } from "../command/index.js";
|
|
5
6
|
import { CursorNode, registerCursorNode } from "../node/cursor.js";
|
|
7
|
+
import { INodeIdentityService } from "../service/i-node-identity-service.js";
|
|
8
|
+
import { NodeIdentityService } from "../service/node-identity-service.js";
|
|
6
9
|
import { ILitexmlService } from "../../litexml/service/litexml-service.js";
|
|
7
10
|
import { isPunctuationChar } from "../../markdown/utils/index.js";
|
|
8
11
|
import { IMarkdownShortCutService } from "../../markdown/service/shortcut.js";
|
|
@@ -14,13 +17,14 @@ import { handleFilePaste, handlePlainTextPaste, handleVSCodePaste, runPasteHandl
|
|
|
14
17
|
import { registerProgressiveSelectAll } from "./progressive-select-all.js";
|
|
15
18
|
import { registerBlockBackspace, registerLastElement, registerRichKeydown } from "./register.js";
|
|
16
19
|
import { registerHistory } from "@lexical/history";
|
|
17
|
-
import { $createLineBreakNode, $createParagraphNode, $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_HIGH, INSERT_LINE_BREAK_COMMAND, INSERT_PARAGRAPH_COMMAND, PASTE_COMMAND, ParagraphNode, TEXT_TYPE_TO_FORMAT, TextNode } from "lexical";
|
|
20
|
+
import { $createLineBreakNode, $createParagraphNode, $getSelection, $isElementNode, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_HIGH, INSERT_LINE_BREAK_COMMAND, INSERT_PARAGRAPH_COMMAND, PASTE_COMMAND, ParagraphNode, RootNode, SELECTION_INSERT_CLIPBOARD_NODES_COMMAND, TEXT_TYPE_TO_FORMAT, TextNode } from "lexical";
|
|
18
21
|
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode, HeadingNode, QuoteNode, registerRichText } from "@lexical/rich-text";
|
|
19
22
|
import { CAN_USE_DOM } from "@lexical/utils";
|
|
20
23
|
import { registerDragonSupport } from "@lexical/dragon";
|
|
21
24
|
//#region src/plugins/common/plugin/index.ts
|
|
22
25
|
init_helper();
|
|
23
26
|
init_plugin();
|
|
27
|
+
init_node_id();
|
|
24
28
|
init_utils();
|
|
25
29
|
const CommonPlugin = class extends KernelPlugin {
|
|
26
30
|
static {
|
|
@@ -30,6 +34,7 @@ const CommonPlugin = class extends KernelPlugin {
|
|
|
30
34
|
super();
|
|
31
35
|
this.kernel = kernel;
|
|
32
36
|
this.config = config;
|
|
37
|
+
this.identityService = new NodeIdentityService();
|
|
33
38
|
this.formats = {
|
|
34
39
|
bold: true,
|
|
35
40
|
header: true,
|
|
@@ -39,6 +44,7 @@ const CommonPlugin = class extends KernelPlugin {
|
|
|
39
44
|
subscript: false,
|
|
40
45
|
superscript: false
|
|
41
46
|
};
|
|
47
|
+
kernel.registerService(INodeIdentityService, this.identityService);
|
|
42
48
|
const markdownOption = config.markdownOption ?? true;
|
|
43
49
|
if (typeof markdownOption === "object") {
|
|
44
50
|
this.formats.bold = markdownOption.bold ?? true;
|
|
@@ -179,6 +185,15 @@ const CommonPlugin = class extends KernelPlugin {
|
|
|
179
185
|
});
|
|
180
186
|
markdownService.registerMarkdownWriter("text", (ctx, node) => {
|
|
181
187
|
if (!$isTextNode(node)) return;
|
|
188
|
+
let parentNode = node.getParent();
|
|
189
|
+
let isInTableCell = false;
|
|
190
|
+
while (parentNode) {
|
|
191
|
+
if (parentNode.getType() === "tablecell" || parentNode.getType() === "table-cell-diff") {
|
|
192
|
+
isInTableCell = true;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
parentNode = parentNode.getParent();
|
|
196
|
+
}
|
|
182
197
|
const isBold = formats.bold && node.hasFormat("bold");
|
|
183
198
|
const isItalic = formats.italic && node.hasFormat("italic");
|
|
184
199
|
const isUnderline = node.hasFormat("underline");
|
|
@@ -197,7 +212,8 @@ const CommonPlugin = class extends KernelPlugin {
|
|
|
197
212
|
if (res) tailSpace = res[0];
|
|
198
213
|
const append = textContent.trimEnd();
|
|
199
214
|
const lastChar = append.at(-1);
|
|
200
|
-
|
|
215
|
+
const markdownText = isInTableCell ? append.replaceAll("\\", "\\\\").replaceAll("|", "\\|") : append;
|
|
216
|
+
ctx.appendLine(markdownText);
|
|
201
217
|
if (isSubscript) ctx.appendLine("~");
|
|
202
218
|
if (isSuperscript) ctx.appendLine("^");
|
|
203
219
|
if (isUnderline) ctx.appendLine("</ins>");
|
|
@@ -213,6 +229,16 @@ const CommonPlugin = class extends KernelPlugin {
|
|
|
213
229
|
registerMDReader(markdownService);
|
|
214
230
|
}
|
|
215
231
|
onInit(editor) {
|
|
232
|
+
this.register(this.identityService.bindEditor(editor));
|
|
233
|
+
this.register(editor.registerNodeTransform(RootNode, $normalizeNodeIds));
|
|
234
|
+
this.register(editor.registerCommand(SELECTION_INSERT_CLIPBOARD_NODES_COMMAND, ({ nodes }) => {
|
|
235
|
+
const clearCopiedIds = (node) => {
|
|
236
|
+
$clearNodeId(node);
|
|
237
|
+
if ($isElementNode(node)) node.getChildren().forEach(clearCopiedIds);
|
|
238
|
+
};
|
|
239
|
+
nodes.forEach(clearCopiedIds);
|
|
240
|
+
return false;
|
|
241
|
+
}, COMMAND_PRIORITY_CRITICAL));
|
|
216
242
|
this.register(this.kernel.registerHighCommand(PASTE_COMMAND, (event) => {
|
|
217
243
|
if (!(event instanceof ClipboardEvent)) return false;
|
|
218
244
|
const clipboardData = event.clipboardData;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IServiceID } from "../../../types/kernel.js";
|
|
2
|
+
import "../../../types/index.js";
|
|
3
|
+
//#region src/plugins/common/service/i-node-identity-service.d.ts
|
|
4
|
+
/** A detached, immutable description of the currently active logical node. */
|
|
5
|
+
interface NodeIdentitySnapshot {
|
|
6
|
+
readonly id: string;
|
|
7
|
+
/** Native Lexical text; a review container can include both pending sides. */
|
|
8
|
+
readonly textContent: string;
|
|
9
|
+
readonly type: string;
|
|
10
|
+
}
|
|
11
|
+
interface INodeIdentityService {
|
|
12
|
+
/** Read the last committed editor state without retaining a LexicalNode. */
|
|
13
|
+
getNodeById(nodeId: string): Readonly<NodeIdentitySnapshot> | null;
|
|
14
|
+
/** Subscribe to committed updates; query the service in the callback. */
|
|
15
|
+
subscribe(listener: () => void): () => void;
|
|
16
|
+
}
|
|
17
|
+
declare const INodeIdentityService: IServiceID<INodeIdentityService>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { INodeIdentityService, NodeIdentitySnapshot };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createDebugLogger, init_debug } from "../../../utils/debug.js";
|
|
2
|
+
import { getNodeIdentityPolicyRevision, init_node_identity_policy, subscribeNodeIdentityPolicy } from "../node/node-identity-policy.js";
|
|
3
|
+
import { $getActiveNodeIdKeys, $getNodeId, init_node_id } from "../node/node-id.js";
|
|
4
|
+
import { $getNodeByKey } from "lexical";
|
|
5
|
+
//#region src/plugins/common/service/node-identity-service.ts
|
|
6
|
+
init_node_id();
|
|
7
|
+
init_node_identity_policy();
|
|
8
|
+
init_debug();
|
|
9
|
+
const logger = createDebugLogger("service", "node-identity");
|
|
10
|
+
/** Implementation owned by CommonPlugin; external callers use INodeIdentityService. */
|
|
11
|
+
var NodeIdentityService = class {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.editor = null;
|
|
14
|
+
this.indexes = /* @__PURE__ */ new WeakMap();
|
|
15
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
16
|
+
this.bindingToken = null;
|
|
17
|
+
this.unregisterBinding = null;
|
|
18
|
+
}
|
|
19
|
+
bindEditor(editor) {
|
|
20
|
+
this.unregisterBinding?.();
|
|
21
|
+
const bindingToken = {};
|
|
22
|
+
this.bindingToken = bindingToken;
|
|
23
|
+
this.indexes = /* @__PURE__ */ new WeakMap();
|
|
24
|
+
this.editor = editor;
|
|
25
|
+
const unregisterUpdate = editor.registerUpdateListener(({ editorState, prevEditorState }) => {
|
|
26
|
+
if (editorState !== prevEditorState) this.notify();
|
|
27
|
+
});
|
|
28
|
+
const unregisterPolicy = subscribeNodeIdentityPolicy(editor, () => this.notify());
|
|
29
|
+
let active = true;
|
|
30
|
+
const unregister = () => {
|
|
31
|
+
if (!active) return;
|
|
32
|
+
active = false;
|
|
33
|
+
unregisterUpdate();
|
|
34
|
+
unregisterPolicy();
|
|
35
|
+
};
|
|
36
|
+
this.unregisterBinding = unregister;
|
|
37
|
+
return () => {
|
|
38
|
+
unregister();
|
|
39
|
+
if (this.bindingToken !== bindingToken) return;
|
|
40
|
+
this.bindingToken = null;
|
|
41
|
+
this.unregisterBinding = null;
|
|
42
|
+
this.editor = null;
|
|
43
|
+
this.indexes = /* @__PURE__ */ new WeakMap();
|
|
44
|
+
this.listeners.clear();
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
getNodeById(nodeId) {
|
|
48
|
+
if (typeof nodeId !== "string" || !nodeId.trim()) return null;
|
|
49
|
+
const editor = this.editor;
|
|
50
|
+
if (!editor) return null;
|
|
51
|
+
const editorState = editor.getEditorState();
|
|
52
|
+
const revision = getNodeIdentityPolicyRevision(editor);
|
|
53
|
+
let index = this.indexes.get(editorState);
|
|
54
|
+
if (!index || index.revision !== revision) {
|
|
55
|
+
index = {
|
|
56
|
+
keys: editorState.read(() => $getActiveNodeIdKeys(), { editor }),
|
|
57
|
+
revision
|
|
58
|
+
};
|
|
59
|
+
this.indexes.set(editorState, index);
|
|
60
|
+
}
|
|
61
|
+
const key = index.keys.get(nodeId);
|
|
62
|
+
if (!key) return null;
|
|
63
|
+
return editorState.read(() => {
|
|
64
|
+
const node = $getNodeByKey(key);
|
|
65
|
+
const id = node && $getNodeId(node);
|
|
66
|
+
return node && id === nodeId ? Object.freeze({
|
|
67
|
+
id,
|
|
68
|
+
textContent: node.getTextContent(),
|
|
69
|
+
type: node.getType()
|
|
70
|
+
}) : null;
|
|
71
|
+
}, { editor });
|
|
72
|
+
}
|
|
73
|
+
subscribe(listener) {
|
|
74
|
+
this.listeners.add(listener);
|
|
75
|
+
return () => this.listeners.delete(listener);
|
|
76
|
+
}
|
|
77
|
+
notify() {
|
|
78
|
+
const listeners = Array.from(this.listeners);
|
|
79
|
+
for (const listener of listeners) try {
|
|
80
|
+
listener();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
logger.error("Node identity subscriber failed:", error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
//#endregion
|
|
87
|
+
export { NodeIdentityService };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { INodeHelper, init_helper } from "../../../editor-kernel/inode/helper.js";
|
|
3
|
+
import { $getNodeId, init_node_id } from "../node/node-id.js";
|
|
3
4
|
import { $isTableCellNode, $isTableNode } from "@lexical/table";
|
|
4
5
|
import { $getRoot, $isDecoratorNode, $isElementNode, $isParagraphNode, $isRangeSelection, $isTextNode } from "lexical";
|
|
5
6
|
import { $isQuoteNode } from "@lexical/rich-text";
|
|
@@ -99,7 +100,7 @@ function $isCursorInQuote(selection) {
|
|
|
99
100
|
function exportNodeToJSON(node) {
|
|
100
101
|
const serializedNode = node.exportJSON();
|
|
101
102
|
const nodeClass = node.constructor;
|
|
102
|
-
serializedNode.id = node
|
|
103
|
+
serializedNode.id = $getNodeId(node);
|
|
103
104
|
if (serializedNode.type !== nodeClass.getType()) throw new Error(`LexicalNode: Node ${nodeClass.name} does not match the serialized type. Check if .exportJSON() is implemented and it is returning the correct type.`);
|
|
104
105
|
if ($isElementNode(node)) {
|
|
105
106
|
const serializedChildren = serializedNode.children;
|
|
@@ -115,6 +116,7 @@ function exportNodeToJSON(node) {
|
|
|
115
116
|
var sampleReader, createBlockNode;
|
|
116
117
|
var init_utils = __esmMin((() => {
|
|
117
118
|
init_helper();
|
|
119
|
+
init_node_id();
|
|
118
120
|
sampleReader = (format, xmlElement, children) => {
|
|
119
121
|
children.forEach((child) => {
|
|
120
122
|
if (INodeHelper.isTextNode(child)) child.format = (child.format || 0) | format;
|
|
@@ -62,7 +62,11 @@ const ListPlugin = class extends KernelPlugin {
|
|
|
62
62
|
return false;
|
|
63
63
|
});
|
|
64
64
|
litexmlService.registerXMLWriter(ListItemNode.getType(), (node, ctx) => {
|
|
65
|
-
if ($isListItemNode(node))
|
|
65
|
+
if ($isListItemNode(node)) {
|
|
66
|
+
const child = node.getFirstChild();
|
|
67
|
+
if (child?.getType() === "diff" && "diffType" in child && child.diffType === "listItemRemove") return { lines: [] };
|
|
68
|
+
return ctx.createXmlNode("li");
|
|
69
|
+
}
|
|
66
70
|
return false;
|
|
67
71
|
});
|
|
68
72
|
litexmlService.registerXMLReader("ol", (xmlNode, children) => {
|
|
@@ -136,6 +140,8 @@ const ListPlugin = class extends KernelPlugin {
|
|
|
136
140
|
markdownService.registerMarkdownWriter(ListItemNode.getType(), (ctx, node) => {
|
|
137
141
|
const parent = node.getParent();
|
|
138
142
|
if ($isListItemNode(node) && $isListNode(parent)) {
|
|
143
|
+
const child = node.getFirstChild();
|
|
144
|
+
if (child?.getType() === "diff" && "diffType" in child && child.diffType === "listItemRemove") return true;
|
|
139
145
|
if ($isListNode(node.getFirstChild())) return;
|
|
140
146
|
const level = getLevel(parent);
|
|
141
147
|
const prefix = " ".repeat(level);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import "../data-source/litexml-data-source.js";
|
|
2
|
-
import { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND } from "./symbols.js";
|
|
2
|
+
import { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_MODIFY_WITH_RESULTS_COMMAND, LITEXML_REMOVE_COMMAND, LiteXmlModifyOperation, LiteXmlOperationResult } from "./symbols.js";
|
|
3
3
|
import { LexicalEditor } from "lexical";
|
|
4
|
-
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND };
|
|
4
|
+
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_MODIFY_WITH_RESULTS_COMMAND, LITEXML_REMOVE_COMMAND, type LiteXmlModifyOperation, type LiteXmlOperationResult };
|